]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
[gdb/testsuite] Fix typo in gdb.multi/multi-arch-exec.exp
[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"
0d646226 60#include "demanguse.h"
19e6b90e 61#include "dwarf.h"
7d9813f1 62#include "ctf-api.h"
79bc120c 63#include "demangle.h"
252b5132
RH
64
65#include "elf/common.h"
66#include "elf/external.h"
67#include "elf/internal.h"
252b5132 68
4b78141a
NC
69
70/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
71 we can obtain the H8 reloc numbers. We need these for the
72 get_reloc_size() function. We include h8.h again after defining
73 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
74
75#include "elf/h8.h"
76#undef _ELF_H8_H
77
78/* Undo the effects of #including reloc-macros.h. */
79
80#undef START_RELOC_NUMBERS
81#undef RELOC_NUMBER
82#undef FAKE_RELOC
83#undef EMPTY_RELOC
84#undef END_RELOC_NUMBERS
85#undef _RELOC_MACROS_H
86
252b5132
RH
87/* The following headers use the elf/reloc-macros.h file to
88 automatically generate relocation recognition functions
89 such as elf_mips_reloc_type() */
90
91#define RELOC_MACROS_GEN_FUNC
92
a06ea964 93#include "elf/aarch64.h"
252b5132 94#include "elf/alpha.h"
3b16e843 95#include "elf/arc.h"
252b5132 96#include "elf/arm.h"
3b16e843 97#include "elf/avr.h"
1d65ded4 98#include "elf/bfin.h"
60bca95a 99#include "elf/cr16.h"
3b16e843 100#include "elf/cris.h"
1c0d3aa6 101#include "elf/crx.h"
b8891f8d 102#include "elf/csky.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
aca4efc7 106#include "elf/bpf.h"
cfb8c092 107#include "elf/epiphany.h"
252b5132 108#include "elf/fr30.h"
5c70f934 109#include "elf/frv.h"
3f8107ab 110#include "elf/ft32.h"
3b16e843
NC
111#include "elf/h8.h"
112#include "elf/hppa.h"
113#include "elf/i386.h"
f954747f
AM
114#include "elf/i370.h"
115#include "elf/i860.h"
116#include "elf/i960.h"
3b16e843 117#include "elf/ia64.h"
1e4cf259 118#include "elf/ip2k.h"
84e94c90 119#include "elf/lm32.h"
1c0d3aa6 120#include "elf/iq2000.h"
49f58d10 121#include "elf/m32c.h"
3b16e843
NC
122#include "elf/m32r.h"
123#include "elf/m68k.h"
75751cd9 124#include "elf/m68hc11.h"
7b4ae824 125#include "elf/s12z.h"
252b5132 126#include "elf/mcore.h"
15ab5209 127#include "elf/mep.h"
a3c62988 128#include "elf/metag.h"
7ba29e2a 129#include "elf/microblaze.h"
3b16e843 130#include "elf/mips.h"
3c3bdf30 131#include "elf/mmix.h"
3b16e843
NC
132#include "elf/mn10200.h"
133#include "elf/mn10300.h"
5506d11a 134#include "elf/moxie.h"
4970f871 135#include "elf/mt.h"
2469cfa2 136#include "elf/msp430.h"
35c08157 137#include "elf/nds32.h"
fe944acf 138#include "elf/nfp.h"
13761a11 139#include "elf/nios2.h"
73589c9d 140#include "elf/or1k.h"
7d466069 141#include "elf/pj.h"
3b16e843 142#include "elf/ppc.h"
c833c019 143#include "elf/ppc64.h"
2b100bb5 144#include "elf/pru.h"
03336641 145#include "elf/riscv.h"
99c513f6 146#include "elf/rl78.h"
c7927a3c 147#include "elf/rx.h"
a85d7ed0 148#include "elf/s390.h"
1c0d3aa6 149#include "elf/score.h"
3b16e843
NC
150#include "elf/sh.h"
151#include "elf/sparc.h"
e9f53129 152#include "elf/spu.h"
40b36596 153#include "elf/tic6x.h"
aa137e4d
NC
154#include "elf/tilegx.h"
155#include "elf/tilepro.h"
3b16e843 156#include "elf/v850.h"
179d3252 157#include "elf/vax.h"
619ed720 158#include "elf/visium.h"
f96bd6c2 159#include "elf/wasm32.h"
3b16e843 160#include "elf/x86-64.h"
c29aca4a 161#include "elf/xc16x.h"
f6c1a2d5 162#include "elf/xgate.h"
93fbbb04 163#include "elf/xstormy16.h"
88da6820 164#include "elf/xtensa.h"
6655dba2 165#include "elf/z80.h"
e9a0721f 166#include "elf/loongarch.h"
252b5132 167
252b5132 168#include "getopt.h"
566b0d53 169#include "libiberty.h"
09c11c86 170#include "safe-ctype.h"
2cf0635d 171#include "filenames.h"
252b5132 172
15b42fb0
AM
173#ifndef offsetof
174#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
175#endif
176
6a40cf0c
NC
177typedef struct elf_section_list
178{
dda8d76d
NC
179 Elf_Internal_Shdr * hdr;
180 struct elf_section_list * next;
6a40cf0c
NC
181} elf_section_list;
182
dda8d76d
NC
183/* Flag bits indicating particular types of dump. */
184#define HEX_DUMP (1 << 0) /* The -x command line switch. */
185#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
186#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
187#define STRING_DUMP (1 << 3) /* The -p command line switch. */
188#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 189#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
190
191typedef unsigned char dump_type;
192
193/* A linked list of the section names for which dumps were requested. */
194struct dump_list_entry
195{
196 char * name;
197 dump_type type;
198 struct dump_list_entry * next;
199};
200
6431e409
AM
201/* A dynamic array of flags indicating for which sections a dump
202 has been requested via command line switches. */
1b513401
NC
203struct dump_data
204{
6431e409
AM
205 dump_type * dump_sects;
206 unsigned int num_dump_sects;
207};
208
209static struct dump_data cmdline;
210
211static struct dump_list_entry * dump_sects_byname;
212
2cf0635d 213char * program_name = "readelf";
dda8d76d 214
015dc7e1
AM
215static bool show_name = false;
216static bool do_dynamic = false;
217static bool do_syms = false;
218static bool do_dyn_syms = false;
219static bool do_lto_syms = false;
220static bool do_reloc = false;
221static bool do_sections = false;
222static bool do_section_groups = false;
223static bool do_section_details = false;
224static bool do_segments = false;
225static bool do_unwind = false;
226static bool do_using_dynamic = false;
227static bool do_header = false;
228static bool do_dump = false;
229static bool do_version = false;
230static bool do_histogram = false;
231static bool do_debugging = false;
232static bool do_ctf = false;
233static bool do_arch = false;
234static bool do_notes = false;
235static bool do_archive_index = false;
236static bool check_all = false;
237static bool is_32bit_elf = false;
238static bool decompress_dumps = false;
239static bool do_not_show_symbol_truncation = false;
240static bool do_demangle = false; /* Pretty print C++ symbol names. */
241static bool process_links = false;
79bc120c 242static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 243static int sym_base = 0;
252b5132 244
7d9813f1
NA
245static char *dump_ctf_parent_name;
246static char *dump_ctf_symtab_name;
247static char *dump_ctf_strtab_name;
248
e4b17d5c
L
249struct group_list
250{
dda8d76d
NC
251 struct group_list * next;
252 unsigned int section_index;
e4b17d5c
L
253};
254
255struct group
256{
dda8d76d
NC
257 struct group_list * root;
258 unsigned int group_index;
e4b17d5c
L
259};
260
978c4450
AM
261typedef struct filedata
262{
263 const char * file_name;
015dc7e1 264 bool is_separate;
978c4450
AM
265 FILE * handle;
266 bfd_size_type file_size;
267 Elf_Internal_Ehdr file_header;
066f8fbe
AM
268 unsigned long archive_file_offset;
269 unsigned long archive_file_size;
270 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
271 Elf_Internal_Shdr * section_headers;
272 Elf_Internal_Phdr * program_headers;
273 char * string_table;
274 unsigned long string_table_length;
978c4450
AM
275 unsigned long dynamic_addr;
276 bfd_size_type dynamic_size;
277 size_t dynamic_nent;
278 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 279 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
280 char * dynamic_strings;
281 unsigned long dynamic_strings_length;
8ac10c5b 282 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
283 unsigned long num_dynamic_syms;
284 Elf_Internal_Sym * dynamic_symbols;
285 bfd_vma version_info[16];
286 unsigned int dynamic_syminfo_nent;
287 Elf_Internal_Syminfo * dynamic_syminfo;
288 unsigned long dynamic_syminfo_offset;
289 bfd_size_type nbuckets;
290 bfd_size_type nchains;
291 bfd_vma * buckets;
292 bfd_vma * chains;
293 bfd_size_type ngnubuckets;
294 bfd_size_type ngnuchains;
295 bfd_vma * gnubuckets;
296 bfd_vma * gnuchains;
297 bfd_vma * mipsxlat;
298 bfd_vma gnusymidx;
13acb58d 299 char * program_interpreter;
978c4450
AM
300 bfd_vma dynamic_info[DT_ENCODING];
301 bfd_vma dynamic_info_DT_GNU_HASH;
302 bfd_vma dynamic_info_DT_MIPS_XHASH;
303 elf_section_list * symtab_shndx_list;
304 size_t group_count;
305 struct group * section_groups;
306 struct group ** section_headers_groups;
307 /* A dynamic array of flags indicating for which sections a dump of
308 some kind has been requested. It is reset on a per-object file
309 basis and then initialised from the cmdline_dump_sects array,
310 the results of interpreting the -w switch, and the
311 dump_sects_byname list. */
312 struct dump_data dump;
313} Filedata;
aef1f6d0 314
c256ffe7 315/* How to print a vma value. */
843dd992
NC
316typedef enum print_mode
317{
318 HEX,
047c3dbf 319 HEX_5,
843dd992
NC
320 DEC,
321 DEC_5,
322 UNSIGNED,
047c3dbf 323 UNSIGNED_5,
843dd992 324 PREFIX_HEX,
047c3dbf 325 PREFIX_HEX_5,
843dd992 326 FULL_HEX,
047c3dbf
NL
327 LONG_HEX,
328 OCTAL,
329 OCTAL_5
843dd992
NC
330}
331print_mode;
332
b3aa80b4
NC
333typedef enum unicode_display_type
334{
335 unicode_default = 0,
336 unicode_locale,
337 unicode_escape,
338 unicode_hex,
339 unicode_highlight,
340 unicode_invalid
341} unicode_display_type;
342
343static unicode_display_type unicode_display = unicode_default;
344
a7fd1186
FS
345typedef enum
346{
347 reltype_unknown,
348 reltype_rel,
349 reltype_rela,
350 reltype_relr
351} relocation_type;
352
bb4d2ac2
L
353/* Versioned symbol info. */
354enum versioned_symbol_info
355{
356 symbol_undefined,
357 symbol_hidden,
358 symbol_public
359};
360
32ec8896 361static const char * get_symbol_version_string
015dc7e1 362 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 363 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 364
9c19a809
NC
365#define UNKNOWN -1
366
84714f86
AM
367static inline const char *
368section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
369{
370 return filedata->string_table + hdr->sh_name;
371}
b9e920ec 372
84714f86
AM
373static inline bool
374section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
375{
376 return (hdr != NULL
377 && filedata->string_table != NULL
378 && hdr->sh_name < filedata->string_table_length);
379}
b9e920ec 380
84714f86
AM
381static inline const char *
382section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
383{
384 if (hdr == NULL)
385 return _("<none>");
386 if (filedata->string_table == NULL)
387 return _("<no-strings>");
388 if (hdr->sh_name >= filedata->string_table_length)
389 return _("<corrupt>");
390 return section_name (filedata, hdr);
391}
252b5132 392
ee42cf8c 393#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 394
84714f86
AM
395static inline bool
396valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
397{
398 return strtab != NULL && offset < strtab_size;
399}
400
401static inline bool
402valid_dynamic_name (const Filedata *filedata, uint64_t offset)
403{
404 return valid_symbol_name (filedata->dynamic_strings,
405 filedata->dynamic_strings_length, offset);
406}
407
d79b3d50
NC
408/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
409 already been called and verified that the string exists. */
84714f86
AM
410static inline const char *
411get_dynamic_name (const Filedata *filedata, size_t offset)
412{
413 return filedata->dynamic_strings + offset;
414}
18bd398b 415
61865e30
NC
416#define REMOVE_ARCH_BITS(ADDR) \
417 do \
418 { \
dda8d76d 419 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
420 (ADDR) &= ~1; \
421 } \
422 while (0)
f16a9783
MS
423
424/* Get the correct GNU hash section name. */
978c4450
AM
425#define GNU_HASH_SECTION_NAME(filedata) \
426 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 427\f
66cfc0fd
AM
428/* Print a BFD_VMA to an internal buffer, for use in error messages.
429 BFD_FMA_FMT can't be used in translated strings. */
430
431static const char *
432bfd_vmatoa (char *fmtch, bfd_vma value)
433{
434 /* bfd_vmatoa is used more then once in a printf call for output.
435 Cycle through an array of buffers. */
436 static int buf_pos = 0;
437 static struct bfd_vmatoa_buf
438 {
439 char place[64];
440 } buf[4];
441 char *ret;
442 char fmt[32];
443
444 ret = buf[buf_pos++].place;
445 buf_pos %= ARRAY_SIZE (buf);
446
447 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
448 snprintf (ret, sizeof (buf[0].place), fmt, value);
449 return ret;
450}
451
dda8d76d
NC
452/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
453 OFFSET + the offset of the current archive member, if we are examining an
454 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
455 allocate a buffer using malloc and fill that. In either case return the
456 pointer to the start of the retrieved data or NULL if something went wrong.
457 If something does go wrong and REASON is not NULL then emit an error
458 message using REASON as part of the context. */
59245841 459
c256ffe7 460static void *
dda8d76d
NC
461get_data (void * var,
462 Filedata * filedata,
463 unsigned long offset,
464 bfd_size_type size,
465 bfd_size_type nmemb,
466 const char * reason)
a6e9f9df 467{
2cf0635d 468 void * mvar;
57028622 469 bfd_size_type amt = size * nmemb;
a6e9f9df 470
c256ffe7 471 if (size == 0 || nmemb == 0)
a6e9f9df
AM
472 return NULL;
473
57028622
NC
474 /* If the size_t type is smaller than the bfd_size_type, eg because
475 you are building a 32-bit tool on a 64-bit host, then make sure
476 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
477 if ((size_t) size != size
478 || (size_t) nmemb != nmemb
479 || (size_t) amt != amt)
57028622
NC
480 {
481 if (reason)
66cfc0fd
AM
482 error (_("Size truncation prevents reading %s"
483 " elements of size %s for %s\n"),
484 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
485 return NULL;
486 }
487
488 /* Check for size overflow. */
7c1c1904 489 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
490 {
491 if (reason)
66cfc0fd
AM
492 error (_("Size overflow prevents reading %s"
493 " elements of size %s for %s\n"),
494 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
495 return NULL;
496 }
497
c22b42ce 498 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 499 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
500 if (filedata->archive_file_offset > filedata->file_size
501 || offset > filedata->file_size - filedata->archive_file_offset
502 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 503 {
049b0c3a 504 if (reason)
66cfc0fd
AM
505 error (_("Reading %s bytes extends past end of file for %s\n"),
506 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
507 return NULL;
508 }
509
978c4450
AM
510 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
511 SEEK_SET))
071436c6
NC
512 {
513 if (reason)
c9c1d674 514 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 515 filedata->archive_file_offset + offset, reason);
071436c6
NC
516 return NULL;
517 }
518
a6e9f9df
AM
519 mvar = var;
520 if (mvar == NULL)
521 {
7c1c1904
AM
522 /* + 1 so that we can '\0' terminate invalid string table sections. */
523 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
524
525 if (mvar == NULL)
526 {
049b0c3a 527 if (reason)
66cfc0fd
AM
528 error (_("Out of memory allocating %s bytes for %s\n"),
529 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
530 return NULL;
531 }
c256ffe7 532
c9c1d674 533 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
534 }
535
dda8d76d 536 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 537 {
049b0c3a 538 if (reason)
66cfc0fd
AM
539 error (_("Unable to read in %s bytes of %s\n"),
540 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
541 if (mvar != var)
542 free (mvar);
543 return NULL;
544 }
545
546 return mvar;
547}
548
32ec8896
NC
549/* Print a VMA value in the MODE specified.
550 Returns the number of characters displayed. */
cb8f3167 551
32ec8896 552static unsigned int
14a91970 553print_vma (bfd_vma vma, print_mode mode)
66543521 554{
32ec8896 555 unsigned int nc = 0;
66543521 556
14a91970 557 switch (mode)
66543521 558 {
14a91970
AM
559 case FULL_HEX:
560 nc = printf ("0x");
1a0670f3 561 /* Fall through. */
14a91970 562 case LONG_HEX:
f7a99963 563#ifdef BFD64
14a91970 564 if (is_32bit_elf)
437c2fb7 565 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 566#endif
14a91970
AM
567 printf_vma (vma);
568 return nc + 16;
b19aac67 569
14a91970
AM
570 case DEC_5:
571 if (vma <= 99999)
572 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 573 /* Fall through. */
14a91970
AM
574 case PREFIX_HEX:
575 nc = printf ("0x");
1a0670f3 576 /* Fall through. */
14a91970
AM
577 case HEX:
578 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 579
047c3dbf
NL
580 case PREFIX_HEX_5:
581 nc = printf ("0x");
582 /* Fall through. */
583 case HEX_5:
584 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
585
14a91970
AM
586 case DEC:
587 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 588
14a91970
AM
589 case UNSIGNED:
590 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 591
047c3dbf
NL
592 case UNSIGNED_5:
593 return printf ("%5" BFD_VMA_FMT "u", vma);
594
595 case OCTAL:
596 return printf ("%" BFD_VMA_FMT "o", vma);
597
598 case OCTAL_5:
599 return printf ("%5" BFD_VMA_FMT "o", vma);
600
32ec8896
NC
601 default:
602 /* FIXME: Report unrecognised mode ? */
603 return 0;
f7a99963 604 }
f7a99963
NC
605}
606
047c3dbf 607
7bfd842d 608/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 609 multibye characters (assuming the host environment supports them).
31104126 610
7bfd842d
NC
611 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
612
0942c7ab
NC
613 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
614 abs(WIDTH) - 5 characters followed by "[...]".
615
7bfd842d
NC
616 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
617 padding as necessary.
171191ba
NC
618
619 Returns the number of emitted characters. */
620
621static unsigned int
0942c7ab 622print_symbol (signed int width, const char * symbol)
31104126 623{
015dc7e1
AM
624 bool extra_padding = false;
625 bool do_dots = false;
32ec8896 626 signed int num_printed = 0;
3bfcb652 627#ifdef HAVE_MBSTATE_T
7bfd842d 628 mbstate_t state;
3bfcb652 629#endif
32ec8896 630 unsigned int width_remaining;
79bc120c 631 const void * alloced_symbol = NULL;
961c521f 632
7bfd842d 633 if (width < 0)
961c521f 634 {
88305e1b 635 /* Keep the width positive. This helps the code below. */
961c521f 636 width = - width;
015dc7e1 637 extra_padding = true;
0b4362b0 638 }
56d8f8a9
NC
639 else if (width == 0)
640 return 0;
961c521f 641
7bfd842d
NC
642 if (do_wide)
643 /* Set the remaining width to a very large value.
644 This simplifies the code below. */
645 width_remaining = INT_MAX;
646 else
0942c7ab
NC
647 {
648 width_remaining = width;
649 if (! do_not_show_symbol_truncation
650 && (int) strlen (symbol) > width)
651 {
652 width_remaining -= 5;
653 if ((int) width_remaining < 0)
654 width_remaining = 0;
015dc7e1 655 do_dots = true;
0942c7ab
NC
656 }
657 }
cb8f3167 658
3bfcb652 659#ifdef HAVE_MBSTATE_T
7bfd842d
NC
660 /* Initialise the multibyte conversion state. */
661 memset (& state, 0, sizeof (state));
3bfcb652 662#endif
961c521f 663
79bc120c
NC
664 if (do_demangle && *symbol)
665 {
666 const char * res = cplus_demangle (symbol, demangle_flags);
667
668 if (res != NULL)
669 alloced_symbol = symbol = res;
670 }
671
7bfd842d
NC
672 while (width_remaining)
673 {
674 size_t n;
7bfd842d 675 const char c = *symbol++;
961c521f 676
7bfd842d 677 if (c == 0)
961c521f
NC
678 break;
679
b3aa80b4
NC
680 if (ISPRINT (c))
681 {
682 putchar (c);
683 width_remaining --;
684 num_printed ++;
685 }
686 else if (ISCNTRL (c))
961c521f 687 {
b3aa80b4
NC
688 /* Do not print control characters directly as they can affect terminal
689 settings. Such characters usually appear in the names generated
690 by the assembler for local labels. */
691
7bfd842d 692 if (width_remaining < 2)
961c521f
NC
693 break;
694
7bfd842d
NC
695 printf ("^%c", c + 0x40);
696 width_remaining -= 2;
171191ba 697 num_printed += 2;
961c521f 698 }
b3aa80b4 699 else if (c == 0x7f)
7bfd842d 700 {
b3aa80b4
NC
701 if (width_remaining < 5)
702 break;
703 printf ("<DEL>");
704 width_remaining -= 5;
705 num_printed += 5;
706 }
707 else if (unicode_display != unicode_locale
708 && unicode_display != unicode_default)
709 {
710 /* Display unicode characters as something else. */
711 unsigned char bytes[4];
712 bool is_utf8;
795588ae 713 unsigned int nbytes;
b3aa80b4
NC
714
715 bytes[0] = c;
716
717 if (bytes[0] < 0xc0)
718 {
719 nbytes = 1;
720 is_utf8 = false;
721 }
722 else
723 {
724 bytes[1] = *symbol++;
725
726 if ((bytes[1] & 0xc0) != 0x80)
727 {
728 is_utf8 = false;
729 /* Do not consume this character. It may only
730 be the first byte in the sequence that was
731 corrupt. */
732 --symbol;
733 nbytes = 1;
734 }
735 else if ((bytes[0] & 0x20) == 0)
736 {
737 is_utf8 = true;
738 nbytes = 2;
739 }
740 else
741 {
742 bytes[2] = *symbol++;
743
744 if ((bytes[2] & 0xc0) != 0x80)
745 {
746 is_utf8 = false;
747 symbol -= 2;
748 nbytes = 1;
749 }
750 else if ((bytes[0] & 0x10) == 0)
751 {
752 is_utf8 = true;
753 nbytes = 3;
754 }
755 else
756 {
757 bytes[3] = *symbol++;
758
759 nbytes = 4;
760
761 if ((bytes[3] & 0xc0) != 0x80)
762 {
763 is_utf8 = false;
764 symbol -= 3;
765 nbytes = 1;
766 }
767 else
768 is_utf8 = true;
769 }
770 }
771 }
772
773 if (unicode_display == unicode_invalid)
774 is_utf8 = false;
775
776 if (unicode_display == unicode_hex || ! is_utf8)
777 {
795588ae 778 unsigned int i;
b3aa80b4
NC
779
780 if (width_remaining < (nbytes * 2) + 2)
781 break;
782
783 putchar (is_utf8 ? '<' : '{');
784 printf ("0x");
785 for (i = 0; i < nbytes; i++)
786 printf ("%02x", bytes[i]);
787 putchar (is_utf8 ? '>' : '}');
788 }
789 else
790 {
791 if (unicode_display == unicode_highlight && isatty (1))
792 printf ("\x1B[31;47m"); /* Red. */
793
794 switch (nbytes)
795 {
796 case 2:
797 if (width_remaining < 6)
798 break;
799 printf ("\\u%02x%02x",
800 (bytes[0] & 0x1c) >> 2,
801 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
802 break;
803 case 3:
804 if (width_remaining < 6)
805 break;
806 printf ("\\u%02x%02x",
807 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
808 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
809 break;
810 case 4:
811 if (width_remaining < 8)
812 break;
813 printf ("\\u%02x%02x%02x",
814 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
815 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
816 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
817
818 break;
819 default:
820 /* URG. */
821 break;
822 }
823
824 if (unicode_display == unicode_highlight && isatty (1))
825 printf ("\033[0m"); /* Default colour. */
826 }
827
828 if (bytes[nbytes - 1] == 0)
829 break;
7bfd842d 830 }
961c521f
NC
831 else
832 {
3bfcb652
NC
833#ifdef HAVE_MBSTATE_T
834 wchar_t w;
835#endif
7bfd842d
NC
836 /* Let printf do the hard work of displaying multibyte characters. */
837 printf ("%.1s", symbol - 1);
838 width_remaining --;
839 num_printed ++;
840
3bfcb652 841#ifdef HAVE_MBSTATE_T
7bfd842d
NC
842 /* Try to find out how many bytes made up the character that was
843 just printed. Advance the symbol pointer past the bytes that
844 were displayed. */
845 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
846#else
847 n = 1;
848#endif
7bfd842d
NC
849 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
850 symbol += (n - 1);
961c521f 851 }
961c521f 852 }
171191ba 853
0942c7ab
NC
854 if (do_dots)
855 num_printed += printf ("[...]");
856
7bfd842d 857 if (extra_padding && num_printed < width)
171191ba
NC
858 {
859 /* Fill in the remaining spaces. */
7bfd842d
NC
860 printf ("%-*s", width - num_printed, " ");
861 num_printed = width;
171191ba
NC
862 }
863
79bc120c 864 free ((void *) alloced_symbol);
171191ba 865 return num_printed;
31104126
NC
866}
867
1449284b 868/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
869 the given section's name. Like print_symbol, except that it does not try
870 to print multibyte characters, it just interprets them as hex values. */
871
872static const char *
dda8d76d 873printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 874{
ca0e11aa 875#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 876 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 877 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
878 char * buf = sec_name_buf;
879 char c;
880 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
881
882 while ((c = * name ++) != 0)
883 {
884 if (ISCNTRL (c))
885 {
886 if (remaining < 2)
887 break;
948f632f 888
74e1a04b
NC
889 * buf ++ = '^';
890 * buf ++ = c + 0x40;
891 remaining -= 2;
892 }
893 else if (ISPRINT (c))
894 {
895 * buf ++ = c;
896 remaining -= 1;
897 }
898 else
899 {
900 static char hex[17] = "0123456789ABCDEF";
901
902 if (remaining < 4)
903 break;
904 * buf ++ = '<';
905 * buf ++ = hex[(c & 0xf0) >> 4];
906 * buf ++ = hex[c & 0x0f];
907 * buf ++ = '>';
908 remaining -= 4;
909 }
910
911 if (remaining == 0)
912 break;
913 }
914
915 * buf = 0;
916 return sec_name_buf;
917}
918
919static const char *
dda8d76d 920printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 921{
dda8d76d 922 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
923 return _("<corrupt>");
924
dda8d76d 925 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
926}
927
89fac5e3
RS
928/* Return a pointer to section NAME, or NULL if no such section exists. */
929
930static Elf_Internal_Shdr *
dda8d76d 931find_section (Filedata * filedata, const char * name)
89fac5e3
RS
932{
933 unsigned int i;
934
68807c3c
NC
935 if (filedata->section_headers == NULL)
936 return NULL;
dda8d76d
NC
937
938 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
939 if (section_name_valid (filedata, filedata->section_headers + i)
940 && streq (section_name (filedata, filedata->section_headers + i),
941 name))
dda8d76d 942 return filedata->section_headers + i;
89fac5e3
RS
943
944 return NULL;
945}
946
0b6ae522
DJ
947/* Return a pointer to a section containing ADDR, or NULL if no such
948 section exists. */
949
950static Elf_Internal_Shdr *
dda8d76d 951find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
952{
953 unsigned int i;
954
68807c3c
NC
955 if (filedata->section_headers == NULL)
956 return NULL;
957
dda8d76d 958 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 959 {
dda8d76d
NC
960 Elf_Internal_Shdr *sec = filedata->section_headers + i;
961
0b6ae522
DJ
962 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
963 return sec;
964 }
965
966 return NULL;
967}
968
071436c6 969static Elf_Internal_Shdr *
dda8d76d 970find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
971{
972 unsigned int i;
973
68807c3c
NC
974 if (filedata->section_headers == NULL)
975 return NULL;
976
dda8d76d 977 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 978 {
dda8d76d
NC
979 Elf_Internal_Shdr *sec = filedata->section_headers + i;
980
071436c6
NC
981 if (sec->sh_type == type)
982 return sec;
983 }
984
985 return NULL;
986}
987
657d0d47
CC
988/* Return a pointer to section NAME, or NULL if no such section exists,
989 restricted to the list of sections given in SET. */
990
991static Elf_Internal_Shdr *
dda8d76d 992find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
993{
994 unsigned int i;
995
68807c3c
NC
996 if (filedata->section_headers == NULL)
997 return NULL;
998
657d0d47
CC
999 if (set != NULL)
1000 {
1001 while ((i = *set++) > 0)
b814a36d
NC
1002 {
1003 /* See PR 21156 for a reproducer. */
dda8d76d 1004 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1005 continue; /* FIXME: Should we issue an error message ? */
1006
84714f86
AM
1007 if (section_name_valid (filedata, filedata->section_headers + i)
1008 && streq (section_name (filedata, filedata->section_headers + i),
1009 name))
dda8d76d 1010 return filedata->section_headers + i;
b814a36d 1011 }
657d0d47
CC
1012 }
1013
dda8d76d 1014 return find_section (filedata, name);
657d0d47
CC
1015}
1016
32ec8896 1017/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
1018 This OS has so many departures from the ELF standard that we test it at
1019 many places. */
1020
015dc7e1 1021static inline bool
dda8d76d 1022is_ia64_vms (Filedata * filedata)
28f997cf 1023{
dda8d76d
NC
1024 return filedata->file_header.e_machine == EM_IA_64
1025 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
1026}
1027
bcedfee6 1028/* Guess the relocation size commonly used by the specific machines. */
252b5132 1029
015dc7e1 1030static bool
2dc4cec1 1031guess_is_rela (unsigned int e_machine)
252b5132 1032{
9c19a809 1033 switch (e_machine)
252b5132
RH
1034 {
1035 /* Targets that use REL relocations. */
252b5132 1036 case EM_386:
22abe556 1037 case EM_IAMCU:
f954747f 1038 case EM_960:
e9f53129 1039 case EM_ARM:
2b0337b0 1040 case EM_D10V:
252b5132 1041 case EM_CYGNUS_D10V:
e9f53129 1042 case EM_DLX:
252b5132 1043 case EM_MIPS:
4fe85591 1044 case EM_MIPS_RS3_LE:
e9f53129 1045 case EM_CYGNUS_M32R:
1c0d3aa6 1046 case EM_SCORE:
f6c1a2d5 1047 case EM_XGATE:
fe944acf 1048 case EM_NFP:
aca4efc7 1049 case EM_BPF:
015dc7e1 1050 return false;
103f02d3 1051
252b5132
RH
1052 /* Targets that use RELA relocations. */
1053 case EM_68K:
f954747f 1054 case EM_860:
a06ea964 1055 case EM_AARCH64:
cfb8c092 1056 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1057 case EM_ALPHA:
1058 case EM_ALTERA_NIOS2:
886a2506
NC
1059 case EM_ARC:
1060 case EM_ARC_COMPACT:
1061 case EM_ARC_COMPACT2:
e9f53129
AM
1062 case EM_AVR:
1063 case EM_AVR_OLD:
1064 case EM_BLACKFIN:
60bca95a 1065 case EM_CR16:
e9f53129
AM
1066 case EM_CRIS:
1067 case EM_CRX:
b8891f8d 1068 case EM_CSKY:
2b0337b0 1069 case EM_D30V:
252b5132 1070 case EM_CYGNUS_D30V:
2b0337b0 1071 case EM_FR30:
3f8107ab 1072 case EM_FT32:
252b5132 1073 case EM_CYGNUS_FR30:
5c70f934 1074 case EM_CYGNUS_FRV:
e9f53129
AM
1075 case EM_H8S:
1076 case EM_H8_300:
1077 case EM_H8_300H:
800eeca4 1078 case EM_IA_64:
1e4cf259
NC
1079 case EM_IP2K:
1080 case EM_IP2K_OLD:
3b36097d 1081 case EM_IQ2000:
84e94c90 1082 case EM_LATTICEMICO32:
ff7eeb89 1083 case EM_M32C_OLD:
49f58d10 1084 case EM_M32C:
e9f53129
AM
1085 case EM_M32R:
1086 case EM_MCORE:
15ab5209 1087 case EM_CYGNUS_MEP:
a3c62988 1088 case EM_METAG:
e9f53129
AM
1089 case EM_MMIX:
1090 case EM_MN10200:
1091 case EM_CYGNUS_MN10200:
1092 case EM_MN10300:
1093 case EM_CYGNUS_MN10300:
5506d11a 1094 case EM_MOXIE:
e9f53129
AM
1095 case EM_MSP430:
1096 case EM_MSP430_OLD:
d031aafb 1097 case EM_MT:
35c08157 1098 case EM_NDS32:
64fd6348 1099 case EM_NIOS32:
73589c9d 1100 case EM_OR1K:
e9f53129
AM
1101 case EM_PPC64:
1102 case EM_PPC:
2b100bb5 1103 case EM_TI_PRU:
e23eba97 1104 case EM_RISCV:
99c513f6 1105 case EM_RL78:
c7927a3c 1106 case EM_RX:
e9f53129
AM
1107 case EM_S390:
1108 case EM_S390_OLD:
1109 case EM_SH:
1110 case EM_SPARC:
1111 case EM_SPARC32PLUS:
1112 case EM_SPARCV9:
1113 case EM_SPU:
40b36596 1114 case EM_TI_C6000:
aa137e4d
NC
1115 case EM_TILEGX:
1116 case EM_TILEPRO:
708e2187 1117 case EM_V800:
e9f53129
AM
1118 case EM_V850:
1119 case EM_CYGNUS_V850:
1120 case EM_VAX:
619ed720 1121 case EM_VISIUM:
e9f53129 1122 case EM_X86_64:
8a9036a4 1123 case EM_L1OM:
7a9068fe 1124 case EM_K1OM:
e9f53129
AM
1125 case EM_XSTORMY16:
1126 case EM_XTENSA:
1127 case EM_XTENSA_OLD:
7ba29e2a
NC
1128 case EM_MICROBLAZE:
1129 case EM_MICROBLAZE_OLD:
f96bd6c2 1130 case EM_WEBASSEMBLY:
015dc7e1 1131 return true;
103f02d3 1132
e9f53129
AM
1133 case EM_68HC05:
1134 case EM_68HC08:
1135 case EM_68HC11:
1136 case EM_68HC16:
1137 case EM_FX66:
1138 case EM_ME16:
d1133906 1139 case EM_MMA:
d1133906
NC
1140 case EM_NCPU:
1141 case EM_NDR1:
e9f53129 1142 case EM_PCP:
d1133906 1143 case EM_ST100:
e9f53129 1144 case EM_ST19:
d1133906 1145 case EM_ST7:
e9f53129
AM
1146 case EM_ST9PLUS:
1147 case EM_STARCORE:
d1133906 1148 case EM_SVX:
e9f53129 1149 case EM_TINYJ:
9c19a809
NC
1150 default:
1151 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1152 return false;
9c19a809
NC
1153 }
1154}
252b5132 1155
dda8d76d 1156/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1157 Returns TRUE upon success, FALSE otherwise. If successful then a
1158 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1159 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1160 responsibility to free the allocated buffer. */
1161
015dc7e1 1162static bool
dda8d76d
NC
1163slurp_rela_relocs (Filedata * filedata,
1164 unsigned long rel_offset,
1165 unsigned long rel_size,
1166 Elf_Internal_Rela ** relasp,
1167 unsigned long * nrelasp)
9c19a809 1168{
2cf0635d 1169 Elf_Internal_Rela * relas;
8b73c356 1170 size_t nrelas;
4d6ed7c8 1171 unsigned int i;
252b5132 1172
4d6ed7c8
NC
1173 if (is_32bit_elf)
1174 {
2cf0635d 1175 Elf32_External_Rela * erelas;
103f02d3 1176
dda8d76d 1177 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1178 rel_size, _("32-bit relocation data"));
a6e9f9df 1179 if (!erelas)
015dc7e1 1180 return false;
252b5132 1181
4d6ed7c8 1182 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1183
3f5e193b
NC
1184 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1185 sizeof (Elf_Internal_Rela));
103f02d3 1186
4d6ed7c8
NC
1187 if (relas == NULL)
1188 {
c256ffe7 1189 free (erelas);
591a748a 1190 error (_("out of memory parsing relocs\n"));
015dc7e1 1191 return false;
4d6ed7c8 1192 }
103f02d3 1193
4d6ed7c8
NC
1194 for (i = 0; i < nrelas; i++)
1195 {
1196 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1197 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1198 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1199 }
103f02d3 1200
4d6ed7c8
NC
1201 free (erelas);
1202 }
1203 else
1204 {
2cf0635d 1205 Elf64_External_Rela * erelas;
103f02d3 1206
dda8d76d 1207 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1208 rel_size, _("64-bit relocation data"));
a6e9f9df 1209 if (!erelas)
015dc7e1 1210 return false;
4d6ed7c8
NC
1211
1212 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1213
3f5e193b
NC
1214 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1215 sizeof (Elf_Internal_Rela));
103f02d3 1216
4d6ed7c8
NC
1217 if (relas == NULL)
1218 {
c256ffe7 1219 free (erelas);
591a748a 1220 error (_("out of memory parsing relocs\n"));
015dc7e1 1221 return false;
9c19a809 1222 }
4d6ed7c8
NC
1223
1224 for (i = 0; i < nrelas; i++)
9c19a809 1225 {
66543521
AM
1226 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1227 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1228 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1229
1230 /* The #ifdef BFD64 below is to prevent a compile time
1231 warning. We know that if we do not have a 64 bit data
1232 type that we will never execute this code anyway. */
1233#ifdef BFD64
dda8d76d
NC
1234 if (filedata->file_header.e_machine == EM_MIPS
1235 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1236 {
1237 /* In little-endian objects, r_info isn't really a
1238 64-bit little-endian value: it has a 32-bit
1239 little-endian symbol index followed by four
1240 individual byte fields. Reorder INFO
1241 accordingly. */
91d6fa6a
NC
1242 bfd_vma inf = relas[i].r_info;
1243 inf = (((inf & 0xffffffff) << 32)
1244 | ((inf >> 56) & 0xff)
1245 | ((inf >> 40) & 0xff00)
1246 | ((inf >> 24) & 0xff0000)
1247 | ((inf >> 8) & 0xff000000));
1248 relas[i].r_info = inf;
861fb55a
DJ
1249 }
1250#endif /* BFD64 */
4d6ed7c8 1251 }
103f02d3 1252
4d6ed7c8
NC
1253 free (erelas);
1254 }
32ec8896 1255
4d6ed7c8
NC
1256 *relasp = relas;
1257 *nrelasp = nrelas;
015dc7e1 1258 return true;
4d6ed7c8 1259}
103f02d3 1260
dda8d76d 1261/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1262 Returns TRUE upon success, FALSE otherwise. If successful then a
1263 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1264 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1265 responsibility to free the allocated buffer. */
1266
015dc7e1 1267static bool
dda8d76d
NC
1268slurp_rel_relocs (Filedata * filedata,
1269 unsigned long rel_offset,
1270 unsigned long rel_size,
1271 Elf_Internal_Rela ** relsp,
1272 unsigned long * nrelsp)
4d6ed7c8 1273{
2cf0635d 1274 Elf_Internal_Rela * rels;
8b73c356 1275 size_t nrels;
4d6ed7c8 1276 unsigned int i;
103f02d3 1277
4d6ed7c8
NC
1278 if (is_32bit_elf)
1279 {
2cf0635d 1280 Elf32_External_Rel * erels;
103f02d3 1281
dda8d76d 1282 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1283 rel_size, _("32-bit relocation data"));
a6e9f9df 1284 if (!erels)
015dc7e1 1285 return false;
103f02d3 1286
4d6ed7c8 1287 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1288
3f5e193b 1289 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1290
4d6ed7c8
NC
1291 if (rels == NULL)
1292 {
c256ffe7 1293 free (erels);
591a748a 1294 error (_("out of memory parsing relocs\n"));
015dc7e1 1295 return false;
4d6ed7c8
NC
1296 }
1297
1298 for (i = 0; i < nrels; i++)
1299 {
1300 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1301 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1302 rels[i].r_addend = 0;
9ea033b2 1303 }
4d6ed7c8
NC
1304
1305 free (erels);
9c19a809
NC
1306 }
1307 else
1308 {
2cf0635d 1309 Elf64_External_Rel * erels;
9ea033b2 1310
dda8d76d 1311 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1312 rel_size, _("64-bit relocation data"));
a6e9f9df 1313 if (!erels)
015dc7e1 1314 return false;
103f02d3 1315
4d6ed7c8 1316 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1317
3f5e193b 1318 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1319
4d6ed7c8 1320 if (rels == NULL)
9c19a809 1321 {
c256ffe7 1322 free (erels);
591a748a 1323 error (_("out of memory parsing relocs\n"));
015dc7e1 1324 return false;
4d6ed7c8 1325 }
103f02d3 1326
4d6ed7c8
NC
1327 for (i = 0; i < nrels; i++)
1328 {
66543521
AM
1329 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1330 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1331 rels[i].r_addend = 0;
861fb55a
DJ
1332
1333 /* The #ifdef BFD64 below is to prevent a compile time
1334 warning. We know that if we do not have a 64 bit data
1335 type that we will never execute this code anyway. */
1336#ifdef BFD64
dda8d76d
NC
1337 if (filedata->file_header.e_machine == EM_MIPS
1338 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1339 {
1340 /* In little-endian objects, r_info isn't really a
1341 64-bit little-endian value: it has a 32-bit
1342 little-endian symbol index followed by four
1343 individual byte fields. Reorder INFO
1344 accordingly. */
91d6fa6a
NC
1345 bfd_vma inf = rels[i].r_info;
1346 inf = (((inf & 0xffffffff) << 32)
1347 | ((inf >> 56) & 0xff)
1348 | ((inf >> 40) & 0xff00)
1349 | ((inf >> 24) & 0xff0000)
1350 | ((inf >> 8) & 0xff000000));
1351 rels[i].r_info = inf;
861fb55a
DJ
1352 }
1353#endif /* BFD64 */
4d6ed7c8 1354 }
103f02d3 1355
4d6ed7c8
NC
1356 free (erels);
1357 }
32ec8896 1358
4d6ed7c8
NC
1359 *relsp = rels;
1360 *nrelsp = nrels;
015dc7e1 1361 return true;
4d6ed7c8 1362}
103f02d3 1363
a7fd1186
FS
1364static bool
1365slurp_relr_relocs (Filedata * filedata,
1366 unsigned long relr_offset,
1367 unsigned long relr_size,
1368 bfd_vma ** relrsp,
1369 unsigned long * nrelrsp)
1370{
1371 void *relrs;
1372 size_t size = 0, nentries, i;
1373 bfd_vma base = 0, addr, entry;
1374
1375 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1376 _("RELR relocation data"));
1377 if (!relrs)
1378 return false;
1379
1380 if (is_32bit_elf)
1381 nentries = relr_size / sizeof (Elf32_External_Relr);
1382 else
1383 nentries = relr_size / sizeof (Elf64_External_Relr);
1384 for (i = 0; i < nentries; i++)
1385 {
1386 if (is_32bit_elf)
1387 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1388 else
1389 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1390 if ((entry & 1) == 0)
1391 size++;
1392 else
1393 while ((entry >>= 1) != 0)
1394 if ((entry & 1) == 1)
1395 size++;
1396 }
1397
1398 *relrsp = (bfd_vma *) xmalloc (size * sizeof (bfd_vma));
1399 if (*relrsp == NULL)
1400 {
1401 free (relrs);
1402 error (_("out of memory parsing relocs\n"));
1403 return false;
1404 }
1405
1406 size = 0;
1407 for (i = 0; i < nentries; i++)
1408 {
1409 const bfd_vma entry_bytes = is_32bit_elf ? 4 : 8;
1410
1411 if (is_32bit_elf)
1412 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1413 else
1414 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1415 if ((entry & 1) == 0)
1416 {
1417 (*relrsp)[size++] = entry;
1418 base = entry + entry_bytes;
1419 }
1420 else
1421 {
1422 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1423 if ((entry & 1) != 0)
1424 (*relrsp)[size++] = addr;
1425 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1426 }
1427 }
1428
1429 *nrelrsp = size;
1430 free (relrs);
1431 return true;
1432}
1433
aca88567
NC
1434/* Returns the reloc type extracted from the reloc info field. */
1435
1436static unsigned int
dda8d76d 1437get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1438{
1439 if (is_32bit_elf)
1440 return ELF32_R_TYPE (reloc_info);
1441
dda8d76d 1442 switch (filedata->file_header.e_machine)
aca88567
NC
1443 {
1444 case EM_MIPS:
1445 /* Note: We assume that reloc_info has already been adjusted for us. */
1446 return ELF64_MIPS_R_TYPE (reloc_info);
1447
1448 case EM_SPARCV9:
1449 return ELF64_R_TYPE_ID (reloc_info);
1450
1451 default:
1452 return ELF64_R_TYPE (reloc_info);
1453 }
1454}
1455
1456/* Return the symbol index extracted from the reloc info field. */
1457
1458static bfd_vma
1459get_reloc_symindex (bfd_vma reloc_info)
1460{
1461 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1462}
1463
015dc7e1 1464static inline bool
dda8d76d 1465uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1466{
1467 return
dda8d76d 1468 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1469 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1470 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1471 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1472 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1473}
1474
d3ba0551
AM
1475/* Display the contents of the relocation data found at the specified
1476 offset. */
ee42cf8c 1477
015dc7e1 1478static bool
dda8d76d
NC
1479dump_relocations (Filedata * filedata,
1480 unsigned long rel_offset,
1481 unsigned long rel_size,
1482 Elf_Internal_Sym * symtab,
1483 unsigned long nsyms,
1484 char * strtab,
1485 unsigned long strtablen,
a7fd1186 1486 relocation_type rel_type,
015dc7e1 1487 bool is_dynsym)
4d6ed7c8 1488{
32ec8896 1489 unsigned long i;
2cf0635d 1490 Elf_Internal_Rela * rels;
015dc7e1 1491 bool res = true;
103f02d3 1492
a7fd1186
FS
1493 if (rel_type == reltype_unknown)
1494 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1495
a7fd1186 1496 if (rel_type == reltype_rela)
4d6ed7c8 1497 {
dda8d76d 1498 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1499 return false;
4d6ed7c8 1500 }
a7fd1186 1501 else if (rel_type == reltype_rel)
4d6ed7c8 1502 {
dda8d76d 1503 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1504 return false;
252b5132 1505 }
a7fd1186
FS
1506 else if (rel_type == reltype_relr)
1507 {
1508 bfd_vma * relrs;
1509 const char *format
1510 = is_32bit_elf ? "%08" BFD_VMA_FMT "x\n" : "%016" BFD_VMA_FMT "x\n";
1511
1512 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1513 &rel_size))
1514 return false;
1515
1516 printf (ngettext (" %lu offset\n", " %lu offsets\n", rel_size), rel_size);
1517 for (i = 0; i < rel_size; i++)
1518 printf (format, relrs[i]);
1519 free (relrs);
1520 return true;
1521 }
252b5132 1522
410f7a12
L
1523 if (is_32bit_elf)
1524 {
a7fd1186 1525 if (rel_type == reltype_rela)
2c71103e
NC
1526 {
1527 if (do_wide)
1528 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1529 else
1530 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1531 }
410f7a12 1532 else
2c71103e
NC
1533 {
1534 if (do_wide)
1535 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1536 else
1537 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1538 }
410f7a12 1539 }
252b5132 1540 else
410f7a12 1541 {
a7fd1186 1542 if (rel_type == reltype_rela)
2c71103e
NC
1543 {
1544 if (do_wide)
8beeaeb7 1545 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1546 else
1547 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1548 }
410f7a12 1549 else
2c71103e
NC
1550 {
1551 if (do_wide)
8beeaeb7 1552 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1553 else
1554 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1555 }
410f7a12 1556 }
252b5132
RH
1557
1558 for (i = 0; i < rel_size; i++)
1559 {
2cf0635d 1560 const char * rtype;
b34976b6 1561 bfd_vma offset;
91d6fa6a 1562 bfd_vma inf;
b34976b6
AM
1563 bfd_vma symtab_index;
1564 bfd_vma type;
103f02d3 1565
b34976b6 1566 offset = rels[i].r_offset;
91d6fa6a 1567 inf = rels[i].r_info;
103f02d3 1568
dda8d76d 1569 type = get_reloc_type (filedata, inf);
91d6fa6a 1570 symtab_index = get_reloc_symindex (inf);
252b5132 1571
410f7a12
L
1572 if (is_32bit_elf)
1573 {
39dbeff8
AM
1574 printf ("%8.8lx %8.8lx ",
1575 (unsigned long) offset & 0xffffffff,
91d6fa6a 1576 (unsigned long) inf & 0xffffffff);
410f7a12
L
1577 }
1578 else
1579 {
39dbeff8 1580 printf (do_wide
d1ce973e
AM
1581 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1582 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1583 offset, inf);
410f7a12 1584 }
103f02d3 1585
dda8d76d 1586 switch (filedata->file_header.e_machine)
252b5132
RH
1587 {
1588 default:
1589 rtype = NULL;
1590 break;
1591
a06ea964
NC
1592 case EM_AARCH64:
1593 rtype = elf_aarch64_reloc_type (type);
1594 break;
1595
2b0337b0 1596 case EM_M32R:
252b5132 1597 case EM_CYGNUS_M32R:
9ea033b2 1598 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1599 break;
1600
1601 case EM_386:
22abe556 1602 case EM_IAMCU:
9ea033b2 1603 rtype = elf_i386_reloc_type (type);
252b5132
RH
1604 break;
1605
ba2685cc
AM
1606 case EM_68HC11:
1607 case EM_68HC12:
1608 rtype = elf_m68hc11_reloc_type (type);
1609 break;
75751cd9 1610
7b4ae824
JD
1611 case EM_S12Z:
1612 rtype = elf_s12z_reloc_type (type);
1613 break;
1614
252b5132 1615 case EM_68K:
9ea033b2 1616 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1617 break;
1618
f954747f
AM
1619 case EM_960:
1620 rtype = elf_i960_reloc_type (type);
1621 break;
1622
adde6300 1623 case EM_AVR:
2b0337b0 1624 case EM_AVR_OLD:
adde6300
AM
1625 rtype = elf_avr_reloc_type (type);
1626 break;
1627
9ea033b2
NC
1628 case EM_OLD_SPARCV9:
1629 case EM_SPARC32PLUS:
1630 case EM_SPARCV9:
252b5132 1631 case EM_SPARC:
9ea033b2 1632 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1633 break;
1634
e9f53129
AM
1635 case EM_SPU:
1636 rtype = elf_spu_reloc_type (type);
1637 break;
1638
708e2187
NC
1639 case EM_V800:
1640 rtype = v800_reloc_type (type);
1641 break;
2b0337b0 1642 case EM_V850:
252b5132 1643 case EM_CYGNUS_V850:
9ea033b2 1644 rtype = v850_reloc_type (type);
252b5132
RH
1645 break;
1646
2b0337b0 1647 case EM_D10V:
252b5132 1648 case EM_CYGNUS_D10V:
9ea033b2 1649 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1650 break;
1651
2b0337b0 1652 case EM_D30V:
252b5132 1653 case EM_CYGNUS_D30V:
9ea033b2 1654 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1655 break;
1656
d172d4ba
NC
1657 case EM_DLX:
1658 rtype = elf_dlx_reloc_type (type);
1659 break;
1660
252b5132 1661 case EM_SH:
9ea033b2 1662 rtype = elf_sh_reloc_type (type);
252b5132
RH
1663 break;
1664
2b0337b0 1665 case EM_MN10300:
252b5132 1666 case EM_CYGNUS_MN10300:
9ea033b2 1667 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1668 break;
1669
2b0337b0 1670 case EM_MN10200:
252b5132 1671 case EM_CYGNUS_MN10200:
9ea033b2 1672 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1673 break;
1674
2b0337b0 1675 case EM_FR30:
252b5132 1676 case EM_CYGNUS_FR30:
9ea033b2 1677 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1678 break;
1679
ba2685cc
AM
1680 case EM_CYGNUS_FRV:
1681 rtype = elf_frv_reloc_type (type);
1682 break;
5c70f934 1683
b8891f8d
AJ
1684 case EM_CSKY:
1685 rtype = elf_csky_reloc_type (type);
1686 break;
1687
3f8107ab
AM
1688 case EM_FT32:
1689 rtype = elf_ft32_reloc_type (type);
1690 break;
1691
252b5132 1692 case EM_MCORE:
9ea033b2 1693 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1694 break;
1695
3c3bdf30
NC
1696 case EM_MMIX:
1697 rtype = elf_mmix_reloc_type (type);
1698 break;
1699
5506d11a
AM
1700 case EM_MOXIE:
1701 rtype = elf_moxie_reloc_type (type);
1702 break;
1703
2469cfa2 1704 case EM_MSP430:
dda8d76d 1705 if (uses_msp430x_relocs (filedata))
13761a11
NC
1706 {
1707 rtype = elf_msp430x_reloc_type (type);
1708 break;
1709 }
1a0670f3 1710 /* Fall through. */
2469cfa2
NC
1711 case EM_MSP430_OLD:
1712 rtype = elf_msp430_reloc_type (type);
1713 break;
1714
35c08157
KLC
1715 case EM_NDS32:
1716 rtype = elf_nds32_reloc_type (type);
1717 break;
1718
252b5132 1719 case EM_PPC:
9ea033b2 1720 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1721 break;
1722
c833c019
AM
1723 case EM_PPC64:
1724 rtype = elf_ppc64_reloc_type (type);
1725 break;
1726
252b5132 1727 case EM_MIPS:
4fe85591 1728 case EM_MIPS_RS3_LE:
9ea033b2 1729 rtype = elf_mips_reloc_type (type);
252b5132
RH
1730 break;
1731
e23eba97
NC
1732 case EM_RISCV:
1733 rtype = elf_riscv_reloc_type (type);
1734 break;
1735
252b5132 1736 case EM_ALPHA:
9ea033b2 1737 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1738 break;
1739
1740 case EM_ARM:
9ea033b2 1741 rtype = elf_arm_reloc_type (type);
252b5132
RH
1742 break;
1743
584da044 1744 case EM_ARC:
886a2506
NC
1745 case EM_ARC_COMPACT:
1746 case EM_ARC_COMPACT2:
9ea033b2 1747 rtype = elf_arc_reloc_type (type);
252b5132
RH
1748 break;
1749
1750 case EM_PARISC:
69e617ca 1751 rtype = elf_hppa_reloc_type (type);
252b5132 1752 break;
7d466069 1753
b8720f9d
JL
1754 case EM_H8_300:
1755 case EM_H8_300H:
1756 case EM_H8S:
1757 rtype = elf_h8_reloc_type (type);
1758 break;
1759
73589c9d
CS
1760 case EM_OR1K:
1761 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1762 break;
1763
7d466069 1764 case EM_PJ:
2b0337b0 1765 case EM_PJ_OLD:
7d466069
ILT
1766 rtype = elf_pj_reloc_type (type);
1767 break;
800eeca4
JW
1768 case EM_IA_64:
1769 rtype = elf_ia64_reloc_type (type);
1770 break;
1b61cf92
HPN
1771
1772 case EM_CRIS:
1773 rtype = elf_cris_reloc_type (type);
1774 break;
535c37ff 1775
f954747f
AM
1776 case EM_860:
1777 rtype = elf_i860_reloc_type (type);
1778 break;
1779
bcedfee6 1780 case EM_X86_64:
8a9036a4 1781 case EM_L1OM:
7a9068fe 1782 case EM_K1OM:
bcedfee6
NC
1783 rtype = elf_x86_64_reloc_type (type);
1784 break;
a85d7ed0 1785
f954747f
AM
1786 case EM_S370:
1787 rtype = i370_reloc_type (type);
1788 break;
1789
53c7db4b
KH
1790 case EM_S390_OLD:
1791 case EM_S390:
1792 rtype = elf_s390_reloc_type (type);
1793 break;
93fbbb04 1794
1c0d3aa6
NC
1795 case EM_SCORE:
1796 rtype = elf_score_reloc_type (type);
1797 break;
1798
93fbbb04
GK
1799 case EM_XSTORMY16:
1800 rtype = elf_xstormy16_reloc_type (type);
1801 break;
179d3252 1802
1fe1f39c
NC
1803 case EM_CRX:
1804 rtype = elf_crx_reloc_type (type);
1805 break;
1806
179d3252
JT
1807 case EM_VAX:
1808 rtype = elf_vax_reloc_type (type);
1809 break;
1e4cf259 1810
619ed720
EB
1811 case EM_VISIUM:
1812 rtype = elf_visium_reloc_type (type);
1813 break;
1814
aca4efc7
JM
1815 case EM_BPF:
1816 rtype = elf_bpf_reloc_type (type);
1817 break;
1818
cfb8c092
NC
1819 case EM_ADAPTEVA_EPIPHANY:
1820 rtype = elf_epiphany_reloc_type (type);
1821 break;
1822
1e4cf259
NC
1823 case EM_IP2K:
1824 case EM_IP2K_OLD:
1825 rtype = elf_ip2k_reloc_type (type);
1826 break;
3b36097d
SC
1827
1828 case EM_IQ2000:
1829 rtype = elf_iq2000_reloc_type (type);
1830 break;
88da6820
NC
1831
1832 case EM_XTENSA_OLD:
1833 case EM_XTENSA:
1834 rtype = elf_xtensa_reloc_type (type);
1835 break;
a34e3ecb 1836
84e94c90
NC
1837 case EM_LATTICEMICO32:
1838 rtype = elf_lm32_reloc_type (type);
1839 break;
1840
ff7eeb89 1841 case EM_M32C_OLD:
49f58d10
JB
1842 case EM_M32C:
1843 rtype = elf_m32c_reloc_type (type);
1844 break;
1845
d031aafb
NS
1846 case EM_MT:
1847 rtype = elf_mt_reloc_type (type);
a34e3ecb 1848 break;
1d65ded4
CM
1849
1850 case EM_BLACKFIN:
1851 rtype = elf_bfin_reloc_type (type);
1852 break;
15ab5209
DB
1853
1854 case EM_CYGNUS_MEP:
1855 rtype = elf_mep_reloc_type (type);
1856 break;
60bca95a
NC
1857
1858 case EM_CR16:
1859 rtype = elf_cr16_reloc_type (type);
1860 break;
dd24e3da 1861
7ba29e2a
NC
1862 case EM_MICROBLAZE:
1863 case EM_MICROBLAZE_OLD:
1864 rtype = elf_microblaze_reloc_type (type);
1865 break;
c7927a3c 1866
99c513f6
DD
1867 case EM_RL78:
1868 rtype = elf_rl78_reloc_type (type);
1869 break;
1870
c7927a3c
NC
1871 case EM_RX:
1872 rtype = elf_rx_reloc_type (type);
1873 break;
c29aca4a 1874
a3c62988
NC
1875 case EM_METAG:
1876 rtype = elf_metag_reloc_type (type);
1877 break;
1878
c29aca4a
NC
1879 case EM_XC16X:
1880 case EM_C166:
1881 rtype = elf_xc16x_reloc_type (type);
1882 break;
40b36596
JM
1883
1884 case EM_TI_C6000:
1885 rtype = elf_tic6x_reloc_type (type);
1886 break;
aa137e4d
NC
1887
1888 case EM_TILEGX:
1889 rtype = elf_tilegx_reloc_type (type);
1890 break;
1891
1892 case EM_TILEPRO:
1893 rtype = elf_tilepro_reloc_type (type);
1894 break;
f6c1a2d5 1895
f96bd6c2
PC
1896 case EM_WEBASSEMBLY:
1897 rtype = elf_wasm32_reloc_type (type);
1898 break;
1899
f6c1a2d5
NC
1900 case EM_XGATE:
1901 rtype = elf_xgate_reloc_type (type);
1902 break;
36591ba1
SL
1903
1904 case EM_ALTERA_NIOS2:
1905 rtype = elf_nios2_reloc_type (type);
1906 break;
2b100bb5
DD
1907
1908 case EM_TI_PRU:
1909 rtype = elf_pru_reloc_type (type);
1910 break;
fe944acf
FT
1911
1912 case EM_NFP:
1913 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1914 rtype = elf_nfp3200_reloc_type (type);
1915 else
1916 rtype = elf_nfp_reloc_type (type);
1917 break;
6655dba2
SB
1918
1919 case EM_Z80:
1920 rtype = elf_z80_reloc_type (type);
1921 break;
e9a0721f 1922
1923 case EM_LOONGARCH:
1924 rtype = elf_loongarch_reloc_type (type);
1925 break;
1926
252b5132
RH
1927 }
1928
1929 if (rtype == NULL)
39dbeff8 1930 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1931 else
5c144731 1932 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1933
dda8d76d 1934 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1935 && rtype != NULL
7ace3541 1936 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1937 && rel_type == reltype_rela)
7ace3541
RH
1938 {
1939 switch (rels[i].r_addend)
1940 {
1941 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1942 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1943 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1944 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1945 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1946 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1947 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1948 default: rtype = NULL;
1949 }
32ec8896 1950
7ace3541
RH
1951 if (rtype)
1952 printf (" (%s)", rtype);
1953 else
1954 {
1955 putchar (' ');
1956 printf (_("<unknown addend: %lx>"),
1957 (unsigned long) rels[i].r_addend);
015dc7e1 1958 res = false;
7ace3541
RH
1959 }
1960 }
1961 else if (symtab_index)
252b5132 1962 {
af3fc3bc 1963 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1964 {
27a45f42
AS
1965 error (_(" bad symbol index: %08lx in reloc\n"),
1966 (unsigned long) symtab_index);
015dc7e1 1967 res = false;
32ec8896 1968 }
af3fc3bc 1969 else
19936277 1970 {
2cf0635d 1971 Elf_Internal_Sym * psym;
bb4d2ac2
L
1972 const char * version_string;
1973 enum versioned_symbol_info sym_info;
1974 unsigned short vna_other;
19936277 1975
af3fc3bc 1976 psym = symtab + symtab_index;
103f02d3 1977
bb4d2ac2 1978 version_string
dda8d76d 1979 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1980 strtab, strtablen,
1981 symtab_index,
1982 psym,
1983 &sym_info,
1984 &vna_other);
1985
af3fc3bc 1986 printf (" ");
171191ba 1987
d8045f23
NC
1988 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1989 {
1990 const char * name;
1991 unsigned int len;
1992 unsigned int width = is_32bit_elf ? 8 : 14;
1993
1994 /* Relocations against GNU_IFUNC symbols do not use the value
1995 of the symbol as the address to relocate against. Instead
1996 they invoke the function named by the symbol and use its
1997 result as the address for relocation.
1998
1999 To indicate this to the user, do not display the value of
2000 the symbol in the "Symbols's Value" field. Instead show
2001 its name followed by () as a hint that the symbol is
2002 invoked. */
2003
2004 if (strtab == NULL
2005 || psym->st_name == 0
2006 || psym->st_name >= strtablen)
2007 name = "??";
2008 else
2009 name = strtab + psym->st_name;
2010
2011 len = print_symbol (width, name);
bb4d2ac2
L
2012 if (version_string)
2013 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2014 version_string);
d8045f23
NC
2015 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2016 }
2017 else
2018 {
2019 print_vma (psym->st_value, LONG_HEX);
171191ba 2020
d8045f23
NC
2021 printf (is_32bit_elf ? " " : " ");
2022 }
103f02d3 2023
af3fc3bc 2024 if (psym->st_name == 0)
f1ef08cb 2025 {
2cf0635d 2026 const char * sec_name = "<null>";
f1ef08cb
AM
2027 char name_buf[40];
2028
2029 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2030 {
b9af6379
AM
2031 if (psym->st_shndx < filedata->file_header.e_shnum
2032 && filedata->section_headers != NULL)
84714f86
AM
2033 sec_name = section_name_print (filedata,
2034 filedata->section_headers
b9e920ec 2035 + psym->st_shndx);
f1ef08cb
AM
2036 else if (psym->st_shndx == SHN_ABS)
2037 sec_name = "ABS";
2038 else if (psym->st_shndx == SHN_COMMON)
2039 sec_name = "COMMON";
dda8d76d 2040 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2041 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2042 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2043 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2044 sec_name = "SCOMMON";
dda8d76d 2045 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2046 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2047 sec_name = "SUNDEF";
dda8d76d
NC
2048 else if ((filedata->file_header.e_machine == EM_X86_64
2049 || filedata->file_header.e_machine == EM_L1OM
2050 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2051 && psym->st_shndx == SHN_X86_64_LCOMMON)
2052 sec_name = "LARGE_COMMON";
dda8d76d
NC
2053 else if (filedata->file_header.e_machine == EM_IA_64
2054 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2055 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2056 sec_name = "ANSI_COM";
dda8d76d 2057 else if (is_ia64_vms (filedata)
148b93f2
NC
2058 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2059 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2060 else
2061 {
2062 sprintf (name_buf, "<section 0x%x>",
2063 (unsigned int) psym->st_shndx);
2064 sec_name = name_buf;
2065 }
2066 }
2067 print_symbol (22, sec_name);
2068 }
af3fc3bc 2069 else if (strtab == NULL)
d79b3d50 2070 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2071 else if (psym->st_name >= strtablen)
32ec8896 2072 {
27a45f42
AS
2073 error (_("<corrupt string table index: %3ld>\n"),
2074 psym->st_name);
015dc7e1 2075 res = false;
32ec8896 2076 }
af3fc3bc 2077 else
bb4d2ac2
L
2078 {
2079 print_symbol (22, strtab + psym->st_name);
2080 if (version_string)
2081 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2082 version_string);
2083 }
103f02d3 2084
a7fd1186 2085 if (rel_type == reltype_rela)
171191ba 2086 {
7360e63f 2087 bfd_vma off = rels[i].r_addend;
171191ba 2088
7360e63f 2089 if ((bfd_signed_vma) off < 0)
598aaa76 2090 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 2091 else
598aaa76 2092 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 2093 }
19936277 2094 }
252b5132 2095 }
a7fd1186 2096 else if (rel_type == reltype_rela)
f7a99963 2097 {
7360e63f 2098 bfd_vma off = rels[i].r_addend;
e04d7088
L
2099
2100 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 2101 if ((bfd_signed_vma) off < 0)
e04d7088
L
2102 printf ("-%" BFD_VMA_FMT "x", - off);
2103 else
2104 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 2105 }
252b5132 2106
dda8d76d 2107 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2108 && rtype != NULL
2109 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 2110 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 2111
252b5132 2112 putchar ('\n');
2c71103e 2113
aca88567 2114#ifdef BFD64
dda8d76d 2115 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2116 {
91d6fa6a
NC
2117 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
2118 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2119 const char * rtype2 = elf_mips_reloc_type (type2);
2120 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2121
2c71103e
NC
2122 printf (" Type2: ");
2123
2124 if (rtype2 == NULL)
39dbeff8
AM
2125 printf (_("unrecognized: %-7lx"),
2126 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2127 else
2128 printf ("%-17.17s", rtype2);
2129
18bd398b 2130 printf ("\n Type3: ");
2c71103e
NC
2131
2132 if (rtype3 == NULL)
39dbeff8
AM
2133 printf (_("unrecognized: %-7lx"),
2134 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2135 else
2136 printf ("%-17.17s", rtype3);
2137
53c7db4b 2138 putchar ('\n');
2c71103e 2139 }
aca88567 2140#endif /* BFD64 */
252b5132
RH
2141 }
2142
c8286bd1 2143 free (rels);
32ec8896
NC
2144
2145 return res;
252b5132
RH
2146}
2147
37c18eed
SD
2148static const char *
2149get_aarch64_dynamic_type (unsigned long type)
2150{
2151 switch (type)
2152 {
2153 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2154 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2155 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2156 default:
2157 return NULL;
2158 }
2159}
2160
252b5132 2161static const char *
d3ba0551 2162get_mips_dynamic_type (unsigned long type)
252b5132
RH
2163{
2164 switch (type)
2165 {
2166 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2167 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2168 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2169 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2170 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2171 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2172 case DT_MIPS_MSYM: return "MIPS_MSYM";
2173 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2174 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2175 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2176 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2177 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2178 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2179 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2180 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2181 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2182 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2183 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2184 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2185 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2186 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2187 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2188 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2189 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2190 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2191 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2192 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2193 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2194 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2195 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2196 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2197 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2198 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2199 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2200 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2201 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2202 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2203 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2204 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2205 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2206 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2207 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2208 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2209 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2210 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2211 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2212 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2213 default:
2214 return NULL;
2215 }
2216}
2217
9a097730 2218static const char *
d3ba0551 2219get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2220{
2221 switch (type)
2222 {
2223 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2224 default:
2225 return NULL;
2226 }
103f02d3
UD
2227}
2228
7490d522
AM
2229static const char *
2230get_ppc_dynamic_type (unsigned long type)
2231{
2232 switch (type)
2233 {
a7f2871e 2234 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2235 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2236 default:
2237 return NULL;
2238 }
2239}
2240
f1cb7e17 2241static const char *
d3ba0551 2242get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2243{
2244 switch (type)
2245 {
a7f2871e
AM
2246 case DT_PPC64_GLINK: return "PPC64_GLINK";
2247 case DT_PPC64_OPD: return "PPC64_OPD";
2248 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2249 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2250 default:
2251 return NULL;
2252 }
2253}
2254
103f02d3 2255static const char *
d3ba0551 2256get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2257{
2258 switch (type)
2259 {
2260 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2261 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2262 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2263 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2264 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2265 case DT_HP_PREINIT: return "HP_PREINIT";
2266 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2267 case DT_HP_NEEDED: return "HP_NEEDED";
2268 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2269 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2270 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2271 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2272 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2273 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2274 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2275 case DT_HP_FILTERED: return "HP_FILTERED";
2276 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2277 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2278 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2279 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2280 case DT_PLT: return "PLT";
2281 case DT_PLT_SIZE: return "PLT_SIZE";
2282 case DT_DLT: return "DLT";
2283 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2284 default:
2285 return NULL;
2286 }
2287}
9a097730 2288
ecc51f48 2289static const char *
d3ba0551 2290get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2291{
2292 switch (type)
2293 {
148b93f2
NC
2294 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2295 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2296 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2297 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2298 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2299 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2300 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2301 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2302 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2303 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2304 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2305 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2306 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2307 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2308 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2309 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2310 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2311 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2312 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2313 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2314 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2315 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2316 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2317 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2318 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2319 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2320 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2321 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2322 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2323 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2324 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2325 default:
2326 return NULL;
2327 }
2328}
2329
fd85a6a1
NC
2330static const char *
2331get_solaris_section_type (unsigned long type)
2332{
2333 switch (type)
2334 {
2335 case 0x6fffffee: return "SUNW_ancillary";
2336 case 0x6fffffef: return "SUNW_capchain";
2337 case 0x6ffffff0: return "SUNW_capinfo";
2338 case 0x6ffffff1: return "SUNW_symsort";
2339 case 0x6ffffff2: return "SUNW_tlssort";
2340 case 0x6ffffff3: return "SUNW_LDYNSYM";
2341 case 0x6ffffff4: return "SUNW_dof";
2342 case 0x6ffffff5: return "SUNW_cap";
2343 case 0x6ffffff6: return "SUNW_SIGNATURE";
2344 case 0x6ffffff7: return "SUNW_ANNOTATE";
2345 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2346 case 0x6ffffff9: return "SUNW_DEBUG";
2347 case 0x6ffffffa: return "SUNW_move";
2348 case 0x6ffffffb: return "SUNW_COMDAT";
2349 case 0x6ffffffc: return "SUNW_syminfo";
2350 case 0x6ffffffd: return "SUNW_verdef";
2351 case 0x6ffffffe: return "SUNW_verneed";
2352 case 0x6fffffff: return "SUNW_versym";
2353 case 0x70000000: return "SPARC_GOTDATA";
2354 default: return NULL;
2355 }
2356}
2357
fabcb361
RH
2358static const char *
2359get_alpha_dynamic_type (unsigned long type)
2360{
2361 switch (type)
2362 {
2363 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2364 default: return NULL;
fabcb361
RH
2365 }
2366}
2367
1c0d3aa6
NC
2368static const char *
2369get_score_dynamic_type (unsigned long type)
2370{
2371 switch (type)
2372 {
2373 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2374 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2375 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2376 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2377 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2378 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2379 default: return NULL;
1c0d3aa6
NC
2380 }
2381}
2382
40b36596
JM
2383static const char *
2384get_tic6x_dynamic_type (unsigned long type)
2385{
2386 switch (type)
2387 {
2388 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2389 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2390 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2391 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2392 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2393 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2394 default: return NULL;
40b36596
JM
2395 }
2396}
1c0d3aa6 2397
36591ba1
SL
2398static const char *
2399get_nios2_dynamic_type (unsigned long type)
2400{
2401 switch (type)
2402 {
2403 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2404 default: return NULL;
36591ba1
SL
2405 }
2406}
2407
fd85a6a1
NC
2408static const char *
2409get_solaris_dynamic_type (unsigned long type)
2410{
2411 switch (type)
2412 {
2413 case 0x6000000d: return "SUNW_AUXILIARY";
2414 case 0x6000000e: return "SUNW_RTLDINF";
2415 case 0x6000000f: return "SUNW_FILTER";
2416 case 0x60000010: return "SUNW_CAP";
2417 case 0x60000011: return "SUNW_SYMTAB";
2418 case 0x60000012: return "SUNW_SYMSZ";
2419 case 0x60000013: return "SUNW_SORTENT";
2420 case 0x60000014: return "SUNW_SYMSORT";
2421 case 0x60000015: return "SUNW_SYMSORTSZ";
2422 case 0x60000016: return "SUNW_TLSSORT";
2423 case 0x60000017: return "SUNW_TLSSORTSZ";
2424 case 0x60000018: return "SUNW_CAPINFO";
2425 case 0x60000019: return "SUNW_STRPAD";
2426 case 0x6000001a: return "SUNW_CAPCHAIN";
2427 case 0x6000001b: return "SUNW_LDMACH";
2428 case 0x6000001d: return "SUNW_CAPCHAINENT";
2429 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2430 case 0x60000021: return "SUNW_PARENT";
2431 case 0x60000023: return "SUNW_ASLR";
2432 case 0x60000025: return "SUNW_RELAX";
2433 case 0x60000029: return "SUNW_NXHEAP";
2434 case 0x6000002b: return "SUNW_NXSTACK";
2435
2436 case 0x70000001: return "SPARC_REGISTER";
2437 case 0x7ffffffd: return "AUXILIARY";
2438 case 0x7ffffffe: return "USED";
2439 case 0x7fffffff: return "FILTER";
2440
15f205b1 2441 default: return NULL;
fd85a6a1
NC
2442 }
2443}
2444
8155b853
NC
2445static const char *
2446get_riscv_dynamic_type (unsigned long type)
2447{
2448 switch (type)
2449 {
2450 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2451 default:
2452 return NULL;
2453 }
2454}
2455
252b5132 2456static const char *
dda8d76d 2457get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2458{
e9e44622 2459 static char buff[64];
252b5132
RH
2460
2461 switch (type)
2462 {
2463 case DT_NULL: return "NULL";
2464 case DT_NEEDED: return "NEEDED";
2465 case DT_PLTRELSZ: return "PLTRELSZ";
2466 case DT_PLTGOT: return "PLTGOT";
2467 case DT_HASH: return "HASH";
2468 case DT_STRTAB: return "STRTAB";
2469 case DT_SYMTAB: return "SYMTAB";
2470 case DT_RELA: return "RELA";
2471 case DT_RELASZ: return "RELASZ";
2472 case DT_RELAENT: return "RELAENT";
2473 case DT_STRSZ: return "STRSZ";
2474 case DT_SYMENT: return "SYMENT";
2475 case DT_INIT: return "INIT";
2476 case DT_FINI: return "FINI";
2477 case DT_SONAME: return "SONAME";
2478 case DT_RPATH: return "RPATH";
2479 case DT_SYMBOLIC: return "SYMBOLIC";
2480 case DT_REL: return "REL";
2481 case DT_RELSZ: return "RELSZ";
2482 case DT_RELENT: return "RELENT";
dd207c13
FS
2483 case DT_RELR: return "RELR";
2484 case DT_RELRSZ: return "RELRSZ";
2485 case DT_RELRENT: return "RELRENT";
252b5132
RH
2486 case DT_PLTREL: return "PLTREL";
2487 case DT_DEBUG: return "DEBUG";
2488 case DT_TEXTREL: return "TEXTREL";
2489 case DT_JMPREL: return "JMPREL";
2490 case DT_BIND_NOW: return "BIND_NOW";
2491 case DT_INIT_ARRAY: return "INIT_ARRAY";
2492 case DT_FINI_ARRAY: return "FINI_ARRAY";
2493 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2494 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2495 case DT_RUNPATH: return "RUNPATH";
2496 case DT_FLAGS: return "FLAGS";
2d0e6f43 2497
d1133906
NC
2498 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2499 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2500 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2501
05107a46 2502 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2503 case DT_PLTPADSZ: return "PLTPADSZ";
2504 case DT_MOVEENT: return "MOVEENT";
2505 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2506 case DT_FEATURE: return "FEATURE";
252b5132
RH
2507 case DT_POSFLAG_1: return "POSFLAG_1";
2508 case DT_SYMINSZ: return "SYMINSZ";
2509 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2510
252b5132 2511 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2512 case DT_CONFIG: return "CONFIG";
2513 case DT_DEPAUDIT: return "DEPAUDIT";
2514 case DT_AUDIT: return "AUDIT";
2515 case DT_PLTPAD: return "PLTPAD";
2516 case DT_MOVETAB: return "MOVETAB";
252b5132 2517 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2518
252b5132 2519 case DT_VERSYM: return "VERSYM";
103f02d3 2520
67a4f2b7
AO
2521 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2522 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2523 case DT_RELACOUNT: return "RELACOUNT";
2524 case DT_RELCOUNT: return "RELCOUNT";
2525 case DT_FLAGS_1: return "FLAGS_1";
2526 case DT_VERDEF: return "VERDEF";
2527 case DT_VERDEFNUM: return "VERDEFNUM";
2528 case DT_VERNEED: return "VERNEED";
2529 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2530
019148e4 2531 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2532 case DT_USED: return "USED";
2533 case DT_FILTER: return "FILTER";
103f02d3 2534
047b2264
JJ
2535 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2536 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2537 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2538 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2539 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2540 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2541 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2542
252b5132
RH
2543 default:
2544 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2545 {
2cf0635d 2546 const char * result;
103f02d3 2547
dda8d76d 2548 switch (filedata->file_header.e_machine)
252b5132 2549 {
37c18eed
SD
2550 case EM_AARCH64:
2551 result = get_aarch64_dynamic_type (type);
2552 break;
252b5132 2553 case EM_MIPS:
4fe85591 2554 case EM_MIPS_RS3_LE:
252b5132
RH
2555 result = get_mips_dynamic_type (type);
2556 break;
9a097730
RH
2557 case EM_SPARCV9:
2558 result = get_sparc64_dynamic_type (type);
2559 break;
7490d522
AM
2560 case EM_PPC:
2561 result = get_ppc_dynamic_type (type);
2562 break;
f1cb7e17
AM
2563 case EM_PPC64:
2564 result = get_ppc64_dynamic_type (type);
2565 break;
ecc51f48
NC
2566 case EM_IA_64:
2567 result = get_ia64_dynamic_type (type);
2568 break;
fabcb361
RH
2569 case EM_ALPHA:
2570 result = get_alpha_dynamic_type (type);
2571 break;
1c0d3aa6
NC
2572 case EM_SCORE:
2573 result = get_score_dynamic_type (type);
2574 break;
40b36596
JM
2575 case EM_TI_C6000:
2576 result = get_tic6x_dynamic_type (type);
2577 break;
36591ba1
SL
2578 case EM_ALTERA_NIOS2:
2579 result = get_nios2_dynamic_type (type);
2580 break;
8155b853
NC
2581 case EM_RISCV:
2582 result = get_riscv_dynamic_type (type);
2583 break;
252b5132 2584 default:
dda8d76d 2585 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2586 result = get_solaris_dynamic_type (type);
2587 else
2588 result = NULL;
252b5132
RH
2589 break;
2590 }
2591
2592 if (result != NULL)
2593 return result;
2594
e9e44622 2595 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2596 }
eec8f817 2597 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2598 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2599 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2600 {
2cf0635d 2601 const char * result;
103f02d3 2602
dda8d76d 2603 switch (filedata->file_header.e_machine)
103f02d3
UD
2604 {
2605 case EM_PARISC:
2606 result = get_parisc_dynamic_type (type);
2607 break;
148b93f2
NC
2608 case EM_IA_64:
2609 result = get_ia64_dynamic_type (type);
2610 break;
103f02d3 2611 default:
dda8d76d 2612 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2613 result = get_solaris_dynamic_type (type);
2614 else
2615 result = NULL;
103f02d3
UD
2616 break;
2617 }
2618
2619 if (result != NULL)
2620 return result;
2621
e9e44622
JJ
2622 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2623 type);
103f02d3 2624 }
252b5132 2625 else
e9e44622 2626 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2627
252b5132
RH
2628 return buff;
2629 }
2630}
2631
93df3340
AM
2632static bool get_program_headers (Filedata *);
2633static bool get_dynamic_section (Filedata *);
2634
2635static void
2636locate_dynamic_section (Filedata *filedata)
2637{
2638 unsigned long dynamic_addr = 0;
2639 bfd_size_type dynamic_size = 0;
2640
2641 if (filedata->file_header.e_phnum != 0
2642 && get_program_headers (filedata))
2643 {
2644 Elf_Internal_Phdr *segment;
2645 unsigned int i;
2646
2647 for (i = 0, segment = filedata->program_headers;
2648 i < filedata->file_header.e_phnum;
2649 i++, segment++)
2650 {
2651 if (segment->p_type == PT_DYNAMIC)
2652 {
2653 dynamic_addr = segment->p_offset;
2654 dynamic_size = segment->p_filesz;
2655
2656 if (filedata->section_headers != NULL)
2657 {
2658 Elf_Internal_Shdr *sec;
2659
2660 sec = find_section (filedata, ".dynamic");
2661 if (sec != NULL)
2662 {
2663 if (sec->sh_size == 0
2664 || sec->sh_type == SHT_NOBITS)
2665 {
2666 dynamic_addr = 0;
2667 dynamic_size = 0;
2668 }
2669 else
2670 {
2671 dynamic_addr = sec->sh_offset;
2672 dynamic_size = sec->sh_size;
2673 }
2674 }
2675 }
2676
2677 if (dynamic_addr > filedata->file_size
2678 || (dynamic_size > filedata->file_size - dynamic_addr))
2679 {
2680 dynamic_addr = 0;
2681 dynamic_size = 0;
2682 }
2683 break;
2684 }
2685 }
2686 }
2687 filedata->dynamic_addr = dynamic_addr;
2688 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2689}
2690
2691static bool
2692is_pie (Filedata *filedata)
2693{
2694 Elf_Internal_Dyn *entry;
2695
2696 if (filedata->dynamic_size == 0)
2697 locate_dynamic_section (filedata);
2698 if (filedata->dynamic_size <= 1)
2699 return false;
2700
2701 if (!get_dynamic_section (filedata))
2702 return false;
2703
2704 for (entry = filedata->dynamic_section;
2705 entry < filedata->dynamic_section + filedata->dynamic_nent;
2706 entry++)
2707 {
2708 if (entry->d_tag == DT_FLAGS_1)
2709 {
2710 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2711 return true;
2712 break;
2713 }
2714 }
2715 return false;
2716}
2717
252b5132 2718static char *
93df3340 2719get_file_type (Filedata *filedata)
252b5132 2720{
93df3340 2721 unsigned e_type = filedata->file_header.e_type;
89246a0e 2722 static char buff[64];
252b5132
RH
2723
2724 switch (e_type)
2725 {
32ec8896
NC
2726 case ET_NONE: return _("NONE (None)");
2727 case ET_REL: return _("REL (Relocatable file)");
2728 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2729 case ET_DYN:
2730 if (is_pie (filedata))
2731 return _("DYN (Position-Independent Executable file)");
2732 else
2733 return _("DYN (Shared object file)");
32ec8896 2734 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2735
2736 default:
2737 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2738 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2739 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2740 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2741 else
e9e44622 2742 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2743 return buff;
2744 }
2745}
2746
2747static char *
d3ba0551 2748get_machine_name (unsigned e_machine)
252b5132 2749{
b34976b6 2750 static char buff[64]; /* XXX */
252b5132
RH
2751
2752 switch (e_machine)
2753 {
55e22ca8
NC
2754 /* Please keep this switch table sorted by increasing EM_ value. */
2755 /* 0 */
c45021f2
NC
2756 case EM_NONE: return _("None");
2757 case EM_M32: return "WE32100";
2758 case EM_SPARC: return "Sparc";
2759 case EM_386: return "Intel 80386";
2760 case EM_68K: return "MC68000";
2761 case EM_88K: return "MC88000";
22abe556 2762 case EM_IAMCU: return "Intel MCU";
fb70ec17 2763 case EM_860: return "Intel 80860";
c45021f2
NC
2764 case EM_MIPS: return "MIPS R3000";
2765 case EM_S370: return "IBM System/370";
55e22ca8 2766 /* 10 */
7036c0e1 2767 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2768 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2769 case EM_PARISC: return "HPPA";
55e22ca8 2770 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2771 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2772 case EM_960: return "Intel 80960";
c45021f2 2773 case EM_PPC: return "PowerPC";
55e22ca8 2774 /* 20 */
285d1771 2775 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2776 case EM_S390_OLD:
2777 case EM_S390: return "IBM S/390";
2778 case EM_SPU: return "SPU";
2779 /* 30 */
2780 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2781 case EM_FR20: return "Fujitsu FR20";
2782 case EM_RH32: return "TRW RH32";
b34976b6 2783 case EM_MCORE: return "MCORE";
55e22ca8 2784 /* 40 */
7036c0e1
AJ
2785 case EM_ARM: return "ARM";
2786 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2787 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2788 case EM_SPARCV9: return "Sparc v9";
2789 case EM_TRICORE: return "Siemens Tricore";
584da044 2790 case EM_ARC: return "ARC";
c2dcd04e
NC
2791 case EM_H8_300: return "Renesas H8/300";
2792 case EM_H8_300H: return "Renesas H8/300H";
2793 case EM_H8S: return "Renesas H8S";
2794 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2795 /* 50 */
30800947 2796 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2797 case EM_MIPS_X: return "Stanford MIPS-X";
2798 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2799 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2800 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2801 case EM_PCP: return "Siemens PCP";
2802 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2803 case EM_NDR1: return "Denso NDR1 microprocesspr";
2804 case EM_STARCORE: return "Motorola Star*Core processor";
2805 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2806 /* 60 */
7036c0e1
AJ
2807 case EM_ST100: return "STMicroelectronics ST100 processor";
2808 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2809 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2810 case EM_PDSP: return "Sony DSP processor";
2811 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2812 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2813 case EM_FX66: return "Siemens FX66 microcontroller";
2814 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2815 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2816 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2817 /* 70 */
7036c0e1
AJ
2818 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2819 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2820 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2821 case EM_SVX: return "Silicon Graphics SVx";
2822 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2823 case EM_VAX: return "Digital VAX";
1b61cf92 2824 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2825 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2826 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2827 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2828 /* 80 */
b34976b6 2829 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2830 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2831 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2832 case EM_AVR_OLD:
2833 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2834 case EM_CYGNUS_FR30:
2835 case EM_FR30: return "Fujitsu FR30";
2836 case EM_CYGNUS_D10V:
2837 case EM_D10V: return "d10v";
2838 case EM_CYGNUS_D30V:
2839 case EM_D30V: return "d30v";
2840 case EM_CYGNUS_V850:
2841 case EM_V850: return "Renesas V850";
2842 case EM_CYGNUS_M32R:
2843 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2844 case EM_CYGNUS_MN10300:
2845 case EM_MN10300: return "mn10300";
2846 /* 90 */
2847 case EM_CYGNUS_MN10200:
2848 case EM_MN10200: return "mn10200";
2849 case EM_PJ: return "picoJava";
73589c9d 2850 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2851 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2852 case EM_XTENSA_OLD:
2853 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2854 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2855 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2856 case EM_NS32K: return "National Semiconductor 32000 series";
2857 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2858 case EM_SNP1K: return "Trebia SNP 1000 processor";
2859 /* 100 */
9abca702 2860 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2861 case EM_IP2K_OLD:
2862 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2863 case EM_MAX: return "MAX Processor";
2864 case EM_CR: return "National Semiconductor CompactRISC";
2865 case EM_F2MC16: return "Fujitsu F2MC16";
2866 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2867 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2868 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2869 case EM_SEP: return "Sharp embedded microprocessor";
2870 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2871 /* 110 */
11636f9e
JM
2872 case EM_UNICORE: return "Unicore";
2873 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2874 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2875 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2876 case EM_CRX: return "National Semiconductor CRX microprocessor";
2877 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2878 case EM_C166:
d70c5fc7 2879 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2880 case EM_M16C: return "Renesas M16C series microprocessors";
2881 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2882 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2883 /* 120 */
2884 case EM_M32C: return "Renesas M32c";
2885 /* 130 */
11636f9e
JM
2886 case EM_TSK3000: return "Altium TSK3000 core";
2887 case EM_RS08: return "Freescale RS08 embedded processor";
2888 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2889 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2890 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2891 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2892 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2893 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2894 /* 140 */
11636f9e
JM
2895 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2896 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2897 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2898 case EM_TI_PRU: return "TI PRU I/O processor";
2899 /* 160 */
11636f9e
JM
2900 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2901 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2902 case EM_R32C: return "Renesas R32C series microprocessors";
2903 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2904 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2905 case EM_8051: return "Intel 8051 and variants";
2906 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2907 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2908 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2909 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2910 /* 170 */
11636f9e
JM
2911 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2912 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2913 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2914 case EM_RX: return "Renesas RX";
a3c62988 2915 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2916 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2917 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2918 case EM_CR16:
2919 case EM_MICROBLAZE:
2920 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2921 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2922 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2923 /* 180 */
2924 case EM_L1OM: return "Intel L1OM";
2925 case EM_K1OM: return "Intel K1OM";
2926 case EM_INTEL182: return "Intel (reserved)";
2927 case EM_AARCH64: return "AArch64";
2928 case EM_ARM184: return "ARM (reserved)";
2929 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2930 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2931 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2932 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2933 /* 190 */
11636f9e 2934 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2935 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2936 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2937 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2938 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2939 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2940 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2941 case EM_RL78: return "Renesas RL78";
6d913794 2942 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2943 case EM_78K0R: return "Renesas 78K0R";
2944 /* 200 */
6d913794 2945 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2946 case EM_BA1: return "Beyond BA1 CPU architecture";
2947 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2948 case EM_XCORE: return "XMOS xCORE processor family";
2949 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2950 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2951 /* 210 */
6d913794
NC
2952 case EM_KM32: return "KM211 KM32 32-bit processor";
2953 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2954 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2955 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2956 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2957 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2958 case EM_COGE: return "Cognitive Smart Memory Processor";
2959 case EM_COOL: return "Bluechip Systems CoolEngine";
2960 case EM_NORC: return "Nanoradio Optimized RISC";
2961 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2962 /* 220 */
15f205b1 2963 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2964 case EM_VISIUM: return "CDS VISIUMcore processor";
2965 case EM_FT32: return "FTDI Chip FT32";
2966 case EM_MOXIE: return "Moxie";
2967 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2968 /* 230 (all reserved) */
2969 /* 240 */
55e22ca8
NC
2970 case EM_RISCV: return "RISC-V";
2971 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2972 case EM_CEVA: return "CEVA Processor Architecture Family";
2973 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2974 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2975 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2976 case EM_IMG1: return "Imagination Technologies";
2977 /* 250 */
fe944acf 2978 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2979 case EM_VE: return "NEC Vector Engine";
2980 case EM_CSKY: return "C-SKY";
2981 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2982 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2983 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2984 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2985 case EM_65816: return "WDC 65816/65C816";
01a8c731 2986 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2987 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2988
2989 /* Large numbers... */
2990 case EM_MT: return "Morpho Techologies MT processor";
2991 case EM_ALPHA: return "Alpha";
2992 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2993 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2994 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2995 case EM_IQ2000: return "Vitesse IQ2000";
2996 case EM_M32C_OLD:
2997 case EM_NIOS32: return "Altera Nios";
2998 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2999 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3000 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3001 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3002
252b5132 3003 default:
35d9dd2f 3004 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3005 return buff;
3006 }
3007}
3008
a9522a21
AB
3009static void
3010decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
3011{
3012 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3013 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3014 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3015 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3016 architectures.
3017
3018 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3019 but also sets a specific architecture type in the e_flags field.
3020
3021 However, when decoding the flags we don't worry if we see an
3022 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3023 ARCEM architecture type. */
3024
3025 switch (e_flags & EF_ARC_MACH_MSK)
3026 {
3027 /* We only expect these to occur for EM_ARC_COMPACT2. */
3028 case EF_ARC_CPU_ARCV2EM:
3029 strcat (buf, ", ARC EM");
3030 break;
3031 case EF_ARC_CPU_ARCV2HS:
3032 strcat (buf, ", ARC HS");
3033 break;
3034
3035 /* We only expect these to occur for EM_ARC_COMPACT. */
3036 case E_ARC_MACH_ARC600:
3037 strcat (buf, ", ARC600");
3038 break;
3039 case E_ARC_MACH_ARC601:
3040 strcat (buf, ", ARC601");
3041 break;
3042 case E_ARC_MACH_ARC700:
3043 strcat (buf, ", ARC700");
3044 break;
3045
3046 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3047 new ELF with new architecture being read by an old version of
3048 readelf, or (c) An ELF built with non-GNU compiler that does not
3049 set the architecture in the e_flags. */
3050 default:
3051 if (e_machine == EM_ARC_COMPACT)
3052 strcat (buf, ", Unknown ARCompact");
3053 else
3054 strcat (buf, ", Unknown ARC");
3055 break;
3056 }
3057
3058 switch (e_flags & EF_ARC_OSABI_MSK)
3059 {
3060 case E_ARC_OSABI_ORIG:
3061 strcat (buf, ", (ABI:legacy)");
3062 break;
3063 case E_ARC_OSABI_V2:
3064 strcat (buf, ", (ABI:v2)");
3065 break;
3066 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3067 case E_ARC_OSABI_V3:
3068 strcat (buf, ", v3 no-legacy-syscalls ABI");
3069 break;
53a346d8
CZ
3070 case E_ARC_OSABI_V4:
3071 strcat (buf, ", v4 ABI");
3072 break;
a9522a21
AB
3073 default:
3074 strcat (buf, ", unrecognised ARC OSABI flag");
3075 break;
3076 }
3077}
3078
f3485b74 3079static void
d3ba0551 3080decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3081{
3082 unsigned eabi;
015dc7e1 3083 bool unknown = false;
f3485b74
NC
3084
3085 eabi = EF_ARM_EABI_VERSION (e_flags);
3086 e_flags &= ~ EF_ARM_EABIMASK;
3087
3088 /* Handle "generic" ARM flags. */
3089 if (e_flags & EF_ARM_RELEXEC)
3090 {
3091 strcat (buf, ", relocatable executable");
3092 e_flags &= ~ EF_ARM_RELEXEC;
3093 }
76da6bbe 3094
18a20338
CL
3095 if (e_flags & EF_ARM_PIC)
3096 {
3097 strcat (buf, ", position independent");
3098 e_flags &= ~ EF_ARM_PIC;
3099 }
3100
f3485b74
NC
3101 /* Now handle EABI specific flags. */
3102 switch (eabi)
3103 {
3104 default:
2c71103e 3105 strcat (buf, ", <unrecognized EABI>");
f3485b74 3106 if (e_flags)
015dc7e1 3107 unknown = true;
f3485b74
NC
3108 break;
3109
3110 case EF_ARM_EABI_VER1:
a5bcd848 3111 strcat (buf, ", Version1 EABI");
f3485b74
NC
3112 while (e_flags)
3113 {
3114 unsigned flag;
76da6bbe 3115
f3485b74
NC
3116 /* Process flags one bit at a time. */
3117 flag = e_flags & - e_flags;
3118 e_flags &= ~ flag;
76da6bbe 3119
f3485b74
NC
3120 switch (flag)
3121 {
a5bcd848 3122 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3123 strcat (buf, ", sorted symbol tables");
3124 break;
76da6bbe 3125
f3485b74 3126 default:
015dc7e1 3127 unknown = true;
f3485b74
NC
3128 break;
3129 }
3130 }
3131 break;
76da6bbe 3132
a5bcd848
PB
3133 case EF_ARM_EABI_VER2:
3134 strcat (buf, ", Version2 EABI");
3135 while (e_flags)
3136 {
3137 unsigned flag;
3138
3139 /* Process flags one bit at a time. */
3140 flag = e_flags & - e_flags;
3141 e_flags &= ~ flag;
3142
3143 switch (flag)
3144 {
3145 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3146 strcat (buf, ", sorted symbol tables");
3147 break;
3148
3149 case EF_ARM_DYNSYMSUSESEGIDX:
3150 strcat (buf, ", dynamic symbols use segment index");
3151 break;
3152
3153 case EF_ARM_MAPSYMSFIRST:
3154 strcat (buf, ", mapping symbols precede others");
3155 break;
3156
3157 default:
015dc7e1 3158 unknown = true;
a5bcd848
PB
3159 break;
3160 }
3161 }
3162 break;
3163
d507cf36
PB
3164 case EF_ARM_EABI_VER3:
3165 strcat (buf, ", Version3 EABI");
8cb51566
PB
3166 break;
3167
3168 case EF_ARM_EABI_VER4:
3169 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3170 while (e_flags)
3171 {
3172 unsigned flag;
3173
3174 /* Process flags one bit at a time. */
3175 flag = e_flags & - e_flags;
3176 e_flags &= ~ flag;
3177
3178 switch (flag)
3179 {
3180 case EF_ARM_BE8:
3181 strcat (buf, ", BE8");
3182 break;
3183
3184 case EF_ARM_LE8:
3185 strcat (buf, ", LE8");
3186 break;
3187
3188 default:
015dc7e1 3189 unknown = true;
3bfcb652
NC
3190 break;
3191 }
3bfcb652
NC
3192 }
3193 break;
3a4a14e9
PB
3194
3195 case EF_ARM_EABI_VER5:
3196 strcat (buf, ", Version5 EABI");
d507cf36
PB
3197 while (e_flags)
3198 {
3199 unsigned flag;
3200
3201 /* Process flags one bit at a time. */
3202 flag = e_flags & - e_flags;
3203 e_flags &= ~ flag;
3204
3205 switch (flag)
3206 {
3207 case EF_ARM_BE8:
3208 strcat (buf, ", BE8");
3209 break;
3210
3211 case EF_ARM_LE8:
3212 strcat (buf, ", LE8");
3213 break;
3214
3bfcb652
NC
3215 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3216 strcat (buf, ", soft-float ABI");
3217 break;
3218
3219 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3220 strcat (buf, ", hard-float ABI");
3221 break;
3222
d507cf36 3223 default:
015dc7e1 3224 unknown = true;
d507cf36
PB
3225 break;
3226 }
3227 }
3228 break;
3229
f3485b74 3230 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3231 strcat (buf, ", GNU EABI");
f3485b74
NC
3232 while (e_flags)
3233 {
3234 unsigned flag;
76da6bbe 3235
f3485b74
NC
3236 /* Process flags one bit at a time. */
3237 flag = e_flags & - e_flags;
3238 e_flags &= ~ flag;
76da6bbe 3239
f3485b74
NC
3240 switch (flag)
3241 {
a5bcd848 3242 case EF_ARM_INTERWORK:
f3485b74
NC
3243 strcat (buf, ", interworking enabled");
3244 break;
76da6bbe 3245
a5bcd848 3246 case EF_ARM_APCS_26:
f3485b74
NC
3247 strcat (buf, ", uses APCS/26");
3248 break;
76da6bbe 3249
a5bcd848 3250 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3251 strcat (buf, ", uses APCS/float");
3252 break;
76da6bbe 3253
a5bcd848 3254 case EF_ARM_PIC:
f3485b74
NC
3255 strcat (buf, ", position independent");
3256 break;
76da6bbe 3257
a5bcd848 3258 case EF_ARM_ALIGN8:
f3485b74
NC
3259 strcat (buf, ", 8 bit structure alignment");
3260 break;
76da6bbe 3261
a5bcd848 3262 case EF_ARM_NEW_ABI:
f3485b74
NC
3263 strcat (buf, ", uses new ABI");
3264 break;
76da6bbe 3265
a5bcd848 3266 case EF_ARM_OLD_ABI:
f3485b74
NC
3267 strcat (buf, ", uses old ABI");
3268 break;
76da6bbe 3269
a5bcd848 3270 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3271 strcat (buf, ", software FP");
3272 break;
76da6bbe 3273
90e01f86
ILT
3274 case EF_ARM_VFP_FLOAT:
3275 strcat (buf, ", VFP");
3276 break;
3277
fde78edd
NC
3278 case EF_ARM_MAVERICK_FLOAT:
3279 strcat (buf, ", Maverick FP");
3280 break;
3281
f3485b74 3282 default:
015dc7e1 3283 unknown = true;
f3485b74
NC
3284 break;
3285 }
3286 }
3287 }
f3485b74
NC
3288
3289 if (unknown)
2b692964 3290 strcat (buf,_(", <unknown>"));
f3485b74
NC
3291}
3292
343433df
AB
3293static void
3294decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3295{
3296 --size; /* Leave space for null terminator. */
3297
3298 switch (e_flags & EF_AVR_MACH)
3299 {
3300 case E_AVR_MACH_AVR1:
3301 strncat (buf, ", avr:1", size);
3302 break;
3303 case E_AVR_MACH_AVR2:
3304 strncat (buf, ", avr:2", size);
3305 break;
3306 case E_AVR_MACH_AVR25:
3307 strncat (buf, ", avr:25", size);
3308 break;
3309 case E_AVR_MACH_AVR3:
3310 strncat (buf, ", avr:3", size);
3311 break;
3312 case E_AVR_MACH_AVR31:
3313 strncat (buf, ", avr:31", size);
3314 break;
3315 case E_AVR_MACH_AVR35:
3316 strncat (buf, ", avr:35", size);
3317 break;
3318 case E_AVR_MACH_AVR4:
3319 strncat (buf, ", avr:4", size);
3320 break;
3321 case E_AVR_MACH_AVR5:
3322 strncat (buf, ", avr:5", size);
3323 break;
3324 case E_AVR_MACH_AVR51:
3325 strncat (buf, ", avr:51", size);
3326 break;
3327 case E_AVR_MACH_AVR6:
3328 strncat (buf, ", avr:6", size);
3329 break;
3330 case E_AVR_MACH_AVRTINY:
3331 strncat (buf, ", avr:100", size);
3332 break;
3333 case E_AVR_MACH_XMEGA1:
3334 strncat (buf, ", avr:101", size);
3335 break;
3336 case E_AVR_MACH_XMEGA2:
3337 strncat (buf, ", avr:102", size);
3338 break;
3339 case E_AVR_MACH_XMEGA3:
3340 strncat (buf, ", avr:103", size);
3341 break;
3342 case E_AVR_MACH_XMEGA4:
3343 strncat (buf, ", avr:104", size);
3344 break;
3345 case E_AVR_MACH_XMEGA5:
3346 strncat (buf, ", avr:105", size);
3347 break;
3348 case E_AVR_MACH_XMEGA6:
3349 strncat (buf, ", avr:106", size);
3350 break;
3351 case E_AVR_MACH_XMEGA7:
3352 strncat (buf, ", avr:107", size);
3353 break;
3354 default:
3355 strncat (buf, ", avr:<unknown>", size);
3356 break;
3357 }
3358
3359 size -= strlen (buf);
3360 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3361 strncat (buf, ", link-relax", size);
3362}
3363
35c08157
KLC
3364static void
3365decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3366{
3367 unsigned abi;
3368 unsigned arch;
3369 unsigned config;
3370 unsigned version;
015dc7e1 3371 bool has_fpu = false;
32ec8896 3372 unsigned int r = 0;
35c08157
KLC
3373
3374 static const char *ABI_STRINGS[] =
3375 {
3376 "ABI v0", /* use r5 as return register; only used in N1213HC */
3377 "ABI v1", /* use r0 as return register */
3378 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3379 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3380 "AABI",
3381 "ABI2 FP+"
35c08157
KLC
3382 };
3383 static const char *VER_STRINGS[] =
3384 {
3385 "Andes ELF V1.3 or older",
3386 "Andes ELF V1.3.1",
3387 "Andes ELF V1.4"
3388 };
3389 static const char *ARCH_STRINGS[] =
3390 {
3391 "",
3392 "Andes Star v1.0",
3393 "Andes Star v2.0",
3394 "Andes Star v3.0",
3395 "Andes Star v3.0m"
3396 };
3397
3398 abi = EF_NDS_ABI & e_flags;
3399 arch = EF_NDS_ARCH & e_flags;
3400 config = EF_NDS_INST & e_flags;
3401 version = EF_NDS32_ELF_VERSION & e_flags;
3402
3403 memset (buf, 0, size);
3404
3405 switch (abi)
3406 {
3407 case E_NDS_ABI_V0:
3408 case E_NDS_ABI_V1:
3409 case E_NDS_ABI_V2:
3410 case E_NDS_ABI_V2FP:
3411 case E_NDS_ABI_AABI:
40c7a7cb 3412 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3413 /* In case there are holes in the array. */
3414 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3415 break;
3416
3417 default:
3418 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3419 break;
3420 }
3421
3422 switch (version)
3423 {
3424 case E_NDS32_ELF_VER_1_2:
3425 case E_NDS32_ELF_VER_1_3:
3426 case E_NDS32_ELF_VER_1_4:
3427 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3428 break;
3429
3430 default:
3431 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3432 break;
3433 }
3434
3435 if (E_NDS_ABI_V0 == abi)
3436 {
3437 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3438 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3439 if (arch == E_NDS_ARCH_STAR_V1_0)
3440 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3441 return;
3442 }
3443
3444 switch (arch)
3445 {
3446 case E_NDS_ARCH_STAR_V1_0:
3447 case E_NDS_ARCH_STAR_V2_0:
3448 case E_NDS_ARCH_STAR_V3_0:
3449 case E_NDS_ARCH_STAR_V3_M:
3450 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3451 break;
3452
3453 default:
3454 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3455 /* ARCH version determines how the e_flags are interpreted.
3456 If it is unknown, we cannot proceed. */
3457 return;
3458 }
3459
3460 /* Newer ABI; Now handle architecture specific flags. */
3461 if (arch == E_NDS_ARCH_STAR_V1_0)
3462 {
3463 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3464 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3465
3466 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3467 r += snprintf (buf + r, size -r, ", MAC");
3468
3469 if (config & E_NDS32_HAS_DIV_INST)
3470 r += snprintf (buf + r, size -r, ", DIV");
3471
3472 if (config & E_NDS32_HAS_16BIT_INST)
3473 r += snprintf (buf + r, size -r, ", 16b");
3474 }
3475 else
3476 {
3477 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3478 {
3479 if (version <= E_NDS32_ELF_VER_1_3)
3480 r += snprintf (buf + r, size -r, ", [B8]");
3481 else
3482 r += snprintf (buf + r, size -r, ", EX9");
3483 }
3484
3485 if (config & E_NDS32_HAS_MAC_DX_INST)
3486 r += snprintf (buf + r, size -r, ", MAC_DX");
3487
3488 if (config & E_NDS32_HAS_DIV_DX_INST)
3489 r += snprintf (buf + r, size -r, ", DIV_DX");
3490
3491 if (config & E_NDS32_HAS_16BIT_INST)
3492 {
3493 if (version <= E_NDS32_ELF_VER_1_3)
3494 r += snprintf (buf + r, size -r, ", 16b");
3495 else
3496 r += snprintf (buf + r, size -r, ", IFC");
3497 }
3498 }
3499
3500 if (config & E_NDS32_HAS_EXT_INST)
3501 r += snprintf (buf + r, size -r, ", PERF1");
3502
3503 if (config & E_NDS32_HAS_EXT2_INST)
3504 r += snprintf (buf + r, size -r, ", PERF2");
3505
3506 if (config & E_NDS32_HAS_FPU_INST)
3507 {
015dc7e1 3508 has_fpu = true;
35c08157
KLC
3509 r += snprintf (buf + r, size -r, ", FPU_SP");
3510 }
3511
3512 if (config & E_NDS32_HAS_FPU_DP_INST)
3513 {
015dc7e1 3514 has_fpu = true;
35c08157
KLC
3515 r += snprintf (buf + r, size -r, ", FPU_DP");
3516 }
3517
3518 if (config & E_NDS32_HAS_FPU_MAC_INST)
3519 {
015dc7e1 3520 has_fpu = true;
35c08157
KLC
3521 r += snprintf (buf + r, size -r, ", FPU_MAC");
3522 }
3523
3524 if (has_fpu)
3525 {
3526 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3527 {
3528 case E_NDS32_FPU_REG_8SP_4DP:
3529 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3530 break;
3531 case E_NDS32_FPU_REG_16SP_8DP:
3532 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3533 break;
3534 case E_NDS32_FPU_REG_32SP_16DP:
3535 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3536 break;
3537 case E_NDS32_FPU_REG_32SP_32DP:
3538 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3539 break;
3540 }
3541 }
3542
3543 if (config & E_NDS32_HAS_AUDIO_INST)
3544 r += snprintf (buf + r, size -r, ", AUDIO");
3545
3546 if (config & E_NDS32_HAS_STRING_INST)
3547 r += snprintf (buf + r, size -r, ", STR");
3548
3549 if (config & E_NDS32_HAS_REDUCED_REGS)
3550 r += snprintf (buf + r, size -r, ", 16REG");
3551
3552 if (config & E_NDS32_HAS_VIDEO_INST)
3553 {
3554 if (version <= E_NDS32_ELF_VER_1_3)
3555 r += snprintf (buf + r, size -r, ", VIDEO");
3556 else
3557 r += snprintf (buf + r, size -r, ", SATURATION");
3558 }
3559
3560 if (config & E_NDS32_HAS_ENCRIPT_INST)
3561 r += snprintf (buf + r, size -r, ", ENCRP");
3562
3563 if (config & E_NDS32_HAS_L2C_INST)
3564 r += snprintf (buf + r, size -r, ", L2C");
3565}
3566
252b5132 3567static char *
dda8d76d 3568get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3569{
b34976b6 3570 static char buf[1024];
252b5132
RH
3571
3572 buf[0] = '\0';
76da6bbe 3573
252b5132
RH
3574 if (e_flags)
3575 {
3576 switch (e_machine)
3577 {
3578 default:
3579 break;
3580
886a2506 3581 case EM_ARC_COMPACT2:
886a2506 3582 case EM_ARC_COMPACT:
a9522a21
AB
3583 decode_ARC_machine_flags (e_flags, e_machine, buf);
3584 break;
886a2506 3585
f3485b74
NC
3586 case EM_ARM:
3587 decode_ARM_machine_flags (e_flags, buf);
3588 break;
76da6bbe 3589
343433df
AB
3590 case EM_AVR:
3591 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3592 break;
3593
781303ce
MF
3594 case EM_BLACKFIN:
3595 if (e_flags & EF_BFIN_PIC)
3596 strcat (buf, ", PIC");
3597
3598 if (e_flags & EF_BFIN_FDPIC)
3599 strcat (buf, ", FDPIC");
3600
3601 if (e_flags & EF_BFIN_CODE_IN_L1)
3602 strcat (buf, ", code in L1");
3603
3604 if (e_flags & EF_BFIN_DATA_IN_L1)
3605 strcat (buf, ", data in L1");
3606
3607 break;
3608
ec2dfb42
AO
3609 case EM_CYGNUS_FRV:
3610 switch (e_flags & EF_FRV_CPU_MASK)
3611 {
3612 case EF_FRV_CPU_GENERIC:
3613 break;
3614
3615 default:
3616 strcat (buf, ", fr???");
3617 break;
57346661 3618
ec2dfb42
AO
3619 case EF_FRV_CPU_FR300:
3620 strcat (buf, ", fr300");
3621 break;
3622
3623 case EF_FRV_CPU_FR400:
3624 strcat (buf, ", fr400");
3625 break;
3626 case EF_FRV_CPU_FR405:
3627 strcat (buf, ", fr405");
3628 break;
3629
3630 case EF_FRV_CPU_FR450:
3631 strcat (buf, ", fr450");
3632 break;
3633
3634 case EF_FRV_CPU_FR500:
3635 strcat (buf, ", fr500");
3636 break;
3637 case EF_FRV_CPU_FR550:
3638 strcat (buf, ", fr550");
3639 break;
3640
3641 case EF_FRV_CPU_SIMPLE:
3642 strcat (buf, ", simple");
3643 break;
3644 case EF_FRV_CPU_TOMCAT:
3645 strcat (buf, ", tomcat");
3646 break;
3647 }
1c877e87 3648 break;
ec2dfb42 3649
53c7db4b 3650 case EM_68K:
425c6cb0 3651 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3652 strcat (buf, ", m68000");
425c6cb0 3653 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3654 strcat (buf, ", cpu32");
3655 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3656 strcat (buf, ", fido_a");
425c6cb0 3657 else
266abb8f 3658 {
2cf0635d
NC
3659 char const * isa = _("unknown");
3660 char const * mac = _("unknown mac");
3661 char const * additional = NULL;
0112cd26 3662
c694fd50 3663 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3664 {
c694fd50 3665 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3666 isa = "A";
3667 additional = ", nodiv";
3668 break;
c694fd50 3669 case EF_M68K_CF_ISA_A:
266abb8f
NS
3670 isa = "A";
3671 break;
c694fd50 3672 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3673 isa = "A+";
3674 break;
c694fd50 3675 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3676 isa = "B";
3677 additional = ", nousp";
3678 break;
c694fd50 3679 case EF_M68K_CF_ISA_B:
266abb8f
NS
3680 isa = "B";
3681 break;
f608cd77
NS
3682 case EF_M68K_CF_ISA_C:
3683 isa = "C";
3684 break;
3685 case EF_M68K_CF_ISA_C_NODIV:
3686 isa = "C";
3687 additional = ", nodiv";
3688 break;
266abb8f
NS
3689 }
3690 strcat (buf, ", cf, isa ");
3691 strcat (buf, isa);
0b2e31dc
NS
3692 if (additional)
3693 strcat (buf, additional);
c694fd50 3694 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3695 strcat (buf, ", float");
c694fd50 3696 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3697 {
3698 case 0:
3699 mac = NULL;
3700 break;
c694fd50 3701 case EF_M68K_CF_MAC:
266abb8f
NS
3702 mac = "mac";
3703 break;
c694fd50 3704 case EF_M68K_CF_EMAC:
266abb8f
NS
3705 mac = "emac";
3706 break;
f608cd77
NS
3707 case EF_M68K_CF_EMAC_B:
3708 mac = "emac_b";
3709 break;
266abb8f
NS
3710 }
3711 if (mac)
3712 {
3713 strcat (buf, ", ");
3714 strcat (buf, mac);
3715 }
266abb8f 3716 }
53c7db4b 3717 break;
33c63f9d 3718
153a2776
NC
3719 case EM_CYGNUS_MEP:
3720 switch (e_flags & EF_MEP_CPU_MASK)
3721 {
3722 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3723 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3724 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3725 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3726 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3727 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3728 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3729 }
3730
3731 switch (e_flags & EF_MEP_COP_MASK)
3732 {
3733 case EF_MEP_COP_NONE: break;
3734 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3735 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3736 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3737 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3738 default: strcat (buf, _("<unknown MeP copro type>")); break;
3739 }
3740
3741 if (e_flags & EF_MEP_LIBRARY)
3742 strcat (buf, ", Built for Library");
3743
3744 if (e_flags & EF_MEP_INDEX_MASK)
3745 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3746 e_flags & EF_MEP_INDEX_MASK);
3747
3748 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3749 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3750 e_flags & ~ EF_MEP_ALL_FLAGS);
3751 break;
3752
252b5132
RH
3753 case EM_PPC:
3754 if (e_flags & EF_PPC_EMB)
3755 strcat (buf, ", emb");
3756
3757 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3758 strcat (buf, _(", relocatable"));
252b5132
RH
3759
3760 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3761 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3762 break;
3763
ee67d69a
AM
3764 case EM_PPC64:
3765 if (e_flags & EF_PPC64_ABI)
3766 {
3767 char abi[] = ", abiv0";
3768
3769 abi[6] += e_flags & EF_PPC64_ABI;
3770 strcat (buf, abi);
3771 }
3772 break;
3773
708e2187
NC
3774 case EM_V800:
3775 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3776 strcat (buf, ", RH850 ABI");
0b4362b0 3777
708e2187
NC
3778 if (e_flags & EF_V800_850E3)
3779 strcat (buf, ", V3 architecture");
3780
3781 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3782 strcat (buf, ", FPU not used");
3783
3784 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3785 strcat (buf, ", regmode: COMMON");
3786
3787 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3788 strcat (buf, ", r4 not used");
3789
3790 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3791 strcat (buf, ", r30 not used");
3792
3793 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3794 strcat (buf, ", r5 not used");
3795
3796 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3797 strcat (buf, ", r2 not used");
3798
3799 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3800 {
3801 switch (e_flags & - e_flags)
3802 {
3803 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3804 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3805 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3806 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3807 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3808 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3809 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3810 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3811 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3812 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3813 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3814 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3815 default: break;
3816 }
3817 }
3818 break;
3819
2b0337b0 3820 case EM_V850:
252b5132
RH
3821 case EM_CYGNUS_V850:
3822 switch (e_flags & EF_V850_ARCH)
3823 {
78c8d46c
NC
3824 case E_V850E3V5_ARCH:
3825 strcat (buf, ", v850e3v5");
3826 break;
1cd986c5
NC
3827 case E_V850E2V3_ARCH:
3828 strcat (buf, ", v850e2v3");
3829 break;
3830 case E_V850E2_ARCH:
3831 strcat (buf, ", v850e2");
3832 break;
3833 case E_V850E1_ARCH:
3834 strcat (buf, ", v850e1");
8ad30312 3835 break;
252b5132
RH
3836 case E_V850E_ARCH:
3837 strcat (buf, ", v850e");
3838 break;
252b5132
RH
3839 case E_V850_ARCH:
3840 strcat (buf, ", v850");
3841 break;
3842 default:
2b692964 3843 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3844 break;
3845 }
3846 break;
3847
2b0337b0 3848 case EM_M32R:
252b5132
RH
3849 case EM_CYGNUS_M32R:
3850 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3851 strcat (buf, ", m32r");
252b5132
RH
3852 break;
3853
3854 case EM_MIPS:
4fe85591 3855 case EM_MIPS_RS3_LE:
252b5132
RH
3856 if (e_flags & EF_MIPS_NOREORDER)
3857 strcat (buf, ", noreorder");
3858
3859 if (e_flags & EF_MIPS_PIC)
3860 strcat (buf, ", pic");
3861
3862 if (e_flags & EF_MIPS_CPIC)
3863 strcat (buf, ", cpic");
3864
d1bdd336
TS
3865 if (e_flags & EF_MIPS_UCODE)
3866 strcat (buf, ", ugen_reserved");
3867
252b5132
RH
3868 if (e_flags & EF_MIPS_ABI2)
3869 strcat (buf, ", abi2");
3870
43521d43
TS
3871 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3872 strcat (buf, ", odk first");
3873
a5d22d2a
TS
3874 if (e_flags & EF_MIPS_32BITMODE)
3875 strcat (buf, ", 32bitmode");
3876
ba92f887
MR
3877 if (e_flags & EF_MIPS_NAN2008)
3878 strcat (buf, ", nan2008");
3879
fef1b0b3
SE
3880 if (e_flags & EF_MIPS_FP64)
3881 strcat (buf, ", fp64");
3882
156c2f8b
NC
3883 switch ((e_flags & EF_MIPS_MACH))
3884 {
3885 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3886 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3887 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3888 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3889 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3890 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3891 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3892 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3893 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3894 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3895 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3896 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3897 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3898 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3899 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3900 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3901 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3902 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3903 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3904 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3905 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3906 case 0:
3907 /* We simply ignore the field in this case to avoid confusion:
3908 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3909 extension. */
3910 break;
2b692964 3911 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3912 }
43521d43
TS
3913
3914 switch ((e_flags & EF_MIPS_ABI))
3915 {
3916 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3917 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3918 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3919 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3920 case 0:
3921 /* We simply ignore the field in this case to avoid confusion:
3922 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3923 This means it is likely to be an o32 file, but not for
3924 sure. */
3925 break;
2b692964 3926 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3927 }
3928
3929 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3930 strcat (buf, ", mdmx");
3931
3932 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3933 strcat (buf, ", mips16");
3934
df58fc94
RS
3935 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3936 strcat (buf, ", micromips");
3937
43521d43
TS
3938 switch ((e_flags & EF_MIPS_ARCH))
3939 {
3940 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3941 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3942 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3943 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3944 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3945 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3946 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3947 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3948 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3949 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3950 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3951 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3952 }
252b5132 3953 break;
351b4b40 3954
35c08157
KLC
3955 case EM_NDS32:
3956 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3957 break;
3958
fe944acf
FT
3959 case EM_NFP:
3960 switch (EF_NFP_MACH (e_flags))
3961 {
3962 case E_NFP_MACH_3200:
3963 strcat (buf, ", NFP-32xx");
3964 break;
3965 case E_NFP_MACH_6000:
3966 strcat (buf, ", NFP-6xxx");
3967 break;
3968 }
3969 break;
3970
e23eba97
NC
3971 case EM_RISCV:
3972 if (e_flags & EF_RISCV_RVC)
3973 strcat (buf, ", RVC");
2922d21d 3974
7f999549
JW
3975 if (e_flags & EF_RISCV_RVE)
3976 strcat (buf, ", RVE");
3977
2922d21d
AW
3978 switch (e_flags & EF_RISCV_FLOAT_ABI)
3979 {
3980 case EF_RISCV_FLOAT_ABI_SOFT:
3981 strcat (buf, ", soft-float ABI");
3982 break;
3983
3984 case EF_RISCV_FLOAT_ABI_SINGLE:
3985 strcat (buf, ", single-float ABI");
3986 break;
3987
3988 case EF_RISCV_FLOAT_ABI_DOUBLE:
3989 strcat (buf, ", double-float ABI");
3990 break;
3991
3992 case EF_RISCV_FLOAT_ABI_QUAD:
3993 strcat (buf, ", quad-float ABI");
3994 break;
3995 }
e23eba97
NC
3996 break;
3997
ccde1100
AO
3998 case EM_SH:
3999 switch ((e_flags & EF_SH_MACH_MASK))
4000 {
4001 case EF_SH1: strcat (buf, ", sh1"); break;
4002 case EF_SH2: strcat (buf, ", sh2"); break;
4003 case EF_SH3: strcat (buf, ", sh3"); break;
4004 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4005 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4006 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4007 case EF_SH3E: strcat (buf, ", sh3e"); break;
4008 case EF_SH4: strcat (buf, ", sh4"); break;
4009 case EF_SH5: strcat (buf, ", sh5"); break;
4010 case EF_SH2E: strcat (buf, ", sh2e"); break;
4011 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4012 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4013 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4014 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4015 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4016 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4017 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4018 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4019 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4020 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4021 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4022 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4023 }
4024
cec6a5b8
MR
4025 if (e_flags & EF_SH_PIC)
4026 strcat (buf, ", pic");
4027
4028 if (e_flags & EF_SH_FDPIC)
4029 strcat (buf, ", fdpic");
ccde1100 4030 break;
948f632f 4031
73589c9d
CS
4032 case EM_OR1K:
4033 if (e_flags & EF_OR1K_NODELAY)
4034 strcat (buf, ", no delay");
4035 break;
57346661 4036
351b4b40
RH
4037 case EM_SPARCV9:
4038 if (e_flags & EF_SPARC_32PLUS)
4039 strcat (buf, ", v8+");
4040
4041 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4042 strcat (buf, ", ultrasparcI");
4043
4044 if (e_flags & EF_SPARC_SUN_US3)
4045 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4046
4047 if (e_flags & EF_SPARC_HAL_R1)
4048 strcat (buf, ", halr1");
4049
4050 if (e_flags & EF_SPARC_LEDATA)
4051 strcat (buf, ", ledata");
4052
4053 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4054 strcat (buf, ", tso");
4055
4056 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4057 strcat (buf, ", pso");
4058
4059 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4060 strcat (buf, ", rmo");
4061 break;
7d466069 4062
103f02d3
UD
4063 case EM_PARISC:
4064 switch (e_flags & EF_PARISC_ARCH)
4065 {
4066 case EFA_PARISC_1_0:
4067 strcpy (buf, ", PA-RISC 1.0");
4068 break;
4069 case EFA_PARISC_1_1:
4070 strcpy (buf, ", PA-RISC 1.1");
4071 break;
4072 case EFA_PARISC_2_0:
4073 strcpy (buf, ", PA-RISC 2.0");
4074 break;
4075 default:
4076 break;
4077 }
4078 if (e_flags & EF_PARISC_TRAPNIL)
4079 strcat (buf, ", trapnil");
4080 if (e_flags & EF_PARISC_EXT)
4081 strcat (buf, ", ext");
4082 if (e_flags & EF_PARISC_LSB)
4083 strcat (buf, ", lsb");
4084 if (e_flags & EF_PARISC_WIDE)
4085 strcat (buf, ", wide");
4086 if (e_flags & EF_PARISC_NO_KABP)
4087 strcat (buf, ", no kabp");
4088 if (e_flags & EF_PARISC_LAZYSWAP)
4089 strcat (buf, ", lazyswap");
30800947 4090 break;
76da6bbe 4091
7d466069 4092 case EM_PJ:
2b0337b0 4093 case EM_PJ_OLD:
7d466069
ILT
4094 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4095 strcat (buf, ", new calling convention");
4096
4097 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4098 strcat (buf, ", gnu calling convention");
4099 break;
4d6ed7c8
NC
4100
4101 case EM_IA_64:
4102 if ((e_flags & EF_IA_64_ABI64))
4103 strcat (buf, ", 64-bit");
4104 else
4105 strcat (buf, ", 32-bit");
4106 if ((e_flags & EF_IA_64_REDUCEDFP))
4107 strcat (buf, ", reduced fp model");
4108 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4109 strcat (buf, ", no function descriptors, constant gp");
4110 else if ((e_flags & EF_IA_64_CONS_GP))
4111 strcat (buf, ", constant gp");
4112 if ((e_flags & EF_IA_64_ABSOLUTE))
4113 strcat (buf, ", absolute");
dda8d76d 4114 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4115 {
4116 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4117 strcat (buf, ", vms_linkages");
4118 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4119 {
4120 case EF_IA_64_VMS_COMCOD_SUCCESS:
4121 break;
4122 case EF_IA_64_VMS_COMCOD_WARNING:
4123 strcat (buf, ", warning");
4124 break;
4125 case EF_IA_64_VMS_COMCOD_ERROR:
4126 strcat (buf, ", error");
4127 break;
4128 case EF_IA_64_VMS_COMCOD_ABORT:
4129 strcat (buf, ", abort");
4130 break;
4131 default:
bee0ee85
NC
4132 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4133 e_flags & EF_IA_64_VMS_COMCOD);
4134 strcat (buf, ", <unknown>");
28f997cf
TG
4135 }
4136 }
4d6ed7c8 4137 break;
179d3252
JT
4138
4139 case EM_VAX:
4140 if ((e_flags & EF_VAX_NONPIC))
4141 strcat (buf, ", non-PIC");
4142 if ((e_flags & EF_VAX_DFLOAT))
4143 strcat (buf, ", D-Float");
4144 if ((e_flags & EF_VAX_GFLOAT))
4145 strcat (buf, ", G-Float");
4146 break;
c7927a3c 4147
619ed720
EB
4148 case EM_VISIUM:
4149 if (e_flags & EF_VISIUM_ARCH_MCM)
4150 strcat (buf, ", mcm");
4151 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4152 strcat (buf, ", mcm24");
4153 if (e_flags & EF_VISIUM_ARCH_GR6)
4154 strcat (buf, ", gr6");
4155 break;
4156
4046d87a 4157 case EM_RL78:
1740ba0c
NC
4158 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4159 {
4160 case E_FLAG_RL78_ANY_CPU: break;
4161 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4162 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4163 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4164 }
856ea05c
KP
4165 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4166 strcat (buf, ", 64-bit doubles");
4046d87a 4167 break;
0b4362b0 4168
c7927a3c
NC
4169 case EM_RX:
4170 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4171 strcat (buf, ", 64-bit doubles");
4172 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4173 strcat (buf, ", dsp");
d4cb0ea0 4174 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4175 strcat (buf, ", pid");
708e2187
NC
4176 if (e_flags & E_FLAG_RX_ABI)
4177 strcat (buf, ", RX ABI");
3525236c
NC
4178 if (e_flags & E_FLAG_RX_SINSNS_SET)
4179 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4180 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4181 if (e_flags & E_FLAG_RX_V2)
4182 strcat (buf, ", V2");
f87673e0
YS
4183 if (e_flags & E_FLAG_RX_V3)
4184 strcat (buf, ", V3");
d4cb0ea0 4185 break;
55786da2
AK
4186
4187 case EM_S390:
4188 if (e_flags & EF_S390_HIGH_GPRS)
4189 strcat (buf, ", highgprs");
d4cb0ea0 4190 break;
40b36596
JM
4191
4192 case EM_TI_C6000:
4193 if ((e_flags & EF_C6000_REL))
4194 strcat (buf, ", relocatable module");
d4cb0ea0 4195 break;
13761a11
NC
4196
4197 case EM_MSP430:
4198 strcat (buf, _(": architecture variant: "));
4199 switch (e_flags & EF_MSP430_MACH)
4200 {
4201 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4202 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4203 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4204 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4205 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4206 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4207 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4208 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4209 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4210 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4211 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4212 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4213 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4214 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4215 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4216 default:
4217 strcat (buf, _(": unknown")); break;
4218 }
4219
4220 if (e_flags & ~ EF_MSP430_MACH)
4221 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4222 break;
4223
4224 case EM_Z80:
4225 switch (e_flags & EF_Z80_MACH_MSK)
4226 {
4227 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4228 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4229 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4230 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4231 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4232 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4233 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4234 default:
4235 strcat (buf, _(", unknown")); break;
4236 }
4237 break;
e9a0721f 4238 case EM_LOONGARCH:
4239 if (EF_LOONGARCH_IS_LP64 (e_flags))
4240 strcat (buf, ", LP64");
4241 else if (EF_LOONGARCH_IS_ILP32 (e_flags))
4242 strcat (buf, ", ILP32");
4243
4244 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4245 strcat (buf, ", SOFT-FLOAT");
4246 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4247 strcat (buf, ", SINGLE-FLOAT");
4248 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4249 strcat (buf, ", DOUBLE-FLOAT");
4250
4251 break;
252b5132
RH
4252 }
4253 }
4254
4255 return buf;
4256}
4257
252b5132 4258static const char *
dda8d76d 4259get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4260{
4261 static char buff[32];
4262
4263 switch (osabi)
4264 {
4265 case ELFOSABI_NONE: return "UNIX - System V";
4266 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4267 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4268 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4269 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4270 case ELFOSABI_AIX: return "UNIX - AIX";
4271 case ELFOSABI_IRIX: return "UNIX - IRIX";
4272 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4273 case ELFOSABI_TRU64: return "UNIX - TRU64";
4274 case ELFOSABI_MODESTO: return "Novell - Modesto";
4275 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4276 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4277 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4278 case ELFOSABI_AROS: return "AROS";
11636f9e 4279 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4280 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4281 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4282 default:
40b36596 4283 if (osabi >= 64)
dda8d76d 4284 switch (filedata->file_header.e_machine)
40b36596
JM
4285 {
4286 case EM_ARM:
4287 switch (osabi)
4288 {
4289 case ELFOSABI_ARM: return "ARM";
18a20338 4290 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4291 default:
4292 break;
4293 }
4294 break;
4295
4296 case EM_MSP430:
4297 case EM_MSP430_OLD:
619ed720 4298 case EM_VISIUM:
40b36596
JM
4299 switch (osabi)
4300 {
4301 case ELFOSABI_STANDALONE: return _("Standalone App");
4302 default:
4303 break;
4304 }
4305 break;
4306
4307 case EM_TI_C6000:
4308 switch (osabi)
4309 {
4310 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4311 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4312 default:
4313 break;
4314 }
4315 break;
4316
4317 default:
4318 break;
4319 }
e9e44622 4320 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4321 return buff;
4322 }
4323}
4324
a06ea964
NC
4325static const char *
4326get_aarch64_segment_type (unsigned long type)
4327{
4328 switch (type)
4329 {
32ec8896
NC
4330 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
4331 default: return NULL;
a06ea964 4332 }
a06ea964
NC
4333}
4334
b294bdf8
MM
4335static const char *
4336get_arm_segment_type (unsigned long type)
4337{
4338 switch (type)
4339 {
32ec8896
NC
4340 case PT_ARM_EXIDX: return "EXIDX";
4341 default: return NULL;
b294bdf8 4342 }
b294bdf8
MM
4343}
4344
b4cbbe8f
AK
4345static const char *
4346get_s390_segment_type (unsigned long type)
4347{
4348 switch (type)
4349 {
4350 case PT_S390_PGSTE: return "S390_PGSTE";
4351 default: return NULL;
4352 }
4353}
4354
d3ba0551
AM
4355static const char *
4356get_mips_segment_type (unsigned long type)
252b5132
RH
4357{
4358 switch (type)
4359 {
32ec8896
NC
4360 case PT_MIPS_REGINFO: return "REGINFO";
4361 case PT_MIPS_RTPROC: return "RTPROC";
4362 case PT_MIPS_OPTIONS: return "OPTIONS";
4363 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4364 default: return NULL;
252b5132 4365 }
252b5132
RH
4366}
4367
103f02d3 4368static const char *
d3ba0551 4369get_parisc_segment_type (unsigned long type)
103f02d3
UD
4370{
4371 switch (type)
4372 {
103f02d3
UD
4373 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4374 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4375 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4376 default: return NULL;
103f02d3 4377 }
103f02d3
UD
4378}
4379
4d6ed7c8 4380static const char *
d3ba0551 4381get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4382{
4383 switch (type)
4384 {
4385 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4386 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4387 default: return NULL;
4d6ed7c8 4388 }
4d6ed7c8
NC
4389}
4390
40b36596
JM
4391static const char *
4392get_tic6x_segment_type (unsigned long type)
4393{
4394 switch (type)
4395 {
32ec8896
NC
4396 case PT_C6000_PHATTR: return "C6000_PHATTR";
4397 default: return NULL;
40b36596 4398 }
40b36596
JM
4399}
4400
fbc95f1e
KC
4401static const char *
4402get_riscv_segment_type (unsigned long type)
4403{
4404 switch (type)
4405 {
4406 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4407 default: return NULL;
4408 }
4409}
4410
df3a023b
AM
4411static const char *
4412get_hpux_segment_type (unsigned long type, unsigned e_machine)
4413{
4414 if (e_machine == EM_PARISC)
4415 switch (type)
4416 {
4417 case PT_HP_TLS: return "HP_TLS";
4418 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4419 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4420 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4421 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4422 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4423 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4424 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4425 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4426 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4427 case PT_HP_PARALLEL: return "HP_PARALLEL";
4428 case PT_HP_FASTBIND: return "HP_FASTBIND";
4429 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4430 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4431 case PT_HP_STACK: return "HP_STACK";
4432 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4433 default: return NULL;
4434 }
4435
4436 if (e_machine == EM_IA_64)
4437 switch (type)
4438 {
4439 case PT_HP_TLS: return "HP_TLS";
4440 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4441 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4442 case PT_IA_64_HP_STACK: return "HP_STACK";
4443 default: return NULL;
4444 }
4445
4446 return NULL;
4447}
4448
5522f910
NC
4449static const char *
4450get_solaris_segment_type (unsigned long type)
4451{
4452 switch (type)
4453 {
4454 case 0x6464e550: return "PT_SUNW_UNWIND";
4455 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4456 case 0x6ffffff7: return "PT_LOSUNW";
4457 case 0x6ffffffa: return "PT_SUNWBSS";
4458 case 0x6ffffffb: return "PT_SUNWSTACK";
4459 case 0x6ffffffc: return "PT_SUNWDTRACE";
4460 case 0x6ffffffd: return "PT_SUNWCAP";
4461 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4462 default: return NULL;
5522f910
NC
4463 }
4464}
4465
252b5132 4466static const char *
dda8d76d 4467get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4468{
b34976b6 4469 static char buff[32];
252b5132
RH
4470
4471 switch (p_type)
4472 {
b34976b6
AM
4473 case PT_NULL: return "NULL";
4474 case PT_LOAD: return "LOAD";
252b5132 4475 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4476 case PT_INTERP: return "INTERP";
4477 case PT_NOTE: return "NOTE";
4478 case PT_SHLIB: return "SHLIB";
4479 case PT_PHDR: return "PHDR";
13ae64f3 4480 case PT_TLS: return "TLS";
32ec8896 4481 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4482 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4483 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4484 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4485
3eba3ef3
NC
4486 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4487 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4488 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4489
252b5132 4490 default:
df3a023b 4491 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4492 {
2cf0635d 4493 const char * result;
103f02d3 4494
dda8d76d 4495 switch (filedata->file_header.e_machine)
252b5132 4496 {
a06ea964
NC
4497 case EM_AARCH64:
4498 result = get_aarch64_segment_type (p_type);
4499 break;
b294bdf8
MM
4500 case EM_ARM:
4501 result = get_arm_segment_type (p_type);
4502 break;
252b5132 4503 case EM_MIPS:
4fe85591 4504 case EM_MIPS_RS3_LE:
252b5132
RH
4505 result = get_mips_segment_type (p_type);
4506 break;
103f02d3
UD
4507 case EM_PARISC:
4508 result = get_parisc_segment_type (p_type);
4509 break;
4d6ed7c8
NC
4510 case EM_IA_64:
4511 result = get_ia64_segment_type (p_type);
4512 break;
40b36596
JM
4513 case EM_TI_C6000:
4514 result = get_tic6x_segment_type (p_type);
4515 break;
b4cbbe8f
AK
4516 case EM_S390:
4517 case EM_S390_OLD:
4518 result = get_s390_segment_type (p_type);
4519 break;
fbc95f1e
KC
4520 case EM_RISCV:
4521 result = get_riscv_segment_type (p_type);
4522 break;
252b5132
RH
4523 default:
4524 result = NULL;
4525 break;
4526 }
103f02d3 4527
252b5132
RH
4528 if (result != NULL)
4529 return result;
103f02d3 4530
1a9ccd70 4531 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4532 }
4533 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4534 {
df3a023b 4535 const char * result = NULL;
103f02d3 4536
df3a023b 4537 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4538 {
df3a023b
AM
4539 case ELFOSABI_GNU:
4540 case ELFOSABI_FREEBSD:
4541 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4542 {
4543 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4544 result = buff;
4545 }
103f02d3 4546 break;
df3a023b
AM
4547 case ELFOSABI_HPUX:
4548 result = get_hpux_segment_type (p_type,
4549 filedata->file_header.e_machine);
4550 break;
4551 case ELFOSABI_SOLARIS:
4552 result = get_solaris_segment_type (p_type);
00428cca 4553 break;
103f02d3 4554 default:
103f02d3
UD
4555 break;
4556 }
103f02d3
UD
4557 if (result != NULL)
4558 return result;
4559
1a9ccd70 4560 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4561 }
252b5132 4562 else
e9e44622 4563 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4564
4565 return buff;
4566 }
4567}
4568
53a346d8
CZ
4569static const char *
4570get_arc_section_type_name (unsigned int sh_type)
4571{
4572 switch (sh_type)
4573 {
4574 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4575 default:
4576 break;
4577 }
4578 return NULL;
4579}
4580
252b5132 4581static const char *
d3ba0551 4582get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4583{
4584 switch (sh_type)
4585 {
b34976b6
AM
4586 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4587 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4588 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4589 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4590 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4591 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4592 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4593 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4594 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4595 case SHT_MIPS_RELD: return "MIPS_RELD";
4596 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4597 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4598 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4599 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4600 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4601 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4602 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4603 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4604 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4605 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4606 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4607 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4608 case SHT_MIPS_LINE: return "MIPS_LINE";
4609 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4610 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4611 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4612 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4613 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4614 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4615 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4616 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4617 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4618 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4619 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4620 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4621 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4622 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4623 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4624 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4625 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4626 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4627 default:
4628 break;
4629 }
4630 return NULL;
4631}
4632
103f02d3 4633static const char *
d3ba0551 4634get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4635{
4636 switch (sh_type)
4637 {
4638 case SHT_PARISC_EXT: return "PARISC_EXT";
4639 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4640 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4641 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4642 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4643 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4644 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4645 default: return NULL;
103f02d3 4646 }
103f02d3
UD
4647}
4648
4d6ed7c8 4649static const char *
dda8d76d 4650get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4651{
18bd398b 4652 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4653 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4654 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4655
4d6ed7c8
NC
4656 switch (sh_type)
4657 {
148b93f2
NC
4658 case SHT_IA_64_EXT: return "IA_64_EXT";
4659 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4660 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4661 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4662 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4663 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4664 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4665 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4666 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4667 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4668 default:
4669 break;
4670 }
4671 return NULL;
4672}
4673
d2b2c203
DJ
4674static const char *
4675get_x86_64_section_type_name (unsigned int sh_type)
4676{
4677 switch (sh_type)
4678 {
4679 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4680 default: return NULL;
d2b2c203 4681 }
d2b2c203
DJ
4682}
4683
a06ea964
NC
4684static const char *
4685get_aarch64_section_type_name (unsigned int sh_type)
4686{
4687 switch (sh_type)
4688 {
32ec8896
NC
4689 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4690 default: return NULL;
a06ea964 4691 }
a06ea964
NC
4692}
4693
40a18ebd
NC
4694static const char *
4695get_arm_section_type_name (unsigned int sh_type)
4696{
4697 switch (sh_type)
4698 {
7f6fed87
NC
4699 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4700 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4701 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4702 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4703 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4704 default: return NULL;
40a18ebd 4705 }
40a18ebd
NC
4706}
4707
40b36596
JM
4708static const char *
4709get_tic6x_section_type_name (unsigned int sh_type)
4710{
4711 switch (sh_type)
4712 {
32ec8896
NC
4713 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4714 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4715 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4716 case SHT_TI_ICODE: return "TI_ICODE";
4717 case SHT_TI_XREF: return "TI_XREF";
4718 case SHT_TI_HANDLER: return "TI_HANDLER";
4719 case SHT_TI_INITINFO: return "TI_INITINFO";
4720 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4721 default: return NULL;
40b36596 4722 }
40b36596
JM
4723}
4724
13761a11 4725static const char *
b0191216 4726get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4727{
4728 switch (sh_type)
4729 {
32ec8896
NC
4730 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4731 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4732 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4733 default: return NULL;
13761a11
NC
4734 }
4735}
4736
fe944acf
FT
4737static const char *
4738get_nfp_section_type_name (unsigned int sh_type)
4739{
4740 switch (sh_type)
4741 {
4742 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4743 case SHT_NFP_INITREG: return "NFP_INITREG";
4744 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4745 default: return NULL;
4746 }
4747}
4748
685080f2
NC
4749static const char *
4750get_v850_section_type_name (unsigned int sh_type)
4751{
4752 switch (sh_type)
4753 {
32ec8896
NC
4754 case SHT_V850_SCOMMON: return "V850 Small Common";
4755 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4756 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4757 case SHT_RENESAS_IOP: return "RENESAS IOP";
4758 case SHT_RENESAS_INFO: return "RENESAS INFO";
4759 default: return NULL;
685080f2
NC
4760 }
4761}
4762
2dc8dd17
JW
4763static const char *
4764get_riscv_section_type_name (unsigned int sh_type)
4765{
4766 switch (sh_type)
4767 {
4768 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4769 default: return NULL;
4770 }
4771}
4772
0861f561
CQ
4773static const char *
4774get_csky_section_type_name (unsigned int sh_type)
4775{
4776 switch (sh_type)
4777 {
4778 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4779 default: return NULL;
4780 }
4781}
4782
252b5132 4783static const char *
dda8d76d 4784get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4785{
b34976b6 4786 static char buff[32];
9fb71ee4 4787 const char * result;
252b5132
RH
4788
4789 switch (sh_type)
4790 {
4791 case SHT_NULL: return "NULL";
4792 case SHT_PROGBITS: return "PROGBITS";
4793 case SHT_SYMTAB: return "SYMTAB";
4794 case SHT_STRTAB: return "STRTAB";
4795 case SHT_RELA: return "RELA";
dd207c13 4796 case SHT_RELR: return "RELR";
252b5132
RH
4797 case SHT_HASH: return "HASH";
4798 case SHT_DYNAMIC: return "DYNAMIC";
4799 case SHT_NOTE: return "NOTE";
4800 case SHT_NOBITS: return "NOBITS";
4801 case SHT_REL: return "REL";
4802 case SHT_SHLIB: return "SHLIB";
4803 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4804 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4805 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4806 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4807 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4808 case SHT_GROUP: return "GROUP";
67ce483b 4809 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4810 case SHT_GNU_verdef: return "VERDEF";
4811 case SHT_GNU_verneed: return "VERNEED";
4812 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4813 case 0x6ffffff0: return "VERSYM";
4814 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4815 case 0x7ffffffd: return "AUXILIARY";
4816 case 0x7fffffff: return "FILTER";
047b2264 4817 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4818
4819 default:
4820 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4821 {
dda8d76d 4822 switch (filedata->file_header.e_machine)
252b5132 4823 {
53a346d8
CZ
4824 case EM_ARC:
4825 case EM_ARC_COMPACT:
4826 case EM_ARC_COMPACT2:
4827 result = get_arc_section_type_name (sh_type);
4828 break;
252b5132 4829 case EM_MIPS:
4fe85591 4830 case EM_MIPS_RS3_LE:
252b5132
RH
4831 result = get_mips_section_type_name (sh_type);
4832 break;
103f02d3
UD
4833 case EM_PARISC:
4834 result = get_parisc_section_type_name (sh_type);
4835 break;
4d6ed7c8 4836 case EM_IA_64:
dda8d76d 4837 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4838 break;
d2b2c203 4839 case EM_X86_64:
8a9036a4 4840 case EM_L1OM:
7a9068fe 4841 case EM_K1OM:
d2b2c203
DJ
4842 result = get_x86_64_section_type_name (sh_type);
4843 break;
a06ea964
NC
4844 case EM_AARCH64:
4845 result = get_aarch64_section_type_name (sh_type);
4846 break;
40a18ebd
NC
4847 case EM_ARM:
4848 result = get_arm_section_type_name (sh_type);
4849 break;
40b36596
JM
4850 case EM_TI_C6000:
4851 result = get_tic6x_section_type_name (sh_type);
4852 break;
13761a11 4853 case EM_MSP430:
b0191216 4854 result = get_msp430_section_type_name (sh_type);
13761a11 4855 break;
fe944acf
FT
4856 case EM_NFP:
4857 result = get_nfp_section_type_name (sh_type);
4858 break;
685080f2
NC
4859 case EM_V800:
4860 case EM_V850:
4861 case EM_CYGNUS_V850:
4862 result = get_v850_section_type_name (sh_type);
4863 break;
2dc8dd17
JW
4864 case EM_RISCV:
4865 result = get_riscv_section_type_name (sh_type);
4866 break;
0861f561
CQ
4867 case EM_CSKY:
4868 result = get_csky_section_type_name (sh_type);
4869 break;
252b5132
RH
4870 default:
4871 result = NULL;
4872 break;
4873 }
4874
4875 if (result != NULL)
4876 return result;
4877
9fb71ee4 4878 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4879 }
4880 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4881 {
dda8d76d 4882 switch (filedata->file_header.e_machine)
148b93f2
NC
4883 {
4884 case EM_IA_64:
dda8d76d 4885 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4886 break;
4887 default:
dda8d76d 4888 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4889 result = get_solaris_section_type (sh_type);
4890 else
1b4b80bf
NC
4891 {
4892 switch (sh_type)
4893 {
4894 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4895 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4896 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4897 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4898 default:
4899 result = NULL;
4900 break;
4901 }
4902 }
148b93f2
NC
4903 break;
4904 }
4905
4906 if (result != NULL)
4907 return result;
4908
9fb71ee4 4909 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4910 }
252b5132 4911 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4912 {
dda8d76d 4913 switch (filedata->file_header.e_machine)
685080f2
NC
4914 {
4915 case EM_V800:
4916 case EM_V850:
4917 case EM_CYGNUS_V850:
9fb71ee4 4918 result = get_v850_section_type_name (sh_type);
a9fb83be 4919 break;
685080f2 4920 default:
9fb71ee4 4921 result = NULL;
685080f2
NC
4922 break;
4923 }
4924
9fb71ee4
NC
4925 if (result != NULL)
4926 return result;
4927
4928 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4929 }
252b5132 4930 else
a7dbfd1c
NC
4931 /* This message is probably going to be displayed in a 15
4932 character wide field, so put the hex value first. */
4933 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4934
252b5132
RH
4935 return buff;
4936 }
4937}
4938
79bc120c
NC
4939enum long_option_values
4940{
4941 OPTION_DEBUG_DUMP = 512,
4942 OPTION_DYN_SYMS,
0f03783c 4943 OPTION_LTO_SYMS,
79bc120c
NC
4944 OPTION_DWARF_DEPTH,
4945 OPTION_DWARF_START,
4946 OPTION_DWARF_CHECK,
4947 OPTION_CTF_DUMP,
4948 OPTION_CTF_PARENT,
4949 OPTION_CTF_SYMBOLS,
4950 OPTION_CTF_STRINGS,
4951 OPTION_WITH_SYMBOL_VERSIONS,
4952 OPTION_RECURSE_LIMIT,
4953 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
4954 OPTION_NO_DEMANGLING,
4955 OPTION_SYM_BASE
79bc120c 4956};
2979dc34 4957
85b1c36d 4958static struct option options[] =
252b5132 4959{
79bc120c
NC
4960 /* Note - This table is alpha-sorted on the 'val'
4961 field in order to make adding new options easier. */
4962 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4963 {"all", no_argument, 0, 'a'},
79bc120c
NC
4964 {"demangle", optional_argument, 0, 'C'},
4965 {"archive-index", no_argument, 0, 'c'},
4966 {"use-dynamic", no_argument, 0, 'D'},
4967 {"dynamic", no_argument, 0, 'd'},
b34976b6 4968 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4969 {"section-groups", no_argument, 0, 'g'},
4970 {"help", no_argument, 0, 'H'},
4971 {"file-header", no_argument, 0, 'h'},
b34976b6 4972 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4973 {"lint", no_argument, 0, 'L'},
4974 {"enable-checks", no_argument, 0, 'L'},
4975 {"program-headers", no_argument, 0, 'l'},
b34976b6 4976 {"segments", no_argument, 0, 'l'},
595cf52e 4977 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4978 {"notes", no_argument, 0, 'n'},
ca0e11aa 4979 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4980 {"string-dump", required_argument, 0, 'p'},
4981 {"relocated-dump", required_argument, 0, 'R'},
4982 {"relocs", no_argument, 0, 'r'},
4983 {"section-headers", no_argument, 0, 'S'},
4984 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4985 {"symbols", no_argument, 0, 's'},
4986 {"syms", no_argument, 0, 's'},
79bc120c
NC
4987 {"silent-truncation",no_argument, 0, 'T'},
4988 {"section-details", no_argument, 0, 't'},
b3aa80b4 4989 {"unicode", required_argument, NULL, 'U'},
09c11c86 4990 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4991 {"version-info", no_argument, 0, 'V'},
4992 {"version", no_argument, 0, 'v'},
4993 {"wide", no_argument, 0, 'W'},
b34976b6 4994 {"hex-dump", required_argument, 0, 'x'},
0e602686 4995 {"decompress", no_argument, 0, 'z'},
252b5132 4996
79bc120c
NC
4997 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4998 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4999 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5000 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5001 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5002 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5003 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5004 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5005 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5006 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5007#ifdef ENABLE_LIBCTF
d344b407 5008 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5009 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5010 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5011 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5012#endif
047c3dbf 5013 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5014
b34976b6 5015 {0, no_argument, 0, 0}
252b5132
RH
5016};
5017
5018static void
2cf0635d 5019usage (FILE * stream)
252b5132 5020{
92f01d61
JM
5021 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5022 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5023 fprintf (stream, _(" Options are:\n"));
5024 fprintf (stream, _("\
5025 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5026 fprintf (stream, _("\
5027 -h --file-header Display the ELF file header\n"));
5028 fprintf (stream, _("\
5029 -l --program-headers Display the program headers\n"));
5030 fprintf (stream, _("\
5031 --segments An alias for --program-headers\n"));
5032 fprintf (stream, _("\
5033 -S --section-headers Display the sections' header\n"));
5034 fprintf (stream, _("\
5035 --sections An alias for --section-headers\n"));
5036 fprintf (stream, _("\
5037 -g --section-groups Display the section groups\n"));
5038 fprintf (stream, _("\
5039 -t --section-details Display the section details\n"));
5040 fprintf (stream, _("\
5041 -e --headers Equivalent to: -h -l -S\n"));
5042 fprintf (stream, _("\
5043 -s --syms Display the symbol table\n"));
5044 fprintf (stream, _("\
5045 --symbols An alias for --syms\n"));
5046 fprintf (stream, _("\
5047 --dyn-syms Display the dynamic symbol table\n"));
5048 fprintf (stream, _("\
5049 --lto-syms Display LTO symbol tables\n"));
5050 fprintf (stream, _("\
047c3dbf
NL
5051 --sym-base=[0|8|10|16] \n\
5052 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5053 mixed (the default), octal, decimal, hexadecimal.\n"));
5054 fprintf (stream, _("\
0d646226
AM
5055 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5056 display_demangler_styles (stream, _("\
5057 STYLE can be "));
d6249f5f
AM
5058 fprintf (stream, _("\
5059 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5060 fprintf (stream, _("\
5061 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5062 fprintf (stream, _("\
5063 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5064 fprintf (stream, _("\
5065 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5066 Display unicode characters as determined by the current locale\n\
5067 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5068 escape sequences, or treat them as invalid and display as\n\
5069 \"{hex sequences}\"\n"));
d6249f5f
AM
5070 fprintf (stream, _("\
5071 -n --notes Display the core notes (if present)\n"));
5072 fprintf (stream, _("\
5073 -r --relocs Display the relocations (if present)\n"));
5074 fprintf (stream, _("\
5075 -u --unwind Display the unwind info (if present)\n"));
5076 fprintf (stream, _("\
5077 -d --dynamic Display the dynamic section (if present)\n"));
5078 fprintf (stream, _("\
5079 -V --version-info Display the version sections (if present)\n"));
5080 fprintf (stream, _("\
5081 -A --arch-specific Display architecture specific information (if any)\n"));
5082 fprintf (stream, _("\
5083 -c --archive-index Display the symbol/file index in an archive\n"));
5084 fprintf (stream, _("\
5085 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5086 fprintf (stream, _("\
5087 -L --lint|--enable-checks\n\
5088 Display warning messages for possible problems\n"));
5089 fprintf (stream, _("\
09c11c86 5090 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5091 Dump the contents of section <number|name> as bytes\n"));
5092 fprintf (stream, _("\
09c11c86 5093 -p --string-dump=<number|name>\n\
d6249f5f
AM
5094 Dump the contents of section <number|name> as strings\n"));
5095 fprintf (stream, _("\
cf13d699 5096 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5097 Dump the relocated contents of section <number|name>\n"));
5098 fprintf (stream, _("\
5099 -z --decompress Decompress section before dumping it\n"));
5100 fprintf (stream, _("\
5101 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5102 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5103 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5104 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5105 U/=trace_info]\n\
5106 Display the contents of DWARF debug sections\n"));
5107 fprintf (stream, _("\
5108 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5109 debuginfo files\n"));
5110 fprintf (stream, _("\
5111 -P --process-links Display the contents of non-debug sections in separate\n\
5112 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5113#if DEFAULT_FOR_FOLLOW_LINKS
5114 fprintf (stream, _("\
d6249f5f
AM
5115 -wK --debug-dump=follow-links\n\
5116 Follow links to separate debug info files (default)\n"));
5117 fprintf (stream, _("\
5118 -wN --debug-dump=no-follow-links\n\
5119 Do not follow links to separate debug info files\n"));
c46b7066
NC
5120#else
5121 fprintf (stream, _("\
d6249f5f
AM
5122 -wK --debug-dump=follow-links\n\
5123 Follow links to separate debug info files\n"));
5124 fprintf (stream, _("\
5125 -wN --debug-dump=no-follow-links\n\
5126 Do not follow links to separate debug info files\n\
5127 (default)\n"));
c46b7066 5128#endif
fd2f0033 5129 fprintf (stream, _("\
d6249f5f
AM
5130 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5131 fprintf (stream, _("\
5132 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5133#ifdef ENABLE_LIBCTF
7d9813f1 5134 fprintf (stream, _("\
d6249f5f
AM
5135 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5136 fprintf (stream, _("\
80b56fad 5137 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5138 fprintf (stream, _("\
7d9813f1 5139 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5140 Use section <number|name> as the CTF external symtab\n"));
5141 fprintf (stream, _("\
7d9813f1 5142 --ctf-strings=<number|name>\n\
d6249f5f 5143 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5144#endif
7d9813f1 5145
252b5132 5146#ifdef SUPPORT_DISASSEMBLY
92f01d61 5147 fprintf (stream, _("\
09c11c86
NC
5148 -i --instruction-dump=<number|name>\n\
5149 Disassemble the contents of section <number|name>\n"));
252b5132 5150#endif
92f01d61 5151 fprintf (stream, _("\
d6249f5f
AM
5152 -I --histogram Display histogram of bucket list lengths\n"));
5153 fprintf (stream, _("\
5154 -W --wide Allow output width to exceed 80 characters\n"));
5155 fprintf (stream, _("\
5156 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5157 fprintf (stream, _("\
5158 @<file> Read options from <file>\n"));
5159 fprintf (stream, _("\
5160 -H --help Display this information\n"));
5161 fprintf (stream, _("\
8b53311e 5162 -v --version Display the version number of readelf\n"));
1118d252 5163
92f01d61
JM
5164 if (REPORT_BUGS_TO[0] && stream == stdout)
5165 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5166
92f01d61 5167 exit (stream == stdout ? 0 : 1);
252b5132
RH
5168}
5169
18bd398b
NC
5170/* Record the fact that the user wants the contents of section number
5171 SECTION to be displayed using the method(s) encoded as flags bits
5172 in TYPE. Note, TYPE can be zero if we are creating the array for
5173 the first time. */
5174
252b5132 5175static void
6431e409
AM
5176request_dump_bynumber (struct dump_data *dumpdata,
5177 unsigned int section, dump_type type)
252b5132 5178{
6431e409 5179 if (section >= dumpdata->num_dump_sects)
252b5132 5180 {
2cf0635d 5181 dump_type * new_dump_sects;
252b5132 5182
3f5e193b 5183 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5184 sizeof (* new_dump_sects));
252b5132
RH
5185
5186 if (new_dump_sects == NULL)
591a748a 5187 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5188 else
5189 {
6431e409 5190 if (dumpdata->dump_sects)
21b65bac
NC
5191 {
5192 /* Copy current flag settings. */
6431e409
AM
5193 memcpy (new_dump_sects, dumpdata->dump_sects,
5194 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5195
6431e409 5196 free (dumpdata->dump_sects);
21b65bac 5197 }
252b5132 5198
6431e409
AM
5199 dumpdata->dump_sects = new_dump_sects;
5200 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5201 }
5202 }
5203
6431e409
AM
5204 if (dumpdata->dump_sects)
5205 dumpdata->dump_sects[section] |= type;
252b5132
RH
5206}
5207
aef1f6d0
DJ
5208/* Request a dump by section name. */
5209
5210static void
2cf0635d 5211request_dump_byname (const char * section, dump_type type)
aef1f6d0 5212{
2cf0635d 5213 struct dump_list_entry * new_request;
aef1f6d0 5214
3f5e193b
NC
5215 new_request = (struct dump_list_entry *)
5216 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5217 if (!new_request)
591a748a 5218 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5219
5220 new_request->name = strdup (section);
5221 if (!new_request->name)
591a748a 5222 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5223
5224 new_request->type = type;
5225
5226 new_request->next = dump_sects_byname;
5227 dump_sects_byname = new_request;
5228}
5229
cf13d699 5230static inline void
6431e409 5231request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5232{
5233 int section;
5234 char * cp;
5235
015dc7e1 5236 do_dump = true;
cf13d699
NC
5237 section = strtoul (optarg, & cp, 0);
5238
5239 if (! *cp && section >= 0)
6431e409 5240 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5241 else
5242 request_dump_byname (optarg, type);
5243}
5244
252b5132 5245static void
6431e409 5246parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5247{
5248 int c;
5249
5250 if (argc < 2)
92f01d61 5251 usage (stderr);
252b5132
RH
5252
5253 while ((c = getopt_long
b3aa80b4 5254 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5255 {
252b5132
RH
5256 switch (c)
5257 {
5258 case 0:
5259 /* Long options. */
5260 break;
5261 case 'H':
92f01d61 5262 usage (stdout);
252b5132
RH
5263 break;
5264
5265 case 'a':
015dc7e1
AM
5266 do_syms = true;
5267 do_reloc = true;
5268 do_unwind = true;
5269 do_dynamic = true;
5270 do_header = true;
5271 do_sections = true;
5272 do_section_groups = true;
5273 do_segments = true;
5274 do_version = true;
5275 do_histogram = true;
5276 do_arch = true;
5277 do_notes = true;
252b5132 5278 break;
79bc120c 5279
f5842774 5280 case 'g':
015dc7e1 5281 do_section_groups = true;
f5842774 5282 break;
5477e8a0 5283 case 't':
595cf52e 5284 case 'N':
015dc7e1
AM
5285 do_sections = true;
5286 do_section_details = true;
595cf52e 5287 break;
252b5132 5288 case 'e':
015dc7e1
AM
5289 do_header = true;
5290 do_sections = true;
5291 do_segments = true;
252b5132 5292 break;
a952a375 5293 case 'A':
015dc7e1 5294 do_arch = true;
a952a375 5295 break;
252b5132 5296 case 'D':
015dc7e1 5297 do_using_dynamic = true;
252b5132
RH
5298 break;
5299 case 'r':
015dc7e1 5300 do_reloc = true;
252b5132 5301 break;
4d6ed7c8 5302 case 'u':
015dc7e1 5303 do_unwind = true;
4d6ed7c8 5304 break;
252b5132 5305 case 'h':
015dc7e1 5306 do_header = true;
252b5132
RH
5307 break;
5308 case 'l':
015dc7e1 5309 do_segments = true;
252b5132
RH
5310 break;
5311 case 's':
015dc7e1 5312 do_syms = true;
252b5132
RH
5313 break;
5314 case 'S':
015dc7e1 5315 do_sections = true;
252b5132
RH
5316 break;
5317 case 'd':
015dc7e1 5318 do_dynamic = true;
252b5132 5319 break;
a952a375 5320 case 'I':
015dc7e1 5321 do_histogram = true;
a952a375 5322 break;
779fe533 5323 case 'n':
015dc7e1 5324 do_notes = true;
779fe533 5325 break;
4145f1d5 5326 case 'c':
015dc7e1 5327 do_archive_index = true;
4145f1d5 5328 break;
1b513401 5329 case 'L':
015dc7e1 5330 do_checks = true;
1b513401 5331 break;
ca0e11aa 5332 case 'P':
015dc7e1
AM
5333 process_links = true;
5334 do_follow_links = true;
ca0e11aa 5335 break;
252b5132 5336 case 'x':
6431e409 5337 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5338 break;
09c11c86 5339 case 'p':
6431e409 5340 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5341 break;
5342 case 'R':
6431e409 5343 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5344 break;
0e602686 5345 case 'z':
015dc7e1 5346 decompress_dumps = true;
0e602686 5347 break;
252b5132 5348 case 'w':
015dc7e1 5349 do_dump = true;
0f03783c 5350 if (optarg == NULL)
613ff48b 5351 {
015dc7e1 5352 do_debugging = true;
613ff48b
CC
5353 dwarf_select_sections_all ();
5354 }
252b5132
RH
5355 else
5356 {
015dc7e1 5357 do_debugging = false;
4cb93e3b 5358 dwarf_select_sections_by_letters (optarg);
252b5132
RH
5359 }
5360 break;
2979dc34 5361 case OPTION_DEBUG_DUMP:
015dc7e1 5362 do_dump = true;
0f03783c 5363 if (optarg == NULL)
d6249f5f
AM
5364 {
5365 do_debugging = true;
5366 dwarf_select_sections_all ();
5367 }
2979dc34
JJ
5368 else
5369 {
015dc7e1 5370 do_debugging = false;
4cb93e3b 5371 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
5372 }
5373 break;
fd2f0033
TT
5374 case OPTION_DWARF_DEPTH:
5375 {
5376 char *cp;
5377
5378 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5379 }
5380 break;
5381 case OPTION_DWARF_START:
5382 {
5383 char *cp;
5384
5385 dwarf_start_die = strtoul (optarg, & cp, 0);
5386 }
5387 break;
4723351a 5388 case OPTION_DWARF_CHECK:
015dc7e1 5389 dwarf_check = true;
4723351a 5390 break;
7d9813f1 5391 case OPTION_CTF_DUMP:
015dc7e1 5392 do_ctf = true;
6431e409 5393 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5394 break;
5395 case OPTION_CTF_SYMBOLS:
df16e041 5396 free (dump_ctf_symtab_name);
7d9813f1
NA
5397 dump_ctf_symtab_name = strdup (optarg);
5398 break;
5399 case OPTION_CTF_STRINGS:
df16e041 5400 free (dump_ctf_strtab_name);
7d9813f1
NA
5401 dump_ctf_strtab_name = strdup (optarg);
5402 break;
5403 case OPTION_CTF_PARENT:
df16e041 5404 free (dump_ctf_parent_name);
7d9813f1
NA
5405 dump_ctf_parent_name = strdup (optarg);
5406 break;
2c610e4b 5407 case OPTION_DYN_SYMS:
015dc7e1 5408 do_dyn_syms = true;
2c610e4b 5409 break;
0f03783c 5410 case OPTION_LTO_SYMS:
015dc7e1 5411 do_lto_syms = true;
0f03783c 5412 break;
252b5132
RH
5413#ifdef SUPPORT_DISASSEMBLY
5414 case 'i':
6431e409 5415 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5416 break;
252b5132
RH
5417#endif
5418 case 'v':
5419 print_version (program_name);
5420 break;
5421 case 'V':
015dc7e1 5422 do_version = true;
252b5132 5423 break;
d974e256 5424 case 'W':
015dc7e1 5425 do_wide = true;
d974e256 5426 break;
0942c7ab 5427 case 'T':
015dc7e1 5428 do_not_show_symbol_truncation = true;
0942c7ab 5429 break;
79bc120c 5430 case 'C':
015dc7e1 5431 do_demangle = true;
79bc120c
NC
5432 if (optarg != NULL)
5433 {
5434 enum demangling_styles style;
5435
5436 style = cplus_demangle_name_to_style (optarg);
5437 if (style == unknown_demangling)
5438 error (_("unknown demangling style `%s'"), optarg);
5439
5440 cplus_demangle_set_style (style);
5441 }
5442 break;
5443 case OPTION_NO_DEMANGLING:
015dc7e1 5444 do_demangle = false;
79bc120c
NC
5445 break;
5446 case OPTION_RECURSE_LIMIT:
5447 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5448 break;
5449 case OPTION_NO_RECURSE_LIMIT:
5450 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5451 break;
5452 case OPTION_WITH_SYMBOL_VERSIONS:
5453 /* Ignored for backward compatibility. */
5454 break;
b9e920ec 5455
b3aa80b4
NC
5456 case 'U':
5457 if (optarg == NULL)
5458 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5459 else if (streq (optarg, "default") || streq (optarg, "d"))
5460 unicode_display = unicode_default;
5461 else if (streq (optarg, "locale") || streq (optarg, "l"))
5462 unicode_display = unicode_locale;
5463 else if (streq (optarg, "escape") || streq (optarg, "e"))
5464 unicode_display = unicode_escape;
5465 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5466 unicode_display = unicode_invalid;
5467 else if (streq (optarg, "hex") || streq (optarg, "x"))
5468 unicode_display = unicode_hex;
5469 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5470 unicode_display = unicode_highlight;
5471 else
5472 error (_("invalid argument to -U/--unicode: %s"), optarg);
5473 break;
5474
047c3dbf
NL
5475 case OPTION_SYM_BASE:
5476 sym_base = 0;
5477 if (optarg != NULL)
5478 {
5479 sym_base = strtoul (optarg, NULL, 0);
5480 switch (sym_base)
5481 {
5482 case 0:
5483 case 8:
5484 case 10:
5485 case 16:
5486 break;
5487
5488 default:
5489 sym_base = 0;
5490 break;
5491 }
5492 }
5493 break;
5494
252b5132 5495 default:
252b5132
RH
5496 /* xgettext:c-format */
5497 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5498 /* Fall through. */
252b5132 5499 case '?':
92f01d61 5500 usage (stderr);
252b5132
RH
5501 }
5502 }
5503
4d6ed7c8 5504 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5505 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5506 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5507 && !do_section_groups && !do_archive_index
0f03783c 5508 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5509 {
5510 if (do_checks)
5511 {
015dc7e1
AM
5512 check_all = true;
5513 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5514 do_segments = do_header = do_dump = do_version = true;
5515 do_histogram = do_debugging = do_arch = do_notes = true;
5516 do_section_groups = do_archive_index = do_dyn_syms = true;
5517 do_lto_syms = true;
1b513401
NC
5518 }
5519 else
5520 usage (stderr);
5521 }
252b5132
RH
5522}
5523
5524static const char *
d3ba0551 5525get_elf_class (unsigned int elf_class)
252b5132 5526{
b34976b6 5527 static char buff[32];
103f02d3 5528
252b5132
RH
5529 switch (elf_class)
5530 {
5531 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5532 case ELFCLASS32: return "ELF32";
5533 case ELFCLASS64: return "ELF64";
ab5e7794 5534 default:
e9e44622 5535 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5536 return buff;
252b5132
RH
5537 }
5538}
5539
5540static const char *
d3ba0551 5541get_data_encoding (unsigned int encoding)
252b5132 5542{
b34976b6 5543 static char buff[32];
103f02d3 5544
252b5132
RH
5545 switch (encoding)
5546 {
5547 case ELFDATANONE: return _("none");
33c63f9d
CM
5548 case ELFDATA2LSB: return _("2's complement, little endian");
5549 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5550 default:
e9e44622 5551 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5552 return buff;
252b5132
RH
5553 }
5554}
5555
dda8d76d 5556/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5557
015dc7e1 5558static bool
dda8d76d 5559process_file_header (Filedata * filedata)
252b5132 5560{
dda8d76d
NC
5561 Elf_Internal_Ehdr * header = & filedata->file_header;
5562
5563 if ( header->e_ident[EI_MAG0] != ELFMAG0
5564 || header->e_ident[EI_MAG1] != ELFMAG1
5565 || header->e_ident[EI_MAG2] != ELFMAG2
5566 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5567 {
5568 error
5569 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5570 return false;
252b5132
RH
5571 }
5572
ca0e11aa
NC
5573 if (! filedata->is_separate)
5574 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5575
252b5132
RH
5576 if (do_header)
5577 {
32ec8896 5578 unsigned i;
252b5132 5579
ca0e11aa
NC
5580 if (filedata->is_separate)
5581 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5582 else
5583 printf (_("ELF Header:\n"));
252b5132 5584 printf (_(" Magic: "));
b34976b6 5585 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5586 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5587 printf ("\n");
5588 printf (_(" Class: %s\n"),
dda8d76d 5589 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5590 printf (_(" Data: %s\n"),
dda8d76d 5591 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5592 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5593 header->e_ident[EI_VERSION],
5594 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5595 ? _(" (current)")
dda8d76d 5596 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5597 ? _(" <unknown>")
789be9f7 5598 : "")));
252b5132 5599 printf (_(" OS/ABI: %s\n"),
dda8d76d 5600 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5601 printf (_(" ABI Version: %d\n"),
dda8d76d 5602 header->e_ident[EI_ABIVERSION]);
252b5132 5603 printf (_(" Type: %s\n"),
93df3340 5604 get_file_type (filedata));
252b5132 5605 printf (_(" Machine: %s\n"),
dda8d76d 5606 get_machine_name (header->e_machine));
252b5132 5607 printf (_(" Version: 0x%lx\n"),
e8a64888 5608 header->e_version);
76da6bbe 5609
f7a99963 5610 printf (_(" Entry point address: "));
e8a64888 5611 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5612 printf (_("\n Start of program headers: "));
e8a64888 5613 print_vma (header->e_phoff, DEC);
f7a99963 5614 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5615 print_vma (header->e_shoff, DEC);
f7a99963 5616 printf (_(" (bytes into file)\n"));
76da6bbe 5617
252b5132 5618 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5619 header->e_flags,
dda8d76d 5620 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5621 printf (_(" Size of this header: %u (bytes)\n"),
5622 header->e_ehsize);
5623 printf (_(" Size of program headers: %u (bytes)\n"),
5624 header->e_phentsize);
5625 printf (_(" Number of program headers: %u"),
5626 header->e_phnum);
dda8d76d
NC
5627 if (filedata->section_headers != NULL
5628 && header->e_phnum == PN_XNUM
5629 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5630 {
5631 header->e_phnum = filedata->section_headers[0].sh_info;
5632 printf (" (%u)", header->e_phnum);
5633 }
2046a35d 5634 putc ('\n', stdout);
e8a64888
AM
5635 printf (_(" Size of section headers: %u (bytes)\n"),
5636 header->e_shentsize);
5637 printf (_(" Number of section headers: %u"),
5638 header->e_shnum);
dda8d76d 5639 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5640 {
5641 header->e_shnum = filedata->section_headers[0].sh_size;
5642 printf (" (%u)", header->e_shnum);
5643 }
560f3c1c 5644 putc ('\n', stdout);
e8a64888
AM
5645 printf (_(" Section header string table index: %u"),
5646 header->e_shstrndx);
dda8d76d
NC
5647 if (filedata->section_headers != NULL
5648 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5649 {
5650 header->e_shstrndx = filedata->section_headers[0].sh_link;
5651 printf (" (%u)", header->e_shstrndx);
5652 }
5653 if (header->e_shstrndx != SHN_UNDEF
5654 && header->e_shstrndx >= header->e_shnum)
5655 {
5656 header->e_shstrndx = SHN_UNDEF;
5657 printf (_(" <corrupt: out of range>"));
5658 }
560f3c1c
AM
5659 putc ('\n', stdout);
5660 }
5661
dda8d76d 5662 if (filedata->section_headers != NULL)
560f3c1c 5663 {
dda8d76d
NC
5664 if (header->e_phnum == PN_XNUM
5665 && filedata->section_headers[0].sh_info != 0)
5666 header->e_phnum = filedata->section_headers[0].sh_info;
5667 if (header->e_shnum == SHN_UNDEF)
5668 header->e_shnum = filedata->section_headers[0].sh_size;
5669 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5670 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5671 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5672 header->e_shstrndx = SHN_UNDEF;
252b5132 5673 }
103f02d3 5674
015dc7e1 5675 return true;
9ea033b2
NC
5676}
5677
dda8d76d
NC
5678/* Read in the program headers from FILEDATA and store them in PHEADERS.
5679 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5680
015dc7e1 5681static bool
dda8d76d 5682get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5683{
2cf0635d
NC
5684 Elf32_External_Phdr * phdrs;
5685 Elf32_External_Phdr * external;
5686 Elf_Internal_Phdr * internal;
b34976b6 5687 unsigned int i;
dda8d76d
NC
5688 unsigned int size = filedata->file_header.e_phentsize;
5689 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5690
5691 /* PR binutils/17531: Cope with unexpected section header sizes. */
5692 if (size == 0 || num == 0)
015dc7e1 5693 return false;
e0a31db1
NC
5694 if (size < sizeof * phdrs)
5695 {
5696 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5697 return false;
e0a31db1
NC
5698 }
5699 if (size > sizeof * phdrs)
5700 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5701
dda8d76d 5702 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5703 size, num, _("program headers"));
5704 if (phdrs == NULL)
015dc7e1 5705 return false;
9ea033b2 5706
91d6fa6a 5707 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5708 i < filedata->file_header.e_phnum;
b34976b6 5709 i++, internal++, external++)
252b5132 5710 {
9ea033b2
NC
5711 internal->p_type = BYTE_GET (external->p_type);
5712 internal->p_offset = BYTE_GET (external->p_offset);
5713 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5714 internal->p_paddr = BYTE_GET (external->p_paddr);
5715 internal->p_filesz = BYTE_GET (external->p_filesz);
5716 internal->p_memsz = BYTE_GET (external->p_memsz);
5717 internal->p_flags = BYTE_GET (external->p_flags);
5718 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5719 }
5720
9ea033b2 5721 free (phdrs);
015dc7e1 5722 return true;
252b5132
RH
5723}
5724
dda8d76d
NC
5725/* Read in the program headers from FILEDATA and store them in PHEADERS.
5726 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5727
015dc7e1 5728static bool
dda8d76d 5729get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5730{
2cf0635d
NC
5731 Elf64_External_Phdr * phdrs;
5732 Elf64_External_Phdr * external;
5733 Elf_Internal_Phdr * internal;
b34976b6 5734 unsigned int i;
dda8d76d
NC
5735 unsigned int size = filedata->file_header.e_phentsize;
5736 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5737
5738 /* PR binutils/17531: Cope with unexpected section header sizes. */
5739 if (size == 0 || num == 0)
015dc7e1 5740 return false;
e0a31db1
NC
5741 if (size < sizeof * phdrs)
5742 {
5743 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5744 return false;
e0a31db1
NC
5745 }
5746 if (size > sizeof * phdrs)
5747 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5748
dda8d76d 5749 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5750 size, num, _("program headers"));
a6e9f9df 5751 if (!phdrs)
015dc7e1 5752 return false;
9ea033b2 5753
91d6fa6a 5754 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5755 i < filedata->file_header.e_phnum;
b34976b6 5756 i++, internal++, external++)
9ea033b2
NC
5757 {
5758 internal->p_type = BYTE_GET (external->p_type);
5759 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5760 internal->p_offset = BYTE_GET (external->p_offset);
5761 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5762 internal->p_paddr = BYTE_GET (external->p_paddr);
5763 internal->p_filesz = BYTE_GET (external->p_filesz);
5764 internal->p_memsz = BYTE_GET (external->p_memsz);
5765 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5766 }
5767
5768 free (phdrs);
015dc7e1 5769 return true;
9ea033b2 5770}
252b5132 5771
32ec8896 5772/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5773
015dc7e1 5774static bool
dda8d76d 5775get_program_headers (Filedata * filedata)
d93f0186 5776{
2cf0635d 5777 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5778
5779 /* Check cache of prior read. */
dda8d76d 5780 if (filedata->program_headers != NULL)
015dc7e1 5781 return true;
d93f0186 5782
82156ab7
NC
5783 /* Be kind to memory checkers by looking for
5784 e_phnum values which we know must be invalid. */
dda8d76d 5785 if (filedata->file_header.e_phnum
82156ab7 5786 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5787 >= filedata->file_size)
82156ab7
NC
5788 {
5789 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5790 filedata->file_header.e_phnum);
015dc7e1 5791 return false;
82156ab7 5792 }
d93f0186 5793
dda8d76d 5794 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5795 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5796 if (phdrs == NULL)
5797 {
8b73c356 5798 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5799 filedata->file_header.e_phnum);
015dc7e1 5800 return false;
d93f0186
NC
5801 }
5802
5803 if (is_32bit_elf
dda8d76d
NC
5804 ? get_32bit_program_headers (filedata, phdrs)
5805 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5806 {
dda8d76d 5807 filedata->program_headers = phdrs;
015dc7e1 5808 return true;
d93f0186
NC
5809 }
5810
5811 free (phdrs);
015dc7e1 5812 return false;
d93f0186
NC
5813}
5814
93df3340 5815/* Print program header info and locate dynamic section. */
2f62977e 5816
93df3340 5817static void
dda8d76d 5818process_program_headers (Filedata * filedata)
252b5132 5819{
2cf0635d 5820 Elf_Internal_Phdr * segment;
b34976b6 5821 unsigned int i;
1a9ccd70 5822 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5823
dda8d76d 5824 if (filedata->file_header.e_phnum == 0)
252b5132 5825 {
82f2dbf7 5826 /* PR binutils/12467. */
dda8d76d 5827 if (filedata->file_header.e_phoff != 0)
93df3340
AM
5828 warn (_("possibly corrupt ELF header - it has a non-zero program"
5829 " header offset, but no program headers\n"));
82f2dbf7 5830 else if (do_segments)
ca0e11aa
NC
5831 {
5832 if (filedata->is_separate)
5833 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5834 filedata->file_name);
5835 else
5836 printf (_("\nThere are no program headers in this file.\n"));
5837 }
93df3340 5838 goto no_headers;
252b5132
RH
5839 }
5840
5841 if (do_segments && !do_header)
5842 {
ca0e11aa
NC
5843 if (filedata->is_separate)
5844 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 5845 filedata->file_name, get_file_type (filedata));
ca0e11aa 5846 else
93df3340 5847 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
dda8d76d 5848 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5849 printf (ngettext ("There is %d program header, starting at offset %s\n",
5850 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5851 filedata->file_header.e_phnum),
5852 filedata->file_header.e_phnum,
5853 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5854 }
5855
dda8d76d 5856 if (! get_program_headers (filedata))
93df3340 5857 goto no_headers;
103f02d3 5858
252b5132
RH
5859 if (do_segments)
5860 {
dda8d76d 5861 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5862 printf (_("\nProgram Headers:\n"));
5863 else
5864 printf (_("\nProgram Headers:\n"));
76da6bbe 5865
f7a99963
NC
5866 if (is_32bit_elf)
5867 printf
5868 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5869 else if (do_wide)
5870 printf
5871 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5872 else
5873 {
5874 printf
5875 (_(" Type Offset VirtAddr PhysAddr\n"));
5876 printf
5877 (_(" FileSiz MemSiz Flags Align\n"));
5878 }
252b5132
RH
5879 }
5880
93df3340
AM
5881 unsigned long dynamic_addr = 0;
5882 bfd_size_type dynamic_size = 0;
dda8d76d
NC
5883 for (i = 0, segment = filedata->program_headers;
5884 i < filedata->file_header.e_phnum;
b34976b6 5885 i++, segment++)
252b5132
RH
5886 {
5887 if (do_segments)
5888 {
dda8d76d 5889 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5890
5891 if (is_32bit_elf)
5892 {
5893 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5894 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5895 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5896 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5897 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5898 printf ("%c%c%c ",
5899 (segment->p_flags & PF_R ? 'R' : ' '),
5900 (segment->p_flags & PF_W ? 'W' : ' '),
5901 (segment->p_flags & PF_X ? 'E' : ' '));
5902 printf ("%#lx", (unsigned long) segment->p_align);
5903 }
d974e256
JJ
5904 else if (do_wide)
5905 {
5906 if ((unsigned long) segment->p_offset == segment->p_offset)
5907 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5908 else
5909 {
5910 print_vma (segment->p_offset, FULL_HEX);
5911 putchar (' ');
5912 }
5913
5914 print_vma (segment->p_vaddr, FULL_HEX);
5915 putchar (' ');
5916 print_vma (segment->p_paddr, FULL_HEX);
5917 putchar (' ');
5918
5919 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5920 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5921 else
5922 {
5923 print_vma (segment->p_filesz, FULL_HEX);
5924 putchar (' ');
5925 }
5926
5927 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5928 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5929 else
5930 {
f48e6c45 5931 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5932 }
5933
5934 printf (" %c%c%c ",
5935 (segment->p_flags & PF_R ? 'R' : ' '),
5936 (segment->p_flags & PF_W ? 'W' : ' '),
5937 (segment->p_flags & PF_X ? 'E' : ' '));
5938
5939 if ((unsigned long) segment->p_align == segment->p_align)
5940 printf ("%#lx", (unsigned long) segment->p_align);
5941 else
5942 {
5943 print_vma (segment->p_align, PREFIX_HEX);
5944 }
5945 }
f7a99963
NC
5946 else
5947 {
5948 print_vma (segment->p_offset, FULL_HEX);
5949 putchar (' ');
5950 print_vma (segment->p_vaddr, FULL_HEX);
5951 putchar (' ');
5952 print_vma (segment->p_paddr, FULL_HEX);
5953 printf ("\n ");
5954 print_vma (segment->p_filesz, FULL_HEX);
5955 putchar (' ');
5956 print_vma (segment->p_memsz, FULL_HEX);
5957 printf (" %c%c%c ",
5958 (segment->p_flags & PF_R ? 'R' : ' '),
5959 (segment->p_flags & PF_W ? 'W' : ' '),
5960 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5961 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5962 }
252b5132 5963
1a9ccd70
NC
5964 putc ('\n', stdout);
5965 }
f54498b4 5966
252b5132
RH
5967 switch (segment->p_type)
5968 {
1a9ccd70 5969 case PT_LOAD:
502d895c
NC
5970#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5971 required by the ELF standard, several programs, including the Linux
5972 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5973 if (previous_load
5974 && previous_load->p_vaddr > segment->p_vaddr)
5975 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5976#endif
1a9ccd70
NC
5977 if (segment->p_memsz < segment->p_filesz)
5978 error (_("the segment's file size is larger than its memory size\n"));
5979 previous_load = segment;
5980 break;
5981
5982 case PT_PHDR:
5983 /* PR 20815 - Verify that the program header is loaded into memory. */
5984 if (i > 0 && previous_load != NULL)
5985 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5986 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5987 {
5988 unsigned int j;
5989
dda8d76d 5990 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5991 {
5992 Elf_Internal_Phdr *load = filedata->program_headers + j;
5993 if (load->p_type == PT_LOAD
5994 && load->p_offset <= segment->p_offset
5995 && (load->p_offset + load->p_filesz
5996 >= segment->p_offset + segment->p_filesz)
5997 && load->p_vaddr <= segment->p_vaddr
5998 && (load->p_vaddr + load->p_filesz
5999 >= segment->p_vaddr + segment->p_filesz))
6000 break;
6001 }
dda8d76d 6002 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6003 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6004 }
6005 break;
6006
252b5132 6007 case PT_DYNAMIC:
93df3340 6008 if (dynamic_addr)
252b5132
RH
6009 error (_("more than one dynamic segment\n"));
6010
20737c13
AM
6011 /* By default, assume that the .dynamic section is the first
6012 section in the DYNAMIC segment. */
93df3340
AM
6013 dynamic_addr = segment->p_offset;
6014 dynamic_size = segment->p_filesz;
20737c13 6015
b2d38a17
NC
6016 /* Try to locate the .dynamic section. If there is
6017 a section header table, we can easily locate it. */
dda8d76d 6018 if (filedata->section_headers != NULL)
b2d38a17 6019 {
2cf0635d 6020 Elf_Internal_Shdr * sec;
b2d38a17 6021
dda8d76d 6022 sec = find_section (filedata, ".dynamic");
89fac5e3 6023 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6024 {
93df3340
AM
6025 /* A corresponding .dynamic section is expected, but on
6026 IA-64/OpenVMS it is OK for it to be missing. */
6027 if (!is_ia64_vms (filedata))
6028 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6029 break;
6030 }
6031
42bb2e33 6032 if (sec->sh_type == SHT_NOBITS)
20737c13 6033 {
93df3340
AM
6034 dynamic_addr = 0;
6035 dynamic_size = 0;
20737c13
AM
6036 break;
6037 }
42bb2e33 6038
93df3340
AM
6039 dynamic_addr = sec->sh_offset;
6040 dynamic_size = sec->sh_size;
b2d38a17 6041
8ac10c5b
L
6042 /* The PT_DYNAMIC segment, which is used by the run-time
6043 loader, should exactly match the .dynamic section. */
6044 if (do_checks
93df3340
AM
6045 && (dynamic_addr != segment->p_offset
6046 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6047 warn (_("\
6048the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6049 }
39e224f6
MW
6050
6051 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6052 segment. Check this after matching against the section headers
6053 so we don't warn on debuginfo file (which have NOBITS .dynamic
6054 sections). */
93df3340
AM
6055 if (dynamic_addr > filedata->file_size
6056 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6057 {
6058 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6059 dynamic_addr = 0;
6060 dynamic_size = 0;
39e224f6 6061 }
252b5132
RH
6062 break;
6063
6064 case PT_INTERP:
13acb58d
AM
6065 if (segment->p_offset >= filedata->file_size
6066 || segment->p_filesz > filedata->file_size - segment->p_offset
6067 || segment->p_filesz - 1 >= (size_t) -2
6068 || fseek (filedata->handle,
6069 filedata->archive_file_offset + (long) segment->p_offset,
6070 SEEK_SET))
252b5132
RH
6071 error (_("Unable to find program interpreter name\n"));
6072 else
6073 {
13acb58d
AM
6074 size_t len = segment->p_filesz;
6075 free (filedata->program_interpreter);
6076 filedata->program_interpreter = xmalloc (len + 1);
6077 len = fread (filedata->program_interpreter, 1, len,
6078 filedata->handle);
6079 filedata->program_interpreter[len] = 0;
252b5132
RH
6080
6081 if (do_segments)
f54498b4 6082 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6083 filedata->program_interpreter);
252b5132
RH
6084 }
6085 break;
6086 }
252b5132
RH
6087 }
6088
dda8d76d
NC
6089 if (do_segments
6090 && filedata->section_headers != NULL
6091 && filedata->string_table != NULL)
252b5132
RH
6092 {
6093 printf (_("\n Section to Segment mapping:\n"));
6094 printf (_(" Segment Sections...\n"));
6095
dda8d76d 6096 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6097 {
9ad5cbcf 6098 unsigned int j;
2cf0635d 6099 Elf_Internal_Shdr * section;
252b5132 6100
dda8d76d
NC
6101 segment = filedata->program_headers + i;
6102 section = filedata->section_headers + 1;
252b5132
RH
6103
6104 printf (" %2.2d ", i);
6105
dda8d76d 6106 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6107 {
f4638467
AM
6108 if (!ELF_TBSS_SPECIAL (section, segment)
6109 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6110 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6111 }
6112
6113 putc ('\n',stdout);
6114 }
6115 }
6116
93df3340
AM
6117 filedata->dynamic_addr = dynamic_addr;
6118 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6119 return;
6120
6121 no_headers:
6122 filedata->dynamic_addr = 0;
6123 filedata->dynamic_size = 1;
252b5132
RH
6124}
6125
6126
d93f0186
NC
6127/* Find the file offset corresponding to VMA by using the program headers. */
6128
6129static long
dda8d76d 6130offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 6131{
2cf0635d 6132 Elf_Internal_Phdr * seg;
d93f0186 6133
dda8d76d 6134 if (! get_program_headers (filedata))
d93f0186
NC
6135 {
6136 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6137 return (long) vma;
6138 }
6139
dda8d76d
NC
6140 for (seg = filedata->program_headers;
6141 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6142 ++seg)
6143 {
6144 if (seg->p_type != PT_LOAD)
6145 continue;
6146
6147 if (vma >= (seg->p_vaddr & -seg->p_align)
6148 && vma + size <= seg->p_vaddr + seg->p_filesz)
6149 return vma - seg->p_vaddr + seg->p_offset;
6150 }
6151
6152 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6153 (unsigned long) vma);
d93f0186
NC
6154 return (long) vma;
6155}
6156
6157
dda8d76d
NC
6158/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6159 If PROBE is true, this is just a probe and we do not generate any error
6160 messages if the load fails. */
049b0c3a 6161
015dc7e1
AM
6162static bool
6163get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6164{
2cf0635d
NC
6165 Elf32_External_Shdr * shdrs;
6166 Elf_Internal_Shdr * internal;
dda8d76d
NC
6167 unsigned int i;
6168 unsigned int size = filedata->file_header.e_shentsize;
6169 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6170
6171 /* PR binutils/17531: Cope with unexpected section header sizes. */
6172 if (size == 0 || num == 0)
015dc7e1 6173 return false;
049b0c3a
NC
6174 if (size < sizeof * shdrs)
6175 {
6176 if (! probe)
6177 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6178 return false;
049b0c3a
NC
6179 }
6180 if (!probe && size > sizeof * shdrs)
6181 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6182
dda8d76d 6183 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6184 size, num,
6185 probe ? NULL : _("section headers"));
6186 if (shdrs == NULL)
015dc7e1 6187 return false;
252b5132 6188
dda8d76d
NC
6189 filedata->section_headers = (Elf_Internal_Shdr *)
6190 cmalloc (num, sizeof (Elf_Internal_Shdr));
6191 if (filedata->section_headers == NULL)
252b5132 6192 {
049b0c3a 6193 if (!probe)
8b73c356 6194 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6195 free (shdrs);
015dc7e1 6196 return false;
252b5132
RH
6197 }
6198
dda8d76d 6199 for (i = 0, internal = filedata->section_headers;
560f3c1c 6200 i < num;
b34976b6 6201 i++, internal++)
252b5132
RH
6202 {
6203 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6204 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6205 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6206 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6207 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6208 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6209 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6210 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6211 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6212 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6213 if (!probe && internal->sh_link > num)
6214 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6215 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6216 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6217 }
6218
6219 free (shdrs);
015dc7e1 6220 return true;
252b5132
RH
6221}
6222
dda8d76d
NC
6223/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6224
015dc7e1
AM
6225static bool
6226get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6227{
dda8d76d
NC
6228 Elf64_External_Shdr * shdrs;
6229 Elf_Internal_Shdr * internal;
6230 unsigned int i;
6231 unsigned int size = filedata->file_header.e_shentsize;
6232 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6233
6234 /* PR binutils/17531: Cope with unexpected section header sizes. */
6235 if (size == 0 || num == 0)
015dc7e1 6236 return false;
dda8d76d 6237
049b0c3a
NC
6238 if (size < sizeof * shdrs)
6239 {
6240 if (! probe)
6241 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6242 return false;
049b0c3a 6243 }
dda8d76d 6244
049b0c3a
NC
6245 if (! probe && size > sizeof * shdrs)
6246 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6247
dda8d76d
NC
6248 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6249 filedata->file_header.e_shoff,
049b0c3a
NC
6250 size, num,
6251 probe ? NULL : _("section headers"));
6252 if (shdrs == NULL)
015dc7e1 6253 return false;
9ea033b2 6254
dda8d76d
NC
6255 filedata->section_headers = (Elf_Internal_Shdr *)
6256 cmalloc (num, sizeof (Elf_Internal_Shdr));
6257 if (filedata->section_headers == NULL)
9ea033b2 6258 {
049b0c3a 6259 if (! probe)
8b73c356 6260 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6261 free (shdrs);
015dc7e1 6262 return false;
9ea033b2
NC
6263 }
6264
dda8d76d 6265 for (i = 0, internal = filedata->section_headers;
560f3c1c 6266 i < num;
b34976b6 6267 i++, internal++)
9ea033b2
NC
6268 {
6269 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6270 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6271 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6272 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6273 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6274 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6275 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6276 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6277 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6278 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6279 if (!probe && internal->sh_link > num)
6280 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6281 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6282 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6283 }
6284
6285 free (shdrs);
015dc7e1 6286 return true;
9ea033b2
NC
6287}
6288
4de91c10
AM
6289static bool
6290get_section_headers (Filedata *filedata, bool probe)
6291{
6292 if (filedata->section_headers != NULL)
6293 return true;
6294
4de91c10
AM
6295 if (is_32bit_elf)
6296 return get_32bit_section_headers (filedata, probe);
6297 else
6298 return get_64bit_section_headers (filedata, probe);
6299}
6300
252b5132 6301static Elf_Internal_Sym *
dda8d76d
NC
6302get_32bit_elf_symbols (Filedata * filedata,
6303 Elf_Internal_Shdr * section,
6304 unsigned long * num_syms_return)
252b5132 6305{
ba5cdace 6306 unsigned long number = 0;
dd24e3da 6307 Elf32_External_Sym * esyms = NULL;
ba5cdace 6308 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6309 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6310 Elf_Internal_Sym * psym;
b34976b6 6311 unsigned int j;
e3d39609 6312 elf_section_list * entry;
252b5132 6313
c9c1d674
EG
6314 if (section->sh_size == 0)
6315 {
6316 if (num_syms_return != NULL)
6317 * num_syms_return = 0;
6318 return NULL;
6319 }
6320
dd24e3da 6321 /* Run some sanity checks first. */
c9c1d674 6322 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6323 {
c9c1d674 6324 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6325 printable_section_name (filedata, section),
6326 (unsigned long) section->sh_entsize);
ba5cdace 6327 goto exit_point;
dd24e3da
NC
6328 }
6329
dda8d76d 6330 if (section->sh_size > filedata->file_size)
f54498b4
NC
6331 {
6332 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6333 printable_section_name (filedata, section),
6334 (unsigned long) section->sh_size);
f54498b4
NC
6335 goto exit_point;
6336 }
6337
dd24e3da
NC
6338 number = section->sh_size / section->sh_entsize;
6339
6340 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6341 {
c9c1d674 6342 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6343 (unsigned long) section->sh_size,
dda8d76d 6344 printable_section_name (filedata, section),
8066deb1 6345 (unsigned long) section->sh_entsize);
ba5cdace 6346 goto exit_point;
dd24e3da
NC
6347 }
6348
dda8d76d 6349 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6350 section->sh_size, _("symbols"));
dd24e3da 6351 if (esyms == NULL)
ba5cdace 6352 goto exit_point;
252b5132 6353
e3d39609 6354 shndx = NULL;
978c4450 6355 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6356 {
6357 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6358 continue;
6359
6360 if (shndx != NULL)
6361 {
6362 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6363 free (shndx);
6364 }
6365
6366 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6367 entry->hdr->sh_offset,
6368 1, entry->hdr->sh_size,
6369 _("symbol table section indices"));
6370 if (shndx == NULL)
6371 goto exit_point;
6372
6373 /* PR17531: file: heap-buffer-overflow */
6374 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6375 {
6376 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6377 printable_section_name (filedata, entry->hdr),
6378 (unsigned long) entry->hdr->sh_size,
6379 (unsigned long) section->sh_size);
6380 goto exit_point;
c9c1d674 6381 }
e3d39609 6382 }
9ad5cbcf 6383
3f5e193b 6384 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6385
6386 if (isyms == NULL)
6387 {
8b73c356
NC
6388 error (_("Out of memory reading %lu symbols\n"),
6389 (unsigned long) number);
dd24e3da 6390 goto exit_point;
252b5132
RH
6391 }
6392
dd24e3da 6393 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6394 {
6395 psym->st_name = BYTE_GET (esyms[j].st_name);
6396 psym->st_value = BYTE_GET (esyms[j].st_value);
6397 psym->st_size = BYTE_GET (esyms[j].st_size);
6398 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6399 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6400 psym->st_shndx
6401 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6402 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6403 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6404 psym->st_info = BYTE_GET (esyms[j].st_info);
6405 psym->st_other = BYTE_GET (esyms[j].st_other);
6406 }
6407
dd24e3da 6408 exit_point:
e3d39609
NC
6409 free (shndx);
6410 free (esyms);
252b5132 6411
ba5cdace
NC
6412 if (num_syms_return != NULL)
6413 * num_syms_return = isyms == NULL ? 0 : number;
6414
252b5132
RH
6415 return isyms;
6416}
6417
9ea033b2 6418static Elf_Internal_Sym *
dda8d76d
NC
6419get_64bit_elf_symbols (Filedata * filedata,
6420 Elf_Internal_Shdr * section,
6421 unsigned long * num_syms_return)
9ea033b2 6422{
ba5cdace
NC
6423 unsigned long number = 0;
6424 Elf64_External_Sym * esyms = NULL;
6425 Elf_External_Sym_Shndx * shndx = NULL;
6426 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6427 Elf_Internal_Sym * psym;
b34976b6 6428 unsigned int j;
e3d39609 6429 elf_section_list * entry;
9ea033b2 6430
c9c1d674
EG
6431 if (section->sh_size == 0)
6432 {
6433 if (num_syms_return != NULL)
6434 * num_syms_return = 0;
6435 return NULL;
6436 }
6437
dd24e3da 6438 /* Run some sanity checks first. */
c9c1d674 6439 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6440 {
c9c1d674 6441 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6442 printable_section_name (filedata, section),
8066deb1 6443 (unsigned long) section->sh_entsize);
ba5cdace 6444 goto exit_point;
dd24e3da
NC
6445 }
6446
dda8d76d 6447 if (section->sh_size > filedata->file_size)
f54498b4
NC
6448 {
6449 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6450 printable_section_name (filedata, section),
8066deb1 6451 (unsigned long) section->sh_size);
f54498b4
NC
6452 goto exit_point;
6453 }
6454
dd24e3da
NC
6455 number = section->sh_size / section->sh_entsize;
6456
6457 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6458 {
c9c1d674 6459 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6460 (unsigned long) section->sh_size,
dda8d76d 6461 printable_section_name (filedata, section),
8066deb1 6462 (unsigned long) section->sh_entsize);
ba5cdace 6463 goto exit_point;
dd24e3da
NC
6464 }
6465
dda8d76d 6466 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6467 section->sh_size, _("symbols"));
a6e9f9df 6468 if (!esyms)
ba5cdace 6469 goto exit_point;
9ea033b2 6470
e3d39609 6471 shndx = NULL;
978c4450 6472 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6473 {
6474 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6475 continue;
6476
6477 if (shndx != NULL)
6478 {
6479 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6480 free (shndx);
c9c1d674 6481 }
e3d39609
NC
6482
6483 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6484 entry->hdr->sh_offset,
6485 1, entry->hdr->sh_size,
6486 _("symbol table section indices"));
6487 if (shndx == NULL)
6488 goto exit_point;
6489
6490 /* PR17531: file: heap-buffer-overflow */
6491 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6492 {
6493 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6494 printable_section_name (filedata, entry->hdr),
6495 (unsigned long) entry->hdr->sh_size,
6496 (unsigned long) section->sh_size);
6497 goto exit_point;
6498 }
6499 }
9ad5cbcf 6500
3f5e193b 6501 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6502
6503 if (isyms == NULL)
6504 {
8b73c356
NC
6505 error (_("Out of memory reading %lu symbols\n"),
6506 (unsigned long) number);
ba5cdace 6507 goto exit_point;
9ea033b2
NC
6508 }
6509
ba5cdace 6510 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6511 {
6512 psym->st_name = BYTE_GET (esyms[j].st_name);
6513 psym->st_info = BYTE_GET (esyms[j].st_info);
6514 psym->st_other = BYTE_GET (esyms[j].st_other);
6515 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6516
4fbb74a6 6517 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6518 psym->st_shndx
6519 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6520 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6521 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6522
66543521
AM
6523 psym->st_value = BYTE_GET (esyms[j].st_value);
6524 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6525 }
6526
ba5cdace 6527 exit_point:
e3d39609
NC
6528 free (shndx);
6529 free (esyms);
ba5cdace
NC
6530
6531 if (num_syms_return != NULL)
6532 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6533
6534 return isyms;
6535}
6536
4de91c10
AM
6537static Elf_Internal_Sym *
6538get_elf_symbols (Filedata *filedata,
6539 Elf_Internal_Shdr *section,
6540 unsigned long *num_syms_return)
6541{
6542 if (is_32bit_elf)
6543 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6544 else
6545 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6546}
6547
d1133906 6548static const char *
dda8d76d 6549get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6550{
5477e8a0 6551 static char buff[1024];
2cf0635d 6552 char * p = buff;
32ec8896
NC
6553 unsigned int field_size = is_32bit_elf ? 8 : 16;
6554 signed int sindex;
6555 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6556 bfd_vma os_flags = 0;
6557 bfd_vma proc_flags = 0;
6558 bfd_vma unknown_flags = 0;
148b93f2 6559 static const struct
5477e8a0 6560 {
2cf0635d 6561 const char * str;
32ec8896 6562 unsigned int len;
5477e8a0
L
6563 }
6564 flags [] =
6565 {
cfcac11d
NC
6566 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6567 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6568 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6569 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6570 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6571 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6572 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6573 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6574 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6575 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6576 /* IA-64 specific. */
6577 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6578 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6579 /* IA-64 OpenVMS specific. */
6580 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6581 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6582 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6583 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6584 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6585 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6586 /* Generic. */
cfcac11d 6587 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6588 /* SPARC specific. */
77115a4a 6589 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6590 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6591 /* ARM specific. */
6592 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6593 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6594 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6595 /* GNU specific. */
6596 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6597 /* VLE specific. */
6598 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6599 /* GNU specific. */
6600 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6601 };
6602
6603 if (do_section_details)
6604 {
8d5ff12c
L
6605 sprintf (buff, "[%*.*lx]: ",
6606 field_size, field_size, (unsigned long) sh_flags);
6607 p += field_size + 4;
5477e8a0 6608 }
76da6bbe 6609
d1133906
NC
6610 while (sh_flags)
6611 {
6612 bfd_vma flag;
6613
6614 flag = sh_flags & - sh_flags;
6615 sh_flags &= ~ flag;
76da6bbe 6616
5477e8a0 6617 if (do_section_details)
d1133906 6618 {
5477e8a0
L
6619 switch (flag)
6620 {
91d6fa6a
NC
6621 case SHF_WRITE: sindex = 0; break;
6622 case SHF_ALLOC: sindex = 1; break;
6623 case SHF_EXECINSTR: sindex = 2; break;
6624 case SHF_MERGE: sindex = 3; break;
6625 case SHF_STRINGS: sindex = 4; break;
6626 case SHF_INFO_LINK: sindex = 5; break;
6627 case SHF_LINK_ORDER: sindex = 6; break;
6628 case SHF_OS_NONCONFORMING: sindex = 7; break;
6629 case SHF_GROUP: sindex = 8; break;
6630 case SHF_TLS: sindex = 9; break;
18ae9cc1 6631 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6632 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6633
5477e8a0 6634 default:
91d6fa6a 6635 sindex = -1;
dda8d76d 6636 switch (filedata->file_header.e_machine)
148b93f2 6637 {
cfcac11d 6638 case EM_IA_64:
148b93f2 6639 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6640 sindex = 10;
148b93f2 6641 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6642 sindex = 11;
148b93f2 6643#ifdef BFD64
dda8d76d 6644 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6645 switch (flag)
6646 {
91d6fa6a
NC
6647 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6648 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6649 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6650 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6651 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6652 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6653 default: break;
6654 }
6655#endif
cfcac11d
NC
6656 break;
6657
caa83f8b 6658 case EM_386:
22abe556 6659 case EM_IAMCU:
caa83f8b 6660 case EM_X86_64:
7f502d6c 6661 case EM_L1OM:
7a9068fe 6662 case EM_K1OM:
cfcac11d
NC
6663 case EM_OLD_SPARCV9:
6664 case EM_SPARC32PLUS:
6665 case EM_SPARCV9:
6666 case EM_SPARC:
18ae9cc1 6667 if (flag == SHF_ORDERED)
91d6fa6a 6668 sindex = 19;
cfcac11d 6669 break;
ac4c9b04
MG
6670
6671 case EM_ARM:
6672 switch (flag)
6673 {
6674 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6675 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6676 case SHF_COMDEF: sindex = 23; break;
6677 default: break;
6678 }
6679 break;
83eef883
AFB
6680 case EM_PPC:
6681 if (flag == SHF_PPC_VLE)
6682 sindex = 25;
6683 break;
99fabbc9
JL
6684 default:
6685 break;
6686 }
ac4c9b04 6687
99fabbc9
JL
6688 switch (filedata->file_header.e_ident[EI_OSABI])
6689 {
6690 case ELFOSABI_GNU:
6691 case ELFOSABI_FREEBSD:
6692 if (flag == SHF_GNU_RETAIN)
6693 sindex = 26;
6694 /* Fall through */
6695 case ELFOSABI_NONE:
6696 if (flag == SHF_GNU_MBIND)
6697 /* We should not recognize SHF_GNU_MBIND for
6698 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6699 not set the EI_OSABI header byte. */
6700 sindex = 24;
6701 break;
cfcac11d
NC
6702 default:
6703 break;
148b93f2 6704 }
99fabbc9 6705 break;
5477e8a0
L
6706 }
6707
91d6fa6a 6708 if (sindex != -1)
5477e8a0 6709 {
8d5ff12c
L
6710 if (p != buff + field_size + 4)
6711 {
6712 if (size < (10 + 2))
bee0ee85
NC
6713 {
6714 warn (_("Internal error: not enough buffer room for section flag info"));
6715 return _("<unknown>");
6716 }
8d5ff12c
L
6717 size -= 2;
6718 *p++ = ',';
6719 *p++ = ' ';
6720 }
6721
91d6fa6a
NC
6722 size -= flags [sindex].len;
6723 p = stpcpy (p, flags [sindex].str);
5477e8a0 6724 }
3b22753a 6725 else if (flag & SHF_MASKOS)
8d5ff12c 6726 os_flags |= flag;
d1133906 6727 else if (flag & SHF_MASKPROC)
8d5ff12c 6728 proc_flags |= flag;
d1133906 6729 else
8d5ff12c 6730 unknown_flags |= flag;
5477e8a0
L
6731 }
6732 else
6733 {
6734 switch (flag)
6735 {
6736 case SHF_WRITE: *p = 'W'; break;
6737 case SHF_ALLOC: *p = 'A'; break;
6738 case SHF_EXECINSTR: *p = 'X'; break;
6739 case SHF_MERGE: *p = 'M'; break;
6740 case SHF_STRINGS: *p = 'S'; break;
6741 case SHF_INFO_LINK: *p = 'I'; break;
6742 case SHF_LINK_ORDER: *p = 'L'; break;
6743 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6744 case SHF_GROUP: *p = 'G'; break;
6745 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6746 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6747 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6748
6749 default:
dda8d76d
NC
6750 if ((filedata->file_header.e_machine == EM_X86_64
6751 || filedata->file_header.e_machine == EM_L1OM
6752 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6753 && flag == SHF_X86_64_LARGE)
6754 *p = 'l';
dda8d76d 6755 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6756 && flag == SHF_ARM_PURECODE)
99fabbc9 6757 *p = 'y';
dda8d76d 6758 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6759 && flag == SHF_PPC_VLE)
99fabbc9 6760 *p = 'v';
5477e8a0
L
6761 else if (flag & SHF_MASKOS)
6762 {
99fabbc9
JL
6763 switch (filedata->file_header.e_ident[EI_OSABI])
6764 {
6765 case ELFOSABI_GNU:
6766 case ELFOSABI_FREEBSD:
6767 if (flag == SHF_GNU_RETAIN)
6768 {
6769 *p = 'R';
6770 break;
6771 }
6772 /* Fall through */
6773 case ELFOSABI_NONE:
6774 if (flag == SHF_GNU_MBIND)
6775 {
6776 /* We should not recognize SHF_GNU_MBIND for
6777 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6778 not set the EI_OSABI header byte. */
6779 *p = 'D';
6780 break;
6781 }
6782 /* Fall through */
6783 default:
6784 *p = 'o';
6785 sh_flags &= ~SHF_MASKOS;
6786 break;
6787 }
5477e8a0
L
6788 }
6789 else if (flag & SHF_MASKPROC)
6790 {
6791 *p = 'p';
6792 sh_flags &= ~ SHF_MASKPROC;
6793 }
6794 else
6795 *p = 'x';
6796 break;
6797 }
6798 p++;
d1133906
NC
6799 }
6800 }
76da6bbe 6801
8d5ff12c
L
6802 if (do_section_details)
6803 {
6804 if (os_flags)
6805 {
6806 size -= 5 + field_size;
6807 if (p != buff + field_size + 4)
6808 {
6809 if (size < (2 + 1))
bee0ee85
NC
6810 {
6811 warn (_("Internal error: not enough buffer room for section flag info"));
6812 return _("<unknown>");
6813 }
8d5ff12c
L
6814 size -= 2;
6815 *p++ = ',';
6816 *p++ = ' ';
6817 }
6818 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6819 (unsigned long) os_flags);
6820 p += 5 + field_size;
6821 }
6822 if (proc_flags)
6823 {
6824 size -= 7 + field_size;
6825 if (p != buff + field_size + 4)
6826 {
6827 if (size < (2 + 1))
bee0ee85
NC
6828 {
6829 warn (_("Internal error: not enough buffer room for section flag info"));
6830 return _("<unknown>");
6831 }
8d5ff12c
L
6832 size -= 2;
6833 *p++ = ',';
6834 *p++ = ' ';
6835 }
6836 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6837 (unsigned long) proc_flags);
6838 p += 7 + field_size;
6839 }
6840 if (unknown_flags)
6841 {
6842 size -= 10 + field_size;
6843 if (p != buff + field_size + 4)
6844 {
6845 if (size < (2 + 1))
bee0ee85
NC
6846 {
6847 warn (_("Internal error: not enough buffer room for section flag info"));
6848 return _("<unknown>");
6849 }
8d5ff12c
L
6850 size -= 2;
6851 *p++ = ',';
6852 *p++ = ' ';
6853 }
2b692964 6854 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6855 (unsigned long) unknown_flags);
6856 p += 10 + field_size;
6857 }
6858 }
6859
e9e44622 6860 *p = '\0';
d1133906
NC
6861 return buff;
6862}
6863
5844b465 6864static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6865get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6866{
6867 if (is_32bit_elf)
6868 {
6869 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6870
ebdf1ebf
NC
6871 if (size < sizeof (* echdr))
6872 {
6873 error (_("Compressed section is too small even for a compression header\n"));
6874 return 0;
6875 }
6876
77115a4a
L
6877 chdr->ch_type = BYTE_GET (echdr->ch_type);
6878 chdr->ch_size = BYTE_GET (echdr->ch_size);
6879 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6880 return sizeof (*echdr);
6881 }
6882 else
6883 {
6884 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6885
ebdf1ebf
NC
6886 if (size < sizeof (* echdr))
6887 {
6888 error (_("Compressed section is too small even for a compression header\n"));
6889 return 0;
6890 }
6891
77115a4a
L
6892 chdr->ch_type = BYTE_GET (echdr->ch_type);
6893 chdr->ch_size = BYTE_GET (echdr->ch_size);
6894 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6895 return sizeof (*echdr);
6896 }
6897}
6898
015dc7e1 6899static bool
dda8d76d 6900process_section_headers (Filedata * filedata)
252b5132 6901{
2cf0635d 6902 Elf_Internal_Shdr * section;
b34976b6 6903 unsigned int i;
252b5132 6904
dda8d76d 6905 if (filedata->file_header.e_shnum == 0)
252b5132 6906 {
82f2dbf7 6907 /* PR binutils/12467. */
dda8d76d 6908 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6909 {
6910 warn (_("possibly corrupt ELF file header - it has a non-zero"
6911 " section header offset, but no section headers\n"));
015dc7e1 6912 return false;
32ec8896 6913 }
82f2dbf7 6914 else if (do_sections)
252b5132
RH
6915 printf (_("\nThere are no sections in this file.\n"));
6916
015dc7e1 6917 return true;
252b5132
RH
6918 }
6919
6920 if (do_sections && !do_header)
ca0e11aa
NC
6921 {
6922 if (filedata->is_separate && process_links)
6923 printf (_("In linked file '%s': "), filedata->file_name);
6924 if (! filedata->is_separate || process_links)
6925 printf (ngettext ("There is %d section header, "
6926 "starting at offset 0x%lx:\n",
6927 "There are %d section headers, "
6928 "starting at offset 0x%lx:\n",
6929 filedata->file_header.e_shnum),
6930 filedata->file_header.e_shnum,
6931 (unsigned long) filedata->file_header.e_shoff);
6932 }
252b5132 6933
4de91c10
AM
6934 if (!get_section_headers (filedata, false))
6935 return false;
252b5132
RH
6936
6937 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6938 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6939 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6940 {
dda8d76d 6941 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6942
c256ffe7
JJ
6943 if (section->sh_size != 0)
6944 {
dda8d76d
NC
6945 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6946 1, section->sh_size,
6947 _("string table"));
0de14b54 6948
dda8d76d 6949 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6950 }
252b5132
RH
6951 }
6952
6953 /* Scan the sections for the dynamic symbol table
e3c8793a 6954 and dynamic string table and debug sections. */
89fac5e3 6955 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6956 switch (filedata->file_header.e_machine)
89fac5e3
RS
6957 {
6958 case EM_MIPS:
6959 case EM_MIPS_RS3_LE:
6960 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6961 FDE addresses. However, the ABI also has a semi-official ILP32
6962 variant for which the normal FDE address size rules apply.
6963
6964 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6965 section, where XX is the size of longs in bits. Unfortunately,
6966 earlier compilers provided no way of distinguishing ILP32 objects
6967 from LP64 objects, so if there's any doubt, we should assume that
6968 the official LP64 form is being used. */
dda8d76d
NC
6969 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6970 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6971 eh_addr_size = 8;
6972 break;
0f56a26a
DD
6973
6974 case EM_H8_300:
6975 case EM_H8_300H:
dda8d76d 6976 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6977 {
6978 case E_H8_MACH_H8300:
6979 case E_H8_MACH_H8300HN:
6980 case E_H8_MACH_H8300SN:
6981 case E_H8_MACH_H8300SXN:
6982 eh_addr_size = 2;
6983 break;
6984 case E_H8_MACH_H8300H:
6985 case E_H8_MACH_H8300S:
6986 case E_H8_MACH_H8300SX:
6987 eh_addr_size = 4;
6988 break;
6989 }
f4236fe4
DD
6990 break;
6991
ff7eeb89 6992 case EM_M32C_OLD:
f4236fe4 6993 case EM_M32C:
dda8d76d 6994 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6995 {
6996 case EF_M32C_CPU_M16C:
6997 eh_addr_size = 2;
6998 break;
6999 }
7000 break;
89fac5e3
RS
7001 }
7002
76ca31c0
NC
7003#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7004 do \
7005 { \
7006 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
7007 if (section->sh_entsize != expected_entsize) \
9dd3a467 7008 { \
76ca31c0
NC
7009 char buf[40]; \
7010 sprintf_vma (buf, section->sh_entsize); \
7011 /* Note: coded this way so that there is a single string for \
7012 translation. */ \
7013 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
7014 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
7015 (unsigned) expected_entsize); \
9dd3a467 7016 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7017 } \
7018 } \
08d8fa11 7019 while (0)
9dd3a467
NC
7020
7021#define CHECK_ENTSIZE(section, i, type) \
1b513401 7022 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7023 sizeof (Elf64_External_##type))
7024
dda8d76d
NC
7025 for (i = 0, section = filedata->section_headers;
7026 i < filedata->file_header.e_shnum;
b34976b6 7027 i++, section++)
252b5132 7028 {
84714f86 7029 const char *name = section_name_print (filedata, section);
252b5132 7030
1b513401
NC
7031 /* Run some sanity checks on the headers and
7032 possibly fill in some file data as well. */
7033 switch (section->sh_type)
252b5132 7034 {
1b513401 7035 case SHT_DYNSYM:
978c4450 7036 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7037 {
7038 error (_("File contains multiple dynamic symbol tables\n"));
7039 continue;
7040 }
7041
08d8fa11 7042 CHECK_ENTSIZE (section, i, Sym);
978c4450 7043 filedata->dynamic_symbols
4de91c10 7044 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7045 filedata->dynamic_symtab_section = section;
1b513401
NC
7046 break;
7047
7048 case SHT_STRTAB:
7049 if (streq (name, ".dynstr"))
252b5132 7050 {
1b513401
NC
7051 if (filedata->dynamic_strings != NULL)
7052 {
7053 error (_("File contains multiple dynamic string tables\n"));
7054 continue;
7055 }
7056
7057 filedata->dynamic_strings
7058 = (char *) get_data (NULL, filedata, section->sh_offset,
7059 1, section->sh_size, _("dynamic strings"));
7060 filedata->dynamic_strings_length
7061 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7062 filedata->dynamic_strtab_section = section;
252b5132 7063 }
1b513401
NC
7064 break;
7065
7066 case SHT_SYMTAB_SHNDX:
7067 {
7068 elf_section_list * entry = xmalloc (sizeof * entry);
7069
7070 entry->hdr = section;
7071 entry->next = filedata->symtab_shndx_list;
7072 filedata->symtab_shndx_list = entry;
7073 }
7074 break;
7075
7076 case SHT_SYMTAB:
7077 CHECK_ENTSIZE (section, i, Sym);
7078 break;
7079
7080 case SHT_GROUP:
7081 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7082 break;
252b5132 7083
1b513401
NC
7084 case SHT_REL:
7085 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7086 if (do_checks && section->sh_size == 0)
1b513401
NC
7087 warn (_("Section '%s': zero-sized relocation section\n"), name);
7088 break;
7089
7090 case SHT_RELA:
7091 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7092 if (do_checks && section->sh_size == 0)
1b513401
NC
7093 warn (_("Section '%s': zero-sized relocation section\n"), name);
7094 break;
7095
7096 case SHT_NOTE:
7097 case SHT_PROGBITS:
546cb2d8
NC
7098 /* Having a zero sized section is not illegal according to the
7099 ELF standard, but it might be an indication that something
7100 is wrong. So issue a warning if we are running in lint mode. */
7101 if (do_checks && section->sh_size == 0)
1b513401
NC
7102 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7103 break;
7104
7105 default:
7106 break;
7107 }
7108
7109 if ((do_debugging || do_debug_info || do_debug_abbrevs
7110 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7111 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7112 || do_debug_str || do_debug_str_offsets || do_debug_loc
7113 || do_debug_ranges
1b513401 7114 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7115 && (startswith (name, ".debug_")
7116 || startswith (name, ".zdebug_")))
252b5132 7117 {
1b315056
CS
7118 if (name[1] == 'z')
7119 name += sizeof (".zdebug_") - 1;
7120 else
7121 name += sizeof (".debug_") - 1;
252b5132
RH
7122
7123 if (do_debugging
24d127aa
ML
7124 || (do_debug_info && startswith (name, "info"))
7125 || (do_debug_info && startswith (name, "types"))
7126 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7127 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7128 || (do_debug_lines && startswith (name, "line."))
7129 || (do_debug_pubnames && startswith (name, "pubnames"))
7130 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7131 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7132 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7133 || (do_debug_aranges && startswith (name, "aranges"))
7134 || (do_debug_ranges && startswith (name, "ranges"))
7135 || (do_debug_ranges && startswith (name, "rnglists"))
7136 || (do_debug_frames && startswith (name, "frame"))
7137 || (do_debug_macinfo && startswith (name, "macinfo"))
7138 || (do_debug_macinfo && startswith (name, "macro"))
7139 || (do_debug_str && startswith (name, "str"))
7140 || (do_debug_links && startswith (name, "sup"))
7141 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7142 || (do_debug_loc && startswith (name, "loc"))
7143 || (do_debug_loc && startswith (name, "loclists"))
7144 || (do_debug_addr && startswith (name, "addr"))
7145 || (do_debug_cu_index && startswith (name, "cu_index"))
7146 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7147 )
6431e409 7148 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7149 }
a262ae96 7150 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7151 else if ((do_debugging || do_debug_info)
24d127aa 7152 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7153 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7154 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7155 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7156 else if (do_gdb_index && (streq (name, ".gdb_index")
7157 || streq (name, ".debug_names")))
6431e409 7158 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7159 /* Trace sections for Itanium VMS. */
7160 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7161 || do_trace_aranges)
24d127aa 7162 && startswith (name, ".trace_"))
6f875884
TG
7163 {
7164 name += sizeof (".trace_") - 1;
7165
7166 if (do_debugging
7167 || (do_trace_info && streq (name, "info"))
7168 || (do_trace_abbrevs && streq (name, "abbrev"))
7169 || (do_trace_aranges && streq (name, "aranges"))
7170 )
6431e409 7171 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7172 }
dda8d76d 7173 else if ((do_debugging || do_debug_links)
24d127aa
ML
7174 && (startswith (name, ".gnu_debuglink")
7175 || startswith (name, ".gnu_debugaltlink")))
6431e409 7176 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7177 }
7178
7179 if (! do_sections)
015dc7e1 7180 return true;
252b5132 7181
ca0e11aa 7182 if (filedata->is_separate && ! process_links)
015dc7e1 7183 return true;
ca0e11aa
NC
7184
7185 if (filedata->is_separate)
7186 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7187 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7188 printf (_("\nSection Headers:\n"));
7189 else
7190 printf (_("\nSection Header:\n"));
76da6bbe 7191
f7a99963 7192 if (is_32bit_elf)
595cf52e 7193 {
5477e8a0 7194 if (do_section_details)
595cf52e
L
7195 {
7196 printf (_(" [Nr] Name\n"));
5477e8a0 7197 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7198 }
7199 else
7200 printf
7201 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7202 }
d974e256 7203 else if (do_wide)
595cf52e 7204 {
5477e8a0 7205 if (do_section_details)
595cf52e
L
7206 {
7207 printf (_(" [Nr] Name\n"));
5477e8a0 7208 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7209 }
7210 else
7211 printf
7212 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7213 }
f7a99963
NC
7214 else
7215 {
5477e8a0 7216 if (do_section_details)
595cf52e
L
7217 {
7218 printf (_(" [Nr] Name\n"));
5477e8a0
L
7219 printf (_(" Type Address Offset Link\n"));
7220 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7221 }
7222 else
7223 {
7224 printf (_(" [Nr] Name Type Address Offset\n"));
7225 printf (_(" Size EntSize Flags Link Info Align\n"));
7226 }
f7a99963 7227 }
252b5132 7228
5477e8a0
L
7229 if (do_section_details)
7230 printf (_(" Flags\n"));
7231
dda8d76d
NC
7232 for (i = 0, section = filedata->section_headers;
7233 i < filedata->file_header.e_shnum;
b34976b6 7234 i++, section++)
252b5132 7235 {
dd905818
NC
7236 /* Run some sanity checks on the section header. */
7237
7238 /* Check the sh_link field. */
7239 switch (section->sh_type)
7240 {
285e3f99
AM
7241 case SHT_REL:
7242 case SHT_RELA:
7243 if (section->sh_link == 0
7244 && (filedata->file_header.e_type == ET_EXEC
7245 || filedata->file_header.e_type == ET_DYN))
7246 /* A dynamic relocation section where all entries use a
7247 zero symbol index need not specify a symtab section. */
7248 break;
7249 /* Fall through. */
dd905818
NC
7250 case SHT_SYMTAB_SHNDX:
7251 case SHT_GROUP:
7252 case SHT_HASH:
7253 case SHT_GNU_HASH:
7254 case SHT_GNU_versym:
285e3f99 7255 if (section->sh_link == 0
dda8d76d
NC
7256 || section->sh_link >= filedata->file_header.e_shnum
7257 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7258 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7259 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7260 i, section->sh_link);
7261 break;
7262
7263 case SHT_DYNAMIC:
7264 case SHT_SYMTAB:
7265 case SHT_DYNSYM:
7266 case SHT_GNU_verneed:
7267 case SHT_GNU_verdef:
7268 case SHT_GNU_LIBLIST:
285e3f99 7269 if (section->sh_link == 0
dda8d76d
NC
7270 || section->sh_link >= filedata->file_header.e_shnum
7271 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7272 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7273 i, section->sh_link);
7274 break;
7275
7276 case SHT_INIT_ARRAY:
7277 case SHT_FINI_ARRAY:
7278 case SHT_PREINIT_ARRAY:
7279 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7280 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7281 i, section->sh_link);
7282 break;
7283
7284 default:
7285 /* FIXME: Add support for target specific section types. */
7286#if 0 /* Currently we do not check other section types as there are too
7287 many special cases. Stab sections for example have a type
7288 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7289 section. */
7290 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7291 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7292 i, section->sh_link);
7293#endif
7294 break;
7295 }
7296
7297 /* Check the sh_info field. */
7298 switch (section->sh_type)
7299 {
7300 case SHT_REL:
7301 case SHT_RELA:
285e3f99
AM
7302 if (section->sh_info == 0
7303 && (filedata->file_header.e_type == ET_EXEC
7304 || filedata->file_header.e_type == ET_DYN))
7305 /* Dynamic relocations apply to segments, so they do not
7306 need to specify the section they relocate. */
7307 break;
7308 if (section->sh_info == 0
dda8d76d
NC
7309 || section->sh_info >= filedata->file_header.e_shnum
7310 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7311 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7312 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7313 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7314 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7315 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7316 /* FIXME: Are other section types valid ? */
dda8d76d 7317 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7318 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7319 i, section->sh_info);
dd905818
NC
7320 break;
7321
7322 case SHT_DYNAMIC:
7323 case SHT_HASH:
7324 case SHT_SYMTAB_SHNDX:
7325 case SHT_INIT_ARRAY:
7326 case SHT_FINI_ARRAY:
7327 case SHT_PREINIT_ARRAY:
7328 if (section->sh_info != 0)
7329 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7330 i, section->sh_info);
7331 break;
7332
7333 case SHT_GROUP:
7334 case SHT_SYMTAB:
7335 case SHT_DYNSYM:
7336 /* A symbol index - we assume that it is valid. */
7337 break;
7338
7339 default:
7340 /* FIXME: Add support for target specific section types. */
7341 if (section->sh_type == SHT_NOBITS)
7342 /* NOBITS section headers with non-zero sh_info fields can be
7343 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7344 information. The stripped sections have their headers
7345 preserved but their types set to SHT_NOBITS. So do not check
7346 this type of section. */
dd905818
NC
7347 ;
7348 else if (section->sh_flags & SHF_INFO_LINK)
7349 {
dda8d76d 7350 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7351 warn (_("[%2u]: Expected link to another section in info field"), i);
7352 }
a91e1603
L
7353 else if (section->sh_type < SHT_LOOS
7354 && (section->sh_flags & SHF_GNU_MBIND) == 0
7355 && section->sh_info != 0)
dd905818
NC
7356 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7357 i, section->sh_info);
7358 break;
7359 }
7360
3e6b6445 7361 /* Check the sh_size field. */
dda8d76d 7362 if (section->sh_size > filedata->file_size
3e6b6445
NC
7363 && section->sh_type != SHT_NOBITS
7364 && section->sh_type != SHT_NULL
7365 && section->sh_type < SHT_LOOS)
7366 warn (_("Size of section %u is larger than the entire file!\n"), i);
7367
7bfd842d 7368 printf (" [%2u] ", i);
5477e8a0 7369 if (do_section_details)
dda8d76d 7370 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7371 else
84714f86 7372 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7373
ea52a088 7374 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7375 get_section_type_name (filedata, section->sh_type));
0b4362b0 7376
f7a99963
NC
7377 if (is_32bit_elf)
7378 {
cfcac11d
NC
7379 const char * link_too_big = NULL;
7380
f7a99963 7381 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7382
f7a99963
NC
7383 printf ( " %6.6lx %6.6lx %2.2lx",
7384 (unsigned long) section->sh_offset,
7385 (unsigned long) section->sh_size,
7386 (unsigned long) section->sh_entsize);
d1133906 7387
5477e8a0
L
7388 if (do_section_details)
7389 fputs (" ", stdout);
7390 else
dda8d76d 7391 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7392
dda8d76d 7393 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7394 {
7395 link_too_big = "";
7396 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7397 an error but it can have special values in Solaris binaries. */
dda8d76d 7398 switch (filedata->file_header.e_machine)
cfcac11d 7399 {
caa83f8b 7400 case EM_386:
22abe556 7401 case EM_IAMCU:
caa83f8b 7402 case EM_X86_64:
7f502d6c 7403 case EM_L1OM:
7a9068fe 7404 case EM_K1OM:
cfcac11d
NC
7405 case EM_OLD_SPARCV9:
7406 case EM_SPARC32PLUS:
7407 case EM_SPARCV9:
7408 case EM_SPARC:
7409 if (section->sh_link == (SHN_BEFORE & 0xffff))
7410 link_too_big = "BEFORE";
7411 else if (section->sh_link == (SHN_AFTER & 0xffff))
7412 link_too_big = "AFTER";
7413 break;
7414 default:
7415 break;
7416 }
7417 }
7418
7419 if (do_section_details)
7420 {
7421 if (link_too_big != NULL && * link_too_big)
7422 printf ("<%s> ", link_too_big);
7423 else
7424 printf ("%2u ", section->sh_link);
7425 printf ("%3u %2lu\n", section->sh_info,
7426 (unsigned long) section->sh_addralign);
7427 }
7428 else
7429 printf ("%2u %3u %2lu\n",
7430 section->sh_link,
7431 section->sh_info,
7432 (unsigned long) section->sh_addralign);
7433
7434 if (link_too_big && ! * link_too_big)
7435 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7436 i, section->sh_link);
f7a99963 7437 }
d974e256
JJ
7438 else if (do_wide)
7439 {
7440 print_vma (section->sh_addr, LONG_HEX);
7441
7442 if ((long) section->sh_offset == section->sh_offset)
7443 printf (" %6.6lx", (unsigned long) section->sh_offset);
7444 else
7445 {
7446 putchar (' ');
7447 print_vma (section->sh_offset, LONG_HEX);
7448 }
7449
7450 if ((unsigned long) section->sh_size == section->sh_size)
7451 printf (" %6.6lx", (unsigned long) section->sh_size);
7452 else
7453 {
7454 putchar (' ');
7455 print_vma (section->sh_size, LONG_HEX);
7456 }
7457
7458 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7459 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7460 else
7461 {
7462 putchar (' ');
7463 print_vma (section->sh_entsize, LONG_HEX);
7464 }
7465
5477e8a0
L
7466 if (do_section_details)
7467 fputs (" ", stdout);
7468 else
dda8d76d 7469 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7470
72de5009 7471 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7472
7473 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7474 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7475 else
7476 {
7477 print_vma (section->sh_addralign, DEC);
7478 putchar ('\n');
7479 }
7480 }
5477e8a0 7481 else if (do_section_details)
595cf52e 7482 {
55cc53e9 7483 putchar (' ');
595cf52e
L
7484 print_vma (section->sh_addr, LONG_HEX);
7485 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7486 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7487 else
7488 {
7489 printf (" ");
7490 print_vma (section->sh_offset, LONG_HEX);
7491 }
72de5009 7492 printf (" %u\n ", section->sh_link);
595cf52e 7493 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7494 putchar (' ');
595cf52e
L
7495 print_vma (section->sh_entsize, LONG_HEX);
7496
72de5009
AM
7497 printf (" %-16u %lu\n",
7498 section->sh_info,
595cf52e
L
7499 (unsigned long) section->sh_addralign);
7500 }
f7a99963
NC
7501 else
7502 {
7503 putchar (' ');
7504 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7505 if ((long) section->sh_offset == section->sh_offset)
7506 printf (" %8.8lx", (unsigned long) section->sh_offset);
7507 else
7508 {
7509 printf (" ");
7510 print_vma (section->sh_offset, LONG_HEX);
7511 }
f7a99963
NC
7512 printf ("\n ");
7513 print_vma (section->sh_size, LONG_HEX);
7514 printf (" ");
7515 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7516
dda8d76d 7517 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7518
72de5009
AM
7519 printf (" %2u %3u %lu\n",
7520 section->sh_link,
7521 section->sh_info,
f7a99963
NC
7522 (unsigned long) section->sh_addralign);
7523 }
5477e8a0
L
7524
7525 if (do_section_details)
77115a4a 7526 {
dda8d76d 7527 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7528 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7529 {
7530 /* Minimum section size is 12 bytes for 32-bit compression
7531 header + 12 bytes for compressed data header. */
7532 unsigned char buf[24];
d8024a91 7533
77115a4a 7534 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7535 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7536 sizeof (buf), _("compression header")))
7537 {
7538 Elf_Internal_Chdr chdr;
d8024a91 7539
5844b465
NC
7540 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7541 printf (_(" [<corrupt>]\n"));
77115a4a 7542 else
5844b465
NC
7543 {
7544 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7545 printf (" ZLIB, ");
7546 else
7547 printf (_(" [<unknown>: 0x%x], "),
7548 chdr.ch_type);
7549 print_vma (chdr.ch_size, LONG_HEX);
7550 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7551 }
77115a4a
L
7552 }
7553 }
7554 }
252b5132
RH
7555 }
7556
5477e8a0 7557 if (!do_section_details)
3dbcc61d 7558 {
9fb71ee4
NC
7559 /* The ordering of the letters shown here matches the ordering of the
7560 corresponding SHF_xxx values, and hence the order in which these
7561 letters will be displayed to the user. */
7562 printf (_("Key to Flags:\n\
7563 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7564 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7565 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7566 switch (filedata->file_header.e_ident[EI_OSABI])
7567 {
7568 case ELFOSABI_GNU:
7569 case ELFOSABI_FREEBSD:
7570 printf (_("R (retain), "));
7571 /* Fall through */
7572 case ELFOSABI_NONE:
7573 printf (_("D (mbind), "));
7574 break;
7575 default:
7576 break;
7577 }
dda8d76d
NC
7578 if (filedata->file_header.e_machine == EM_X86_64
7579 || filedata->file_header.e_machine == EM_L1OM
7580 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7581 printf (_("l (large), "));
dda8d76d 7582 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7583 printf (_("y (purecode), "));
dda8d76d 7584 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7585 printf (_("v (VLE), "));
9fb71ee4 7586 printf ("p (processor specific)\n");
0b4362b0 7587 }
d1133906 7588
015dc7e1 7589 return true;
252b5132
RH
7590}
7591
015dc7e1 7592static bool
28d13567
AM
7593get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7594 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7595 char **strtab, unsigned long *strtablen)
7596{
7597 *strtab = NULL;
7598 *strtablen = 0;
4de91c10 7599 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7600
7601 if (*symtab == NULL)
015dc7e1 7602 return false;
28d13567
AM
7603
7604 if (symsec->sh_link != 0)
7605 {
7606 Elf_Internal_Shdr *strsec;
7607
7608 if (symsec->sh_link >= filedata->file_header.e_shnum)
7609 {
7610 error (_("Bad sh_link in symbol table section\n"));
7611 free (*symtab);
7612 *symtab = NULL;
7613 *nsyms = 0;
015dc7e1 7614 return false;
28d13567
AM
7615 }
7616
7617 strsec = filedata->section_headers + symsec->sh_link;
7618
7619 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7620 1, strsec->sh_size, _("string table"));
7621 if (*strtab == NULL)
7622 {
7623 free (*symtab);
7624 *symtab = NULL;
7625 *nsyms = 0;
015dc7e1 7626 return false;
28d13567
AM
7627 }
7628 *strtablen = strsec->sh_size;
7629 }
015dc7e1 7630 return true;
28d13567
AM
7631}
7632
f5842774
L
7633static const char *
7634get_group_flags (unsigned int flags)
7635{
1449284b 7636 static char buff[128];
220453ec 7637
6d913794
NC
7638 if (flags == 0)
7639 return "";
7640 else if (flags == GRP_COMDAT)
7641 return "COMDAT ";
f5842774 7642
89246a0e
AM
7643 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7644 flags,
7645 flags & GRP_MASKOS ? _("<OS specific>") : "",
7646 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7647 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7648 ? _("<unknown>") : ""));
6d913794 7649
f5842774
L
7650 return buff;
7651}
7652
015dc7e1 7653static bool
dda8d76d 7654process_section_groups (Filedata * filedata)
f5842774 7655{
2cf0635d 7656 Elf_Internal_Shdr * section;
f5842774 7657 unsigned int i;
2cf0635d
NC
7658 struct group * group;
7659 Elf_Internal_Shdr * symtab_sec;
7660 Elf_Internal_Shdr * strtab_sec;
7661 Elf_Internal_Sym * symtab;
ba5cdace 7662 unsigned long num_syms;
2cf0635d 7663 char * strtab;
c256ffe7 7664 size_t strtab_size;
d1f5c6e3
L
7665
7666 /* Don't process section groups unless needed. */
7667 if (!do_unwind && !do_section_groups)
015dc7e1 7668 return true;
f5842774 7669
dda8d76d 7670 if (filedata->file_header.e_shnum == 0)
f5842774
L
7671 {
7672 if (do_section_groups)
ca0e11aa
NC
7673 {
7674 if (filedata->is_separate)
7675 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7676 filedata->file_name);
7677 else
7678 printf (_("\nThere are no section groups in this file.\n"));
7679 }
015dc7e1 7680 return true;
f5842774
L
7681 }
7682
dda8d76d 7683 if (filedata->section_headers == NULL)
f5842774
L
7684 {
7685 error (_("Section headers are not available!\n"));
fa1908fd 7686 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7687 return false;
f5842774
L
7688 }
7689
978c4450
AM
7690 filedata->section_headers_groups
7691 = (struct group **) calloc (filedata->file_header.e_shnum,
7692 sizeof (struct group *));
e4b17d5c 7693
978c4450 7694 if (filedata->section_headers_groups == NULL)
e4b17d5c 7695 {
8b73c356 7696 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7697 filedata->file_header.e_shnum);
015dc7e1 7698 return false;
e4b17d5c
L
7699 }
7700
f5842774 7701 /* Scan the sections for the group section. */
978c4450 7702 filedata->group_count = 0;
dda8d76d
NC
7703 for (i = 0, section = filedata->section_headers;
7704 i < filedata->file_header.e_shnum;
f5842774 7705 i++, section++)
e4b17d5c 7706 if (section->sh_type == SHT_GROUP)
978c4450 7707 filedata->group_count++;
e4b17d5c 7708
978c4450 7709 if (filedata->group_count == 0)
d1f5c6e3
L
7710 {
7711 if (do_section_groups)
ca0e11aa
NC
7712 {
7713 if (filedata->is_separate)
7714 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7715 filedata->file_name);
7716 else
7717 printf (_("\nThere are no section groups in this file.\n"));
7718 }
d1f5c6e3 7719
015dc7e1 7720 return true;
d1f5c6e3
L
7721 }
7722
978c4450
AM
7723 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7724 sizeof (struct group));
e4b17d5c 7725
978c4450 7726 if (filedata->section_groups == NULL)
e4b17d5c 7727 {
8b73c356 7728 error (_("Out of memory reading %lu groups\n"),
978c4450 7729 (unsigned long) filedata->group_count);
015dc7e1 7730 return false;
e4b17d5c
L
7731 }
7732
d1f5c6e3
L
7733 symtab_sec = NULL;
7734 strtab_sec = NULL;
7735 symtab = NULL;
ba5cdace 7736 num_syms = 0;
d1f5c6e3 7737 strtab = NULL;
c256ffe7 7738 strtab_size = 0;
ca0e11aa
NC
7739
7740 if (filedata->is_separate)
7741 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7742
978c4450 7743 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7744 i < filedata->file_header.e_shnum;
e4b17d5c 7745 i++, section++)
f5842774
L
7746 {
7747 if (section->sh_type == SHT_GROUP)
7748 {
dda8d76d 7749 const char * name = printable_section_name (filedata, section);
74e1a04b 7750 const char * group_name;
2cf0635d
NC
7751 unsigned char * start;
7752 unsigned char * indices;
f5842774 7753 unsigned int entry, j, size;
2cf0635d
NC
7754 Elf_Internal_Shdr * sec;
7755 Elf_Internal_Sym * sym;
f5842774
L
7756
7757 /* Get the symbol table. */
dda8d76d
NC
7758 if (section->sh_link >= filedata->file_header.e_shnum
7759 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7760 != SHT_SYMTAB))
f5842774
L
7761 {
7762 error (_("Bad sh_link in group section `%s'\n"), name);
7763 continue;
7764 }
d1f5c6e3
L
7765
7766 if (symtab_sec != sec)
7767 {
7768 symtab_sec = sec;
9db70fc3 7769 free (symtab);
4de91c10 7770 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7771 }
f5842774 7772
dd24e3da
NC
7773 if (symtab == NULL)
7774 {
7775 error (_("Corrupt header in group section `%s'\n"), name);
7776 continue;
7777 }
7778
ba5cdace
NC
7779 if (section->sh_info >= num_syms)
7780 {
7781 error (_("Bad sh_info in group section `%s'\n"), name);
7782 continue;
7783 }
7784
f5842774
L
7785 sym = symtab + section->sh_info;
7786
7787 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7788 {
4fbb74a6 7789 if (sym->st_shndx == 0
dda8d76d 7790 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7791 {
7792 error (_("Bad sh_info in group section `%s'\n"), name);
7793 continue;
7794 }
ba2685cc 7795
84714f86
AM
7796 group_name = section_name_print (filedata,
7797 filedata->section_headers
b9e920ec 7798 + sym->st_shndx);
c256ffe7 7799 strtab_sec = NULL;
9db70fc3 7800 free (strtab);
f5842774 7801 strtab = NULL;
c256ffe7 7802 strtab_size = 0;
f5842774
L
7803 }
7804 else
7805 {
7806 /* Get the string table. */
dda8d76d 7807 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7808 {
7809 strtab_sec = NULL;
9db70fc3 7810 free (strtab);
c256ffe7
JJ
7811 strtab = NULL;
7812 strtab_size = 0;
7813 }
7814 else if (strtab_sec
dda8d76d 7815 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7816 {
7817 strtab_sec = sec;
9db70fc3 7818 free (strtab);
071436c6 7819
dda8d76d 7820 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7821 1, strtab_sec->sh_size,
7822 _("string table"));
c256ffe7 7823 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7824 }
c256ffe7 7825 group_name = sym->st_name < strtab_size
2b692964 7826 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7827 }
7828
c9c1d674
EG
7829 /* PR 17531: file: loop. */
7830 if (section->sh_entsize > section->sh_size)
7831 {
7832 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7833 printable_section_name (filedata, section),
8066deb1
AM
7834 (unsigned long) section->sh_entsize,
7835 (unsigned long) section->sh_size);
61dd8e19 7836 continue;
c9c1d674
EG
7837 }
7838
dda8d76d 7839 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7840 1, section->sh_size,
7841 _("section data"));
59245841
NC
7842 if (start == NULL)
7843 continue;
f5842774
L
7844
7845 indices = start;
7846 size = (section->sh_size / section->sh_entsize) - 1;
7847 entry = byte_get (indices, 4);
7848 indices += 4;
e4b17d5c
L
7849
7850 if (do_section_groups)
7851 {
2b692964 7852 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7853 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7854
e4b17d5c
L
7855 printf (_(" [Index] Name\n"));
7856 }
7857
7858 group->group_index = i;
7859
f5842774
L
7860 for (j = 0; j < size; j++)
7861 {
2cf0635d 7862 struct group_list * g;
e4b17d5c 7863
f5842774
L
7864 entry = byte_get (indices, 4);
7865 indices += 4;
7866
dda8d76d 7867 if (entry >= filedata->file_header.e_shnum)
391cb864 7868 {
57028622
NC
7869 static unsigned num_group_errors = 0;
7870
7871 if (num_group_errors ++ < 10)
7872 {
7873 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7874 entry, i, filedata->file_header.e_shnum - 1);
57028622 7875 if (num_group_errors == 10)
67ce483b 7876 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7877 }
391cb864
L
7878 continue;
7879 }
391cb864 7880
978c4450 7881 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7882 {
d1f5c6e3
L
7883 if (entry)
7884 {
57028622
NC
7885 static unsigned num_errs = 0;
7886
7887 if (num_errs ++ < 10)
7888 {
7889 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7890 entry, i,
978c4450 7891 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7892 if (num_errs == 10)
7893 warn (_("Further error messages about already contained group sections suppressed\n"));
7894 }
d1f5c6e3
L
7895 continue;
7896 }
7897 else
7898 {
7899 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7900 section group. We just warn it the first time
d1f5c6e3 7901 and ignore it afterwards. */
015dc7e1 7902 static bool warned = false;
d1f5c6e3
L
7903 if (!warned)
7904 {
7905 error (_("section 0 in group section [%5u]\n"),
978c4450 7906 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7907 warned = true;
d1f5c6e3
L
7908 }
7909 }
e4b17d5c
L
7910 }
7911
978c4450 7912 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7913
7914 if (do_section_groups)
7915 {
dda8d76d
NC
7916 sec = filedata->section_headers + entry;
7917 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7918 }
7919
3f5e193b 7920 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7921 g->section_index = entry;
7922 g->next = group->root;
7923 group->root = g;
f5842774
L
7924 }
7925
9db70fc3 7926 free (start);
e4b17d5c
L
7927
7928 group++;
f5842774
L
7929 }
7930 }
7931
9db70fc3
AM
7932 free (symtab);
7933 free (strtab);
015dc7e1 7934 return true;
f5842774
L
7935}
7936
28f997cf
TG
7937/* Data used to display dynamic fixups. */
7938
7939struct ia64_vms_dynfixup
7940{
7941 bfd_vma needed_ident; /* Library ident number. */
7942 bfd_vma needed; /* Index in the dstrtab of the library name. */
7943 bfd_vma fixup_needed; /* Index of the library. */
7944 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7945 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7946};
7947
7948/* Data used to display dynamic relocations. */
7949
7950struct ia64_vms_dynimgrela
7951{
7952 bfd_vma img_rela_cnt; /* Number of relocations. */
7953 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7954};
7955
7956/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7957 library). */
7958
015dc7e1 7959static bool
dda8d76d
NC
7960dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7961 struct ia64_vms_dynfixup * fixup,
7962 const char * strtab,
7963 unsigned int strtab_sz)
28f997cf 7964{
32ec8896 7965 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7966 long i;
32ec8896 7967 const char * lib_name;
28f997cf 7968
978c4450
AM
7969 imfs = get_data (NULL, filedata,
7970 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7971 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7972 _("dynamic section image fixups"));
7973 if (!imfs)
015dc7e1 7974 return false;
28f997cf
TG
7975
7976 if (fixup->needed < strtab_sz)
7977 lib_name = strtab + fixup->needed;
7978 else
7979 {
32ec8896 7980 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7981 (unsigned long) fixup->needed);
28f997cf
TG
7982 lib_name = "???";
7983 }
736990c4 7984
28f997cf
TG
7985 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7986 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7987 printf
7988 (_("Seg Offset Type SymVec DataType\n"));
7989
7990 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7991 {
7992 unsigned int type;
7993 const char *rtype;
7994
7995 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7996 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7997 type = BYTE_GET (imfs [i].type);
7998 rtype = elf_ia64_reloc_type (type);
7999 if (rtype == NULL)
8000 printf (" 0x%08x ", type);
8001 else
8002 printf (" %-32s ", rtype);
8003 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8004 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8005 }
8006
8007 free (imfs);
015dc7e1 8008 return true;
28f997cf
TG
8009}
8010
8011/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8012
015dc7e1 8013static bool
dda8d76d 8014dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8015{
8016 Elf64_External_VMS_IMAGE_RELA *imrs;
8017 long i;
8018
978c4450
AM
8019 imrs = get_data (NULL, filedata,
8020 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8021 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8022 _("dynamic section image relocations"));
28f997cf 8023 if (!imrs)
015dc7e1 8024 return false;
28f997cf
TG
8025
8026 printf (_("\nImage relocs\n"));
8027 printf
8028 (_("Seg Offset Type Addend Seg Sym Off\n"));
8029
8030 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8031 {
8032 unsigned int type;
8033 const char *rtype;
8034
8035 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
8036 printf ("%08" BFD_VMA_FMT "x ",
8037 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
8038 type = BYTE_GET (imrs [i].type);
8039 rtype = elf_ia64_reloc_type (type);
8040 if (rtype == NULL)
8041 printf ("0x%08x ", type);
8042 else
8043 printf ("%-31s ", rtype);
8044 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8045 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
8046 printf ("%08" BFD_VMA_FMT "x\n",
8047 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
8048 }
8049
8050 free (imrs);
015dc7e1 8051 return true;
28f997cf
TG
8052}
8053
8054/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8055
015dc7e1 8056static bool
dda8d76d 8057process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8058{
8059 struct ia64_vms_dynfixup fixup;
8060 struct ia64_vms_dynimgrela imgrela;
8061 Elf_Internal_Dyn *entry;
28f997cf
TG
8062 bfd_vma strtab_off = 0;
8063 bfd_vma strtab_sz = 0;
8064 char *strtab = NULL;
015dc7e1 8065 bool res = true;
28f997cf
TG
8066
8067 memset (&fixup, 0, sizeof (fixup));
8068 memset (&imgrela, 0, sizeof (imgrela));
8069
8070 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8071 for (entry = filedata->dynamic_section;
8072 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8073 entry++)
8074 {
8075 switch (entry->d_tag)
8076 {
8077 case DT_IA_64_VMS_STRTAB_OFFSET:
8078 strtab_off = entry->d_un.d_val;
8079 break;
8080 case DT_STRSZ:
8081 strtab_sz = entry->d_un.d_val;
8082 if (strtab == NULL)
978c4450
AM
8083 strtab = get_data (NULL, filedata,
8084 filedata->dynamic_addr + strtab_off,
28f997cf 8085 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8086 if (strtab == NULL)
8087 strtab_sz = 0;
28f997cf
TG
8088 break;
8089
8090 case DT_IA_64_VMS_NEEDED_IDENT:
8091 fixup.needed_ident = entry->d_un.d_val;
8092 break;
8093 case DT_NEEDED:
8094 fixup.needed = entry->d_un.d_val;
8095 break;
8096 case DT_IA_64_VMS_FIXUP_NEEDED:
8097 fixup.fixup_needed = entry->d_un.d_val;
8098 break;
8099 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8100 fixup.fixup_rela_cnt = entry->d_un.d_val;
8101 break;
8102 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8103 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8104 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8105 res = false;
28f997cf 8106 break;
28f997cf
TG
8107 case DT_IA_64_VMS_IMG_RELA_CNT:
8108 imgrela.img_rela_cnt = entry->d_un.d_val;
8109 break;
8110 case DT_IA_64_VMS_IMG_RELA_OFF:
8111 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8112 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8113 res = false;
28f997cf
TG
8114 break;
8115
8116 default:
8117 break;
8118 }
8119 }
8120
9db70fc3 8121 free (strtab);
28f997cf
TG
8122
8123 return res;
8124}
8125
85b1c36d 8126static struct
566b0d53 8127{
2cf0635d 8128 const char * name;
566b0d53
L
8129 int reloc;
8130 int size;
a7fd1186 8131 relocation_type rel_type;
32ec8896
NC
8132}
8133 dynamic_relocations [] =
566b0d53 8134{
a7fd1186
FS
8135 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8136 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8137 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8138 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8139};
8140
252b5132 8141/* Process the reloc section. */
18bd398b 8142
015dc7e1 8143static bool
dda8d76d 8144process_relocs (Filedata * filedata)
252b5132 8145{
b34976b6
AM
8146 unsigned long rel_size;
8147 unsigned long rel_offset;
252b5132 8148
252b5132 8149 if (!do_reloc)
015dc7e1 8150 return true;
252b5132
RH
8151
8152 if (do_using_dynamic)
8153 {
a7fd1186 8154 relocation_type rel_type;
2cf0635d 8155 const char * name;
015dc7e1 8156 bool has_dynamic_reloc;
566b0d53 8157 unsigned int i;
0de14b54 8158
015dc7e1 8159 has_dynamic_reloc = false;
252b5132 8160
566b0d53 8161 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8162 {
a7fd1186 8163 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8164 name = dynamic_relocations [i].name;
978c4450
AM
8165 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8166 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8167
32ec8896 8168 if (rel_size)
015dc7e1 8169 has_dynamic_reloc = true;
566b0d53 8170
a7fd1186 8171 if (rel_type == reltype_unknown)
aa903cfb 8172 {
566b0d53 8173 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8174 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8175 {
8176 case DT_REL:
a7fd1186 8177 rel_type = reltype_rel;
566b0d53
L
8178 break;
8179 case DT_RELA:
a7fd1186 8180 rel_type = reltype_rela;
566b0d53
L
8181 break;
8182 }
aa903cfb 8183 }
252b5132 8184
566b0d53
L
8185 if (rel_size)
8186 {
ca0e11aa
NC
8187 if (filedata->is_separate)
8188 printf
8189 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8190 filedata->file_name, name, rel_offset, rel_size);
8191 else
8192 printf
8193 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8194 name, rel_offset, rel_size);
252b5132 8195
dda8d76d
NC
8196 dump_relocations (filedata,
8197 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8198 rel_size,
978c4450
AM
8199 filedata->dynamic_symbols,
8200 filedata->num_dynamic_syms,
8201 filedata->dynamic_strings,
8202 filedata->dynamic_strings_length,
a7fd1186 8203 rel_type, true /* is_dynamic */);
566b0d53 8204 }
252b5132 8205 }
566b0d53 8206
dda8d76d
NC
8207 if (is_ia64_vms (filedata))
8208 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8209 has_dynamic_reloc = true;
28f997cf 8210
566b0d53 8211 if (! has_dynamic_reloc)
ca0e11aa
NC
8212 {
8213 if (filedata->is_separate)
8214 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8215 filedata->file_name);
8216 else
8217 printf (_("\nThere are no dynamic relocations in this file.\n"));
8218 }
252b5132
RH
8219 }
8220 else
8221 {
2cf0635d 8222 Elf_Internal_Shdr * section;
b34976b6 8223 unsigned long i;
015dc7e1 8224 bool found = false;
252b5132 8225
dda8d76d
NC
8226 for (i = 0, section = filedata->section_headers;
8227 i < filedata->file_header.e_shnum;
b34976b6 8228 i++, section++)
252b5132
RH
8229 {
8230 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8231 && section->sh_type != SHT_REL
8232 && section->sh_type != SHT_RELR)
252b5132
RH
8233 continue;
8234
8235 rel_offset = section->sh_offset;
8236 rel_size = section->sh_size;
8237
8238 if (rel_size)
8239 {
a7fd1186 8240 relocation_type rel_type;
d3a49aa8 8241 unsigned long num_rela;
103f02d3 8242
ca0e11aa
NC
8243 if (filedata->is_separate)
8244 printf (_("\nIn linked file '%s' relocation section "),
8245 filedata->file_name);
8246 else
8247 printf (_("\nRelocation section "));
252b5132 8248
dda8d76d 8249 if (filedata->string_table == NULL)
19936277 8250 printf ("%d", section->sh_name);
252b5132 8251 else
dda8d76d 8252 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8253
d3a49aa8
AM
8254 num_rela = rel_size / section->sh_entsize;
8255 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8256 " at offset 0x%lx contains %lu entries:\n",
8257 num_rela),
8258 rel_offset, num_rela);
252b5132 8259
a7fd1186
FS
8260 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8261 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8262
4fbb74a6 8263 if (section->sh_link != 0
dda8d76d 8264 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8265 {
2cf0635d
NC
8266 Elf_Internal_Shdr * symsec;
8267 Elf_Internal_Sym * symtab;
d79b3d50 8268 unsigned long nsyms;
c256ffe7 8269 unsigned long strtablen = 0;
2cf0635d 8270 char * strtab = NULL;
57346661 8271
dda8d76d 8272 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8273 if (symsec->sh_type != SHT_SYMTAB
8274 && symsec->sh_type != SHT_DYNSYM)
8275 continue;
8276
28d13567
AM
8277 if (!get_symtab (filedata, symsec,
8278 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8279 continue;
252b5132 8280
dda8d76d 8281 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8282 symtab, nsyms, strtab, strtablen,
a7fd1186 8283 rel_type,
bb4d2ac2 8284 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8285 free (strtab);
d79b3d50
NC
8286 free (symtab);
8287 }
8288 else
dda8d76d 8289 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8290 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8291
015dc7e1 8292 found = true;
252b5132
RH
8293 }
8294 }
8295
8296 if (! found)
45ac8f4f
NC
8297 {
8298 /* Users sometimes forget the -D option, so try to be helpful. */
8299 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8300 {
978c4450 8301 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8302 {
ca0e11aa
NC
8303 if (filedata->is_separate)
8304 printf (_("\nThere are no static relocations in linked file '%s'."),
8305 filedata->file_name);
8306 else
8307 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8308 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8309
8310 break;
8311 }
8312 }
8313 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8314 {
8315 if (filedata->is_separate)
8316 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8317 filedata->file_name);
8318 else
8319 printf (_("\nThere are no relocations in this file.\n"));
8320 }
45ac8f4f 8321 }
252b5132
RH
8322 }
8323
015dc7e1 8324 return true;
252b5132
RH
8325}
8326
4d6ed7c8
NC
8327/* An absolute address consists of a section and an offset. If the
8328 section is NULL, the offset itself is the address, otherwise, the
8329 address equals to LOAD_ADDRESS(section) + offset. */
8330
8331struct absaddr
948f632f
DA
8332{
8333 unsigned short section;
8334 bfd_vma offset;
8335};
4d6ed7c8 8336
948f632f
DA
8337/* Find the nearest symbol at or below ADDR. Returns the symbol
8338 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8339
4d6ed7c8 8340static void
dda8d76d
NC
8341find_symbol_for_address (Filedata * filedata,
8342 Elf_Internal_Sym * symtab,
8343 unsigned long nsyms,
8344 const char * strtab,
8345 unsigned long strtab_size,
8346 struct absaddr addr,
8347 const char ** symname,
8348 bfd_vma * offset)
4d6ed7c8 8349{
d3ba0551 8350 bfd_vma dist = 0x100000;
2cf0635d 8351 Elf_Internal_Sym * sym;
948f632f
DA
8352 Elf_Internal_Sym * beg;
8353 Elf_Internal_Sym * end;
2cf0635d 8354 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8355
0b6ae522 8356 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8357 beg = symtab;
8358 end = symtab + nsyms;
0b6ae522 8359
948f632f 8360 while (beg < end)
4d6ed7c8 8361 {
948f632f
DA
8362 bfd_vma value;
8363
8364 sym = beg + (end - beg) / 2;
0b6ae522 8365
948f632f 8366 value = sym->st_value;
0b6ae522
DJ
8367 REMOVE_ARCH_BITS (value);
8368
948f632f 8369 if (sym->st_name != 0
4d6ed7c8 8370 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8371 && addr.offset >= value
8372 && addr.offset - value < dist)
4d6ed7c8
NC
8373 {
8374 best = sym;
0b6ae522 8375 dist = addr.offset - value;
4d6ed7c8
NC
8376 if (!dist)
8377 break;
8378 }
948f632f
DA
8379
8380 if (addr.offset < value)
8381 end = sym;
8382 else
8383 beg = sym + 1;
4d6ed7c8 8384 }
1b31d05e 8385
4d6ed7c8
NC
8386 if (best)
8387 {
57346661 8388 *symname = (best->st_name >= strtab_size
2b692964 8389 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8390 *offset = dist;
8391 return;
8392 }
1b31d05e 8393
4d6ed7c8
NC
8394 *symname = NULL;
8395 *offset = addr.offset;
8396}
8397
32ec8896 8398static /* signed */ int
948f632f
DA
8399symcmp (const void *p, const void *q)
8400{
8401 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8402 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8403
8404 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8405}
8406
8407/* Process the unwind section. */
8408
8409#include "unwind-ia64.h"
8410
8411struct ia64_unw_table_entry
8412{
8413 struct absaddr start;
8414 struct absaddr end;
8415 struct absaddr info;
8416};
8417
8418struct ia64_unw_aux_info
8419{
32ec8896
NC
8420 struct ia64_unw_table_entry * table; /* Unwind table. */
8421 unsigned long table_len; /* Length of unwind table. */
8422 unsigned char * info; /* Unwind info. */
8423 unsigned long info_size; /* Size of unwind info. */
8424 bfd_vma info_addr; /* Starting address of unwind info. */
8425 bfd_vma seg_base; /* Starting address of segment. */
8426 Elf_Internal_Sym * symtab; /* The symbol table. */
8427 unsigned long nsyms; /* Number of symbols. */
8428 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8429 unsigned long nfuns; /* Number of entries in funtab. */
8430 char * strtab; /* The string table. */
8431 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8432};
8433
015dc7e1 8434static bool
dda8d76d 8435dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8436{
2cf0635d 8437 struct ia64_unw_table_entry * tp;
948f632f 8438 unsigned long j, nfuns;
4d6ed7c8 8439 int in_body;
015dc7e1 8440 bool res = true;
7036c0e1 8441
948f632f
DA
8442 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8443 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8444 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8445 aux->funtab[nfuns++] = aux->symtab[j];
8446 aux->nfuns = nfuns;
8447 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8448
4d6ed7c8
NC
8449 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8450 {
8451 bfd_vma stamp;
8452 bfd_vma offset;
2cf0635d
NC
8453 const unsigned char * dp;
8454 const unsigned char * head;
53774b7e 8455 const unsigned char * end;
2cf0635d 8456 const char * procname;
4d6ed7c8 8457
dda8d76d 8458 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8459 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8460
8461 fputs ("\n<", stdout);
8462
8463 if (procname)
8464 {
8465 fputs (procname, stdout);
8466
8467 if (offset)
8468 printf ("+%lx", (unsigned long) offset);
8469 }
8470
8471 fputs (">: [", stdout);
8472 print_vma (tp->start.offset, PREFIX_HEX);
8473 fputc ('-', stdout);
8474 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8475 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8476 (unsigned long) (tp->info.offset - aux->seg_base));
8477
53774b7e
NC
8478 /* PR 17531: file: 86232b32. */
8479 if (aux->info == NULL)
8480 continue;
8481
97c0a079
AM
8482 offset = tp->info.offset;
8483 if (tp->info.section)
8484 {
8485 if (tp->info.section >= filedata->file_header.e_shnum)
8486 {
8487 warn (_("Invalid section %u in table entry %ld\n"),
8488 tp->info.section, (long) (tp - aux->table));
015dc7e1 8489 res = false;
97c0a079
AM
8490 continue;
8491 }
8492 offset += filedata->section_headers[tp->info.section].sh_addr;
8493 }
8494 offset -= aux->info_addr;
53774b7e 8495 /* PR 17531: file: 0997b4d1. */
90679903
AM
8496 if (offset >= aux->info_size
8497 || aux->info_size - offset < 8)
53774b7e
NC
8498 {
8499 warn (_("Invalid offset %lx in table entry %ld\n"),
8500 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8501 res = false;
53774b7e
NC
8502 continue;
8503 }
8504
97c0a079 8505 head = aux->info + offset;
a4a00738 8506 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8507
86f55779 8508 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8509 (unsigned) UNW_VER (stamp),
8510 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8511 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8512 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8513 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8514
8515 if (UNW_VER (stamp) != 1)
8516 {
2b692964 8517 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8518 continue;
8519 }
8520
8521 in_body = 0;
53774b7e
NC
8522 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8523 /* PR 17531: file: 16ceda89. */
8524 if (end > aux->info + aux->info_size)
8525 end = aux->info + aux->info_size;
8526 for (dp = head + 8; dp < end;)
b4477bc8 8527 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8528 }
948f632f
DA
8529
8530 free (aux->funtab);
32ec8896
NC
8531
8532 return res;
4d6ed7c8
NC
8533}
8534
015dc7e1 8535static bool
dda8d76d
NC
8536slurp_ia64_unwind_table (Filedata * filedata,
8537 struct ia64_unw_aux_info * aux,
8538 Elf_Internal_Shdr * sec)
4d6ed7c8 8539{
89fac5e3 8540 unsigned long size, nrelas, i;
2cf0635d
NC
8541 Elf_Internal_Phdr * seg;
8542 struct ia64_unw_table_entry * tep;
8543 Elf_Internal_Shdr * relsec;
8544 Elf_Internal_Rela * rela;
8545 Elf_Internal_Rela * rp;
8546 unsigned char * table;
8547 unsigned char * tp;
8548 Elf_Internal_Sym * sym;
8549 const char * relname;
4d6ed7c8 8550
53774b7e
NC
8551 aux->table_len = 0;
8552
4d6ed7c8
NC
8553 /* First, find the starting address of the segment that includes
8554 this section: */
8555
dda8d76d 8556 if (filedata->file_header.e_phnum)
4d6ed7c8 8557 {
dda8d76d 8558 if (! get_program_headers (filedata))
015dc7e1 8559 return false;
4d6ed7c8 8560
dda8d76d
NC
8561 for (seg = filedata->program_headers;
8562 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8563 ++seg)
4d6ed7c8
NC
8564 {
8565 if (seg->p_type != PT_LOAD)
8566 continue;
8567
8568 if (sec->sh_addr >= seg->p_vaddr
8569 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8570 {
8571 aux->seg_base = seg->p_vaddr;
8572 break;
8573 }
8574 }
4d6ed7c8
NC
8575 }
8576
8577 /* Second, build the unwind table from the contents of the unwind section: */
8578 size = sec->sh_size;
dda8d76d 8579 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8580 _("unwind table"));
a6e9f9df 8581 if (!table)
015dc7e1 8582 return false;
4d6ed7c8 8583
53774b7e 8584 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8585 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8586 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8587 tep = aux->table;
53774b7e
NC
8588
8589 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8590 {
8591 tep->start.section = SHN_UNDEF;
8592 tep->end.section = SHN_UNDEF;
8593 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8594 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8595 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8596 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8597 tep->start.offset += aux->seg_base;
8598 tep->end.offset += aux->seg_base;
8599 tep->info.offset += aux->seg_base;
8600 }
8601 free (table);
8602
41e92641 8603 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8604 for (relsec = filedata->section_headers;
8605 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8606 ++relsec)
8607 {
8608 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8609 || relsec->sh_info >= filedata->file_header.e_shnum
8610 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8611 continue;
8612
dda8d76d 8613 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8614 & rela, & nrelas))
53774b7e
NC
8615 {
8616 free (aux->table);
8617 aux->table = NULL;
8618 aux->table_len = 0;
015dc7e1 8619 return false;
53774b7e 8620 }
4d6ed7c8
NC
8621
8622 for (rp = rela; rp < rela + nrelas; ++rp)
8623 {
4770fb94 8624 unsigned int sym_ndx;
726bd37d
AM
8625 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8626 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8627
82b1b41b
NC
8628 /* PR 17531: file: 9fa67536. */
8629 if (relname == NULL)
8630 {
726bd37d 8631 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8632 continue;
8633 }
948f632f 8634
24d127aa 8635 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8636 {
82b1b41b 8637 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8638 continue;
8639 }
8640
89fac5e3 8641 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8642
53774b7e
NC
8643 /* PR 17531: file: 5bc8d9bf. */
8644 if (i >= aux->table_len)
8645 {
8646 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8647 continue;
8648 }
8649
4770fb94
AM
8650 sym_ndx = get_reloc_symindex (rp->r_info);
8651 if (sym_ndx >= aux->nsyms)
8652 {
8653 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8654 sym_ndx);
8655 continue;
8656 }
8657 sym = aux->symtab + sym_ndx;
8658
53774b7e 8659 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8660 {
8661 case 0:
8662 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8663 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8664 break;
8665 case 1:
8666 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8667 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8668 break;
8669 case 2:
8670 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8671 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8672 break;
8673 default:
8674 break;
8675 }
8676 }
8677
8678 free (rela);
8679 }
8680
015dc7e1 8681 return true;
4d6ed7c8
NC
8682}
8683
015dc7e1 8684static bool
dda8d76d 8685ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8686{
2cf0635d
NC
8687 Elf_Internal_Shdr * sec;
8688 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8689 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8690 struct ia64_unw_aux_info aux;
015dc7e1 8691 bool res = true;
f1467e33 8692
4d6ed7c8
NC
8693 memset (& aux, 0, sizeof (aux));
8694
dda8d76d 8695 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8696 {
28d13567 8697 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8698 {
28d13567 8699 if (aux.symtab)
4082ef84 8700 {
28d13567
AM
8701 error (_("Multiple symbol tables encountered\n"));
8702 free (aux.symtab);
8703 aux.symtab = NULL;
4082ef84 8704 free (aux.strtab);
28d13567 8705 aux.strtab = NULL;
4082ef84 8706 }
28d13567
AM
8707 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8708 &aux.strtab, &aux.strtab_size))
015dc7e1 8709 return false;
4d6ed7c8
NC
8710 }
8711 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8712 unwcount++;
8713 }
8714
8715 if (!unwcount)
8716 printf (_("\nThere are no unwind sections in this file.\n"));
8717
8718 while (unwcount-- > 0)
8719 {
84714f86 8720 const char *suffix;
579f31ac
JJ
8721 size_t len, len2;
8722
dda8d76d
NC
8723 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8724 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8725 if (sec->sh_type == SHT_IA_64_UNWIND)
8726 {
8727 unwsec = sec;
8728 break;
8729 }
4082ef84
NC
8730 /* We have already counted the number of SHT_IA64_UNWIND
8731 sections so the loop above should never fail. */
8732 assert (unwsec != NULL);
579f31ac
JJ
8733
8734 unwstart = i + 1;
8735 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8736
e4b17d5c
L
8737 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8738 {
8739 /* We need to find which section group it is in. */
4082ef84 8740 struct group_list * g;
e4b17d5c 8741
978c4450
AM
8742 if (filedata->section_headers_groups == NULL
8743 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8744 i = filedata->file_header.e_shnum;
4082ef84 8745 else
e4b17d5c 8746 {
978c4450 8747 g = filedata->section_headers_groups[i]->root;
18bd398b 8748
4082ef84
NC
8749 for (; g != NULL; g = g->next)
8750 {
dda8d76d 8751 sec = filedata->section_headers + g->section_index;
e4b17d5c 8752
84714f86
AM
8753 if (section_name_valid (filedata, sec)
8754 && streq (section_name (filedata, sec),
8755 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8756 break;
8757 }
8758
8759 if (g == NULL)
dda8d76d 8760 i = filedata->file_header.e_shnum;
4082ef84 8761 }
e4b17d5c 8762 }
84714f86
AM
8763 else if (section_name_valid (filedata, unwsec)
8764 && startswith (section_name (filedata, unwsec),
e9b095a5 8765 ELF_STRING_ia64_unwind_once))
579f31ac 8766 {
18bd398b 8767 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8768 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8769 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8770 for (i = 0, sec = filedata->section_headers;
8771 i < filedata->file_header.e_shnum;
579f31ac 8772 ++i, ++sec)
84714f86
AM
8773 if (section_name_valid (filedata, sec)
8774 && startswith (section_name (filedata, sec),
e9b095a5 8775 ELF_STRING_ia64_unwind_info_once)
84714f86 8776 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8777 break;
8778 }
8779 else
8780 {
8781 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8782 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8783 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8784 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8785 suffix = "";
84714f86
AM
8786 if (section_name_valid (filedata, unwsec)
8787 && startswith (section_name (filedata, unwsec),
8788 ELF_STRING_ia64_unwind))
8789 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8790 for (i = 0, sec = filedata->section_headers;
8791 i < filedata->file_header.e_shnum;
579f31ac 8792 ++i, ++sec)
84714f86
AM
8793 if (section_name_valid (filedata, sec)
8794 && startswith (section_name (filedata, sec),
8795 ELF_STRING_ia64_unwind_info)
8796 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8797 break;
8798 }
8799
dda8d76d 8800 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8801 {
8802 printf (_("\nCould not find unwind info section for "));
8803
dda8d76d 8804 if (filedata->string_table == NULL)
579f31ac
JJ
8805 printf ("%d", unwsec->sh_name);
8806 else
dda8d76d 8807 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8808 }
8809 else
4d6ed7c8 8810 {
4d6ed7c8 8811 aux.info_addr = sec->sh_addr;
dda8d76d 8812 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8813 sec->sh_size,
8814 _("unwind info"));
59245841 8815 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8816
579f31ac 8817 printf (_("\nUnwind section "));
4d6ed7c8 8818
dda8d76d 8819 if (filedata->string_table == NULL)
579f31ac
JJ
8820 printf ("%d", unwsec->sh_name);
8821 else
dda8d76d 8822 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8823
579f31ac 8824 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8825 (unsigned long) unwsec->sh_offset,
89fac5e3 8826 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8827
dda8d76d 8828 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8829 && aux.table_len > 0)
dda8d76d 8830 dump_ia64_unwind (filedata, & aux);
579f31ac 8831
9db70fc3
AM
8832 free ((char *) aux.table);
8833 free ((char *) aux.info);
579f31ac
JJ
8834 aux.table = NULL;
8835 aux.info = NULL;
8836 }
4d6ed7c8 8837 }
4d6ed7c8 8838
9db70fc3
AM
8839 free (aux.symtab);
8840 free ((char *) aux.strtab);
32ec8896
NC
8841
8842 return res;
4d6ed7c8
NC
8843}
8844
3f5e193b 8845struct hppa_unw_table_entry
32ec8896
NC
8846{
8847 struct absaddr start;
8848 struct absaddr end;
8849 unsigned int Cannot_unwind:1; /* 0 */
8850 unsigned int Millicode:1; /* 1 */
8851 unsigned int Millicode_save_sr0:1; /* 2 */
8852 unsigned int Region_description:2; /* 3..4 */
8853 unsigned int reserved1:1; /* 5 */
8854 unsigned int Entry_SR:1; /* 6 */
8855 unsigned int Entry_FR:4; /* Number saved 7..10 */
8856 unsigned int Entry_GR:5; /* Number saved 11..15 */
8857 unsigned int Args_stored:1; /* 16 */
8858 unsigned int Variable_Frame:1; /* 17 */
8859 unsigned int Separate_Package_Body:1; /* 18 */
8860 unsigned int Frame_Extension_Millicode:1; /* 19 */
8861 unsigned int Stack_Overflow_Check:1; /* 20 */
8862 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8863 unsigned int Ada_Region:1; /* 22 */
8864 unsigned int cxx_info:1; /* 23 */
8865 unsigned int cxx_try_catch:1; /* 24 */
8866 unsigned int sched_entry_seq:1; /* 25 */
8867 unsigned int reserved2:1; /* 26 */
8868 unsigned int Save_SP:1; /* 27 */
8869 unsigned int Save_RP:1; /* 28 */
8870 unsigned int Save_MRP_in_frame:1; /* 29 */
8871 unsigned int extn_ptr_defined:1; /* 30 */
8872 unsigned int Cleanup_defined:1; /* 31 */
8873
8874 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8875 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8876 unsigned int Large_frame:1; /* 2 */
8877 unsigned int Pseudo_SP_Set:1; /* 3 */
8878 unsigned int reserved4:1; /* 4 */
8879 unsigned int Total_frame_size:27; /* 5..31 */
8880};
3f5e193b 8881
57346661 8882struct hppa_unw_aux_info
948f632f 8883{
32ec8896
NC
8884 struct hppa_unw_table_entry * table; /* Unwind table. */
8885 unsigned long table_len; /* Length of unwind table. */
8886 bfd_vma seg_base; /* Starting address of segment. */
8887 Elf_Internal_Sym * symtab; /* The symbol table. */
8888 unsigned long nsyms; /* Number of symbols. */
8889 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8890 unsigned long nfuns; /* Number of entries in funtab. */
8891 char * strtab; /* The string table. */
8892 unsigned long strtab_size; /* Size of string table. */
948f632f 8893};
57346661 8894
015dc7e1 8895static bool
dda8d76d 8896dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8897{
2cf0635d 8898 struct hppa_unw_table_entry * tp;
948f632f 8899 unsigned long j, nfuns;
015dc7e1 8900 bool res = true;
948f632f
DA
8901
8902 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8903 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8904 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8905 aux->funtab[nfuns++] = aux->symtab[j];
8906 aux->nfuns = nfuns;
8907 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8908
57346661
AM
8909 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8910 {
8911 bfd_vma offset;
2cf0635d 8912 const char * procname;
57346661 8913
dda8d76d 8914 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8915 aux->strtab_size, tp->start, &procname,
8916 &offset);
8917
8918 fputs ("\n<", stdout);
8919
8920 if (procname)
8921 {
8922 fputs (procname, stdout);
8923
8924 if (offset)
8925 printf ("+%lx", (unsigned long) offset);
8926 }
8927
8928 fputs (">: [", stdout);
8929 print_vma (tp->start.offset, PREFIX_HEX);
8930 fputc ('-', stdout);
8931 print_vma (tp->end.offset, PREFIX_HEX);
8932 printf ("]\n\t");
8933
18bd398b
NC
8934#define PF(_m) if (tp->_m) printf (#_m " ");
8935#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8936 PF(Cannot_unwind);
8937 PF(Millicode);
8938 PF(Millicode_save_sr0);
18bd398b 8939 /* PV(Region_description); */
57346661
AM
8940 PF(Entry_SR);
8941 PV(Entry_FR);
8942 PV(Entry_GR);
8943 PF(Args_stored);
8944 PF(Variable_Frame);
8945 PF(Separate_Package_Body);
8946 PF(Frame_Extension_Millicode);
8947 PF(Stack_Overflow_Check);
8948 PF(Two_Instruction_SP_Increment);
8949 PF(Ada_Region);
8950 PF(cxx_info);
8951 PF(cxx_try_catch);
8952 PF(sched_entry_seq);
8953 PF(Save_SP);
8954 PF(Save_RP);
8955 PF(Save_MRP_in_frame);
8956 PF(extn_ptr_defined);
8957 PF(Cleanup_defined);
8958 PF(MPE_XL_interrupt_marker);
8959 PF(HP_UX_interrupt_marker);
8960 PF(Large_frame);
8961 PF(Pseudo_SP_Set);
8962 PV(Total_frame_size);
8963#undef PF
8964#undef PV
8965 }
8966
18bd398b 8967 printf ("\n");
948f632f
DA
8968
8969 free (aux->funtab);
32ec8896
NC
8970
8971 return res;
57346661
AM
8972}
8973
015dc7e1 8974static bool
dda8d76d
NC
8975slurp_hppa_unwind_table (Filedata * filedata,
8976 struct hppa_unw_aux_info * aux,
8977 Elf_Internal_Shdr * sec)
57346661 8978{
1c0751b2 8979 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8980 Elf_Internal_Phdr * seg;
8981 struct hppa_unw_table_entry * tep;
8982 Elf_Internal_Shdr * relsec;
8983 Elf_Internal_Rela * rela;
8984 Elf_Internal_Rela * rp;
8985 unsigned char * table;
8986 unsigned char * tp;
8987 Elf_Internal_Sym * sym;
8988 const char * relname;
57346661 8989
57346661
AM
8990 /* First, find the starting address of the segment that includes
8991 this section. */
dda8d76d 8992 if (filedata->file_header.e_phnum)
57346661 8993 {
dda8d76d 8994 if (! get_program_headers (filedata))
015dc7e1 8995 return false;
57346661 8996
dda8d76d
NC
8997 for (seg = filedata->program_headers;
8998 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8999 ++seg)
9000 {
9001 if (seg->p_type != PT_LOAD)
9002 continue;
9003
9004 if (sec->sh_addr >= seg->p_vaddr
9005 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9006 {
9007 aux->seg_base = seg->p_vaddr;
9008 break;
9009 }
9010 }
9011 }
9012
9013 /* Second, build the unwind table from the contents of the unwind
9014 section. */
9015 size = sec->sh_size;
dda8d76d 9016 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9017 _("unwind table"));
57346661 9018 if (!table)
015dc7e1 9019 return false;
57346661 9020
1c0751b2
DA
9021 unw_ent_size = 16;
9022 nentries = size / unw_ent_size;
9023 size = unw_ent_size * nentries;
57346661 9024
e3fdc001 9025 aux->table_len = nentries;
3f5e193b
NC
9026 tep = aux->table = (struct hppa_unw_table_entry *)
9027 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9028
1c0751b2 9029 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9030 {
9031 unsigned int tmp1, tmp2;
9032
9033 tep->start.section = SHN_UNDEF;
9034 tep->end.section = SHN_UNDEF;
9035
1c0751b2
DA
9036 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9037 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9038 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9039 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9040
9041 tep->start.offset += aux->seg_base;
9042 tep->end.offset += aux->seg_base;
57346661
AM
9043
9044 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9045 tep->Millicode = (tmp1 >> 30) & 0x1;
9046 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9047 tep->Region_description = (tmp1 >> 27) & 0x3;
9048 tep->reserved1 = (tmp1 >> 26) & 0x1;
9049 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9050 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9051 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9052 tep->Args_stored = (tmp1 >> 15) & 0x1;
9053 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9054 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9055 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9056 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9057 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9058 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9059 tep->cxx_info = (tmp1 >> 8) & 0x1;
9060 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9061 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9062 tep->reserved2 = (tmp1 >> 5) & 0x1;
9063 tep->Save_SP = (tmp1 >> 4) & 0x1;
9064 tep->Save_RP = (tmp1 >> 3) & 0x1;
9065 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9066 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9067 tep->Cleanup_defined = tmp1 & 0x1;
9068
9069 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9070 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9071 tep->Large_frame = (tmp2 >> 29) & 0x1;
9072 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9073 tep->reserved4 = (tmp2 >> 27) & 0x1;
9074 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9075 }
9076 free (table);
9077
9078 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9079 for (relsec = filedata->section_headers;
9080 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9081 ++relsec)
9082 {
9083 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9084 || relsec->sh_info >= filedata->file_header.e_shnum
9085 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9086 continue;
9087
dda8d76d 9088 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9089 & rela, & nrelas))
015dc7e1 9090 return false;
57346661
AM
9091
9092 for (rp = rela; rp < rela + nrelas; ++rp)
9093 {
4770fb94 9094 unsigned int sym_ndx;
726bd37d
AM
9095 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9096 relname = elf_hppa_reloc_type (r_type);
57346661 9097
726bd37d
AM
9098 if (relname == NULL)
9099 {
9100 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9101 continue;
9102 }
9103
57346661 9104 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9105 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9106 {
726bd37d 9107 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9108 continue;
9109 }
9110
9111 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9112 if (i >= aux->table_len)
9113 {
9114 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9115 continue;
9116 }
57346661 9117
4770fb94
AM
9118 sym_ndx = get_reloc_symindex (rp->r_info);
9119 if (sym_ndx >= aux->nsyms)
9120 {
9121 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9122 sym_ndx);
9123 continue;
9124 }
9125 sym = aux->symtab + sym_ndx;
9126
43f6cd05 9127 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9128 {
9129 case 0:
9130 aux->table[i].start.section = sym->st_shndx;
1e456d54 9131 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9132 break;
9133 case 1:
9134 aux->table[i].end.section = sym->st_shndx;
1e456d54 9135 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9136 break;
9137 default:
9138 break;
9139 }
9140 }
9141
9142 free (rela);
9143 }
9144
015dc7e1 9145 return true;
57346661
AM
9146}
9147
015dc7e1 9148static bool
dda8d76d 9149hppa_process_unwind (Filedata * filedata)
57346661 9150{
57346661 9151 struct hppa_unw_aux_info aux;
2cf0635d 9152 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9153 Elf_Internal_Shdr * sec;
18bd398b 9154 unsigned long i;
015dc7e1 9155 bool res = true;
57346661 9156
dda8d76d 9157 if (filedata->string_table == NULL)
015dc7e1 9158 return false;
1b31d05e
NC
9159
9160 memset (& aux, 0, sizeof (aux));
57346661 9161
dda8d76d 9162 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9163 {
28d13567 9164 if (sec->sh_type == SHT_SYMTAB)
57346661 9165 {
28d13567 9166 if (aux.symtab)
4082ef84 9167 {
28d13567
AM
9168 error (_("Multiple symbol tables encountered\n"));
9169 free (aux.symtab);
9170 aux.symtab = NULL;
4082ef84 9171 free (aux.strtab);
28d13567 9172 aux.strtab = NULL;
4082ef84 9173 }
28d13567
AM
9174 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9175 &aux.strtab, &aux.strtab_size))
015dc7e1 9176 return false;
57346661 9177 }
84714f86
AM
9178 else if (section_name_valid (filedata, sec)
9179 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9180 unwsec = sec;
9181 }
9182
9183 if (!unwsec)
9184 printf (_("\nThere are no unwind sections in this file.\n"));
9185
dda8d76d 9186 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9187 {
84714f86
AM
9188 if (section_name_valid (filedata, sec)
9189 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9190 {
43f6cd05 9191 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9192
d3a49aa8
AM
9193 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9194 "contains %lu entry:\n",
9195 "\nUnwind section '%s' at offset 0x%lx "
9196 "contains %lu entries:\n",
9197 num_unwind),
dda8d76d 9198 printable_section_name (filedata, sec),
57346661 9199 (unsigned long) sec->sh_offset,
d3a49aa8 9200 num_unwind);
57346661 9201
dda8d76d 9202 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9203 res = false;
66b09c7e
S
9204
9205 if (res && aux.table_len > 0)
32ec8896 9206 {
dda8d76d 9207 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9208 res = false;
32ec8896 9209 }
57346661 9210
9db70fc3 9211 free ((char *) aux.table);
57346661
AM
9212 aux.table = NULL;
9213 }
9214 }
9215
9db70fc3
AM
9216 free (aux.symtab);
9217 free ((char *) aux.strtab);
32ec8896
NC
9218
9219 return res;
57346661
AM
9220}
9221
0b6ae522
DJ
9222struct arm_section
9223{
a734115a
NC
9224 unsigned char * data; /* The unwind data. */
9225 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9226 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9227 unsigned long nrelas; /* The number of relocations. */
9228 unsigned int rel_type; /* REL or RELA ? */
9229 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9230};
9231
9232struct arm_unw_aux_info
9233{
dda8d76d 9234 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9235 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9236 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9237 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9238 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9239 char * strtab; /* The file's string table. */
9240 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9241};
9242
9243static const char *
dda8d76d
NC
9244arm_print_vma_and_name (Filedata * filedata,
9245 struct arm_unw_aux_info * aux,
9246 bfd_vma fn,
9247 struct absaddr addr)
0b6ae522
DJ
9248{
9249 const char *procname;
9250 bfd_vma sym_offset;
9251
9252 if (addr.section == SHN_UNDEF)
9253 addr.offset = fn;
9254
dda8d76d 9255 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9256 aux->strtab_size, addr, &procname,
9257 &sym_offset);
9258
9259 print_vma (fn, PREFIX_HEX);
9260
9261 if (procname)
9262 {
9263 fputs (" <", stdout);
9264 fputs (procname, stdout);
9265
9266 if (sym_offset)
9267 printf ("+0x%lx", (unsigned long) sym_offset);
9268 fputc ('>', stdout);
9269 }
9270
9271 return procname;
9272}
9273
9274static void
9275arm_free_section (struct arm_section *arm_sec)
9276{
9db70fc3
AM
9277 free (arm_sec->data);
9278 free (arm_sec->rela);
0b6ae522
DJ
9279}
9280
a734115a
NC
9281/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9282 cached section and install SEC instead.
9283 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9284 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9285 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9286 relocation's offset in ADDR.
1b31d05e
NC
9287 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9288 into the string table of the symbol associated with the reloc. If no
9289 reloc was applied store -1 there.
9290 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9291
015dc7e1 9292static bool
dda8d76d
NC
9293get_unwind_section_word (Filedata * filedata,
9294 struct arm_unw_aux_info * aux,
1b31d05e
NC
9295 struct arm_section * arm_sec,
9296 Elf_Internal_Shdr * sec,
9297 bfd_vma word_offset,
9298 unsigned int * wordp,
9299 struct absaddr * addr,
9300 bfd_vma * sym_name)
0b6ae522
DJ
9301{
9302 Elf_Internal_Rela *rp;
9303 Elf_Internal_Sym *sym;
9304 const char * relname;
9305 unsigned int word;
015dc7e1 9306 bool wrapped;
0b6ae522 9307
e0a31db1 9308 if (sec == NULL || arm_sec == NULL)
015dc7e1 9309 return false;
e0a31db1 9310
0b6ae522
DJ
9311 addr->section = SHN_UNDEF;
9312 addr->offset = 0;
9313
1b31d05e
NC
9314 if (sym_name != NULL)
9315 *sym_name = (bfd_vma) -1;
9316
a734115a 9317 /* If necessary, update the section cache. */
0b6ae522
DJ
9318 if (sec != arm_sec->sec)
9319 {
9320 Elf_Internal_Shdr *relsec;
9321
9322 arm_free_section (arm_sec);
9323
9324 arm_sec->sec = sec;
dda8d76d 9325 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9326 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9327 arm_sec->rela = NULL;
9328 arm_sec->nrelas = 0;
9329
dda8d76d
NC
9330 for (relsec = filedata->section_headers;
9331 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9332 ++relsec)
9333 {
dda8d76d
NC
9334 if (relsec->sh_info >= filedata->file_header.e_shnum
9335 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9336 /* PR 15745: Check the section type as well. */
9337 || (relsec->sh_type != SHT_REL
9338 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9339 continue;
9340
a734115a 9341 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9342 if (relsec->sh_type == SHT_REL)
9343 {
dda8d76d 9344 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9345 relsec->sh_size,
9346 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9347 return false;
0b6ae522 9348 }
1ae40aa4 9349 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9350 {
dda8d76d 9351 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9352 relsec->sh_size,
9353 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9354 return false;
0b6ae522 9355 }
1ae40aa4 9356 break;
0b6ae522
DJ
9357 }
9358
9359 arm_sec->next_rela = arm_sec->rela;
9360 }
9361
a734115a 9362 /* If there is no unwind data we can do nothing. */
0b6ae522 9363 if (arm_sec->data == NULL)
015dc7e1 9364 return false;
0b6ae522 9365
e0a31db1 9366 /* If the offset is invalid then fail. */
f32ba729
NC
9367 if (/* PR 21343 *//* PR 18879 */
9368 sec->sh_size < 4
9369 || word_offset > (sec->sh_size - 4)
1a915552 9370 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9371 return false;
e0a31db1 9372
a734115a 9373 /* Get the word at the required offset. */
0b6ae522
DJ
9374 word = byte_get (arm_sec->data + word_offset, 4);
9375
0eff7165
NC
9376 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9377 if (arm_sec->rela == NULL)
9378 {
9379 * wordp = word;
015dc7e1 9380 return true;
0eff7165
NC
9381 }
9382
a734115a 9383 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9384 wrapped = false;
0b6ae522
DJ
9385 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9386 {
9387 bfd_vma prelval, offset;
9388
9389 if (rp->r_offset > word_offset && !wrapped)
9390 {
9391 rp = arm_sec->rela;
015dc7e1 9392 wrapped = true;
0b6ae522
DJ
9393 }
9394 if (rp->r_offset > word_offset)
9395 break;
9396
9397 if (rp->r_offset & 3)
9398 {
9399 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9400 (unsigned long) rp->r_offset);
9401 continue;
9402 }
9403
9404 if (rp->r_offset < word_offset)
9405 continue;
9406
74e1a04b
NC
9407 /* PR 17531: file: 027-161405-0.004 */
9408 if (aux->symtab == NULL)
9409 continue;
9410
0b6ae522
DJ
9411 if (arm_sec->rel_type == SHT_REL)
9412 {
9413 offset = word & 0x7fffffff;
9414 if (offset & 0x40000000)
9415 offset |= ~ (bfd_vma) 0x7fffffff;
9416 }
a734115a 9417 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9418 offset = rp->r_addend;
a734115a 9419 else
74e1a04b
NC
9420 {
9421 error (_("Unknown section relocation type %d encountered\n"),
9422 arm_sec->rel_type);
9423 break;
9424 }
0b6ae522 9425
071436c6
NC
9426 /* PR 17531 file: 027-1241568-0.004. */
9427 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9428 {
9429 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9430 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9431 break;
9432 }
9433
9434 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9435 offset += sym->st_value;
9436 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9437
a734115a 9438 /* Check that we are processing the expected reloc type. */
dda8d76d 9439 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9440 {
9441 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9442 if (relname == NULL)
9443 {
9444 warn (_("Skipping unknown ARM relocation type: %d\n"),
9445 (int) ELF32_R_TYPE (rp->r_info));
9446 continue;
9447 }
a734115a
NC
9448
9449 if (streq (relname, "R_ARM_NONE"))
9450 continue;
0b4362b0 9451
a734115a
NC
9452 if (! streq (relname, "R_ARM_PREL31"))
9453 {
071436c6 9454 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9455 continue;
9456 }
9457 }
dda8d76d 9458 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9459 {
9460 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9461 if (relname == NULL)
9462 {
9463 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9464 (int) ELF32_R_TYPE (rp->r_info));
9465 continue;
9466 }
0b4362b0 9467
a734115a
NC
9468 if (streq (relname, "R_C6000_NONE"))
9469 continue;
9470
9471 if (! streq (relname, "R_C6000_PREL31"))
9472 {
071436c6 9473 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9474 continue;
9475 }
9476
9477 prelval >>= 1;
9478 }
9479 else
74e1a04b
NC
9480 {
9481 /* This function currently only supports ARM and TI unwinders. */
9482 warn (_("Only TI and ARM unwinders are currently supported\n"));
9483 break;
9484 }
fa197c1c 9485
0b6ae522
DJ
9486 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9487 addr->section = sym->st_shndx;
9488 addr->offset = offset;
74e1a04b 9489
1b31d05e
NC
9490 if (sym_name)
9491 * sym_name = sym->st_name;
0b6ae522
DJ
9492 break;
9493 }
9494
9495 *wordp = word;
9496 arm_sec->next_rela = rp;
9497
015dc7e1 9498 return true;
0b6ae522
DJ
9499}
9500
a734115a
NC
9501static const char *tic6x_unwind_regnames[16] =
9502{
0b4362b0
RM
9503 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9504 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9505 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9506};
fa197c1c 9507
0b6ae522 9508static void
fa197c1c 9509decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9510{
fa197c1c
PB
9511 int i;
9512
9513 for (i = 12; mask; mask >>= 1, i--)
9514 {
9515 if (mask & 1)
9516 {
9517 fputs (tic6x_unwind_regnames[i], stdout);
9518 if (mask > 1)
9519 fputs (", ", stdout);
9520 }
9521 }
9522}
0b6ae522
DJ
9523
9524#define ADVANCE \
9525 if (remaining == 0 && more_words) \
9526 { \
9527 data_offset += 4; \
dda8d76d 9528 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9529 data_offset, & word, & addr, NULL)) \
015dc7e1 9530 return false; \
0b6ae522
DJ
9531 remaining = 4; \
9532 more_words--; \
9533 } \
9534
9535#define GET_OP(OP) \
9536 ADVANCE; \
9537 if (remaining) \
9538 { \
9539 remaining--; \
9540 (OP) = word >> 24; \
9541 word <<= 8; \
9542 } \
9543 else \
9544 { \
2b692964 9545 printf (_("[Truncated opcode]\n")); \
015dc7e1 9546 return false; \
0b6ae522 9547 } \
cc5914eb 9548 printf ("0x%02x ", OP)
0b6ae522 9549
015dc7e1 9550static bool
dda8d76d
NC
9551decode_arm_unwind_bytecode (Filedata * filedata,
9552 struct arm_unw_aux_info * aux,
948f632f
DA
9553 unsigned int word,
9554 unsigned int remaining,
9555 unsigned int more_words,
9556 bfd_vma data_offset,
9557 Elf_Internal_Shdr * data_sec,
9558 struct arm_section * data_arm_sec)
fa197c1c
PB
9559{
9560 struct absaddr addr;
015dc7e1 9561 bool res = true;
0b6ae522
DJ
9562
9563 /* Decode the unwinding instructions. */
9564 while (1)
9565 {
9566 unsigned int op, op2;
9567
9568 ADVANCE;
9569 if (remaining == 0)
9570 break;
9571 remaining--;
9572 op = word >> 24;
9573 word <<= 8;
9574
cc5914eb 9575 printf (" 0x%02x ", op);
0b6ae522
DJ
9576
9577 if ((op & 0xc0) == 0x00)
9578 {
9579 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9580
cc5914eb 9581 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9582 }
9583 else if ((op & 0xc0) == 0x40)
9584 {
9585 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9586
cc5914eb 9587 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9588 }
9589 else if ((op & 0xf0) == 0x80)
9590 {
9591 GET_OP (op2);
9592 if (op == 0x80 && op2 == 0)
9593 printf (_("Refuse to unwind"));
9594 else
9595 {
9596 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9597 bool first = true;
0b6ae522 9598 int i;
2b692964 9599
0b6ae522
DJ
9600 printf ("pop {");
9601 for (i = 0; i < 12; i++)
9602 if (mask & (1 << i))
9603 {
9604 if (first)
015dc7e1 9605 first = false;
0b6ae522
DJ
9606 else
9607 printf (", ");
9608 printf ("r%d", 4 + i);
9609 }
9610 printf ("}");
9611 }
9612 }
9613 else if ((op & 0xf0) == 0x90)
9614 {
9615 if (op == 0x9d || op == 0x9f)
9616 printf (_(" [Reserved]"));
9617 else
cc5914eb 9618 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9619 }
9620 else if ((op & 0xf0) == 0xa0)
9621 {
9622 int end = 4 + (op & 0x07);
015dc7e1 9623 bool first = true;
0b6ae522 9624 int i;
61865e30 9625
0b6ae522
DJ
9626 printf (" pop {");
9627 for (i = 4; i <= end; i++)
9628 {
9629 if (first)
015dc7e1 9630 first = false;
0b6ae522
DJ
9631 else
9632 printf (", ");
9633 printf ("r%d", i);
9634 }
9635 if (op & 0x08)
9636 {
1b31d05e 9637 if (!first)
0b6ae522
DJ
9638 printf (", ");
9639 printf ("r14");
9640 }
9641 printf ("}");
9642 }
9643 else if (op == 0xb0)
9644 printf (_(" finish"));
9645 else if (op == 0xb1)
9646 {
9647 GET_OP (op2);
9648 if (op2 == 0 || (op2 & 0xf0) != 0)
9649 printf (_("[Spare]"));
9650 else
9651 {
9652 unsigned int mask = op2 & 0x0f;
015dc7e1 9653 bool first = true;
0b6ae522 9654 int i;
61865e30 9655
0b6ae522
DJ
9656 printf ("pop {");
9657 for (i = 0; i < 12; i++)
9658 if (mask & (1 << i))
9659 {
9660 if (first)
015dc7e1 9661 first = false;
0b6ae522
DJ
9662 else
9663 printf (", ");
9664 printf ("r%d", i);
9665 }
9666 printf ("}");
9667 }
9668 }
9669 else if (op == 0xb2)
9670 {
b115cf96 9671 unsigned char buf[9];
0b6ae522
DJ
9672 unsigned int i, len;
9673 unsigned long offset;
61865e30 9674
b115cf96 9675 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9676 {
9677 GET_OP (buf[i]);
9678 if ((buf[i] & 0x80) == 0)
9679 break;
9680 }
4082ef84 9681 if (i == sizeof (buf))
32ec8896 9682 {
27a45f42 9683 error (_("corrupt change to vsp\n"));
015dc7e1 9684 res = false;
32ec8896 9685 }
4082ef84
NC
9686 else
9687 {
015dc7e1 9688 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9689 assert (len == i + 1);
9690 offset = offset * 4 + 0x204;
9691 printf ("vsp = vsp + %ld", offset);
9692 }
0b6ae522 9693 }
61865e30 9694 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9695 {
61865e30
NC
9696 unsigned int first, last;
9697
9698 GET_OP (op2);
9699 first = op2 >> 4;
9700 last = op2 & 0x0f;
9701 if (op == 0xc8)
9702 first = first + 16;
9703 printf ("pop {D%d", first);
9704 if (last)
9705 printf ("-D%d", first + last);
9706 printf ("}");
9707 }
09854a88
TB
9708 else if (op == 0xb4)
9709 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9710 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9711 {
9712 unsigned int count = op & 0x07;
9713
9714 printf ("pop {D8");
9715 if (count)
9716 printf ("-D%d", 8 + count);
9717 printf ("}");
9718 }
9719 else if (op >= 0xc0 && op <= 0xc5)
9720 {
9721 unsigned int count = op & 0x07;
9722
9723 printf (" pop {wR10");
9724 if (count)
9725 printf ("-wR%d", 10 + count);
9726 printf ("}");
9727 }
9728 else if (op == 0xc6)
9729 {
9730 unsigned int first, last;
9731
9732 GET_OP (op2);
9733 first = op2 >> 4;
9734 last = op2 & 0x0f;
9735 printf ("pop {wR%d", first);
9736 if (last)
9737 printf ("-wR%d", first + last);
9738 printf ("}");
9739 }
9740 else if (op == 0xc7)
9741 {
9742 GET_OP (op2);
9743 if (op2 == 0 || (op2 & 0xf0) != 0)
9744 printf (_("[Spare]"));
0b6ae522
DJ
9745 else
9746 {
61865e30 9747 unsigned int mask = op2 & 0x0f;
015dc7e1 9748 bool first = true;
61865e30
NC
9749 int i;
9750
9751 printf ("pop {");
9752 for (i = 0; i < 4; i++)
9753 if (mask & (1 << i))
9754 {
9755 if (first)
015dc7e1 9756 first = false;
61865e30
NC
9757 else
9758 printf (", ");
9759 printf ("wCGR%d", i);
9760 }
9761 printf ("}");
0b6ae522
DJ
9762 }
9763 }
61865e30 9764 else
32ec8896
NC
9765 {
9766 printf (_(" [unsupported opcode]"));
015dc7e1 9767 res = false;
32ec8896
NC
9768 }
9769
0b6ae522
DJ
9770 printf ("\n");
9771 }
32ec8896
NC
9772
9773 return res;
fa197c1c
PB
9774}
9775
015dc7e1 9776static bool
dda8d76d
NC
9777decode_tic6x_unwind_bytecode (Filedata * filedata,
9778 struct arm_unw_aux_info * aux,
948f632f
DA
9779 unsigned int word,
9780 unsigned int remaining,
9781 unsigned int more_words,
9782 bfd_vma data_offset,
9783 Elf_Internal_Shdr * data_sec,
9784 struct arm_section * data_arm_sec)
fa197c1c
PB
9785{
9786 struct absaddr addr;
9787
9788 /* Decode the unwinding instructions. */
9789 while (1)
9790 {
9791 unsigned int op, op2;
9792
9793 ADVANCE;
9794 if (remaining == 0)
9795 break;
9796 remaining--;
9797 op = word >> 24;
9798 word <<= 8;
9799
9cf03b7e 9800 printf (" 0x%02x ", op);
fa197c1c
PB
9801
9802 if ((op & 0xc0) == 0x00)
9803 {
9804 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9805 printf (" sp = sp + %d", offset);
fa197c1c
PB
9806 }
9807 else if ((op & 0xc0) == 0x80)
9808 {
9809 GET_OP (op2);
9810 if (op == 0x80 && op2 == 0)
9811 printf (_("Refuse to unwind"));
9812 else
9813 {
9814 unsigned int mask = ((op & 0x1f) << 8) | op2;
9815 if (op & 0x20)
9816 printf ("pop compact {");
9817 else
9818 printf ("pop {");
9819
9820 decode_tic6x_unwind_regmask (mask);
9821 printf("}");
9822 }
9823 }
9824 else if ((op & 0xf0) == 0xc0)
9825 {
9826 unsigned int reg;
9827 unsigned int nregs;
9828 unsigned int i;
9829 const char *name;
a734115a
NC
9830 struct
9831 {
32ec8896
NC
9832 unsigned int offset;
9833 unsigned int reg;
fa197c1c
PB
9834 } regpos[16];
9835
9836 /* Scan entire instruction first so that GET_OP output is not
9837 interleaved with disassembly. */
9838 nregs = 0;
9839 for (i = 0; nregs < (op & 0xf); i++)
9840 {
9841 GET_OP (op2);
9842 reg = op2 >> 4;
9843 if (reg != 0xf)
9844 {
9845 regpos[nregs].offset = i * 2;
9846 regpos[nregs].reg = reg;
9847 nregs++;
9848 }
9849
9850 reg = op2 & 0xf;
9851 if (reg != 0xf)
9852 {
9853 regpos[nregs].offset = i * 2 + 1;
9854 regpos[nregs].reg = reg;
9855 nregs++;
9856 }
9857 }
9858
9859 printf (_("pop frame {"));
18344509 9860 if (nregs == 0)
fa197c1c 9861 {
18344509
NC
9862 printf (_("*corrupt* - no registers specified"));
9863 }
9864 else
9865 {
9866 reg = nregs - 1;
9867 for (i = i * 2; i > 0; i--)
fa197c1c 9868 {
18344509
NC
9869 if (regpos[reg].offset == i - 1)
9870 {
9871 name = tic6x_unwind_regnames[regpos[reg].reg];
9872 if (reg > 0)
9873 reg--;
9874 }
9875 else
9876 name = _("[pad]");
fa197c1c 9877
18344509
NC
9878 fputs (name, stdout);
9879 if (i > 1)
9880 printf (", ");
9881 }
fa197c1c
PB
9882 }
9883
9884 printf ("}");
9885 }
9886 else if (op == 0xd0)
9887 printf (" MOV FP, SP");
9888 else if (op == 0xd1)
9889 printf (" __c6xabi_pop_rts");
9890 else if (op == 0xd2)
9891 {
9892 unsigned char buf[9];
9893 unsigned int i, len;
9894 unsigned long offset;
a734115a 9895
fa197c1c
PB
9896 for (i = 0; i < sizeof (buf); i++)
9897 {
9898 GET_OP (buf[i]);
9899 if ((buf[i] & 0x80) == 0)
9900 break;
9901 }
0eff7165
NC
9902 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9903 if (i == sizeof (buf))
9904 {
0eff7165 9905 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9906 return false;
0eff7165 9907 }
948f632f 9908
015dc7e1 9909 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9910 assert (len == i + 1);
9911 offset = offset * 8 + 0x408;
9912 printf (_("sp = sp + %ld"), offset);
9913 }
9914 else if ((op & 0xf0) == 0xe0)
9915 {
9916 if ((op & 0x0f) == 7)
9917 printf (" RETURN");
9918 else
9919 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9920 }
9921 else
9922 {
9923 printf (_(" [unsupported opcode]"));
9924 }
9925 putchar ('\n');
9926 }
32ec8896 9927
015dc7e1 9928 return true;
fa197c1c
PB
9929}
9930
9931static bfd_vma
dda8d76d 9932arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9933{
9934 bfd_vma offset;
9935
9936 offset = word & 0x7fffffff;
9937 if (offset & 0x40000000)
9938 offset |= ~ (bfd_vma) 0x7fffffff;
9939
dda8d76d 9940 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9941 offset <<= 1;
9942
9943 return offset + where;
9944}
9945
015dc7e1 9946static bool
dda8d76d
NC
9947decode_arm_unwind (Filedata * filedata,
9948 struct arm_unw_aux_info * aux,
1b31d05e
NC
9949 unsigned int word,
9950 unsigned int remaining,
9951 bfd_vma data_offset,
9952 Elf_Internal_Shdr * data_sec,
9953 struct arm_section * data_arm_sec)
fa197c1c
PB
9954{
9955 int per_index;
9956 unsigned int more_words = 0;
37e14bc3 9957 struct absaddr addr;
1b31d05e 9958 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9959 bool res = true;
fa197c1c
PB
9960
9961 if (remaining == 0)
9962 {
1b31d05e
NC
9963 /* Fetch the first word.
9964 Note - when decoding an object file the address extracted
9965 here will always be 0. So we also pass in the sym_name
9966 parameter so that we can find the symbol associated with
9967 the personality routine. */
dda8d76d 9968 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9969 & word, & addr, & sym_name))
015dc7e1 9970 return false;
1b31d05e 9971
fa197c1c
PB
9972 remaining = 4;
9973 }
c93dbb25
CZ
9974 else
9975 {
9976 addr.section = SHN_UNDEF;
9977 addr.offset = 0;
9978 }
fa197c1c
PB
9979
9980 if ((word & 0x80000000) == 0)
9981 {
9982 /* Expand prel31 for personality routine. */
9983 bfd_vma fn;
9984 const char *procname;
9985
dda8d76d 9986 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9987 printf (_(" Personality routine: "));
1b31d05e
NC
9988 if (fn == 0
9989 && addr.section == SHN_UNDEF && addr.offset == 0
9990 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9991 {
9992 procname = aux->strtab + sym_name;
9993 print_vma (fn, PREFIX_HEX);
9994 if (procname)
9995 {
9996 fputs (" <", stdout);
9997 fputs (procname, stdout);
9998 fputc ('>', stdout);
9999 }
10000 }
10001 else
dda8d76d 10002 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10003 fputc ('\n', stdout);
10004
10005 /* The GCC personality routines use the standard compact
10006 encoding, starting with one byte giving the number of
10007 words. */
10008 if (procname != NULL
24d127aa
ML
10009 && (startswith (procname, "__gcc_personality_v0")
10010 || startswith (procname, "__gxx_personality_v0")
10011 || startswith (procname, "__gcj_personality_v0")
10012 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10013 {
10014 remaining = 0;
10015 more_words = 1;
10016 ADVANCE;
10017 if (!remaining)
10018 {
10019 printf (_(" [Truncated data]\n"));
015dc7e1 10020 return false;
fa197c1c
PB
10021 }
10022 more_words = word >> 24;
10023 word <<= 8;
10024 remaining--;
10025 per_index = -1;
10026 }
10027 else
015dc7e1 10028 return true;
fa197c1c
PB
10029 }
10030 else
10031 {
1b31d05e 10032 /* ARM EHABI Section 6.3:
0b4362b0 10033
1b31d05e 10034 An exception-handling table entry for the compact model looks like:
0b4362b0 10035
1b31d05e
NC
10036 31 30-28 27-24 23-0
10037 -- ----- ----- ----
10038 1 0 index Data for personalityRoutine[index] */
10039
dda8d76d 10040 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10041 && (word & 0x70000000))
32ec8896
NC
10042 {
10043 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10044 res = false;
32ec8896 10045 }
1b31d05e 10046
fa197c1c 10047 per_index = (word >> 24) & 0x7f;
1b31d05e 10048 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10049 if (per_index == 0)
10050 {
10051 more_words = 0;
10052 word <<= 8;
10053 remaining--;
10054 }
10055 else if (per_index < 3)
10056 {
10057 more_words = (word >> 16) & 0xff;
10058 word <<= 16;
10059 remaining -= 2;
10060 }
10061 }
10062
dda8d76d 10063 switch (filedata->file_header.e_machine)
fa197c1c
PB
10064 {
10065 case EM_ARM:
10066 if (per_index < 3)
10067 {
dda8d76d 10068 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10069 data_offset, data_sec, data_arm_sec))
015dc7e1 10070 res = false;
fa197c1c
PB
10071 }
10072 else
1b31d05e
NC
10073 {
10074 warn (_("Unknown ARM compact model index encountered\n"));
10075 printf (_(" [reserved]\n"));
015dc7e1 10076 res = false;
1b31d05e 10077 }
fa197c1c
PB
10078 break;
10079
10080 case EM_TI_C6000:
10081 if (per_index < 3)
10082 {
dda8d76d 10083 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10084 data_offset, data_sec, data_arm_sec))
015dc7e1 10085 res = false;
fa197c1c
PB
10086 }
10087 else if (per_index < 5)
10088 {
10089 if (((word >> 17) & 0x7f) == 0x7f)
10090 printf (_(" Restore stack from frame pointer\n"));
10091 else
10092 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10093 printf (_(" Registers restored: "));
10094 if (per_index == 4)
10095 printf (" (compact) ");
10096 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10097 putchar ('\n');
10098 printf (_(" Return register: %s\n"),
10099 tic6x_unwind_regnames[word & 0xf]);
10100 }
10101 else
1b31d05e 10102 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10103 break;
10104
10105 default:
74e1a04b 10106 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10107 filedata->file_header.e_machine);
015dc7e1 10108 res = false;
fa197c1c 10109 }
0b6ae522
DJ
10110
10111 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10112
10113 return res;
0b6ae522
DJ
10114}
10115
015dc7e1 10116static bool
dda8d76d
NC
10117dump_arm_unwind (Filedata * filedata,
10118 struct arm_unw_aux_info * aux,
10119 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10120{
10121 struct arm_section exidx_arm_sec, extab_arm_sec;
10122 unsigned int i, exidx_len;
948f632f 10123 unsigned long j, nfuns;
015dc7e1 10124 bool res = true;
0b6ae522
DJ
10125
10126 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10127 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10128 exidx_len = exidx_sec->sh_size / 8;
10129
948f632f
DA
10130 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10131 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10132 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10133 aux->funtab[nfuns++] = aux->symtab[j];
10134 aux->nfuns = nfuns;
10135 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10136
0b6ae522
DJ
10137 for (i = 0; i < exidx_len; i++)
10138 {
10139 unsigned int exidx_fn, exidx_entry;
10140 struct absaddr fn_addr, entry_addr;
10141 bfd_vma fn;
10142
10143 fputc ('\n', stdout);
10144
dda8d76d 10145 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10146 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10147 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10148 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10149 {
948f632f 10150 free (aux->funtab);
1b31d05e
NC
10151 arm_free_section (& exidx_arm_sec);
10152 arm_free_section (& extab_arm_sec);
015dc7e1 10153 return false;
0b6ae522
DJ
10154 }
10155
83c257ca
NC
10156 /* ARM EHABI, Section 5:
10157 An index table entry consists of 2 words.
10158 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10159 if (exidx_fn & 0x80000000)
32ec8896
NC
10160 {
10161 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10162 res = false;
32ec8896 10163 }
83c257ca 10164
dda8d76d 10165 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10166
dda8d76d 10167 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10168 fputs (": ", stdout);
10169
10170 if (exidx_entry == 1)
10171 {
10172 print_vma (exidx_entry, PREFIX_HEX);
10173 fputs (" [cantunwind]\n", stdout);
10174 }
10175 else if (exidx_entry & 0x80000000)
10176 {
10177 print_vma (exidx_entry, PREFIX_HEX);
10178 fputc ('\n', stdout);
dda8d76d 10179 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10180 }
10181 else
10182 {
8f73510c 10183 bfd_vma table, table_offset = 0;
0b6ae522
DJ
10184 Elf_Internal_Shdr *table_sec;
10185
10186 fputs ("@", stdout);
dda8d76d 10187 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10188 print_vma (table, PREFIX_HEX);
10189 printf ("\n");
10190
10191 /* Locate the matching .ARM.extab. */
10192 if (entry_addr.section != SHN_UNDEF
dda8d76d 10193 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10194 {
dda8d76d 10195 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10196 table_offset = entry_addr.offset;
1a915552
NC
10197 /* PR 18879 */
10198 if (table_offset > table_sec->sh_size
10199 || ((bfd_signed_vma) table_offset) < 0)
10200 {
10201 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10202 (unsigned long) table_offset,
dda8d76d 10203 printable_section_name (filedata, table_sec));
015dc7e1 10204 res = false;
1a915552
NC
10205 continue;
10206 }
0b6ae522
DJ
10207 }
10208 else
10209 {
dda8d76d 10210 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10211 if (table_sec != NULL)
10212 table_offset = table - table_sec->sh_addr;
10213 }
32ec8896 10214
0b6ae522
DJ
10215 if (table_sec == NULL)
10216 {
10217 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10218 (unsigned long) table);
015dc7e1 10219 res = false;
0b6ae522
DJ
10220 continue;
10221 }
32ec8896 10222
dda8d76d 10223 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10224 &extab_arm_sec))
015dc7e1 10225 res = false;
0b6ae522
DJ
10226 }
10227 }
10228
10229 printf ("\n");
10230
948f632f 10231 free (aux->funtab);
0b6ae522
DJ
10232 arm_free_section (&exidx_arm_sec);
10233 arm_free_section (&extab_arm_sec);
32ec8896
NC
10234
10235 return res;
0b6ae522
DJ
10236}
10237
fa197c1c 10238/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10239
015dc7e1 10240static bool
dda8d76d 10241arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10242{
10243 struct arm_unw_aux_info aux;
10244 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10245 Elf_Internal_Shdr *sec;
10246 unsigned long i;
fa197c1c 10247 unsigned int sec_type;
015dc7e1 10248 bool res = true;
0b6ae522 10249
dda8d76d 10250 switch (filedata->file_header.e_machine)
fa197c1c
PB
10251 {
10252 case EM_ARM:
10253 sec_type = SHT_ARM_EXIDX;
10254 break;
10255
10256 case EM_TI_C6000:
10257 sec_type = SHT_C6000_UNWIND;
10258 break;
10259
0b4362b0 10260 default:
74e1a04b 10261 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10262 filedata->file_header.e_machine);
015dc7e1 10263 return false;
fa197c1c
PB
10264 }
10265
dda8d76d 10266 if (filedata->string_table == NULL)
015dc7e1 10267 return false;
1b31d05e
NC
10268
10269 memset (& aux, 0, sizeof (aux));
dda8d76d 10270 aux.filedata = filedata;
0b6ae522 10271
dda8d76d 10272 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10273 {
28d13567 10274 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10275 {
28d13567 10276 if (aux.symtab)
74e1a04b 10277 {
28d13567
AM
10278 error (_("Multiple symbol tables encountered\n"));
10279 free (aux.symtab);
10280 aux.symtab = NULL;
74e1a04b 10281 free (aux.strtab);
28d13567 10282 aux.strtab = NULL;
74e1a04b 10283 }
28d13567
AM
10284 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10285 &aux.strtab, &aux.strtab_size))
015dc7e1 10286 return false;
0b6ae522 10287 }
fa197c1c 10288 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10289 unwsec = sec;
10290 }
10291
1b31d05e 10292 if (unwsec == NULL)
0b6ae522 10293 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10294 else
dda8d76d 10295 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10296 {
10297 if (sec->sh_type == sec_type)
10298 {
d3a49aa8
AM
10299 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10300 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10301 "contains %lu entry:\n",
10302 "\nUnwind section '%s' at offset 0x%lx "
10303 "contains %lu entries:\n",
10304 num_unwind),
dda8d76d 10305 printable_section_name (filedata, sec),
1b31d05e 10306 (unsigned long) sec->sh_offset,
d3a49aa8 10307 num_unwind);
0b6ae522 10308
dda8d76d 10309 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10310 res = false;
1b31d05e
NC
10311 }
10312 }
0b6ae522 10313
9db70fc3
AM
10314 free (aux.symtab);
10315 free ((char *) aux.strtab);
32ec8896
NC
10316
10317 return res;
0b6ae522
DJ
10318}
10319
3ecc00ec
NC
10320static bool
10321no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10322{
10323 printf (_("No processor specific unwind information to decode\n"));
10324 return true;
10325}
10326
015dc7e1 10327static bool
dda8d76d 10328process_unwind (Filedata * filedata)
57346661 10329{
2cf0635d
NC
10330 struct unwind_handler
10331 {
32ec8896 10332 unsigned int machtype;
015dc7e1 10333 bool (* handler)(Filedata *);
2cf0635d
NC
10334 } handlers[] =
10335 {
0b6ae522 10336 { EM_ARM, arm_process_unwind },
57346661
AM
10337 { EM_IA_64, ia64_process_unwind },
10338 { EM_PARISC, hppa_process_unwind },
fa197c1c 10339 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10340 { EM_386, no_processor_specific_unwind },
10341 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10342 { 0, NULL }
57346661
AM
10343 };
10344 int i;
10345
10346 if (!do_unwind)
015dc7e1 10347 return true;
57346661
AM
10348
10349 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10350 if (filedata->file_header.e_machine == handlers[i].machtype)
10351 return handlers[i].handler (filedata);
57346661 10352
1b31d05e 10353 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10354 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10355 return true;
57346661
AM
10356}
10357
37c18eed
SD
10358static void
10359dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10360{
10361 switch (entry->d_tag)
10362 {
10363 case DT_AARCH64_BTI_PLT:
1dbade74 10364 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10365 break;
10366 default:
10367 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10368 break;
10369 }
10370 putchar ('\n');
10371}
10372
252b5132 10373static void
978c4450 10374dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10375{
10376 switch (entry->d_tag)
10377 {
10378 case DT_MIPS_FLAGS:
10379 if (entry->d_un.d_val == 0)
4b68bca3 10380 printf (_("NONE"));
252b5132
RH
10381 else
10382 {
10383 static const char * opts[] =
10384 {
10385 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10386 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10387 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10388 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10389 "RLD_ORDER_SAFE"
10390 };
10391 unsigned int cnt;
015dc7e1 10392 bool first = true;
2b692964 10393
60bca95a 10394 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10395 if (entry->d_un.d_val & (1 << cnt))
10396 {
10397 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10398 first = false;
252b5132 10399 }
252b5132
RH
10400 }
10401 break;
103f02d3 10402
252b5132 10403 case DT_MIPS_IVERSION:
84714f86 10404 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10405 printf (_("Interface Version: %s"),
84714f86 10406 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10407 else
76ca31c0
NC
10408 {
10409 char buf[40];
10410 sprintf_vma (buf, entry->d_un.d_ptr);
10411 /* Note: coded this way so that there is a single string for translation. */
10412 printf (_("<corrupt: %s>"), buf);
10413 }
252b5132 10414 break;
103f02d3 10415
252b5132
RH
10416 case DT_MIPS_TIME_STAMP:
10417 {
d5b07ef4 10418 char timebuf[128];
2cf0635d 10419 struct tm * tmp;
91d6fa6a 10420 time_t atime = entry->d_un.d_val;
82b1b41b 10421
91d6fa6a 10422 tmp = gmtime (&atime);
82b1b41b
NC
10423 /* PR 17531: file: 6accc532. */
10424 if (tmp == NULL)
10425 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10426 else
10427 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10428 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10429 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10430 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10431 }
10432 break;
103f02d3 10433
252b5132
RH
10434 case DT_MIPS_RLD_VERSION:
10435 case DT_MIPS_LOCAL_GOTNO:
10436 case DT_MIPS_CONFLICTNO:
10437 case DT_MIPS_LIBLISTNO:
10438 case DT_MIPS_SYMTABNO:
10439 case DT_MIPS_UNREFEXTNO:
10440 case DT_MIPS_HIPAGENO:
10441 case DT_MIPS_DELTA_CLASS_NO:
10442 case DT_MIPS_DELTA_INSTANCE_NO:
10443 case DT_MIPS_DELTA_RELOC_NO:
10444 case DT_MIPS_DELTA_SYM_NO:
10445 case DT_MIPS_DELTA_CLASSSYM_NO:
10446 case DT_MIPS_COMPACT_SIZE:
c69075ac 10447 print_vma (entry->d_un.d_val, DEC);
252b5132 10448 break;
103f02d3 10449
f16a9783 10450 case DT_MIPS_XHASH:
978c4450
AM
10451 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10452 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10453 /* Falls through. */
10454
103f02d3 10455 default:
4b68bca3 10456 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10457 }
4b68bca3 10458 putchar ('\n');
103f02d3
UD
10459}
10460
103f02d3 10461static void
2cf0635d 10462dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10463{
10464 switch (entry->d_tag)
10465 {
10466 case DT_HP_DLD_FLAGS:
10467 {
10468 static struct
10469 {
10470 long int bit;
2cf0635d 10471 const char * str;
5e220199
NC
10472 }
10473 flags[] =
10474 {
10475 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10476 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10477 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10478 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10479 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10480 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10481 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10482 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10483 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10484 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10485 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10486 { DT_HP_GST, "HP_GST" },
10487 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10488 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10489 { DT_HP_NODELETE, "HP_NODELETE" },
10490 { DT_HP_GROUP, "HP_GROUP" },
10491 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10492 };
015dc7e1 10493 bool first = true;
5e220199 10494 size_t cnt;
f7a99963 10495 bfd_vma val = entry->d_un.d_val;
103f02d3 10496
60bca95a 10497 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10498 if (val & flags[cnt].bit)
30800947
NC
10499 {
10500 if (! first)
10501 putchar (' ');
10502 fputs (flags[cnt].str, stdout);
015dc7e1 10503 first = false;
30800947
NC
10504 val ^= flags[cnt].bit;
10505 }
76da6bbe 10506
103f02d3 10507 if (val != 0 || first)
f7a99963
NC
10508 {
10509 if (! first)
10510 putchar (' ');
10511 print_vma (val, HEX);
10512 }
103f02d3
UD
10513 }
10514 break;
76da6bbe 10515
252b5132 10516 default:
f7a99963
NC
10517 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10518 break;
252b5132 10519 }
35b1837e 10520 putchar ('\n');
252b5132
RH
10521}
10522
28f997cf
TG
10523#ifdef BFD64
10524
10525/* VMS vs Unix time offset and factor. */
10526
10527#define VMS_EPOCH_OFFSET 35067168000000000LL
10528#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10529#ifndef INT64_MIN
10530#define INT64_MIN (-9223372036854775807LL - 1)
10531#endif
28f997cf
TG
10532
10533/* Display a VMS time in a human readable format. */
10534
10535static void
10536print_vms_time (bfd_int64_t vmstime)
10537{
dccc31de 10538 struct tm *tm = NULL;
28f997cf
TG
10539 time_t unxtime;
10540
dccc31de
AM
10541 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10542 {
10543 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10544 unxtime = vmstime;
10545 if (unxtime == vmstime)
10546 tm = gmtime (&unxtime);
10547 }
10548 if (tm != NULL)
10549 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10550 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10551 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10552}
10553#endif /* BFD64 */
10554
ecc51f48 10555static void
2cf0635d 10556dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10557{
10558 switch (entry->d_tag)
10559 {
0de14b54 10560 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10561 /* First 3 slots reserved. */
ecc51f48
NC
10562 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10563 printf (" -- ");
10564 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10565 break;
10566
28f997cf
TG
10567 case DT_IA_64_VMS_LINKTIME:
10568#ifdef BFD64
10569 print_vms_time (entry->d_un.d_val);
10570#endif
10571 break;
10572
10573 case DT_IA_64_VMS_LNKFLAGS:
10574 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10575 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10576 printf (" CALL_DEBUG");
10577 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10578 printf (" NOP0BUFS");
10579 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10580 printf (" P0IMAGE");
10581 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10582 printf (" MKTHREADS");
10583 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10584 printf (" UPCALLS");
10585 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10586 printf (" IMGSTA");
10587 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10588 printf (" INITIALIZE");
10589 if (entry->d_un.d_val & VMS_LF_MAIN)
10590 printf (" MAIN");
10591 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10592 printf (" EXE_INIT");
10593 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10594 printf (" TBK_IN_IMG");
10595 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10596 printf (" DBG_IN_IMG");
10597 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10598 printf (" TBK_IN_DSF");
10599 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10600 printf (" DBG_IN_DSF");
10601 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10602 printf (" SIGNATURES");
10603 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10604 printf (" REL_SEG_OFF");
10605 break;
10606
bdf4d63a
JJ
10607 default:
10608 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10609 break;
ecc51f48 10610 }
bdf4d63a 10611 putchar ('\n');
ecc51f48
NC
10612}
10613
015dc7e1 10614static bool
dda8d76d 10615get_32bit_dynamic_section (Filedata * filedata)
252b5132 10616{
2cf0635d
NC
10617 Elf32_External_Dyn * edyn;
10618 Elf32_External_Dyn * ext;
10619 Elf_Internal_Dyn * entry;
103f02d3 10620
978c4450
AM
10621 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10622 filedata->dynamic_addr, 1,
10623 filedata->dynamic_size,
10624 _("dynamic section"));
a6e9f9df 10625 if (!edyn)
015dc7e1 10626 return false;
103f02d3 10627
071436c6
NC
10628 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10629 might not have the luxury of section headers. Look for the DT_NULL
10630 terminator to determine the number of entries. */
978c4450
AM
10631 for (ext = edyn, filedata->dynamic_nent = 0;
10632 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10633 ext++)
10634 {
978c4450 10635 filedata->dynamic_nent++;
ba2685cc
AM
10636 if (BYTE_GET (ext->d_tag) == DT_NULL)
10637 break;
10638 }
252b5132 10639
978c4450
AM
10640 filedata->dynamic_section
10641 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10642 if (filedata->dynamic_section == NULL)
252b5132 10643 {
8b73c356 10644 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10645 (unsigned long) filedata->dynamic_nent);
9ea033b2 10646 free (edyn);
015dc7e1 10647 return false;
9ea033b2 10648 }
252b5132 10649
978c4450
AM
10650 for (ext = edyn, entry = filedata->dynamic_section;
10651 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10652 ext++, entry++)
9ea033b2 10653 {
fb514b26
AM
10654 entry->d_tag = BYTE_GET (ext->d_tag);
10655 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10656 }
10657
9ea033b2
NC
10658 free (edyn);
10659
015dc7e1 10660 return true;
9ea033b2
NC
10661}
10662
015dc7e1 10663static bool
dda8d76d 10664get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10665{
2cf0635d
NC
10666 Elf64_External_Dyn * edyn;
10667 Elf64_External_Dyn * ext;
10668 Elf_Internal_Dyn * entry;
103f02d3 10669
071436c6 10670 /* Read in the data. */
978c4450
AM
10671 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10672 filedata->dynamic_addr, 1,
10673 filedata->dynamic_size,
10674 _("dynamic section"));
a6e9f9df 10675 if (!edyn)
015dc7e1 10676 return false;
103f02d3 10677
071436c6
NC
10678 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10679 might not have the luxury of section headers. Look for the DT_NULL
10680 terminator to determine the number of entries. */
978c4450 10681 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10682 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10683 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10684 ext++)
10685 {
978c4450 10686 filedata->dynamic_nent++;
66543521 10687 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10688 break;
10689 }
252b5132 10690
978c4450
AM
10691 filedata->dynamic_section
10692 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10693 if (filedata->dynamic_section == NULL)
252b5132 10694 {
8b73c356 10695 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10696 (unsigned long) filedata->dynamic_nent);
252b5132 10697 free (edyn);
015dc7e1 10698 return false;
252b5132
RH
10699 }
10700
071436c6 10701 /* Convert from external to internal formats. */
978c4450
AM
10702 for (ext = edyn, entry = filedata->dynamic_section;
10703 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10704 ext++, entry++)
252b5132 10705 {
66543521
AM
10706 entry->d_tag = BYTE_GET (ext->d_tag);
10707 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10708 }
10709
10710 free (edyn);
10711
015dc7e1 10712 return true;
9ea033b2
NC
10713}
10714
4de91c10
AM
10715static bool
10716get_dynamic_section (Filedata *filedata)
10717{
10718 if (filedata->dynamic_section)
10719 return true;
10720
10721 if (is_32bit_elf)
10722 return get_32bit_dynamic_section (filedata);
10723 else
10724 return get_64bit_dynamic_section (filedata);
10725}
10726
e9e44622
JJ
10727static void
10728print_dynamic_flags (bfd_vma flags)
d1133906 10729{
015dc7e1 10730 bool first = true;
13ae64f3 10731
d1133906
NC
10732 while (flags)
10733 {
10734 bfd_vma flag;
10735
10736 flag = flags & - flags;
10737 flags &= ~ flag;
10738
e9e44622 10739 if (first)
015dc7e1 10740 first = false;
e9e44622
JJ
10741 else
10742 putc (' ', stdout);
13ae64f3 10743
d1133906
NC
10744 switch (flag)
10745 {
e9e44622
JJ
10746 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10747 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10748 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10749 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10750 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10751 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10752 }
10753 }
e9e44622 10754 puts ("");
d1133906
NC
10755}
10756
10ca4b04
L
10757static bfd_vma *
10758get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10759{
10760 unsigned char * e_data;
10761 bfd_vma * i_data;
10762
10763 /* If the size_t type is smaller than the bfd_size_type, eg because
10764 you are building a 32-bit tool on a 64-bit host, then make sure
10765 that when (number) is cast to (size_t) no information is lost. */
10766 if (sizeof (size_t) < sizeof (bfd_size_type)
10767 && (bfd_size_type) ((size_t) number) != number)
10768 {
10769 error (_("Size truncation prevents reading %s elements of size %u\n"),
10770 bfd_vmatoa ("u", number), ent_size);
10771 return NULL;
10772 }
10773
10774 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10775 attempting to allocate memory when the read is bound to fail. */
10776 if (ent_size * number > filedata->file_size)
10777 {
10778 error (_("Invalid number of dynamic entries: %s\n"),
10779 bfd_vmatoa ("u", number));
10780 return NULL;
10781 }
10782
10783 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10784 if (e_data == NULL)
10785 {
10786 error (_("Out of memory reading %s dynamic entries\n"),
10787 bfd_vmatoa ("u", number));
10788 return NULL;
10789 }
10790
10791 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10792 {
10793 error (_("Unable to read in %s bytes of dynamic data\n"),
10794 bfd_vmatoa ("u", number * ent_size));
10795 free (e_data);
10796 return NULL;
10797 }
10798
10799 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10800 if (i_data == NULL)
10801 {
10802 error (_("Out of memory allocating space for %s dynamic entries\n"),
10803 bfd_vmatoa ("u", number));
10804 free (e_data);
10805 return NULL;
10806 }
10807
10808 while (number--)
10809 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10810
10811 free (e_data);
10812
10813 return i_data;
10814}
10815
10816static unsigned long
10817get_num_dynamic_syms (Filedata * filedata)
10818{
10819 unsigned long num_of_syms = 0;
10820
10821 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10822 return num_of_syms;
10823
978c4450 10824 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10825 {
10826 unsigned char nb[8];
10827 unsigned char nc[8];
10828 unsigned int hash_ent_size = 4;
10829
10830 if ((filedata->file_header.e_machine == EM_ALPHA
10831 || filedata->file_header.e_machine == EM_S390
10832 || filedata->file_header.e_machine == EM_S390_OLD)
10833 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10834 hash_ent_size = 8;
10835
10836 if (fseek (filedata->handle,
978c4450
AM
10837 (filedata->archive_file_offset
10838 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10839 sizeof nb + sizeof nc)),
10840 SEEK_SET))
10841 {
10842 error (_("Unable to seek to start of dynamic information\n"));
10843 goto no_hash;
10844 }
10845
10846 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10847 {
10848 error (_("Failed to read in number of buckets\n"));
10849 goto no_hash;
10850 }
10851
10852 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10853 {
10854 error (_("Failed to read in number of chains\n"));
10855 goto no_hash;
10856 }
10857
978c4450
AM
10858 filedata->nbuckets = byte_get (nb, hash_ent_size);
10859 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10860
2482f306
AM
10861 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10862 {
10863 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10864 hash_ent_size);
10865 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10866 hash_ent_size);
001890e1 10867
2482f306
AM
10868 if (filedata->buckets != NULL && filedata->chains != NULL)
10869 num_of_syms = filedata->nchains;
10870 }
ceb9bf11 10871 no_hash:
10ca4b04
L
10872 if (num_of_syms == 0)
10873 {
9db70fc3
AM
10874 free (filedata->buckets);
10875 filedata->buckets = NULL;
10876 free (filedata->chains);
10877 filedata->chains = NULL;
978c4450 10878 filedata->nbuckets = 0;
10ca4b04
L
10879 }
10880 }
10881
978c4450 10882 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10883 {
10884 unsigned char nb[16];
10885 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10886 bfd_vma buckets_vma;
10887 unsigned long hn;
10ca4b04
L
10888
10889 if (fseek (filedata->handle,
978c4450
AM
10890 (filedata->archive_file_offset
10891 + offset_from_vma (filedata,
10892 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10893 sizeof nb)),
10894 SEEK_SET))
10895 {
10896 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10897 goto no_gnu_hash;
10898 }
10899
10900 if (fread (nb, 16, 1, filedata->handle) != 1)
10901 {
10902 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10903 goto no_gnu_hash;
10904 }
10905
978c4450
AM
10906 filedata->ngnubuckets = byte_get (nb, 4);
10907 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10908 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10909 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10910 if (is_32bit_elf)
10911 buckets_vma += bitmaskwords * 4;
10912 else
10913 buckets_vma += bitmaskwords * 8;
10914
10915 if (fseek (filedata->handle,
978c4450 10916 (filedata->archive_file_offset
10ca4b04
L
10917 + offset_from_vma (filedata, buckets_vma, 4)),
10918 SEEK_SET))
10919 {
10920 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10921 goto no_gnu_hash;
10922 }
10923
978c4450
AM
10924 filedata->gnubuckets
10925 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10926
978c4450 10927 if (filedata->gnubuckets == NULL)
90837ea7 10928 goto no_gnu_hash;
10ca4b04 10929
978c4450
AM
10930 for (i = 0; i < filedata->ngnubuckets; i++)
10931 if (filedata->gnubuckets[i] != 0)
10ca4b04 10932 {
978c4450 10933 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10934 goto no_gnu_hash;
10ca4b04 10935
978c4450
AM
10936 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10937 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10938 }
10939
10940 if (maxchain == 0xffffffff)
90837ea7 10941 goto no_gnu_hash;
10ca4b04 10942
978c4450 10943 maxchain -= filedata->gnusymidx;
10ca4b04
L
10944
10945 if (fseek (filedata->handle,
978c4450
AM
10946 (filedata->archive_file_offset
10947 + offset_from_vma (filedata,
10948 buckets_vma + 4 * (filedata->ngnubuckets
10949 + maxchain),
10950 4)),
10ca4b04
L
10951 SEEK_SET))
10952 {
10953 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10954 goto no_gnu_hash;
10955 }
10956
10957 do
10958 {
10959 if (fread (nb, 4, 1, filedata->handle) != 1)
10960 {
10961 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10962 goto no_gnu_hash;
10963 }
10964
10965 if (maxchain + 1 == 0)
90837ea7 10966 goto no_gnu_hash;
10ca4b04
L
10967
10968 ++maxchain;
10969 }
10970 while ((byte_get (nb, 4) & 1) == 0);
10971
10972 if (fseek (filedata->handle,
978c4450
AM
10973 (filedata->archive_file_offset
10974 + offset_from_vma (filedata, (buckets_vma
10975 + 4 * filedata->ngnubuckets),
10976 4)),
10ca4b04
L
10977 SEEK_SET))
10978 {
10979 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10980 goto no_gnu_hash;
10981 }
10982
978c4450
AM
10983 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10984 filedata->ngnuchains = maxchain;
10ca4b04 10985
978c4450 10986 if (filedata->gnuchains == NULL)
90837ea7 10987 goto no_gnu_hash;
10ca4b04 10988
978c4450 10989 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10990 {
10991 if (fseek (filedata->handle,
978c4450 10992 (filedata->archive_file_offset
10ca4b04 10993 + offset_from_vma (filedata, (buckets_vma
978c4450 10994 + 4 * (filedata->ngnubuckets
10ca4b04
L
10995 + maxchain)), 4)),
10996 SEEK_SET))
10997 {
10998 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10999 goto no_gnu_hash;
11000 }
11001
978c4450 11002 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11003 if (filedata->mipsxlat == NULL)
11004 goto no_gnu_hash;
10ca4b04
L
11005 }
11006
978c4450
AM
11007 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11008 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11009 {
978c4450
AM
11010 bfd_vma si = filedata->gnubuckets[hn];
11011 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
11012
11013 do
11014 {
978c4450 11015 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11016 {
c31ab5a0
AM
11017 if (off < filedata->ngnuchains
11018 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11019 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11020 }
11021 else
11022 {
11023 if (si >= num_of_syms)
11024 num_of_syms = si + 1;
11025 }
11026 si++;
11027 }
978c4450
AM
11028 while (off < filedata->ngnuchains
11029 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11030 }
11031
90837ea7 11032 if (num_of_syms == 0)
10ca4b04 11033 {
90837ea7 11034 no_gnu_hash:
9db70fc3
AM
11035 free (filedata->mipsxlat);
11036 filedata->mipsxlat = NULL;
11037 free (filedata->gnuchains);
11038 filedata->gnuchains = NULL;
11039 free (filedata->gnubuckets);
11040 filedata->gnubuckets = NULL;
978c4450
AM
11041 filedata->ngnubuckets = 0;
11042 filedata->ngnuchains = 0;
10ca4b04
L
11043 }
11044 }
11045
11046 return num_of_syms;
11047}
11048
b2d38a17
NC
11049/* Parse and display the contents of the dynamic section. */
11050
015dc7e1 11051static bool
dda8d76d 11052process_dynamic_section (Filedata * filedata)
9ea033b2 11053{
2cf0635d 11054 Elf_Internal_Dyn * entry;
9ea033b2 11055
93df3340 11056 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11057 {
11058 if (do_dynamic)
ca0e11aa
NC
11059 {
11060 if (filedata->is_separate)
11061 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11062 filedata->file_name);
11063 else
11064 printf (_("\nThere is no dynamic section in this file.\n"));
11065 }
9ea033b2 11066
015dc7e1 11067 return true;
9ea033b2
NC
11068 }
11069
4de91c10
AM
11070 if (!get_dynamic_section (filedata))
11071 return false;
9ea033b2 11072
252b5132 11073 /* Find the appropriate symbol table. */
978c4450 11074 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11075 {
2482f306
AM
11076 unsigned long num_of_syms;
11077
978c4450
AM
11078 for (entry = filedata->dynamic_section;
11079 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11080 ++entry)
10ca4b04 11081 if (entry->d_tag == DT_SYMTAB)
978c4450 11082 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11083 else if (entry->d_tag == DT_SYMENT)
978c4450 11084 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11085 else if (entry->d_tag == DT_HASH)
978c4450 11086 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11087 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11088 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11089 else if ((filedata->file_header.e_machine == EM_MIPS
11090 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11091 && entry->d_tag == DT_MIPS_XHASH)
11092 {
978c4450
AM
11093 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11094 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11095 }
252b5132 11096
2482f306
AM
11097 num_of_syms = get_num_dynamic_syms (filedata);
11098
11099 if (num_of_syms != 0
11100 && filedata->dynamic_symbols == NULL
11101 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11102 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11103 {
11104 Elf_Internal_Phdr *seg;
2482f306 11105 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11106
2482f306
AM
11107 if (! get_program_headers (filedata))
11108 {
11109 error (_("Cannot interpret virtual addresses "
11110 "without program headers.\n"));
015dc7e1 11111 return false;
2482f306 11112 }
252b5132 11113
2482f306
AM
11114 for (seg = filedata->program_headers;
11115 seg < filedata->program_headers + filedata->file_header.e_phnum;
11116 ++seg)
11117 {
11118 if (seg->p_type != PT_LOAD)
11119 continue;
252b5132 11120
2482f306
AM
11121 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11122 {
11123 /* See PR 21379 for a reproducer. */
11124 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11125 return false;
2482f306 11126 }
252b5132 11127
2482f306
AM
11128 if (vma >= (seg->p_vaddr & -seg->p_align)
11129 && vma < seg->p_vaddr + seg->p_filesz)
11130 {
11131 /* Since we do not know how big the symbol table is,
11132 we default to reading in up to the end of PT_LOAD
11133 segment and processing that. This is overkill, I
11134 know, but it should work. */
11135 Elf_Internal_Shdr section;
11136 section.sh_offset = (vma - seg->p_vaddr
11137 + seg->p_offset);
11138 section.sh_size = (num_of_syms
11139 * filedata->dynamic_info[DT_SYMENT]);
11140 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11141
11142 if (do_checks
11143 && filedata->dynamic_symtab_section != NULL
11144 && ((filedata->dynamic_symtab_section->sh_offset
11145 != section.sh_offset)
11146 || (filedata->dynamic_symtab_section->sh_size
11147 != section.sh_size)
11148 || (filedata->dynamic_symtab_section->sh_entsize
11149 != section.sh_entsize)))
11150 warn (_("\
11151the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11152
2482f306
AM
11153 section.sh_name = filedata->string_table_length;
11154 filedata->dynamic_symbols
4de91c10 11155 = get_elf_symbols (filedata, &section,
2482f306
AM
11156 &filedata->num_dynamic_syms);
11157 if (filedata->dynamic_symbols == NULL
11158 || filedata->num_dynamic_syms != num_of_syms)
11159 {
11160 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11161 return false;
2482f306
AM
11162 }
11163 break;
11164 }
11165 }
11166 }
11167 }
252b5132
RH
11168
11169 /* Similarly find a string table. */
978c4450
AM
11170 if (filedata->dynamic_strings == NULL)
11171 for (entry = filedata->dynamic_section;
11172 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11173 ++entry)
11174 {
11175 if (entry->d_tag == DT_STRTAB)
978c4450 11176 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11177
10ca4b04 11178 if (entry->d_tag == DT_STRSZ)
978c4450 11179 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11180
978c4450
AM
11181 if (filedata->dynamic_info[DT_STRTAB]
11182 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11183 {
11184 unsigned long offset;
978c4450 11185 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11186
11187 offset = offset_from_vma (filedata,
978c4450 11188 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11189 str_tab_len);
8ac10c5b
L
11190 if (do_checks
11191 && filedata->dynamic_strtab_section
11192 && ((filedata->dynamic_strtab_section->sh_offset
11193 != (file_ptr) offset)
11194 || (filedata->dynamic_strtab_section->sh_size
11195 != str_tab_len)))
11196 warn (_("\
11197the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11198
978c4450
AM
11199 filedata->dynamic_strings
11200 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11201 _("dynamic string table"));
11202 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11203 {
11204 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11205 break;
11206 }
e3d39609 11207
978c4450 11208 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11209 break;
11210 }
11211 }
252b5132
RH
11212
11213 /* And find the syminfo section if available. */
978c4450 11214 if (filedata->dynamic_syminfo == NULL)
252b5132 11215 {
3e8bba36 11216 unsigned long syminsz = 0;
252b5132 11217
978c4450
AM
11218 for (entry = filedata->dynamic_section;
11219 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11220 ++entry)
252b5132
RH
11221 {
11222 if (entry->d_tag == DT_SYMINENT)
11223 {
11224 /* Note: these braces are necessary to avoid a syntax
11225 error from the SunOS4 C compiler. */
049b0c3a
NC
11226 /* PR binutils/17531: A corrupt file can trigger this test.
11227 So do not use an assert, instead generate an error message. */
11228 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11229 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11230 (int) entry->d_un.d_val);
252b5132
RH
11231 }
11232 else if (entry->d_tag == DT_SYMINSZ)
11233 syminsz = entry->d_un.d_val;
11234 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11235 filedata->dynamic_syminfo_offset
11236 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11237 }
11238
978c4450 11239 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11240 {
2cf0635d
NC
11241 Elf_External_Syminfo * extsyminfo;
11242 Elf_External_Syminfo * extsym;
11243 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11244
11245 /* There is a syminfo section. Read the data. */
3f5e193b 11246 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11247 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11248 1, syminsz, _("symbol information"));
a6e9f9df 11249 if (!extsyminfo)
015dc7e1 11250 return false;
252b5132 11251
978c4450 11252 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11253 {
11254 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11255 free (filedata->dynamic_syminfo);
e3d39609 11256 }
978c4450
AM
11257 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11258 if (filedata->dynamic_syminfo == NULL)
252b5132 11259 {
2482f306
AM
11260 error (_("Out of memory allocating %lu bytes "
11261 "for dynamic symbol info\n"),
8b73c356 11262 (unsigned long) syminsz);
015dc7e1 11263 return false;
252b5132
RH
11264 }
11265
2482f306
AM
11266 filedata->dynamic_syminfo_nent
11267 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11268 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11269 syminfo < (filedata->dynamic_syminfo
11270 + filedata->dynamic_syminfo_nent);
86dba8ee 11271 ++syminfo, ++extsym)
252b5132 11272 {
86dba8ee
AM
11273 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11274 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11275 }
11276
11277 free (extsyminfo);
11278 }
11279 }
11280
978c4450 11281 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11282 {
f253158f
NC
11283 if (filedata->is_separate)
11284 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11285 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11286 (unsigned long) filedata->dynamic_nent),
11287 filedata->file_name,
11288 filedata->dynamic_addr,
11289 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11290 else
f253158f
NC
11291 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11292 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11293 (unsigned long) filedata->dynamic_nent),
ca0e11aa
NC
11294 filedata->dynamic_addr,
11295 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11296 }
252b5132
RH
11297 if (do_dynamic)
11298 printf (_(" Tag Type Name/Value\n"));
11299
978c4450
AM
11300 for (entry = filedata->dynamic_section;
11301 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11302 entry++)
252b5132
RH
11303 {
11304 if (do_dynamic)
f7a99963 11305 {
2cf0635d 11306 const char * dtype;
e699b9ff 11307
f7a99963
NC
11308 putchar (' ');
11309 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11310 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11311 printf (" (%s)%*s", dtype,
32ec8896 11312 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11313 }
252b5132
RH
11314
11315 switch (entry->d_tag)
11316 {
d1133906
NC
11317 case DT_FLAGS:
11318 if (do_dynamic)
e9e44622 11319 print_dynamic_flags (entry->d_un.d_val);
d1133906 11320 break;
76da6bbe 11321
252b5132
RH
11322 case DT_AUXILIARY:
11323 case DT_FILTER:
019148e4
L
11324 case DT_CONFIG:
11325 case DT_DEPAUDIT:
11326 case DT_AUDIT:
252b5132
RH
11327 if (do_dynamic)
11328 {
019148e4 11329 switch (entry->d_tag)
b34976b6 11330 {
019148e4
L
11331 case DT_AUXILIARY:
11332 printf (_("Auxiliary library"));
11333 break;
11334
11335 case DT_FILTER:
11336 printf (_("Filter library"));
11337 break;
11338
b34976b6 11339 case DT_CONFIG:
019148e4
L
11340 printf (_("Configuration file"));
11341 break;
11342
11343 case DT_DEPAUDIT:
11344 printf (_("Dependency audit library"));
11345 break;
11346
11347 case DT_AUDIT:
11348 printf (_("Audit library"));
11349 break;
11350 }
252b5132 11351
84714f86 11352 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11353 printf (": [%s]\n",
84714f86 11354 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11355 else
f7a99963
NC
11356 {
11357 printf (": ");
11358 print_vma (entry->d_un.d_val, PREFIX_HEX);
11359 putchar ('\n');
11360 }
252b5132
RH
11361 }
11362 break;
11363
dcefbbbd 11364 case DT_FEATURE:
252b5132
RH
11365 if (do_dynamic)
11366 {
11367 printf (_("Flags:"));
86f55779 11368
252b5132
RH
11369 if (entry->d_un.d_val == 0)
11370 printf (_(" None\n"));
11371 else
11372 {
11373 unsigned long int val = entry->d_un.d_val;
86f55779 11374
252b5132
RH
11375 if (val & DTF_1_PARINIT)
11376 {
11377 printf (" PARINIT");
11378 val ^= DTF_1_PARINIT;
11379 }
dcefbbbd
L
11380 if (val & DTF_1_CONFEXP)
11381 {
11382 printf (" CONFEXP");
11383 val ^= DTF_1_CONFEXP;
11384 }
252b5132
RH
11385 if (val != 0)
11386 printf (" %lx", val);
11387 puts ("");
11388 }
11389 }
11390 break;
11391
11392 case DT_POSFLAG_1:
11393 if (do_dynamic)
11394 {
11395 printf (_("Flags:"));
86f55779 11396
252b5132
RH
11397 if (entry->d_un.d_val == 0)
11398 printf (_(" None\n"));
11399 else
11400 {
11401 unsigned long int val = entry->d_un.d_val;
86f55779 11402
252b5132
RH
11403 if (val & DF_P1_LAZYLOAD)
11404 {
11405 printf (" LAZYLOAD");
11406 val ^= DF_P1_LAZYLOAD;
11407 }
11408 if (val & DF_P1_GROUPPERM)
11409 {
11410 printf (" GROUPPERM");
11411 val ^= DF_P1_GROUPPERM;
11412 }
11413 if (val != 0)
11414 printf (" %lx", val);
11415 puts ("");
11416 }
11417 }
11418 break;
11419
11420 case DT_FLAGS_1:
11421 if (do_dynamic)
11422 {
11423 printf (_("Flags:"));
11424 if (entry->d_un.d_val == 0)
11425 printf (_(" None\n"));
11426 else
11427 {
11428 unsigned long int val = entry->d_un.d_val;
86f55779 11429
252b5132
RH
11430 if (val & DF_1_NOW)
11431 {
11432 printf (" NOW");
11433 val ^= DF_1_NOW;
11434 }
11435 if (val & DF_1_GLOBAL)
11436 {
11437 printf (" GLOBAL");
11438 val ^= DF_1_GLOBAL;
11439 }
11440 if (val & DF_1_GROUP)
11441 {
11442 printf (" GROUP");
11443 val ^= DF_1_GROUP;
11444 }
11445 if (val & DF_1_NODELETE)
11446 {
11447 printf (" NODELETE");
11448 val ^= DF_1_NODELETE;
11449 }
11450 if (val & DF_1_LOADFLTR)
11451 {
11452 printf (" LOADFLTR");
11453 val ^= DF_1_LOADFLTR;
11454 }
11455 if (val & DF_1_INITFIRST)
11456 {
11457 printf (" INITFIRST");
11458 val ^= DF_1_INITFIRST;
11459 }
11460 if (val & DF_1_NOOPEN)
11461 {
11462 printf (" NOOPEN");
11463 val ^= DF_1_NOOPEN;
11464 }
11465 if (val & DF_1_ORIGIN)
11466 {
11467 printf (" ORIGIN");
11468 val ^= DF_1_ORIGIN;
11469 }
11470 if (val & DF_1_DIRECT)
11471 {
11472 printf (" DIRECT");
11473 val ^= DF_1_DIRECT;
11474 }
11475 if (val & DF_1_TRANS)
11476 {
11477 printf (" TRANS");
11478 val ^= DF_1_TRANS;
11479 }
11480 if (val & DF_1_INTERPOSE)
11481 {
11482 printf (" INTERPOSE");
11483 val ^= DF_1_INTERPOSE;
11484 }
f7db6139 11485 if (val & DF_1_NODEFLIB)
dcefbbbd 11486 {
f7db6139
L
11487 printf (" NODEFLIB");
11488 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11489 }
11490 if (val & DF_1_NODUMP)
11491 {
11492 printf (" NODUMP");
11493 val ^= DF_1_NODUMP;
11494 }
34b60028 11495 if (val & DF_1_CONFALT)
dcefbbbd 11496 {
34b60028
L
11497 printf (" CONFALT");
11498 val ^= DF_1_CONFALT;
11499 }
11500 if (val & DF_1_ENDFILTEE)
11501 {
11502 printf (" ENDFILTEE");
11503 val ^= DF_1_ENDFILTEE;
11504 }
11505 if (val & DF_1_DISPRELDNE)
11506 {
11507 printf (" DISPRELDNE");
11508 val ^= DF_1_DISPRELDNE;
11509 }
11510 if (val & DF_1_DISPRELPND)
11511 {
11512 printf (" DISPRELPND");
11513 val ^= DF_1_DISPRELPND;
11514 }
11515 if (val & DF_1_NODIRECT)
11516 {
11517 printf (" NODIRECT");
11518 val ^= DF_1_NODIRECT;
11519 }
11520 if (val & DF_1_IGNMULDEF)
11521 {
11522 printf (" IGNMULDEF");
11523 val ^= DF_1_IGNMULDEF;
11524 }
11525 if (val & DF_1_NOKSYMS)
11526 {
11527 printf (" NOKSYMS");
11528 val ^= DF_1_NOKSYMS;
11529 }
11530 if (val & DF_1_NOHDR)
11531 {
11532 printf (" NOHDR");
11533 val ^= DF_1_NOHDR;
11534 }
11535 if (val & DF_1_EDITED)
11536 {
11537 printf (" EDITED");
11538 val ^= DF_1_EDITED;
11539 }
11540 if (val & DF_1_NORELOC)
11541 {
11542 printf (" NORELOC");
11543 val ^= DF_1_NORELOC;
11544 }
11545 if (val & DF_1_SYMINTPOSE)
11546 {
11547 printf (" SYMINTPOSE");
11548 val ^= DF_1_SYMINTPOSE;
11549 }
11550 if (val & DF_1_GLOBAUDIT)
11551 {
11552 printf (" GLOBAUDIT");
11553 val ^= DF_1_GLOBAUDIT;
11554 }
11555 if (val & DF_1_SINGLETON)
11556 {
11557 printf (" SINGLETON");
11558 val ^= DF_1_SINGLETON;
dcefbbbd 11559 }
5c383f02
RO
11560 if (val & DF_1_STUB)
11561 {
11562 printf (" STUB");
11563 val ^= DF_1_STUB;
11564 }
11565 if (val & DF_1_PIE)
11566 {
11567 printf (" PIE");
11568 val ^= DF_1_PIE;
11569 }
b1202ffa
L
11570 if (val & DF_1_KMOD)
11571 {
11572 printf (" KMOD");
11573 val ^= DF_1_KMOD;
11574 }
11575 if (val & DF_1_WEAKFILTER)
11576 {
11577 printf (" WEAKFILTER");
11578 val ^= DF_1_WEAKFILTER;
11579 }
11580 if (val & DF_1_NOCOMMON)
11581 {
11582 printf (" NOCOMMON");
11583 val ^= DF_1_NOCOMMON;
11584 }
252b5132
RH
11585 if (val != 0)
11586 printf (" %lx", val);
11587 puts ("");
11588 }
11589 }
11590 break;
11591
11592 case DT_PLTREL:
978c4450 11593 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11594 if (do_dynamic)
dda8d76d 11595 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11596 break;
11597
11598 case DT_NULL :
11599 case DT_NEEDED :
11600 case DT_PLTGOT :
11601 case DT_HASH :
11602 case DT_STRTAB :
11603 case DT_SYMTAB :
11604 case DT_RELA :
11605 case DT_INIT :
11606 case DT_FINI :
11607 case DT_SONAME :
11608 case DT_RPATH :
11609 case DT_SYMBOLIC:
11610 case DT_REL :
a7fd1186 11611 case DT_RELR :
252b5132
RH
11612 case DT_DEBUG :
11613 case DT_TEXTREL :
11614 case DT_JMPREL :
019148e4 11615 case DT_RUNPATH :
978c4450 11616 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11617
11618 if (do_dynamic)
11619 {
84714f86 11620 const char *name;
252b5132 11621
84714f86
AM
11622 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11623 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11624 else
d79b3d50 11625 name = NULL;
252b5132
RH
11626
11627 if (name)
11628 {
11629 switch (entry->d_tag)
11630 {
11631 case DT_NEEDED:
11632 printf (_("Shared library: [%s]"), name);
11633
13acb58d
AM
11634 if (filedata->program_interpreter
11635 && streq (name, filedata->program_interpreter))
f7a99963 11636 printf (_(" program interpreter"));
252b5132
RH
11637 break;
11638
11639 case DT_SONAME:
f7a99963 11640 printf (_("Library soname: [%s]"), name);
252b5132
RH
11641 break;
11642
11643 case DT_RPATH:
f7a99963 11644 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11645 break;
11646
019148e4
L
11647 case DT_RUNPATH:
11648 printf (_("Library runpath: [%s]"), name);
11649 break;
11650
252b5132 11651 default:
f7a99963
NC
11652 print_vma (entry->d_un.d_val, PREFIX_HEX);
11653 break;
252b5132
RH
11654 }
11655 }
11656 else
f7a99963
NC
11657 print_vma (entry->d_un.d_val, PREFIX_HEX);
11658
11659 putchar ('\n');
252b5132
RH
11660 }
11661 break;
11662
11663 case DT_PLTRELSZ:
11664 case DT_RELASZ :
11665 case DT_STRSZ :
11666 case DT_RELSZ :
11667 case DT_RELAENT :
a7fd1186
FS
11668 case DT_RELRENT :
11669 case DT_RELRSZ :
252b5132
RH
11670 case DT_SYMENT :
11671 case DT_RELENT :
978c4450 11672 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11673 /* Fall through. */
252b5132
RH
11674 case DT_PLTPADSZ:
11675 case DT_MOVEENT :
11676 case DT_MOVESZ :
04d8355a 11677 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11678 case DT_INIT_ARRAYSZ:
11679 case DT_FINI_ARRAYSZ:
047b2264
JJ
11680 case DT_GNU_CONFLICTSZ:
11681 case DT_GNU_LIBLISTSZ:
252b5132 11682 if (do_dynamic)
f7a99963
NC
11683 {
11684 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11685 printf (_(" (bytes)\n"));
f7a99963 11686 }
252b5132
RH
11687 break;
11688
11689 case DT_VERDEFNUM:
11690 case DT_VERNEEDNUM:
11691 case DT_RELACOUNT:
11692 case DT_RELCOUNT:
11693 if (do_dynamic)
f7a99963
NC
11694 {
11695 print_vma (entry->d_un.d_val, UNSIGNED);
11696 putchar ('\n');
11697 }
252b5132
RH
11698 break;
11699
11700 case DT_SYMINSZ:
11701 case DT_SYMINENT:
11702 case DT_SYMINFO:
11703 case DT_USED:
11704 case DT_INIT_ARRAY:
11705 case DT_FINI_ARRAY:
11706 if (do_dynamic)
11707 {
d79b3d50 11708 if (entry->d_tag == DT_USED
84714f86 11709 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11710 {
84714f86
AM
11711 const char *name
11712 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11713
b34976b6 11714 if (*name)
252b5132
RH
11715 {
11716 printf (_("Not needed object: [%s]\n"), name);
11717 break;
11718 }
11719 }
103f02d3 11720
f7a99963
NC
11721 print_vma (entry->d_un.d_val, PREFIX_HEX);
11722 putchar ('\n');
252b5132
RH
11723 }
11724 break;
11725
11726 case DT_BIND_NOW:
11727 /* The value of this entry is ignored. */
35b1837e
AM
11728 if (do_dynamic)
11729 putchar ('\n');
252b5132 11730 break;
103f02d3 11731
047b2264
JJ
11732 case DT_GNU_PRELINKED:
11733 if (do_dynamic)
11734 {
2cf0635d 11735 struct tm * tmp;
91d6fa6a 11736 time_t atime = entry->d_un.d_val;
047b2264 11737
91d6fa6a 11738 tmp = gmtime (&atime);
071436c6
NC
11739 /* PR 17533 file: 041-1244816-0.004. */
11740 if (tmp == NULL)
5a2cbcf4
L
11741 printf (_("<corrupt time val: %lx"),
11742 (unsigned long) atime);
071436c6
NC
11743 else
11744 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11745 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11746 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11747
11748 }
11749 break;
11750
fdc90cb4 11751 case DT_GNU_HASH:
978c4450 11752 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11753 if (do_dynamic)
11754 {
11755 print_vma (entry->d_un.d_val, PREFIX_HEX);
11756 putchar ('\n');
11757 }
11758 break;
11759
a5da3dee
VDM
11760 case DT_GNU_FLAGS_1:
11761 if (do_dynamic)
11762 {
11763 printf (_("Flags:"));
11764 if (entry->d_un.d_val == 0)
11765 printf (_(" None\n"));
11766 else
11767 {
11768 unsigned long int val = entry->d_un.d_val;
11769
11770 if (val & DF_GNU_1_UNIQUE)
11771 {
11772 printf (" UNIQUE");
11773 val ^= DF_GNU_1_UNIQUE;
11774 }
11775 if (val != 0)
11776 printf (" %lx", val);
11777 puts ("");
11778 }
11779 }
11780 break;
11781
252b5132
RH
11782 default:
11783 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11784 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11785 = entry->d_un.d_val;
252b5132
RH
11786
11787 if (do_dynamic)
11788 {
dda8d76d 11789 switch (filedata->file_header.e_machine)
252b5132 11790 {
37c18eed
SD
11791 case EM_AARCH64:
11792 dynamic_section_aarch64_val (entry);
11793 break;
252b5132 11794 case EM_MIPS:
4fe85591 11795 case EM_MIPS_RS3_LE:
978c4450 11796 dynamic_section_mips_val (filedata, entry);
252b5132 11797 break;
103f02d3 11798 case EM_PARISC:
b2d38a17 11799 dynamic_section_parisc_val (entry);
103f02d3 11800 break;
ecc51f48 11801 case EM_IA_64:
b2d38a17 11802 dynamic_section_ia64_val (entry);
ecc51f48 11803 break;
252b5132 11804 default:
f7a99963
NC
11805 print_vma (entry->d_un.d_val, PREFIX_HEX);
11806 putchar ('\n');
252b5132
RH
11807 }
11808 }
11809 break;
11810 }
11811 }
11812
015dc7e1 11813 return true;
252b5132
RH
11814}
11815
11816static char *
d3ba0551 11817get_ver_flags (unsigned int flags)
252b5132 11818{
6d4f21f6 11819 static char buff[128];
252b5132
RH
11820
11821 buff[0] = 0;
11822
11823 if (flags == 0)
11824 return _("none");
11825
11826 if (flags & VER_FLG_BASE)
7bb1ad17 11827 strcat (buff, "BASE");
252b5132
RH
11828
11829 if (flags & VER_FLG_WEAK)
11830 {
11831 if (flags & VER_FLG_BASE)
7bb1ad17 11832 strcat (buff, " | ");
252b5132 11833
7bb1ad17 11834 strcat (buff, "WEAK");
252b5132
RH
11835 }
11836
44ec90b9
RO
11837 if (flags & VER_FLG_INFO)
11838 {
11839 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11840 strcat (buff, " | ");
44ec90b9 11841
7bb1ad17 11842 strcat (buff, "INFO");
44ec90b9
RO
11843 }
11844
11845 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11846 {
11847 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11848 strcat (buff, " | ");
11849
11850 strcat (buff, _("<unknown>"));
11851 }
252b5132
RH
11852
11853 return buff;
11854}
11855
11856/* Display the contents of the version sections. */
98fb390a 11857
015dc7e1 11858static bool
dda8d76d 11859process_version_sections (Filedata * filedata)
252b5132 11860{
2cf0635d 11861 Elf_Internal_Shdr * section;
b34976b6 11862 unsigned i;
015dc7e1 11863 bool found = false;
252b5132
RH
11864
11865 if (! do_version)
015dc7e1 11866 return true;
252b5132 11867
dda8d76d
NC
11868 for (i = 0, section = filedata->section_headers;
11869 i < filedata->file_header.e_shnum;
b34976b6 11870 i++, section++)
252b5132
RH
11871 {
11872 switch (section->sh_type)
11873 {
11874 case SHT_GNU_verdef:
11875 {
2cf0635d 11876 Elf_External_Verdef * edefs;
452bf675
AM
11877 unsigned long idx;
11878 unsigned long cnt;
2cf0635d 11879 char * endbuf;
252b5132 11880
015dc7e1 11881 found = true;
252b5132 11882
ca0e11aa
NC
11883 if (filedata->is_separate)
11884 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11885 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11886 section->sh_info),
11887 filedata->file_name,
11888 printable_section_name (filedata, section),
11889 section->sh_info);
11890 else
11891 printf (ngettext ("\nVersion definition section '%s' "
11892 "contains %u entry:\n",
11893 "\nVersion definition section '%s' "
11894 "contains %u entries:\n",
11895 section->sh_info),
11896 printable_section_name (filedata, section),
11897 section->sh_info);
047c3dbf 11898
ae9ac79e 11899 printf (_(" Addr: 0x"));
252b5132 11900 printf_vma (section->sh_addr);
233f82cf 11901 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11902 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11903 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11904
3f5e193b 11905 edefs = (Elf_External_Verdef *)
dda8d76d 11906 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11907 _("version definition section"));
a6e9f9df
AM
11908 if (!edefs)
11909 break;
59245841 11910 endbuf = (char *) edefs + section->sh_size;
252b5132 11911
1445030f 11912 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11913 {
2cf0635d
NC
11914 char * vstart;
11915 Elf_External_Verdef * edef;
b34976b6 11916 Elf_Internal_Verdef ent;
2cf0635d 11917 Elf_External_Verdaux * eaux;
b34976b6 11918 Elf_Internal_Verdaux aux;
452bf675 11919 unsigned long isum;
b34976b6 11920 int j;
103f02d3 11921
252b5132 11922 vstart = ((char *) edefs) + idx;
54806181
AM
11923 if (vstart + sizeof (*edef) > endbuf)
11924 break;
252b5132
RH
11925
11926 edef = (Elf_External_Verdef *) vstart;
11927
11928 ent.vd_version = BYTE_GET (edef->vd_version);
11929 ent.vd_flags = BYTE_GET (edef->vd_flags);
11930 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11931 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11932 ent.vd_hash = BYTE_GET (edef->vd_hash);
11933 ent.vd_aux = BYTE_GET (edef->vd_aux);
11934 ent.vd_next = BYTE_GET (edef->vd_next);
11935
452bf675 11936 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11937 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11938
11939 printf (_(" Index: %d Cnt: %d "),
11940 ent.vd_ndx, ent.vd_cnt);
11941
452bf675 11942 /* Check for overflow. */
1445030f 11943 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11944 break;
11945
252b5132
RH
11946 vstart += ent.vd_aux;
11947
1445030f
AM
11948 if (vstart + sizeof (*eaux) > endbuf)
11949 break;
252b5132
RH
11950 eaux = (Elf_External_Verdaux *) vstart;
11951
11952 aux.vda_name = BYTE_GET (eaux->vda_name);
11953 aux.vda_next = BYTE_GET (eaux->vda_next);
11954
84714f86 11955 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 11956 printf (_("Name: %s\n"),
84714f86 11957 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
11958 else
11959 printf (_("Name index: %ld\n"), aux.vda_name);
11960
11961 isum = idx + ent.vd_aux;
11962
b34976b6 11963 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11964 {
1445030f
AM
11965 if (aux.vda_next < sizeof (*eaux)
11966 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11967 {
11968 warn (_("Invalid vda_next field of %lx\n"),
11969 aux.vda_next);
11970 j = ent.vd_cnt;
11971 break;
11972 }
dd24e3da 11973 /* Check for overflow. */
7e26601c 11974 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11975 break;
11976
252b5132
RH
11977 isum += aux.vda_next;
11978 vstart += aux.vda_next;
11979
54806181
AM
11980 if (vstart + sizeof (*eaux) > endbuf)
11981 break;
1445030f 11982 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11983
11984 aux.vda_name = BYTE_GET (eaux->vda_name);
11985 aux.vda_next = BYTE_GET (eaux->vda_next);
11986
84714f86 11987 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 11988 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 11989 isum, j,
84714f86 11990 get_dynamic_name (filedata, aux.vda_name));
252b5132 11991 else
452bf675 11992 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11993 isum, j, aux.vda_name);
11994 }
dd24e3da 11995
54806181
AM
11996 if (j < ent.vd_cnt)
11997 printf (_(" Version def aux past end of section\n"));
252b5132 11998
c9f02c3e
MR
11999 /* PR 17531:
12000 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12001 if (ent.vd_next < sizeof (*edef)
12002 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12003 {
12004 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12005 cnt = section->sh_info;
12006 break;
12007 }
452bf675 12008 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12009 break;
12010
252b5132
RH
12011 idx += ent.vd_next;
12012 }
dd24e3da 12013
54806181
AM
12014 if (cnt < section->sh_info)
12015 printf (_(" Version definition past end of section\n"));
252b5132
RH
12016
12017 free (edefs);
12018 }
12019 break;
103f02d3 12020
252b5132
RH
12021 case SHT_GNU_verneed:
12022 {
2cf0635d 12023 Elf_External_Verneed * eneed;
452bf675
AM
12024 unsigned long idx;
12025 unsigned long cnt;
2cf0635d 12026 char * endbuf;
252b5132 12027
015dc7e1 12028 found = true;
252b5132 12029
ca0e11aa
NC
12030 if (filedata->is_separate)
12031 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12032 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12033 section->sh_info),
12034 filedata->file_name,
12035 printable_section_name (filedata, section),
12036 section->sh_info);
12037 else
12038 printf (ngettext ("\nVersion needs section '%s' "
12039 "contains %u entry:\n",
12040 "\nVersion needs section '%s' "
12041 "contains %u entries:\n",
12042 section->sh_info),
12043 printable_section_name (filedata, section),
12044 section->sh_info);
047c3dbf 12045
252b5132
RH
12046 printf (_(" Addr: 0x"));
12047 printf_vma (section->sh_addr);
72de5009 12048 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12049 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12050 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12051
dda8d76d 12052 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12053 section->sh_offset, 1,
12054 section->sh_size,
9cf03b7e 12055 _("Version Needs section"));
a6e9f9df
AM
12056 if (!eneed)
12057 break;
59245841 12058 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12059
12060 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12061 {
2cf0635d 12062 Elf_External_Verneed * entry;
b34976b6 12063 Elf_Internal_Verneed ent;
452bf675 12064 unsigned long isum;
b34976b6 12065 int j;
2cf0635d 12066 char * vstart;
252b5132
RH
12067
12068 vstart = ((char *) eneed) + idx;
54806181
AM
12069 if (vstart + sizeof (*entry) > endbuf)
12070 break;
252b5132
RH
12071
12072 entry = (Elf_External_Verneed *) vstart;
12073
12074 ent.vn_version = BYTE_GET (entry->vn_version);
12075 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12076 ent.vn_file = BYTE_GET (entry->vn_file);
12077 ent.vn_aux = BYTE_GET (entry->vn_aux);
12078 ent.vn_next = BYTE_GET (entry->vn_next);
12079
452bf675 12080 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12081
84714f86 12082 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12083 printf (_(" File: %s"),
84714f86 12084 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12085 else
12086 printf (_(" File: %lx"), ent.vn_file);
12087
12088 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12089
dd24e3da 12090 /* Check for overflow. */
7e26601c 12091 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12092 break;
252b5132
RH
12093 vstart += ent.vn_aux;
12094
12095 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12096 {
2cf0635d 12097 Elf_External_Vernaux * eaux;
b34976b6 12098 Elf_Internal_Vernaux aux;
252b5132 12099
54806181
AM
12100 if (vstart + sizeof (*eaux) > endbuf)
12101 break;
252b5132
RH
12102 eaux = (Elf_External_Vernaux *) vstart;
12103
12104 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12105 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12106 aux.vna_other = BYTE_GET (eaux->vna_other);
12107 aux.vna_name = BYTE_GET (eaux->vna_name);
12108 aux.vna_next = BYTE_GET (eaux->vna_next);
12109
84714f86 12110 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12111 printf (_(" %#06lx: Name: %s"),
84714f86 12112 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12113 else
452bf675 12114 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12115 isum, aux.vna_name);
12116
12117 printf (_(" Flags: %s Version: %d\n"),
12118 get_ver_flags (aux.vna_flags), aux.vna_other);
12119
1445030f
AM
12120 if (aux.vna_next < sizeof (*eaux)
12121 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12122 {
12123 warn (_("Invalid vna_next field of %lx\n"),
12124 aux.vna_next);
12125 j = ent.vn_cnt;
12126 break;
12127 }
1445030f
AM
12128 /* Check for overflow. */
12129 if (aux.vna_next > (size_t) (endbuf - vstart))
12130 break;
252b5132
RH
12131 isum += aux.vna_next;
12132 vstart += aux.vna_next;
12133 }
9cf03b7e 12134
54806181 12135 if (j < ent.vn_cnt)
f9a6a8f0 12136 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12137
1445030f
AM
12138 if (ent.vn_next < sizeof (*entry)
12139 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12140 {
452bf675 12141 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12142 cnt = section->sh_info;
12143 break;
12144 }
1445030f
AM
12145 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12146 break;
252b5132
RH
12147 idx += ent.vn_next;
12148 }
9cf03b7e 12149
54806181 12150 if (cnt < section->sh_info)
9cf03b7e 12151 warn (_("Missing Version Needs information\n"));
103f02d3 12152
252b5132
RH
12153 free (eneed);
12154 }
12155 break;
12156
12157 case SHT_GNU_versym:
12158 {
2cf0635d 12159 Elf_Internal_Shdr * link_section;
8b73c356
NC
12160 size_t total;
12161 unsigned int cnt;
2cf0635d
NC
12162 unsigned char * edata;
12163 unsigned short * data;
12164 char * strtab;
12165 Elf_Internal_Sym * symbols;
12166 Elf_Internal_Shdr * string_sec;
ba5cdace 12167 unsigned long num_syms;
d3ba0551 12168 long off;
252b5132 12169
dda8d76d 12170 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12171 break;
12172
dda8d76d 12173 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12174 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12175
dda8d76d 12176 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12177 break;
12178
015dc7e1 12179 found = true;
252b5132 12180
4de91c10 12181 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12182 if (symbols == NULL)
12183 break;
252b5132 12184
dda8d76d 12185 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12186
dda8d76d 12187 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12188 string_sec->sh_size,
12189 _("version string table"));
a6e9f9df 12190 if (!strtab)
0429c154
MS
12191 {
12192 free (symbols);
12193 break;
12194 }
252b5132 12195
ca0e11aa
NC
12196 if (filedata->is_separate)
12197 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12198 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12199 total),
12200 filedata->file_name,
12201 printable_section_name (filedata, section),
12202 (unsigned long) total);
12203 else
12204 printf (ngettext ("\nVersion symbols section '%s' "
12205 "contains %lu entry:\n",
12206 "\nVersion symbols section '%s' "
12207 "contains %lu entries:\n",
12208 total),
12209 printable_section_name (filedata, section),
12210 (unsigned long) total);
252b5132 12211
ae9ac79e 12212 printf (_(" Addr: 0x"));
252b5132 12213 printf_vma (section->sh_addr);
72de5009 12214 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12215 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12216 printable_section_name (filedata, link_section));
252b5132 12217
dda8d76d 12218 off = offset_from_vma (filedata,
978c4450 12219 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12220 total * sizeof (short));
95099889
AM
12221 edata = (unsigned char *) get_data (NULL, filedata, off,
12222 sizeof (short), total,
12223 _("version symbol data"));
a6e9f9df
AM
12224 if (!edata)
12225 {
12226 free (strtab);
0429c154 12227 free (symbols);
a6e9f9df
AM
12228 break;
12229 }
252b5132 12230
3f5e193b 12231 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12232
12233 for (cnt = total; cnt --;)
b34976b6
AM
12234 data[cnt] = byte_get (edata + cnt * sizeof (short),
12235 sizeof (short));
252b5132
RH
12236
12237 free (edata);
12238
12239 for (cnt = 0; cnt < total; cnt += 4)
12240 {
12241 int j, nn;
ab273396
AM
12242 char *name;
12243 char *invalid = _("*invalid*");
252b5132
RH
12244
12245 printf (" %03x:", cnt);
12246
12247 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12248 switch (data[cnt + j])
252b5132
RH
12249 {
12250 case 0:
12251 fputs (_(" 0 (*local*) "), stdout);
12252 break;
12253
12254 case 1:
12255 fputs (_(" 1 (*global*) "), stdout);
12256 break;
12257
12258 default:
c244d050
NC
12259 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12260 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12261
dd24e3da 12262 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12263 array, break to avoid an out-of-bounds read. */
12264 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12265 {
12266 warn (_("invalid index into symbol array\n"));
12267 break;
12268 }
12269
ab273396 12270 name = NULL;
978c4450 12271 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12272 {
b34976b6
AM
12273 Elf_Internal_Verneed ivn;
12274 unsigned long offset;
252b5132 12275
d93f0186 12276 offset = offset_from_vma
978c4450
AM
12277 (filedata,
12278 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12279 sizeof (Elf_External_Verneed));
252b5132 12280
b34976b6 12281 do
252b5132 12282 {
b34976b6
AM
12283 Elf_Internal_Vernaux ivna;
12284 Elf_External_Verneed evn;
12285 Elf_External_Vernaux evna;
12286 unsigned long a_off;
252b5132 12287
dda8d76d 12288 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12289 _("version need")) == NULL)
12290 break;
0b4362b0 12291
252b5132
RH
12292 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12293 ivn.vn_next = BYTE_GET (evn.vn_next);
12294
12295 a_off = offset + ivn.vn_aux;
12296
12297 do
12298 {
dda8d76d 12299 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12300 1, _("version need aux (2)")) == NULL)
12301 {
12302 ivna.vna_next = 0;
12303 ivna.vna_other = 0;
12304 }
12305 else
12306 {
12307 ivna.vna_next = BYTE_GET (evna.vna_next);
12308 ivna.vna_other = BYTE_GET (evna.vna_other);
12309 }
252b5132
RH
12310
12311 a_off += ivna.vna_next;
12312 }
b34976b6 12313 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12314 && ivna.vna_next != 0);
12315
b34976b6 12316 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12317 {
12318 ivna.vna_name = BYTE_GET (evna.vna_name);
12319
54806181 12320 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12321 name = invalid;
54806181
AM
12322 else
12323 name = strtab + ivna.vna_name;
252b5132
RH
12324 break;
12325 }
12326
12327 offset += ivn.vn_next;
12328 }
12329 while (ivn.vn_next);
12330 }
00d93f34 12331
ab273396 12332 if (data[cnt + j] != 0x8001
978c4450 12333 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12334 {
b34976b6
AM
12335 Elf_Internal_Verdef ivd;
12336 Elf_External_Verdef evd;
12337 unsigned long offset;
252b5132 12338
d93f0186 12339 offset = offset_from_vma
978c4450
AM
12340 (filedata,
12341 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12342 sizeof evd);
252b5132
RH
12343
12344 do
12345 {
dda8d76d 12346 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12347 _("version def")) == NULL)
12348 {
12349 ivd.vd_next = 0;
948f632f 12350 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12351 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12352 break;
59245841
NC
12353 }
12354 else
12355 {
12356 ivd.vd_next = BYTE_GET (evd.vd_next);
12357 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12358 }
252b5132
RH
12359
12360 offset += ivd.vd_next;
12361 }
c244d050 12362 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12363 && ivd.vd_next != 0);
12364
c244d050 12365 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12366 {
b34976b6
AM
12367 Elf_External_Verdaux evda;
12368 Elf_Internal_Verdaux ivda;
252b5132
RH
12369
12370 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12371
dda8d76d 12372 if (get_data (&evda, filedata,
59245841
NC
12373 offset - ivd.vd_next + ivd.vd_aux,
12374 sizeof (evda), 1,
12375 _("version def aux")) == NULL)
12376 break;
252b5132
RH
12377
12378 ivda.vda_name = BYTE_GET (evda.vda_name);
12379
54806181 12380 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12381 name = invalid;
12382 else if (name != NULL && name != invalid)
12383 name = _("*both*");
54806181
AM
12384 else
12385 name = strtab + ivda.vda_name;
252b5132
RH
12386 }
12387 }
ab273396
AM
12388 if (name != NULL)
12389 nn += printf ("(%s%-*s",
12390 name,
12391 12 - (int) strlen (name),
12392 ")");
252b5132
RH
12393
12394 if (nn < 18)
12395 printf ("%*c", 18 - nn, ' ');
12396 }
12397
12398 putchar ('\n');
12399 }
12400
12401 free (data);
12402 free (strtab);
12403 free (symbols);
12404 }
12405 break;
103f02d3 12406
252b5132
RH
12407 default:
12408 break;
12409 }
12410 }
12411
12412 if (! found)
ca0e11aa
NC
12413 {
12414 if (filedata->is_separate)
12415 printf (_("\nNo version information found in linked file '%s'.\n"),
12416 filedata->file_name);
12417 else
12418 printf (_("\nNo version information found in this file.\n"));
12419 }
252b5132 12420
015dc7e1 12421 return true;
252b5132
RH
12422}
12423
d1133906 12424static const char *
dda8d76d 12425get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12426{
89246a0e 12427 static char buff[64];
252b5132
RH
12428
12429 switch (binding)
12430 {
b34976b6
AM
12431 case STB_LOCAL: return "LOCAL";
12432 case STB_GLOBAL: return "GLOBAL";
12433 case STB_WEAK: return "WEAK";
252b5132
RH
12434 default:
12435 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12436 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12437 binding);
252b5132 12438 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12439 {
12440 if (binding == STB_GNU_UNIQUE
df3a023b 12441 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12442 return "UNIQUE";
12443 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12444 }
252b5132 12445 else
e9e44622 12446 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12447 return buff;
12448 }
12449}
12450
d1133906 12451static const char *
dda8d76d 12452get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12453{
89246a0e 12454 static char buff[64];
252b5132
RH
12455
12456 switch (type)
12457 {
b34976b6
AM
12458 case STT_NOTYPE: return "NOTYPE";
12459 case STT_OBJECT: return "OBJECT";
12460 case STT_FUNC: return "FUNC";
12461 case STT_SECTION: return "SECTION";
12462 case STT_FILE: return "FILE";
12463 case STT_COMMON: return "COMMON";
12464 case STT_TLS: return "TLS";
15ab5209
DB
12465 case STT_RELC: return "RELC";
12466 case STT_SRELC: return "SRELC";
252b5132
RH
12467 default:
12468 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12469 {
dda8d76d 12470 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12471 return "THUMB_FUNC";
103f02d3 12472
dda8d76d 12473 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12474 return "REGISTER";
12475
dda8d76d 12476 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12477 return "PARISC_MILLI";
12478
e9e44622 12479 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12480 }
252b5132 12481 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12482 {
dda8d76d 12483 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12484 {
12485 if (type == STT_HP_OPAQUE)
12486 return "HP_OPAQUE";
12487 if (type == STT_HP_STUB)
12488 return "HP_STUB";
12489 }
12490
d8045f23 12491 if (type == STT_GNU_IFUNC
dda8d76d 12492 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12493 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12494 return "IFUNC";
12495
e9e44622 12496 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12497 }
252b5132 12498 else
e9e44622 12499 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12500 return buff;
12501 }
12502}
12503
d1133906 12504static const char *
d3ba0551 12505get_symbol_visibility (unsigned int visibility)
d1133906
NC
12506{
12507 switch (visibility)
12508 {
b34976b6
AM
12509 case STV_DEFAULT: return "DEFAULT";
12510 case STV_INTERNAL: return "INTERNAL";
12511 case STV_HIDDEN: return "HIDDEN";
d1133906 12512 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12513 default:
27a45f42 12514 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12515 return _("<unknown>");
d1133906
NC
12516 }
12517}
12518
2057d69d
CZ
12519static const char *
12520get_alpha_symbol_other (unsigned int other)
9abca702 12521{
2057d69d
CZ
12522 switch (other)
12523 {
12524 case STO_ALPHA_NOPV: return "NOPV";
12525 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12526 default:
27a45f42 12527 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12528 return _("<unknown>");
9abca702 12529 }
2057d69d
CZ
12530}
12531
fd85a6a1
NC
12532static const char *
12533get_solaris_symbol_visibility (unsigned int visibility)
12534{
12535 switch (visibility)
12536 {
12537 case 4: return "EXPORTED";
12538 case 5: return "SINGLETON";
12539 case 6: return "ELIMINATE";
12540 default: return get_symbol_visibility (visibility);
12541 }
12542}
12543
2301ed1c
SN
12544static const char *
12545get_aarch64_symbol_other (unsigned int other)
12546{
12547 static char buf[32];
12548
12549 if (other & STO_AARCH64_VARIANT_PCS)
12550 {
12551 other &= ~STO_AARCH64_VARIANT_PCS;
12552 if (other == 0)
12553 return "VARIANT_PCS";
12554 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12555 return buf;
12556 }
12557 return NULL;
12558}
12559
5e2b0d47
NC
12560static const char *
12561get_mips_symbol_other (unsigned int other)
12562{
12563 switch (other)
12564 {
32ec8896
NC
12565 case STO_OPTIONAL: return "OPTIONAL";
12566 case STO_MIPS_PLT: return "MIPS PLT";
12567 case STO_MIPS_PIC: return "MIPS PIC";
12568 case STO_MICROMIPS: return "MICROMIPS";
12569 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12570 case STO_MIPS16: return "MIPS16";
12571 default: return NULL;
5e2b0d47
NC
12572 }
12573}
12574
28f997cf 12575static const char *
dda8d76d 12576get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12577{
dda8d76d 12578 if (is_ia64_vms (filedata))
28f997cf
TG
12579 {
12580 static char res[32];
12581
12582 res[0] = 0;
12583
12584 /* Function types is for images and .STB files only. */
dda8d76d 12585 switch (filedata->file_header.e_type)
28f997cf
TG
12586 {
12587 case ET_DYN:
12588 case ET_EXEC:
12589 switch (VMS_ST_FUNC_TYPE (other))
12590 {
12591 case VMS_SFT_CODE_ADDR:
12592 strcat (res, " CA");
12593 break;
12594 case VMS_SFT_SYMV_IDX:
12595 strcat (res, " VEC");
12596 break;
12597 case VMS_SFT_FD:
12598 strcat (res, " FD");
12599 break;
12600 case VMS_SFT_RESERVE:
12601 strcat (res, " RSV");
12602 break;
12603 default:
bee0ee85
NC
12604 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12605 VMS_ST_FUNC_TYPE (other));
12606 strcat (res, " <unknown>");
12607 break;
28f997cf
TG
12608 }
12609 break;
12610 default:
12611 break;
12612 }
12613 switch (VMS_ST_LINKAGE (other))
12614 {
12615 case VMS_STL_IGNORE:
12616 strcat (res, " IGN");
12617 break;
12618 case VMS_STL_RESERVE:
12619 strcat (res, " RSV");
12620 break;
12621 case VMS_STL_STD:
12622 strcat (res, " STD");
12623 break;
12624 case VMS_STL_LNK:
12625 strcat (res, " LNK");
12626 break;
12627 default:
bee0ee85
NC
12628 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12629 VMS_ST_LINKAGE (other));
12630 strcat (res, " <unknown>");
12631 break;
28f997cf
TG
12632 }
12633
12634 if (res[0] != 0)
12635 return res + 1;
12636 else
12637 return res;
12638 }
12639 return NULL;
12640}
12641
6911b7dc
AM
12642static const char *
12643get_ppc64_symbol_other (unsigned int other)
12644{
14732552
AM
12645 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12646 return NULL;
12647
12648 other >>= STO_PPC64_LOCAL_BIT;
12649 if (other <= 6)
6911b7dc 12650 {
89246a0e 12651 static char buf[64];
14732552
AM
12652 if (other >= 2)
12653 other = ppc64_decode_local_entry (other);
12654 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12655 return buf;
12656 }
12657 return NULL;
12658}
12659
8155b853
NC
12660static const char *
12661get_riscv_symbol_other (unsigned int other)
12662{
12663 static char buf[32];
12664 buf[0] = 0;
12665
12666 if (other & STO_RISCV_VARIANT_CC)
12667 {
12668 strcat (buf, _(" VARIANT_CC"));
12669 other &= ~STO_RISCV_VARIANT_CC;
12670 }
12671
12672 if (other != 0)
12673 snprintf (buf, sizeof buf, " %x", other);
12674
12675
12676 if (buf[0] != 0)
12677 return buf + 1;
12678 else
12679 return buf;
12680}
12681
5e2b0d47 12682static const char *
dda8d76d 12683get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12684{
12685 const char * result = NULL;
89246a0e 12686 static char buff [64];
5e2b0d47
NC
12687
12688 if (other == 0)
12689 return "";
12690
dda8d76d 12691 switch (filedata->file_header.e_machine)
5e2b0d47 12692 {
2057d69d
CZ
12693 case EM_ALPHA:
12694 result = get_alpha_symbol_other (other);
12695 break;
2301ed1c
SN
12696 case EM_AARCH64:
12697 result = get_aarch64_symbol_other (other);
12698 break;
5e2b0d47
NC
12699 case EM_MIPS:
12700 result = get_mips_symbol_other (other);
28f997cf
TG
12701 break;
12702 case EM_IA_64:
dda8d76d 12703 result = get_ia64_symbol_other (filedata, other);
28f997cf 12704 break;
6911b7dc
AM
12705 case EM_PPC64:
12706 result = get_ppc64_symbol_other (other);
12707 break;
8155b853
NC
12708 case EM_RISCV:
12709 result = get_riscv_symbol_other (other);
12710 break;
5e2b0d47 12711 default:
fd85a6a1 12712 result = NULL;
5e2b0d47
NC
12713 break;
12714 }
12715
12716 if (result)
12717 return result;
12718
12719 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12720 return buff;
12721}
12722
d1133906 12723static const char *
dda8d76d 12724get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12725{
b34976b6 12726 static char buff[32];
5cf1065c 12727
252b5132
RH
12728 switch (type)
12729 {
b34976b6
AM
12730 case SHN_UNDEF: return "UND";
12731 case SHN_ABS: return "ABS";
12732 case SHN_COMMON: return "COM";
252b5132 12733 default:
9ce701e2 12734 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12735 && filedata->file_header.e_machine == EM_IA_64
12736 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12737 return "ANSI_COM";
12738 else if ((filedata->file_header.e_machine == EM_X86_64
12739 || filedata->file_header.e_machine == EM_L1OM
12740 || filedata->file_header.e_machine == EM_K1OM)
12741 && type == SHN_X86_64_LCOMMON)
12742 return "LARGE_COM";
12743 else if ((type == SHN_MIPS_SCOMMON
12744 && filedata->file_header.e_machine == EM_MIPS)
12745 || (type == SHN_TIC6X_SCOMMON
12746 && filedata->file_header.e_machine == EM_TI_C6000))
12747 return "SCOM";
12748 else if (type == SHN_MIPS_SUNDEFINED
12749 && filedata->file_header.e_machine == EM_MIPS)
12750 return "SUND";
12751 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12752 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12753 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12754 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12755 else if (type >= SHN_LORESERVE)
12756 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12757 else if (filedata->file_header.e_shnum != 0
12758 && type >= filedata->file_header.e_shnum)
12759 sprintf (buff, _("bad section index[%3d]"), type);
12760 else
12761 sprintf (buff, "%3d", type);
12762 break;
fd85a6a1
NC
12763 }
12764
10ca4b04 12765 return buff;
6bd1a22c
L
12766}
12767
bb4d2ac2 12768static const char *
dda8d76d 12769get_symbol_version_string (Filedata * filedata,
015dc7e1 12770 bool is_dynsym,
1449284b
NC
12771 const char * strtab,
12772 unsigned long int strtab_size,
12773 unsigned int si,
12774 Elf_Internal_Sym * psym,
12775 enum versioned_symbol_info * sym_info,
12776 unsigned short * vna_other)
bb4d2ac2 12777{
ab273396
AM
12778 unsigned char data[2];
12779 unsigned short vers_data;
12780 unsigned long offset;
7a815dd5 12781 unsigned short max_vd_ndx;
bb4d2ac2 12782
ab273396 12783 if (!is_dynsym
978c4450 12784 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12785 return NULL;
bb4d2ac2 12786
978c4450
AM
12787 offset = offset_from_vma (filedata,
12788 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12789 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12790
dda8d76d 12791 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12792 sizeof (data), 1, _("version data")) == NULL)
12793 return NULL;
12794
12795 vers_data = byte_get (data, 2);
bb4d2ac2 12796
1f6f5dba 12797 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12798 return NULL;
bb4d2ac2 12799
0b8b7609 12800 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12801 max_vd_ndx = 0;
12802
ab273396
AM
12803 /* Usually we'd only see verdef for defined symbols, and verneed for
12804 undefined symbols. However, symbols defined by the linker in
12805 .dynbss for variables copied from a shared library in order to
12806 avoid text relocations are defined yet have verneed. We could
12807 use a heuristic to detect the special case, for example, check
12808 for verneed first on symbols defined in SHT_NOBITS sections, but
12809 it is simpler and more reliable to just look for both verdef and
12810 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12811
ab273396
AM
12812 if (psym->st_shndx != SHN_UNDEF
12813 && vers_data != 0x8001
978c4450 12814 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12815 {
12816 Elf_Internal_Verdef ivd;
12817 Elf_Internal_Verdaux ivda;
12818 Elf_External_Verdaux evda;
12819 unsigned long off;
bb4d2ac2 12820
dda8d76d 12821 off = offset_from_vma (filedata,
978c4450 12822 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12823 sizeof (Elf_External_Verdef));
12824
12825 do
bb4d2ac2 12826 {
ab273396
AM
12827 Elf_External_Verdef evd;
12828
dda8d76d 12829 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12830 _("version def")) == NULL)
12831 {
12832 ivd.vd_ndx = 0;
12833 ivd.vd_aux = 0;
12834 ivd.vd_next = 0;
1f6f5dba 12835 ivd.vd_flags = 0;
ab273396
AM
12836 }
12837 else
bb4d2ac2 12838 {
ab273396
AM
12839 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12840 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12841 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12842 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12843 }
bb4d2ac2 12844
7a815dd5
L
12845 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12846 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12847
ab273396
AM
12848 off += ivd.vd_next;
12849 }
12850 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12851
ab273396
AM
12852 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12853 {
9abca702 12854 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12855 return NULL;
12856
ab273396
AM
12857 off -= ivd.vd_next;
12858 off += ivd.vd_aux;
bb4d2ac2 12859
dda8d76d 12860 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12861 _("version def aux")) != NULL)
12862 {
12863 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12864
ab273396 12865 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12866 return (ivda.vda_name < strtab_size
12867 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12868 }
12869 }
12870 }
bb4d2ac2 12871
978c4450 12872 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12873 {
12874 Elf_External_Verneed evn;
12875 Elf_Internal_Verneed ivn;
12876 Elf_Internal_Vernaux ivna;
bb4d2ac2 12877
dda8d76d 12878 offset = offset_from_vma (filedata,
978c4450 12879 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12880 sizeof evn);
12881 do
12882 {
12883 unsigned long vna_off;
bb4d2ac2 12884
dda8d76d 12885 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12886 _("version need")) == NULL)
12887 {
12888 ivna.vna_next = 0;
12889 ivna.vna_other = 0;
12890 ivna.vna_name = 0;
12891 break;
12892 }
bb4d2ac2 12893
ab273396
AM
12894 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12895 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12896
ab273396 12897 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12898
ab273396
AM
12899 do
12900 {
12901 Elf_External_Vernaux evna;
bb4d2ac2 12902
dda8d76d 12903 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12904 _("version need aux (3)")) == NULL)
bb4d2ac2 12905 {
ab273396
AM
12906 ivna.vna_next = 0;
12907 ivna.vna_other = 0;
12908 ivna.vna_name = 0;
bb4d2ac2 12909 }
bb4d2ac2 12910 else
bb4d2ac2 12911 {
ab273396
AM
12912 ivna.vna_other = BYTE_GET (evna.vna_other);
12913 ivna.vna_next = BYTE_GET (evna.vna_next);
12914 ivna.vna_name = BYTE_GET (evna.vna_name);
12915 }
bb4d2ac2 12916
ab273396
AM
12917 vna_off += ivna.vna_next;
12918 }
12919 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12920
ab273396
AM
12921 if (ivna.vna_other == vers_data)
12922 break;
bb4d2ac2 12923
ab273396
AM
12924 offset += ivn.vn_next;
12925 }
12926 while (ivn.vn_next != 0);
bb4d2ac2 12927
ab273396
AM
12928 if (ivna.vna_other == vers_data)
12929 {
12930 *sym_info = symbol_undefined;
12931 *vna_other = ivna.vna_other;
12932 return (ivna.vna_name < strtab_size
12933 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12934 }
7a815dd5
L
12935 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12936 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12937 return _("<corrupt>");
bb4d2ac2 12938 }
ab273396 12939 return NULL;
bb4d2ac2
L
12940}
12941
047c3dbf
NL
12942/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12943
12944static unsigned int
12945print_dynamic_symbol_size (bfd_vma vma, int base)
12946{
12947 switch (base)
12948 {
12949 case 8:
12950 return print_vma (vma, OCTAL_5);
12951
12952 case 10:
12953 return print_vma (vma, UNSIGNED_5);
12954
12955 case 16:
12956 return print_vma (vma, PREFIX_HEX_5);
12957
12958 case 0:
12959 default:
12960 return print_vma (vma, DEC_5);
12961 }
12962}
12963
10ca4b04
L
12964static void
12965print_dynamic_symbol (Filedata *filedata, unsigned long si,
12966 Elf_Internal_Sym *symtab,
12967 Elf_Internal_Shdr *section,
12968 char *strtab, size_t strtab_size)
252b5132 12969{
10ca4b04
L
12970 const char *version_string;
12971 enum versioned_symbol_info sym_info;
12972 unsigned short vna_other;
23356397
NC
12973 bool is_valid;
12974 const char * sstr;
10ca4b04 12975 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12976
10ca4b04
L
12977 printf ("%6ld: ", si);
12978 print_vma (psym->st_value, LONG_HEX);
12979 putchar (' ');
047c3dbf 12980 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12981 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12982 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12983 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12984 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12985 else
252b5132 12986 {
10ca4b04 12987 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12988
10ca4b04
L
12989 printf (" %-7s", get_symbol_visibility (vis));
12990 /* Check to see if any other bits in the st_other field are set.
12991 Note - displaying this information disrupts the layout of the
12992 table being generated, but for the moment this case is very rare. */
12993 if (psym->st_other ^ vis)
12994 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12995 }
10ca4b04 12996 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12997
23356397
NC
12998 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12999 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13000 && filedata->section_headers != NULL
23356397
NC
13001 && psym->st_name == 0)
13002 {
84714f86
AM
13003 is_valid
13004 = section_name_valid (filedata,
13005 filedata->section_headers + psym->st_shndx);
23356397 13006 sstr = is_valid ?
84714f86
AM
13007 section_name_print (filedata,
13008 filedata->section_headers + psym->st_shndx)
23356397
NC
13009 : _("<corrupt>");
13010 }
13011 else
13012 {
84714f86 13013 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13014 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13015 }
10ca4b04
L
13016
13017 version_string
13018 = get_symbol_version_string (filedata,
13019 (section == NULL
13020 || section->sh_type == SHT_DYNSYM),
13021 strtab, strtab_size, si,
13022 psym, &sym_info, &vna_other);
b9e920ec 13023
0942c7ab
NC
13024 int len_avail = 21;
13025 if (! do_wide && version_string != NULL)
13026 {
ddb43bab 13027 char buffer[16];
0942c7ab 13028
ddb43bab 13029 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13030
13031 if (sym_info == symbol_undefined)
13032 len_avail -= sprintf (buffer," (%d)", vna_other);
13033 else if (sym_info != symbol_hidden)
13034 len_avail -= 1;
13035 }
13036
13037 print_symbol (len_avail, sstr);
b9e920ec 13038
10ca4b04
L
13039 if (version_string)
13040 {
13041 if (sym_info == symbol_undefined)
13042 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13043 else
10ca4b04
L
13044 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13045 version_string);
13046 }
6bd1a22c 13047
10ca4b04 13048 putchar ('\n');
6bd1a22c 13049
10ca4b04
L
13050 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13051 && section != NULL
13052 && si >= section->sh_info
13053 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13054 && filedata->file_header.e_machine != EM_MIPS
13055 /* Solaris binaries have been found to violate this requirement as
13056 well. Not sure if this is a bug or an ABI requirement. */
13057 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13058 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13059 si, printable_section_name (filedata, section), section->sh_info);
13060}
f16a9783 13061
0f03783c
NC
13062static const char *
13063get_lto_kind (unsigned int kind)
13064{
13065 switch (kind)
13066 {
13067 case 0: return "DEF";
13068 case 1: return "WEAKDEF";
13069 case 2: return "UNDEF";
13070 case 3: return "WEAKUNDEF";
13071 case 4: return "COMMON";
13072 default:
13073 break;
13074 }
13075
13076 static char buffer[30];
13077 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13078 sprintf (buffer, "<unknown: %u>", kind);
13079 return buffer;
13080}
13081
13082static const char *
13083get_lto_visibility (unsigned int visibility)
13084{
13085 switch (visibility)
13086 {
13087 case 0: return "DEFAULT";
13088 case 1: return "PROTECTED";
13089 case 2: return "INTERNAL";
13090 case 3: return "HIDDEN";
13091 default:
13092 break;
13093 }
13094
13095 static char buffer[30];
13096 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13097 sprintf (buffer, "<unknown: %u>", visibility);
13098 return buffer;
13099}
13100
13101static const char *
13102get_lto_sym_type (unsigned int sym_type)
13103{
13104 switch (sym_type)
13105 {
13106 case 0: return "UNKNOWN";
13107 case 1: return "FUNCTION";
13108 case 2: return "VARIABLE";
13109 default:
13110 break;
13111 }
13112
13113 static char buffer[30];
13114 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13115 sprintf (buffer, "<unknown: %u>", sym_type);
13116 return buffer;
13117}
13118
13119/* Display an LTO format symbol table.
13120 FIXME: The format of LTO symbol tables is not formalized.
13121 So this code could need changing in the future. */
13122
015dc7e1 13123static bool
0f03783c
NC
13124display_lto_symtab (Filedata * filedata,
13125 Elf_Internal_Shdr * section)
13126{
13127 if (section->sh_size == 0)
13128 {
ca0e11aa
NC
13129 if (filedata->is_separate)
13130 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13131 printable_section_name (filedata, section),
13132 filedata->file_name);
13133 else
13134 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13135 printable_section_name (filedata, section));
047c3dbf 13136
015dc7e1 13137 return true;
0f03783c
NC
13138 }
13139
13140 if (section->sh_size > filedata->file_size)
13141 {
13142 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13143 printable_section_name (filedata, section),
13144 (unsigned long) section->sh_size);
015dc7e1 13145 return false;
0f03783c
NC
13146 }
13147
13148 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13149 section->sh_size, 1, _("LTO symbols"));
13150 if (alloced_data == NULL)
015dc7e1 13151 return false;
0f03783c
NC
13152
13153 /* Look for extended data for the symbol table. */
13154 Elf_Internal_Shdr * ext;
13155 void * ext_data_orig = NULL;
13156 char * ext_data = NULL;
13157 char * ext_data_end = NULL;
13158 char * ext_name = NULL;
13159
13160 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13161 (section_name (filedata, section)
13162 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13163 && ext_name != NULL /* Paranoia. */
13164 && (ext = find_section (filedata, ext_name)) != NULL)
13165 {
13166 if (ext->sh_size < 3)
13167 error (_("LTO Symbol extension table '%s' is empty!\n"),
13168 printable_section_name (filedata, ext));
13169 else
13170 {
13171 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13172 ext->sh_size, 1,
13173 _("LTO ext symbol data"));
13174 if (ext_data != NULL)
13175 {
13176 ext_data_end = ext_data + ext->sh_size;
13177 if (* ext_data++ != 1)
13178 error (_("Unexpected version number in symbol extension table\n"));
13179 }
13180 }
13181 }
b9e920ec 13182
0f03783c
NC
13183 const unsigned char * data = (const unsigned char *) alloced_data;
13184 const unsigned char * end = data + section->sh_size;
13185
ca0e11aa
NC
13186 if (filedata->is_separate)
13187 printf (_("\nIn linked file '%s': "), filedata->file_name);
13188 else
13189 printf ("\n");
13190
0f03783c
NC
13191 if (ext_data_orig != NULL)
13192 {
13193 if (do_wide)
ca0e11aa 13194 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13195 printable_section_name (filedata, section),
13196 printable_section_name (filedata, ext));
13197 else
13198 {
ca0e11aa 13199 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13200 printable_section_name (filedata, section));
13201 printf (_(" and extension table '%s' contain:\n"),
13202 printable_section_name (filedata, ext));
13203 }
13204 }
13205 else
ca0e11aa 13206 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13207 printable_section_name (filedata, section));
b9e920ec 13208
0f03783c 13209 /* FIXME: Add a wide version. */
b9e920ec 13210 if (ext_data_orig != NULL)
0f03783c
NC
13211 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13212 else
13213 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13214
13215 /* FIXME: We do not handle style prefixes. */
13216
13217 while (data < end)
13218 {
13219 const unsigned char * sym_name = data;
13220 data += strnlen ((const char *) sym_name, end - data) + 1;
13221 if (data >= end)
13222 goto fail;
13223
13224 const unsigned char * comdat_key = data;
13225 data += strnlen ((const char *) comdat_key, end - data) + 1;
13226 if (data >= end)
13227 goto fail;
13228
13229 if (data + 2 + 8 + 4 > end)
13230 goto fail;
13231
13232 unsigned int kind = *data++;
13233 unsigned int visibility = *data++;
13234
13235 elf_vma size = byte_get (data, 8);
13236 data += 8;
13237
13238 elf_vma slot = byte_get (data, 4);
13239 data += 4;
13240
13241 if (ext_data != NULL)
13242 {
13243 if (ext_data < (ext_data_end - 1))
13244 {
13245 unsigned int sym_type = * ext_data ++;
13246 unsigned int sec_kind = * ext_data ++;
13247
13248 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
13249 * comdat_key == 0 ? "-" : (char *) comdat_key,
13250 get_lto_kind (kind),
13251 get_lto_visibility (visibility),
13252 (long) size,
13253 (long) slot,
13254 get_lto_sym_type (sym_type),
13255 (long) sec_kind);
13256 print_symbol (6, (const char *) sym_name);
13257 }
13258 else
13259 {
13260 error (_("Ran out of LTO symbol extension data\n"));
13261 ext_data = NULL;
13262 /* FIXME: return FAIL result ? */
13263 }
13264 }
13265 else
13266 {
13267 printf (" %10s %10s %11s %08lx %08lx _",
13268 * comdat_key == 0 ? "-" : (char *) comdat_key,
13269 get_lto_kind (kind),
13270 get_lto_visibility (visibility),
13271 (long) size,
13272 (long) slot);
13273 print_symbol (21, (const char *) sym_name);
13274 }
13275 putchar ('\n');
13276 }
13277
13278 if (ext_data != NULL && ext_data < ext_data_end)
13279 {
13280 error (_("Data remains in the LTO symbol extension table\n"));
13281 goto fail;
13282 }
13283
13284 free (alloced_data);
13285 free (ext_data_orig);
13286 free (ext_name);
015dc7e1 13287 return true;
b9e920ec 13288
0f03783c
NC
13289 fail:
13290 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13291 free (alloced_data);
13292 free (ext_data_orig);
13293 free (ext_name);
015dc7e1 13294 return false;
0f03783c
NC
13295}
13296
13297/* Display LTO symbol tables. */
13298
015dc7e1 13299static bool
0f03783c
NC
13300process_lto_symbol_tables (Filedata * filedata)
13301{
13302 Elf_Internal_Shdr * section;
13303 unsigned int i;
015dc7e1 13304 bool res = true;
0f03783c
NC
13305
13306 if (!do_lto_syms)
015dc7e1 13307 return true;
0f03783c
NC
13308
13309 if (filedata->section_headers == NULL)
015dc7e1 13310 return true;
0f03783c
NC
13311
13312 for (i = 0, section = filedata->section_headers;
13313 i < filedata->file_header.e_shnum;
13314 i++, section++)
84714f86
AM
13315 if (section_name_valid (filedata, section)
13316 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13317 res &= display_lto_symtab (filedata, section);
13318
b9e920ec 13319 return res;
0f03783c
NC
13320}
13321
10ca4b04 13322/* Dump the symbol table. */
0f03783c 13323
015dc7e1 13324static bool
10ca4b04
L
13325process_symbol_table (Filedata * filedata)
13326{
13327 Elf_Internal_Shdr * section;
f16a9783 13328
10ca4b04 13329 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13330 return true;
6bd1a22c 13331
978c4450 13332 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13333 && do_syms
13334 && do_using_dynamic
978c4450
AM
13335 && filedata->dynamic_strings != NULL
13336 && filedata->dynamic_symbols != NULL)
6bd1a22c 13337 {
10ca4b04 13338 unsigned long si;
6bd1a22c 13339
ca0e11aa
NC
13340 if (filedata->is_separate)
13341 {
13342 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13343 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13344 filedata->num_dynamic_syms),
13345 filedata->file_name,
13346 filedata->num_dynamic_syms);
13347 }
13348 else
13349 {
13350 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13351 "\nSymbol table for image contains %lu entries:\n",
13352 filedata->num_dynamic_syms),
13353 filedata->num_dynamic_syms);
13354 }
10ca4b04
L
13355 if (is_32bit_elf)
13356 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13357 else
13358 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13359
978c4450
AM
13360 for (si = 0; si < filedata->num_dynamic_syms; si++)
13361 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13362 filedata->dynamic_strings,
13363 filedata->dynamic_strings_length);
252b5132 13364 }
8b73c356 13365 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13366 && filedata->section_headers != NULL)
252b5132 13367 {
b34976b6 13368 unsigned int i;
252b5132 13369
dda8d76d
NC
13370 for (i = 0, section = filedata->section_headers;
13371 i < filedata->file_header.e_shnum;
252b5132
RH
13372 i++, section++)
13373 {
2cf0635d 13374 char * strtab = NULL;
c256ffe7 13375 unsigned long int strtab_size = 0;
2cf0635d 13376 Elf_Internal_Sym * symtab;
ef3df110 13377 unsigned long si, num_syms;
252b5132 13378
2c610e4b
L
13379 if ((section->sh_type != SHT_SYMTAB
13380 && section->sh_type != SHT_DYNSYM)
13381 || (!do_syms
13382 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13383 continue;
13384
dd24e3da
NC
13385 if (section->sh_entsize == 0)
13386 {
13387 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13388 printable_section_name (filedata, section));
dd24e3da
NC
13389 continue;
13390 }
13391
d3a49aa8 13392 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13393
13394 if (filedata->is_separate)
13395 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13396 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13397 num_syms),
13398 filedata->file_name,
13399 printable_section_name (filedata, section),
13400 num_syms);
13401 else
13402 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13403 "\nSymbol table '%s' contains %lu entries:\n",
13404 num_syms),
13405 printable_section_name (filedata, section),
13406 num_syms);
dd24e3da 13407
f7a99963 13408 if (is_32bit_elf)
ca47b30c 13409 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13410 else
ca47b30c 13411 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13412
4de91c10 13413 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13414 if (symtab == NULL)
13415 continue;
13416
dda8d76d 13417 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13418 {
dda8d76d
NC
13419 strtab = filedata->string_table;
13420 strtab_size = filedata->string_table_length;
c256ffe7 13421 }
dda8d76d 13422 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13423 {
2cf0635d 13424 Elf_Internal_Shdr * string_sec;
252b5132 13425
dda8d76d 13426 string_sec = filedata->section_headers + section->sh_link;
252b5132 13427
dda8d76d 13428 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13429 1, string_sec->sh_size,
13430 _("string table"));
c256ffe7 13431 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13432 }
13433
10ca4b04
L
13434 for (si = 0; si < num_syms; si++)
13435 print_dynamic_symbol (filedata, si, symtab, section,
13436 strtab, strtab_size);
252b5132
RH
13437
13438 free (symtab);
dda8d76d 13439 if (strtab != filedata->string_table)
252b5132
RH
13440 free (strtab);
13441 }
13442 }
13443 else if (do_syms)
13444 printf
13445 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13446
978c4450 13447 if (do_histogram && filedata->buckets != NULL)
252b5132 13448 {
2cf0635d
NC
13449 unsigned long * lengths;
13450 unsigned long * counts;
66543521
AM
13451 unsigned long hn;
13452 bfd_vma si;
13453 unsigned long maxlength = 0;
13454 unsigned long nzero_counts = 0;
13455 unsigned long nsyms = 0;
6bd6a03d 13456 char *visited;
252b5132 13457
d3a49aa8
AM
13458 printf (ngettext ("\nHistogram for bucket list length "
13459 "(total of %lu bucket):\n",
13460 "\nHistogram for bucket list length "
13461 "(total of %lu buckets):\n",
978c4450
AM
13462 (unsigned long) filedata->nbuckets),
13463 (unsigned long) filedata->nbuckets);
252b5132 13464
978c4450
AM
13465 lengths = (unsigned long *) calloc (filedata->nbuckets,
13466 sizeof (*lengths));
252b5132
RH
13467 if (lengths == NULL)
13468 {
8b73c356 13469 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13470 goto err_out;
252b5132 13471 }
978c4450
AM
13472 visited = xcmalloc (filedata->nchains, 1);
13473 memset (visited, 0, filedata->nchains);
8b73c356
NC
13474
13475 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13476 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13477 {
978c4450 13478 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13479 {
b34976b6 13480 ++nsyms;
252b5132 13481 if (maxlength < ++lengths[hn])
b34976b6 13482 ++maxlength;
978c4450 13483 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13484 {
13485 error (_("histogram chain is corrupt\n"));
13486 break;
13487 }
13488 visited[si] = 1;
252b5132
RH
13489 }
13490 }
6bd6a03d 13491 free (visited);
252b5132 13492
3f5e193b 13493 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13494 if (counts == NULL)
13495 {
b2e951ec 13496 free (lengths);
8b73c356 13497 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13498 goto err_out;
252b5132
RH
13499 }
13500
978c4450 13501 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13502 ++counts[lengths[hn]];
252b5132 13503
978c4450 13504 if (filedata->nbuckets > 0)
252b5132 13505 {
66543521
AM
13506 unsigned long i;
13507 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13508 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13509 for (i = 1; i <= maxlength; ++i)
103f02d3 13510 {
66543521
AM
13511 nzero_counts += counts[i] * i;
13512 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13513 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13514 (nzero_counts * 100.0) / nsyms);
13515 }
252b5132
RH
13516 }
13517
13518 free (counts);
13519 free (lengths);
13520 }
13521
978c4450
AM
13522 free (filedata->buckets);
13523 filedata->buckets = NULL;
13524 filedata->nbuckets = 0;
13525 free (filedata->chains);
13526 filedata->chains = NULL;
252b5132 13527
978c4450 13528 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13529 {
2cf0635d
NC
13530 unsigned long * lengths;
13531 unsigned long * counts;
fdc90cb4
JJ
13532 unsigned long hn;
13533 unsigned long maxlength = 0;
13534 unsigned long nzero_counts = 0;
13535 unsigned long nsyms = 0;
fdc90cb4 13536
f16a9783 13537 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13538 "(total of %lu bucket):\n",
f16a9783 13539 "\nHistogram for `%s' bucket list length "
d3a49aa8 13540 "(total of %lu buckets):\n",
978c4450
AM
13541 (unsigned long) filedata->ngnubuckets),
13542 GNU_HASH_SECTION_NAME (filedata),
13543 (unsigned long) filedata->ngnubuckets);
8b73c356 13544
978c4450
AM
13545 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13546 sizeof (*lengths));
fdc90cb4
JJ
13547 if (lengths == NULL)
13548 {
8b73c356 13549 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13550 goto err_out;
fdc90cb4
JJ
13551 }
13552
fdc90cb4
JJ
13553 printf (_(" Length Number %% of total Coverage\n"));
13554
978c4450
AM
13555 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13556 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13557 {
13558 bfd_vma off, length = 1;
13559
978c4450 13560 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13561 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13562 off < filedata->ngnuchains
13563 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13564 ++off)
fdc90cb4
JJ
13565 ++length;
13566 lengths[hn] = length;
13567 if (length > maxlength)
13568 maxlength = length;
13569 nsyms += length;
13570 }
13571
3f5e193b 13572 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13573 if (counts == NULL)
13574 {
b2e951ec 13575 free (lengths);
8b73c356 13576 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13577 goto err_out;
fdc90cb4
JJ
13578 }
13579
978c4450 13580 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13581 ++counts[lengths[hn]];
13582
978c4450 13583 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13584 {
13585 unsigned long j;
13586 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13587 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13588 for (j = 1; j <= maxlength; ++j)
13589 {
13590 nzero_counts += counts[j] * j;
13591 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13592 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13593 (nzero_counts * 100.0) / nsyms);
13594 }
13595 }
13596
13597 free (counts);
13598 free (lengths);
fdc90cb4 13599 }
978c4450
AM
13600 free (filedata->gnubuckets);
13601 filedata->gnubuckets = NULL;
13602 filedata->ngnubuckets = 0;
13603 free (filedata->gnuchains);
13604 filedata->gnuchains = NULL;
13605 filedata->ngnuchains = 0;
13606 free (filedata->mipsxlat);
13607 filedata->mipsxlat = NULL;
015dc7e1 13608 return true;
fd486f32
AM
13609
13610 err_out:
978c4450
AM
13611 free (filedata->gnubuckets);
13612 filedata->gnubuckets = NULL;
13613 filedata->ngnubuckets = 0;
13614 free (filedata->gnuchains);
13615 filedata->gnuchains = NULL;
13616 filedata->ngnuchains = 0;
13617 free (filedata->mipsxlat);
13618 filedata->mipsxlat = NULL;
13619 free (filedata->buckets);
13620 filedata->buckets = NULL;
13621 filedata->nbuckets = 0;
13622 free (filedata->chains);
13623 filedata->chains = NULL;
015dc7e1 13624 return false;
252b5132
RH
13625}
13626
015dc7e1 13627static bool
ca0e11aa 13628process_syminfo (Filedata * filedata)
252b5132 13629{
b4c96d0d 13630 unsigned int i;
252b5132 13631
978c4450 13632 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13633 || !do_dynamic)
13634 /* No syminfo, this is ok. */
015dc7e1 13635 return true;
252b5132
RH
13636
13637 /* There better should be a dynamic symbol section. */
978c4450 13638 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13639 return false;
252b5132 13640
ca0e11aa
NC
13641 if (filedata->is_separate)
13642 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13643 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13644 filedata->dynamic_syminfo_nent),
13645 filedata->file_name,
13646 filedata->dynamic_syminfo_offset,
13647 filedata->dynamic_syminfo_nent);
13648 else
d3a49aa8
AM
13649 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13650 "contains %d entry:\n",
13651 "\nDynamic info segment at offset 0x%lx "
13652 "contains %d entries:\n",
978c4450 13653 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13654 filedata->dynamic_syminfo_offset,
13655 filedata->dynamic_syminfo_nent);
252b5132
RH
13656
13657 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13658 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13659 {
978c4450 13660 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13661
31104126 13662 printf ("%4d: ", i);
978c4450 13663 if (i >= filedata->num_dynamic_syms)
4082ef84 13664 printf (_("<corrupt index>"));
84714f86
AM
13665 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13666 print_symbol (30, get_dynamic_name (filedata,
978c4450 13667 filedata->dynamic_symbols[i].st_name));
d79b3d50 13668 else
978c4450 13669 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13670 putchar (' ');
252b5132 13671
978c4450 13672 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13673 {
13674 case SYMINFO_BT_SELF:
13675 fputs ("SELF ", stdout);
13676 break;
13677 case SYMINFO_BT_PARENT:
13678 fputs ("PARENT ", stdout);
13679 break;
13680 default:
978c4450
AM
13681 if (filedata->dynamic_syminfo[i].si_boundto > 0
13682 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13683 && valid_dynamic_name (filedata,
978c4450 13684 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13685 {
84714f86 13686 print_symbol (10, get_dynamic_name (filedata,
978c4450 13687 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13688 putchar (' ' );
13689 }
252b5132 13690 else
978c4450 13691 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13692 break;
13693 }
13694
13695 if (flags & SYMINFO_FLG_DIRECT)
13696 printf (" DIRECT");
13697 if (flags & SYMINFO_FLG_PASSTHRU)
13698 printf (" PASSTHRU");
13699 if (flags & SYMINFO_FLG_COPY)
13700 printf (" COPY");
13701 if (flags & SYMINFO_FLG_LAZYLOAD)
13702 printf (" LAZYLOAD");
13703
13704 puts ("");
13705 }
13706
015dc7e1 13707 return true;
252b5132
RH
13708}
13709
75802ccb
CE
13710/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13711 is contained by the region START .. END. The types of ADDR, START
13712 and END should all be the same. Note both ADDR + NELEM and END
13713 point to just beyond the end of the regions that are being tested. */
13714#define IN_RANGE(START,END,ADDR,NELEM) \
13715 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13716
cf13d699
NC
13717/* Check to see if the given reloc needs to be handled in a target specific
13718 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13719 FALSE.
13720
13721 If called with reloc == NULL, then this is a signal that reloc processing
13722 for the current section has finished, and any saved state should be
13723 discarded. */
09c11c86 13724
015dc7e1 13725static bool
dda8d76d
NC
13726target_specific_reloc_handling (Filedata * filedata,
13727 Elf_Internal_Rela * reloc,
13728 unsigned char * start,
13729 unsigned char * end,
13730 Elf_Internal_Sym * symtab,
13731 unsigned long num_syms)
252b5132 13732{
f84ce13b
NC
13733 unsigned int reloc_type = 0;
13734 unsigned long sym_index = 0;
13735
13736 if (reloc)
13737 {
dda8d76d 13738 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13739 sym_index = get_reloc_symindex (reloc->r_info);
13740 }
252b5132 13741
dda8d76d 13742 switch (filedata->file_header.e_machine)
252b5132 13743 {
13761a11
NC
13744 case EM_MSP430:
13745 case EM_MSP430_OLD:
13746 {
13747 static Elf_Internal_Sym * saved_sym = NULL;
13748
f84ce13b
NC
13749 if (reloc == NULL)
13750 {
13751 saved_sym = NULL;
015dc7e1 13752 return true;
f84ce13b
NC
13753 }
13754
13761a11
NC
13755 switch (reloc_type)
13756 {
13757 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13758 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13759 if (uses_msp430x_relocs (filedata))
13761a11 13760 break;
1a0670f3 13761 /* Fall through. */
13761a11 13762 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13763 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13764 /* PR 21139. */
13765 if (sym_index >= num_syms)
13766 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13767 sym_index);
13768 else
13769 saved_sym = symtab + sym_index;
015dc7e1 13770 return true;
13761a11
NC
13771
13772 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13773 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13774 goto handle_sym_diff;
0b4362b0 13775
13761a11
NC
13776 case 5: /* R_MSP430_16_BYTE */
13777 case 9: /* R_MSP430_8 */
7d81bc93 13778 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13779 if (uses_msp430x_relocs (filedata))
13761a11
NC
13780 break;
13781 goto handle_sym_diff;
13782
13783 case 2: /* R_MSP430_ABS16 */
13784 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13785 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13786 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13787 break;
13788 goto handle_sym_diff;
0b4362b0 13789
13761a11
NC
13790 handle_sym_diff:
13791 if (saved_sym != NULL)
13792 {
13793 bfd_vma value;
5a805384 13794 unsigned int reloc_size = 0;
7d81bc93
JL
13795 int leb_ret = 0;
13796 switch (reloc_type)
13797 {
13798 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13799 reloc_size = 4;
13800 break;
13801 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13802 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13803 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13804 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13805 &reloc_size, &leb_ret);
7d81bc93
JL
13806 break;
13807 default:
13808 reloc_size = 2;
13809 break;
13810 }
13761a11 13811
5a805384 13812 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13813 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13814 "ULEB128 value\n"),
13815 (long) reloc->r_offset);
13816 else if (sym_index >= num_syms)
f84ce13b
NC
13817 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13818 sym_index);
03f7786e 13819 else
f84ce13b
NC
13820 {
13821 value = reloc->r_addend + (symtab[sym_index].st_value
13822 - saved_sym->st_value);
13823
b32e566b 13824 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13825 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13826 else
13827 /* PR 21137 */
13828 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13829 (long) reloc->r_offset);
f84ce13b 13830 }
13761a11
NC
13831
13832 saved_sym = NULL;
015dc7e1 13833 return true;
13761a11
NC
13834 }
13835 break;
13836
13837 default:
13838 if (saved_sym != NULL)
071436c6 13839 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13840 break;
13841 }
13842 break;
13843 }
13844
cf13d699
NC
13845 case EM_MN10300:
13846 case EM_CYGNUS_MN10300:
13847 {
13848 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13849
f84ce13b
NC
13850 if (reloc == NULL)
13851 {
13852 saved_sym = NULL;
015dc7e1 13853 return true;
f84ce13b
NC
13854 }
13855
cf13d699
NC
13856 switch (reloc_type)
13857 {
13858 case 34: /* R_MN10300_ALIGN */
015dc7e1 13859 return true;
cf13d699 13860 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13861 if (sym_index >= num_syms)
13862 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13863 sym_index);
13864 else
13865 saved_sym = symtab + sym_index;
015dc7e1 13866 return true;
f84ce13b 13867
cf13d699
NC
13868 case 1: /* R_MN10300_32 */
13869 case 2: /* R_MN10300_16 */
13870 if (saved_sym != NULL)
13871 {
03f7786e 13872 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13873 bfd_vma value;
252b5132 13874
f84ce13b
NC
13875 if (sym_index >= num_syms)
13876 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13877 sym_index);
03f7786e 13878 else
f84ce13b
NC
13879 {
13880 value = reloc->r_addend + (symtab[sym_index].st_value
13881 - saved_sym->st_value);
13882
b32e566b 13883 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13884 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13885 else
13886 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13887 (long) reloc->r_offset);
f84ce13b 13888 }
252b5132 13889
cf13d699 13890 saved_sym = NULL;
015dc7e1 13891 return true;
cf13d699
NC
13892 }
13893 break;
13894 default:
13895 if (saved_sym != NULL)
071436c6 13896 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13897 break;
13898 }
13899 break;
13900 }
6ff71e76
NC
13901
13902 case EM_RL78:
13903 {
13904 static bfd_vma saved_sym1 = 0;
13905 static bfd_vma saved_sym2 = 0;
13906 static bfd_vma value;
13907
f84ce13b
NC
13908 if (reloc == NULL)
13909 {
13910 saved_sym1 = saved_sym2 = 0;
015dc7e1 13911 return true;
f84ce13b
NC
13912 }
13913
6ff71e76
NC
13914 switch (reloc_type)
13915 {
13916 case 0x80: /* R_RL78_SYM. */
13917 saved_sym1 = saved_sym2;
f84ce13b
NC
13918 if (sym_index >= num_syms)
13919 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13920 sym_index);
13921 else
13922 {
13923 saved_sym2 = symtab[sym_index].st_value;
13924 saved_sym2 += reloc->r_addend;
13925 }
015dc7e1 13926 return true;
6ff71e76
NC
13927
13928 case 0x83: /* R_RL78_OPsub. */
13929 value = saved_sym1 - saved_sym2;
13930 saved_sym2 = saved_sym1 = 0;
015dc7e1 13931 return true;
6ff71e76
NC
13932 break;
13933
13934 case 0x41: /* R_RL78_ABS32. */
b32e566b 13935 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13936 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13937 else
13938 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13939 (long) reloc->r_offset);
6ff71e76 13940 value = 0;
015dc7e1 13941 return true;
6ff71e76
NC
13942
13943 case 0x43: /* R_RL78_ABS16. */
b32e566b 13944 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13945 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13946 else
13947 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13948 (long) reloc->r_offset);
6ff71e76 13949 value = 0;
015dc7e1 13950 return true;
6ff71e76
NC
13951
13952 default:
13953 break;
13954 }
13955 break;
13956 }
252b5132
RH
13957 }
13958
015dc7e1 13959 return false;
252b5132
RH
13960}
13961
aca88567
NC
13962/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13963 DWARF debug sections. This is a target specific test. Note - we do not
13964 go through the whole including-target-headers-multiple-times route, (as
13965 we have already done with <elf/h8.h>) because this would become very
13966 messy and even then this function would have to contain target specific
13967 information (the names of the relocs instead of their numeric values).
13968 FIXME: This is not the correct way to solve this problem. The proper way
13969 is to have target specific reloc sizing and typing functions created by
13970 the reloc-macros.h header, in the same way that it already creates the
13971 reloc naming functions. */
13972
015dc7e1 13973static bool
dda8d76d 13974is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13975{
d347c9df 13976 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13977 switch (filedata->file_header.e_machine)
aca88567 13978 {
41e92641 13979 case EM_386:
22abe556 13980 case EM_IAMCU:
41e92641 13981 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13982 case EM_68K:
13983 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13984 case EM_860:
13985 return reloc_type == 1; /* R_860_32. */
13986 case EM_960:
13987 return reloc_type == 2; /* R_960_32. */
a06ea964 13988 case EM_AARCH64:
9282b95a
JW
13989 return (reloc_type == 258
13990 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13991 case EM_BPF:
13992 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13993 case EM_ADAPTEVA_EPIPHANY:
13994 return reloc_type == 3;
aca88567 13995 case EM_ALPHA:
137b6b5f 13996 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13997 case EM_ARC:
13998 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13999 case EM_ARC_COMPACT:
14000 case EM_ARC_COMPACT2:
14001 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14002 case EM_ARM:
14003 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14004 case EM_AVR_OLD:
aca88567
NC
14005 case EM_AVR:
14006 return reloc_type == 1;
14007 case EM_BLACKFIN:
14008 return reloc_type == 0x12; /* R_byte4_data. */
14009 case EM_CRIS:
14010 return reloc_type == 3; /* R_CRIS_32. */
14011 case EM_CR16:
14012 return reloc_type == 3; /* R_CR16_NUM32. */
14013 case EM_CRX:
14014 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14015 case EM_CSKY:
14016 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14017 case EM_CYGNUS_FRV:
14018 return reloc_type == 1;
41e92641
NC
14019 case EM_CYGNUS_D10V:
14020 case EM_D10V:
14021 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14022 case EM_CYGNUS_D30V:
14023 case EM_D30V:
14024 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14025 case EM_DLX:
14026 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14027 case EM_CYGNUS_FR30:
14028 case EM_FR30:
14029 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14030 case EM_FT32:
14031 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14032 case EM_H8S:
14033 case EM_H8_300:
14034 case EM_H8_300H:
14035 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14036 case EM_IA_64:
262cdac7
AM
14037 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14038 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14039 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14040 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14041 case EM_IP2K_OLD:
14042 case EM_IP2K:
14043 return reloc_type == 2; /* R_IP2K_32. */
14044 case EM_IQ2000:
14045 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14046 case EM_LATTICEMICO32:
14047 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14048 case EM_LOONGARCH:
14049 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14050 case EM_M32C_OLD:
aca88567
NC
14051 case EM_M32C:
14052 return reloc_type == 3; /* R_M32C_32. */
14053 case EM_M32R:
14054 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14055 case EM_68HC11:
14056 case EM_68HC12:
14057 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14058 case EM_S12Z:
2849d19f
JD
14059 return reloc_type == 7 || /* R_S12Z_EXT32 */
14060 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14061 case EM_MCORE:
14062 return reloc_type == 1; /* R_MCORE_ADDR32. */
14063 case EM_CYGNUS_MEP:
14064 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14065 case EM_METAG:
14066 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14067 case EM_MICROBLAZE:
14068 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14069 case EM_MIPS:
14070 return reloc_type == 2; /* R_MIPS_32. */
14071 case EM_MMIX:
14072 return reloc_type == 4; /* R_MMIX_32. */
14073 case EM_CYGNUS_MN10200:
14074 case EM_MN10200:
14075 return reloc_type == 1; /* R_MN10200_32. */
14076 case EM_CYGNUS_MN10300:
14077 case EM_MN10300:
14078 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14079 case EM_MOXIE:
14080 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14081 case EM_MSP430_OLD:
14082 case EM_MSP430:
13761a11 14083 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14084 case EM_MT:
14085 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
14086 case EM_NDS32:
14087 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 14088 case EM_ALTERA_NIOS2:
36591ba1 14089 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14090 case EM_NIOS32:
14091 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14092 case EM_OR1K:
14093 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14094 case EM_PARISC:
9abca702 14095 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14096 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14097 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14098 case EM_PJ:
14099 case EM_PJ_OLD:
14100 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14101 case EM_PPC64:
14102 return reloc_type == 1; /* R_PPC64_ADDR32. */
14103 case EM_PPC:
14104 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14105 case EM_TI_PRU:
14106 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14107 case EM_RISCV:
14108 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14109 case EM_RL78:
14110 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14111 case EM_RX:
14112 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14113 case EM_S370:
14114 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14115 case EM_S390_OLD:
14116 case EM_S390:
14117 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14118 case EM_SCORE:
14119 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14120 case EM_SH:
14121 return reloc_type == 1; /* R_SH_DIR32. */
14122 case EM_SPARC32PLUS:
14123 case EM_SPARCV9:
14124 case EM_SPARC:
14125 return reloc_type == 3 /* R_SPARC_32. */
14126 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14127 case EM_SPU:
14128 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14129 case EM_TI_C6000:
14130 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14131 case EM_TILEGX:
14132 return reloc_type == 2; /* R_TILEGX_32. */
14133 case EM_TILEPRO:
14134 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14135 case EM_CYGNUS_V850:
14136 case EM_V850:
14137 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14138 case EM_V800:
14139 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14140 case EM_VAX:
14141 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14142 case EM_VISIUM:
14143 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14144 case EM_WEBASSEMBLY:
14145 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14146 case EM_X86_64:
8a9036a4 14147 case EM_L1OM:
7a9068fe 14148 case EM_K1OM:
aca88567 14149 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
14150 case EM_XC16X:
14151 case EM_C166:
14152 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
14153 case EM_XGATE:
14154 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14155 case EM_XSTORMY16:
14156 return reloc_type == 1; /* R_XSTROMY16_32. */
14157 case EM_XTENSA_OLD:
14158 case EM_XTENSA:
14159 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14160 case EM_Z80:
14161 return reloc_type == 6; /* R_Z80_32. */
aca88567 14162 default:
bee0ee85
NC
14163 {
14164 static unsigned int prev_warn = 0;
14165
14166 /* Avoid repeating the same warning multiple times. */
dda8d76d 14167 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14168 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14169 filedata->file_header.e_machine);
14170 prev_warn = filedata->file_header.e_machine;
015dc7e1 14171 return false;
bee0ee85 14172 }
aca88567
NC
14173 }
14174}
14175
14176/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14177 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14178
015dc7e1 14179static bool
dda8d76d 14180is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14181{
dda8d76d 14182 switch (filedata->file_header.e_machine)
d347c9df 14183 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14184 {
41e92641 14185 case EM_386:
22abe556 14186 case EM_IAMCU:
3e0873ac 14187 return reloc_type == 2; /* R_386_PC32. */
aca88567 14188 case EM_68K:
3e0873ac 14189 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14190 case EM_AARCH64:
14191 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14192 case EM_ADAPTEVA_EPIPHANY:
14193 return reloc_type == 6;
aca88567
NC
14194 case EM_ALPHA:
14195 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14196 case EM_ARC_COMPACT:
14197 case EM_ARC_COMPACT2:
14198 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14199 case EM_ARM:
3e0873ac 14200 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14201 case EM_AVR_OLD:
14202 case EM_AVR:
14203 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
14204 case EM_MICROBLAZE:
14205 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14206 case EM_OR1K:
14207 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14208 case EM_PARISC:
85acf597 14209 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14210 case EM_PPC:
14211 return reloc_type == 26; /* R_PPC_REL32. */
14212 case EM_PPC64:
3e0873ac 14213 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14214 case EM_RISCV:
14215 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14216 case EM_S390_OLD:
14217 case EM_S390:
3e0873ac 14218 return reloc_type == 5; /* R_390_PC32. */
aca88567 14219 case EM_SH:
3e0873ac 14220 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14221 case EM_SPARC32PLUS:
14222 case EM_SPARCV9:
14223 case EM_SPARC:
3e0873ac 14224 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14225 case EM_SPU:
14226 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14227 case EM_TILEGX:
14228 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14229 case EM_TILEPRO:
14230 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14231 case EM_VISIUM:
14232 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14233 case EM_X86_64:
8a9036a4 14234 case EM_L1OM:
7a9068fe 14235 case EM_K1OM:
3e0873ac 14236 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14237 case EM_VAX:
14238 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14239 case EM_XTENSA_OLD:
14240 case EM_XTENSA:
14241 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14242 default:
14243 /* Do not abort or issue an error message here. Not all targets use
14244 pc-relative 32-bit relocs in their DWARF debug information and we
14245 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14246 more helpful warning message will be generated by apply_relocations
14247 anyway, so just return. */
015dc7e1 14248 return false;
aca88567
NC
14249 }
14250}
14251
14252/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14253 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14254
015dc7e1 14255static bool
dda8d76d 14256is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14257{
dda8d76d 14258 switch (filedata->file_header.e_machine)
aca88567 14259 {
a06ea964
NC
14260 case EM_AARCH64:
14261 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14262 case EM_ALPHA:
14263 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14264 case EM_IA_64:
262cdac7
AM
14265 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14266 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14267 case EM_LOONGARCH:
14268 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14269 case EM_PARISC:
14270 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14271 case EM_PPC64:
14272 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14273 case EM_RISCV:
14274 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14275 case EM_SPARC32PLUS:
14276 case EM_SPARCV9:
14277 case EM_SPARC:
714da62f
NC
14278 return reloc_type == 32 /* R_SPARC_64. */
14279 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14280 case EM_X86_64:
8a9036a4 14281 case EM_L1OM:
7a9068fe 14282 case EM_K1OM:
aca88567 14283 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14284 case EM_S390_OLD:
14285 case EM_S390:
aa137e4d
NC
14286 return reloc_type == 22; /* R_S390_64. */
14287 case EM_TILEGX:
14288 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14289 case EM_MIPS:
aa137e4d 14290 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14291 default:
015dc7e1 14292 return false;
aca88567
NC
14293 }
14294}
14295
85acf597
RH
14296/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14297 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14298
015dc7e1 14299static bool
dda8d76d 14300is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14301{
dda8d76d 14302 switch (filedata->file_header.e_machine)
85acf597 14303 {
a06ea964
NC
14304 case EM_AARCH64:
14305 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14306 case EM_ALPHA:
aa137e4d 14307 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14308 case EM_IA_64:
262cdac7
AM
14309 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14310 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14311 case EM_PARISC:
aa137e4d 14312 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14313 case EM_PPC64:
aa137e4d 14314 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14315 case EM_SPARC32PLUS:
14316 case EM_SPARCV9:
14317 case EM_SPARC:
aa137e4d 14318 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14319 case EM_X86_64:
8a9036a4 14320 case EM_L1OM:
7a9068fe 14321 case EM_K1OM:
aa137e4d 14322 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14323 case EM_S390_OLD:
14324 case EM_S390:
aa137e4d
NC
14325 return reloc_type == 23; /* R_S390_PC64. */
14326 case EM_TILEGX:
14327 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14328 default:
015dc7e1 14329 return false;
85acf597
RH
14330 }
14331}
14332
4dc3c23d
AM
14333/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14334 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14335
015dc7e1 14336static bool
dda8d76d 14337is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14338{
dda8d76d 14339 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14340 {
14341 case EM_CYGNUS_MN10200:
14342 case EM_MN10200:
14343 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14344 case EM_FT32:
14345 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14346 case EM_Z80:
14347 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14348 default:
015dc7e1 14349 return false;
4dc3c23d
AM
14350 }
14351}
14352
aca88567
NC
14353/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14354 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14355
015dc7e1 14356static bool
dda8d76d 14357is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14358{
d347c9df 14359 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14360 switch (filedata->file_header.e_machine)
4b78141a 14361 {
886a2506
NC
14362 case EM_ARC:
14363 case EM_ARC_COMPACT:
14364 case EM_ARC_COMPACT2:
14365 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14366 case EM_ADAPTEVA_EPIPHANY:
14367 return reloc_type == 5;
aca88567
NC
14368 case EM_AVR_OLD:
14369 case EM_AVR:
14370 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14371 case EM_CYGNUS_D10V:
14372 case EM_D10V:
14373 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14374 case EM_FT32:
14375 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14376 case EM_H8S:
14377 case EM_H8_300:
14378 case EM_H8_300H:
aca88567
NC
14379 return reloc_type == R_H8_DIR16;
14380 case EM_IP2K_OLD:
14381 case EM_IP2K:
14382 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14383 case EM_M32C_OLD:
f4236fe4
DD
14384 case EM_M32C:
14385 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14386 case EM_CYGNUS_MN10200:
14387 case EM_MN10200:
14388 return reloc_type == 2; /* R_MN10200_16. */
14389 case EM_CYGNUS_MN10300:
14390 case EM_MN10300:
14391 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14392 case EM_MSP430:
dda8d76d 14393 if (uses_msp430x_relocs (filedata))
13761a11 14394 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14395 /* Fall through. */
78c8d46c 14396 case EM_MSP430_OLD:
aca88567 14397 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
14398 case EM_NDS32:
14399 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 14400 case EM_ALTERA_NIOS2:
36591ba1 14401 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14402 case EM_NIOS32:
14403 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14404 case EM_OR1K:
14405 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14406 case EM_RISCV:
14407 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14408 case EM_TI_PRU:
14409 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14410 case EM_TI_C6000:
14411 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14412 case EM_VISIUM:
14413 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
14414 case EM_XC16X:
14415 case EM_C166:
14416 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
14417 case EM_XGATE:
14418 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14419 case EM_Z80:
14420 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14421 default:
015dc7e1 14422 return false;
4b78141a
NC
14423 }
14424}
14425
39e07931
AS
14426/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14427 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14428
015dc7e1 14429static bool
39e07931
AS
14430is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14431{
14432 switch (filedata->file_header.e_machine)
14433 {
14434 case EM_RISCV:
14435 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14436 case EM_Z80:
14437 return reloc_type == 1; /* R_Z80_8. */
39e07931 14438 default:
015dc7e1 14439 return false;
39e07931
AS
14440 }
14441}
14442
14443/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14444 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14445
015dc7e1 14446static bool
39e07931
AS
14447is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14448{
14449 switch (filedata->file_header.e_machine)
14450 {
14451 case EM_RISCV:
14452 return reloc_type == 53; /* R_RISCV_SET6. */
14453 default:
015dc7e1 14454 return false;
39e07931
AS
14455 }
14456}
14457
03336641
JW
14458/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14459 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14460
015dc7e1 14461static bool
03336641
JW
14462is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14463{
14464 /* Please keep this table alpha-sorted for ease of visual lookup. */
14465 switch (filedata->file_header.e_machine)
14466 {
14467 case EM_RISCV:
14468 return reloc_type == 35; /* R_RISCV_ADD32. */
14469 default:
015dc7e1 14470 return false;
03336641
JW
14471 }
14472}
14473
14474/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14475 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14476
015dc7e1 14477static bool
03336641
JW
14478is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14479{
14480 /* Please keep this table alpha-sorted for ease of visual lookup. */
14481 switch (filedata->file_header.e_machine)
14482 {
14483 case EM_RISCV:
14484 return reloc_type == 39; /* R_RISCV_SUB32. */
14485 default:
015dc7e1 14486 return false;
03336641
JW
14487 }
14488}
14489
14490/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14491 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14492
015dc7e1 14493static bool
03336641
JW
14494is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14495{
14496 /* Please keep this table alpha-sorted for ease of visual lookup. */
14497 switch (filedata->file_header.e_machine)
14498 {
14499 case EM_RISCV:
14500 return reloc_type == 36; /* R_RISCV_ADD64. */
14501 default:
015dc7e1 14502 return false;
03336641
JW
14503 }
14504}
14505
14506/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14507 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14508
015dc7e1 14509static bool
03336641
JW
14510is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14511{
14512 /* Please keep this table alpha-sorted for ease of visual lookup. */
14513 switch (filedata->file_header.e_machine)
14514 {
14515 case EM_RISCV:
14516 return reloc_type == 40; /* R_RISCV_SUB64. */
14517 default:
015dc7e1 14518 return false;
03336641
JW
14519 }
14520}
14521
14522/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14523 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14524
015dc7e1 14525static bool
03336641
JW
14526is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14527{
14528 /* Please keep this table alpha-sorted for ease of visual lookup. */
14529 switch (filedata->file_header.e_machine)
14530 {
14531 case EM_RISCV:
14532 return reloc_type == 34; /* R_RISCV_ADD16. */
14533 default:
015dc7e1 14534 return false;
03336641
JW
14535 }
14536}
14537
14538/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14539 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14540
015dc7e1 14541static bool
03336641
JW
14542is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14543{
14544 /* Please keep this table alpha-sorted for ease of visual lookup. */
14545 switch (filedata->file_header.e_machine)
14546 {
14547 case EM_RISCV:
14548 return reloc_type == 38; /* R_RISCV_SUB16. */
14549 default:
015dc7e1 14550 return false;
03336641
JW
14551 }
14552}
14553
14554/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14555 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14556
015dc7e1 14557static bool
03336641
JW
14558is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14559{
14560 /* Please keep this table alpha-sorted for ease of visual lookup. */
14561 switch (filedata->file_header.e_machine)
14562 {
14563 case EM_RISCV:
14564 return reloc_type == 33; /* R_RISCV_ADD8. */
14565 default:
015dc7e1 14566 return false;
03336641
JW
14567 }
14568}
14569
14570/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14571 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14572
015dc7e1 14573static bool
03336641
JW
14574is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14575{
14576 /* Please keep this table alpha-sorted for ease of visual lookup. */
14577 switch (filedata->file_header.e_machine)
14578 {
14579 case EM_RISCV:
14580 return reloc_type == 37; /* R_RISCV_SUB8. */
14581 default:
015dc7e1 14582 return false;
03336641
JW
14583 }
14584}
14585
39e07931
AS
14586/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14587 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14588
015dc7e1 14589static bool
39e07931
AS
14590is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14591{
14592 switch (filedata->file_header.e_machine)
14593 {
14594 case EM_RISCV:
14595 return reloc_type == 52; /* R_RISCV_SUB6. */
14596 default:
015dc7e1 14597 return false;
39e07931
AS
14598 }
14599}
14600
2a7b2e88
JK
14601/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14602 relocation entries (possibly formerly used for SHT_GROUP sections). */
14603
015dc7e1 14604static bool
dda8d76d 14605is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14606{
dda8d76d 14607 switch (filedata->file_header.e_machine)
2a7b2e88 14608 {
cb8f3167 14609 case EM_386: /* R_386_NONE. */
d347c9df 14610 case EM_68K: /* R_68K_NONE. */
cfb8c092 14611 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14612 case EM_ALPHA: /* R_ALPHA_NONE. */
14613 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14614 case EM_ARC: /* R_ARC_NONE. */
886a2506 14615 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14616 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14617 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14618 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14619 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14620 case EM_FT32: /* R_FT32_NONE. */
14621 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14622 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14623 case EM_L1OM: /* R_X86_64_NONE. */
14624 case EM_M32R: /* R_M32R_NONE. */
14625 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14626 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14627 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14628 case EM_NIOS32: /* R_NIOS_NONE. */
14629 case EM_OR1K: /* R_OR1K_NONE. */
14630 case EM_PARISC: /* R_PARISC_NONE. */
14631 case EM_PPC64: /* R_PPC64_NONE. */
14632 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14633 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14634 case EM_S390: /* R_390_NONE. */
14635 case EM_S390_OLD:
14636 case EM_SH: /* R_SH_NONE. */
14637 case EM_SPARC32PLUS:
14638 case EM_SPARC: /* R_SPARC_NONE. */
14639 case EM_SPARCV9:
aa137e4d
NC
14640 case EM_TILEGX: /* R_TILEGX_NONE. */
14641 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14642 case EM_TI_C6000:/* R_C6000_NONE. */
14643 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14644 case EM_XC16X:
6655dba2 14645 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14646 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14647 return reloc_type == 0;
d347c9df 14648
a06ea964
NC
14649 case EM_AARCH64:
14650 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14651 case EM_AVR_OLD:
14652 case EM_AVR:
14653 return (reloc_type == 0 /* R_AVR_NONE. */
14654 || reloc_type == 30 /* R_AVR_DIFF8. */
14655 || reloc_type == 31 /* R_AVR_DIFF16. */
14656 || reloc_type == 32 /* R_AVR_DIFF32. */);
14657 case EM_METAG:
14658 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14659 case EM_NDS32:
14660 return (reloc_type == 0 /* R_XTENSA_NONE. */
14661 || reloc_type == 204 /* R_NDS32_DIFF8. */
14662 || reloc_type == 205 /* R_NDS32_DIFF16. */
14663 || reloc_type == 206 /* R_NDS32_DIFF32. */
14664 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14665 case EM_TI_PRU:
14666 return (reloc_type == 0 /* R_PRU_NONE. */
14667 || reloc_type == 65 /* R_PRU_DIFF8. */
14668 || reloc_type == 66 /* R_PRU_DIFF16. */
14669 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14670 case EM_XTENSA_OLD:
14671 case EM_XTENSA:
4dc3c23d
AM
14672 return (reloc_type == 0 /* R_XTENSA_NONE. */
14673 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14674 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14675 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14676 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14677 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14678 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14679 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14680 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14681 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14682 }
015dc7e1 14683 return false;
2a7b2e88
JK
14684}
14685
d1c4b12b
NC
14686/* Returns TRUE if there is a relocation against
14687 section NAME at OFFSET bytes. */
14688
015dc7e1 14689bool
d1c4b12b
NC
14690reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14691{
14692 Elf_Internal_Rela * relocs;
14693 Elf_Internal_Rela * rp;
14694
14695 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14696 return false;
d1c4b12b
NC
14697
14698 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14699
14700 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14701 if (rp->r_offset == offset)
015dc7e1 14702 return true;
d1c4b12b 14703
015dc7e1 14704 return false;
d1c4b12b
NC
14705}
14706
cf13d699 14707/* Apply relocations to a section.
32ec8896
NC
14708 Returns TRUE upon success, FALSE otherwise.
14709 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14710 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14711 will be set to the number of relocs loaded.
14712
cf13d699 14713 Note: So far support has been added only for those relocations
32ec8896
NC
14714 which can be found in debug sections. FIXME: Add support for
14715 more relocations ? */
1b315056 14716
015dc7e1 14717static bool
dda8d76d 14718apply_relocations (Filedata * filedata,
d1c4b12b
NC
14719 const Elf_Internal_Shdr * section,
14720 unsigned char * start,
14721 bfd_size_type size,
1449284b 14722 void ** relocs_return,
d1c4b12b 14723 unsigned long * num_relocs_return)
1b315056 14724{
cf13d699 14725 Elf_Internal_Shdr * relsec;
0d2a7a93 14726 unsigned char * end = start + size;
cb8f3167 14727
d1c4b12b
NC
14728 if (relocs_return != NULL)
14729 {
14730 * (Elf_Internal_Rela **) relocs_return = NULL;
14731 * num_relocs_return = 0;
14732 }
14733
dda8d76d 14734 if (filedata->file_header.e_type != ET_REL)
32ec8896 14735 /* No relocs to apply. */
015dc7e1 14736 return true;
1b315056 14737
cf13d699 14738 /* Find the reloc section associated with the section. */
dda8d76d
NC
14739 for (relsec = filedata->section_headers;
14740 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14741 ++relsec)
252b5132 14742 {
015dc7e1 14743 bool is_rela;
41e92641 14744 unsigned long num_relocs;
2cf0635d
NC
14745 Elf_Internal_Rela * relocs;
14746 Elf_Internal_Rela * rp;
14747 Elf_Internal_Shdr * symsec;
14748 Elf_Internal_Sym * symtab;
ba5cdace 14749 unsigned long num_syms;
2cf0635d 14750 Elf_Internal_Sym * sym;
252b5132 14751
41e92641 14752 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14753 || relsec->sh_info >= filedata->file_header.e_shnum
14754 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14755 || relsec->sh_size == 0
dda8d76d 14756 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14757 continue;
428409d5 14758
a788aedd
AM
14759 symsec = filedata->section_headers + relsec->sh_link;
14760 if (symsec->sh_type != SHT_SYMTAB
14761 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14762 return false;
a788aedd 14763
41e92641
NC
14764 is_rela = relsec->sh_type == SHT_RELA;
14765
14766 if (is_rela)
14767 {
dda8d76d 14768 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14769 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14770 return false;
41e92641
NC
14771 }
14772 else
14773 {
dda8d76d 14774 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14775 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14776 return false;
41e92641
NC
14777 }
14778
14779 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14780 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14781 is_rela = false;
428409d5 14782
4de91c10 14783 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14784
41e92641 14785 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14786 {
015dc7e1
AM
14787 bfd_vma addend;
14788 unsigned int reloc_type;
14789 unsigned int reloc_size;
14790 bool reloc_inplace = false;
14791 bool reloc_subtract = false;
14792 unsigned char *rloc;
14793 unsigned long sym_index;
4b78141a 14794
dda8d76d 14795 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14796
dda8d76d 14797 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14798 continue;
dda8d76d 14799 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14800 continue;
dda8d76d
NC
14801 else if (is_32bit_abs_reloc (filedata, reloc_type)
14802 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14803 reloc_size = 4;
dda8d76d
NC
14804 else if (is_64bit_abs_reloc (filedata, reloc_type)
14805 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14806 reloc_size = 8;
dda8d76d 14807 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14808 reloc_size = 3;
dda8d76d 14809 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14810 reloc_size = 2;
39e07931
AS
14811 else if (is_8bit_abs_reloc (filedata, reloc_type)
14812 || is_6bit_abs_reloc (filedata, reloc_type))
14813 reloc_size = 1;
03336641
JW
14814 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14815 reloc_type))
14816 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14817 {
14818 reloc_size = 4;
015dc7e1 14819 reloc_inplace = true;
03336641
JW
14820 }
14821 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14822 reloc_type))
14823 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14824 {
14825 reloc_size = 8;
015dc7e1 14826 reloc_inplace = true;
03336641
JW
14827 }
14828 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14829 reloc_type))
14830 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14831 {
14832 reloc_size = 2;
015dc7e1 14833 reloc_inplace = true;
03336641
JW
14834 }
14835 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14836 reloc_type))
14837 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14838 {
14839 reloc_size = 1;
015dc7e1 14840 reloc_inplace = true;
03336641 14841 }
39e07931
AS
14842 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14843 reloc_type)))
14844 {
14845 reloc_size = 1;
015dc7e1 14846 reloc_inplace = true;
39e07931 14847 }
aca88567 14848 else
4b78141a 14849 {
bee0ee85 14850 static unsigned int prev_reloc = 0;
dda8d76d 14851
bee0ee85
NC
14852 if (reloc_type != prev_reloc)
14853 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14854 reloc_type, printable_section_name (filedata, section));
bee0ee85 14855 prev_reloc = reloc_type;
4b78141a
NC
14856 continue;
14857 }
103f02d3 14858
91d6fa6a 14859 rloc = start + rp->r_offset;
75802ccb 14860 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14861 {
14862 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14863 (unsigned long) rp->r_offset,
dda8d76d 14864 printable_section_name (filedata, section));
700dd8b7
L
14865 continue;
14866 }
103f02d3 14867
ba5cdace
NC
14868 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14869 if (sym_index >= num_syms)
14870 {
14871 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14872 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14873 continue;
14874 }
14875 sym = symtab + sym_index;
41e92641
NC
14876
14877 /* If the reloc has a symbol associated with it,
55f25fc3
L
14878 make sure that it is of an appropriate type.
14879
14880 Relocations against symbols without type can happen.
14881 Gcc -feliminate-dwarf2-dups may generate symbols
14882 without type for debug info.
14883
14884 Icc generates relocations against function symbols
14885 instead of local labels.
14886
14887 Relocations against object symbols can happen, eg when
14888 referencing a global array. For an example of this see
14889 the _clz.o binary in libgcc.a. */
aca88567 14890 if (sym != symtab
b8871f35 14891 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14892 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14893 {
d3a49aa8 14894 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14895 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14896 printable_section_name (filedata, relsec),
d3a49aa8 14897 (long int)(rp - relocs));
aca88567 14898 continue;
5b18a4bc 14899 }
252b5132 14900
4dc3c23d
AM
14901 addend = 0;
14902 if (is_rela)
14903 addend += rp->r_addend;
c47320c3
AM
14904 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14905 partial_inplace. */
4dc3c23d 14906 if (!is_rela
dda8d76d 14907 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14908 && reloc_type == 1)
dda8d76d
NC
14909 || ((filedata->file_header.e_machine == EM_PJ
14910 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14911 && reloc_type == 1)
dda8d76d
NC
14912 || ((filedata->file_header.e_machine == EM_D30V
14913 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14914 && reloc_type == 12)
14915 || reloc_inplace)
39e07931
AS
14916 {
14917 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14918 addend += byte_get (rloc, reloc_size) & 0x3f;
14919 else
14920 addend += byte_get (rloc, reloc_size);
14921 }
cb8f3167 14922
dda8d76d
NC
14923 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14924 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14925 {
14926 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14927 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14928 addend -= 8;
91d6fa6a 14929 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14930 reloc_size);
14931 }
39e07931
AS
14932 else if (is_6bit_abs_reloc (filedata, reloc_type)
14933 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14934 {
14935 if (reloc_subtract)
14936 addend -= sym->st_value;
14937 else
14938 addend += sym->st_value;
14939 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14940 byte_put (rloc, addend, reloc_size);
14941 }
03336641
JW
14942 else if (reloc_subtract)
14943 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14944 else
91d6fa6a 14945 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14946 }
252b5132 14947
5b18a4bc 14948 free (symtab);
f84ce13b
NC
14949 /* Let the target specific reloc processing code know that
14950 we have finished with these relocs. */
dda8d76d 14951 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14952
14953 if (relocs_return)
14954 {
14955 * (Elf_Internal_Rela **) relocs_return = relocs;
14956 * num_relocs_return = num_relocs;
14957 }
14958 else
14959 free (relocs);
14960
5b18a4bc
NC
14961 break;
14962 }
32ec8896 14963
015dc7e1 14964 return true;
5b18a4bc 14965}
103f02d3 14966
cf13d699 14967#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14968static bool
dda8d76d 14969disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14970{
dda8d76d 14971 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14972
74e1a04b 14973 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14974
015dc7e1 14975 return true;
cf13d699
NC
14976}
14977#endif
14978
14979/* Reads in the contents of SECTION from FILE, returning a pointer
14980 to a malloc'ed buffer or NULL if something went wrong. */
14981
14982static char *
dda8d76d 14983get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14984{
dda8d76d 14985 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14986
14987 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14988 {
c6b78c96 14989 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14990 printable_section_name (filedata, section));
cf13d699
NC
14991 return NULL;
14992 }
14993
dda8d76d 14994 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14995 _("section contents"));
cf13d699
NC
14996}
14997
0e602686
NC
14998/* Uncompresses a section that was compressed using zlib, in place. */
14999
015dc7e1 15000static bool
dda8d76d
NC
15001uncompress_section_contents (unsigned char ** buffer,
15002 dwarf_size_type uncompressed_size,
15003 dwarf_size_type * size)
0e602686
NC
15004{
15005 dwarf_size_type compressed_size = *size;
15006 unsigned char * compressed_buffer = *buffer;
15007 unsigned char * uncompressed_buffer;
15008 z_stream strm;
15009 int rc;
15010
15011 /* It is possible the section consists of several compressed
15012 buffers concatenated together, so we uncompress in a loop. */
15013 /* PR 18313: The state field in the z_stream structure is supposed
15014 to be invisible to the user (ie us), but some compilers will
15015 still complain about it being used without initialisation. So
15016 we first zero the entire z_stream structure and then set the fields
15017 that we need. */
15018 memset (& strm, 0, sizeof strm);
15019 strm.avail_in = compressed_size;
15020 strm.next_in = (Bytef *) compressed_buffer;
15021 strm.avail_out = uncompressed_size;
15022 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15023
15024 rc = inflateInit (& strm);
15025 while (strm.avail_in > 0)
15026 {
15027 if (rc != Z_OK)
3624a6c1 15028 break;
0e602686
NC
15029 strm.next_out = ((Bytef *) uncompressed_buffer
15030 + (uncompressed_size - strm.avail_out));
15031 rc = inflate (&strm, Z_FINISH);
15032 if (rc != Z_STREAM_END)
3624a6c1 15033 break;
0e602686
NC
15034 rc = inflateReset (& strm);
15035 }
ad92f33d
AM
15036 if (inflateEnd (& strm) != Z_OK
15037 || rc != Z_OK
0e602686
NC
15038 || strm.avail_out != 0)
15039 goto fail;
15040
15041 *buffer = uncompressed_buffer;
15042 *size = uncompressed_size;
015dc7e1 15043 return true;
0e602686
NC
15044
15045 fail:
15046 free (uncompressed_buffer);
15047 /* Indicate decompression failure. */
15048 *buffer = NULL;
015dc7e1 15049 return false;
0e602686 15050}
dd24e3da 15051
015dc7e1 15052static bool
dda8d76d 15053dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15054{
015dc7e1
AM
15055 Elf_Internal_Shdr *relsec;
15056 bfd_size_type num_bytes;
15057 unsigned char *data;
15058 unsigned char *end;
15059 unsigned char *real_start;
15060 unsigned char *start;
15061 bool some_strings_shown;
cf13d699 15062
dda8d76d 15063 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15064 if (start == NULL)
c6b78c96 15065 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15066 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15067
0e602686 15068 num_bytes = section->sh_size;
cf13d699 15069
835f2fae
NC
15070 if (filedata->is_separate)
15071 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15072 printable_section_name (filedata, section),
15073 filedata->file_name);
15074 else
15075 printf (_("\nString dump of section '%s':\n"),
15076 printable_section_name (filedata, section));
cf13d699 15077
0e602686
NC
15078 if (decompress_dumps)
15079 {
15080 dwarf_size_type new_size = num_bytes;
15081 dwarf_size_type uncompressed_size = 0;
15082
15083 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15084 {
15085 Elf_Internal_Chdr chdr;
15086 unsigned int compression_header_size
ebdf1ebf
NC
15087 = get_compression_header (& chdr, (unsigned char *) start,
15088 num_bytes);
5844b465
NC
15089 if (compression_header_size == 0)
15090 /* An error message will have already been generated
15091 by get_compression_header. */
15092 goto error_out;
0e602686 15093
813dabb9 15094 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15095 {
813dabb9 15096 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15097 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15098 goto error_out;
813dabb9 15099 }
813dabb9
L
15100 uncompressed_size = chdr.ch_size;
15101 start += compression_header_size;
15102 new_size -= compression_header_size;
0e602686
NC
15103 }
15104 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15105 {
15106 /* Read the zlib header. In this case, it should be "ZLIB"
15107 followed by the uncompressed section size, 8 bytes in
15108 big-endian order. */
15109 uncompressed_size = start[4]; uncompressed_size <<= 8;
15110 uncompressed_size += start[5]; uncompressed_size <<= 8;
15111 uncompressed_size += start[6]; uncompressed_size <<= 8;
15112 uncompressed_size += start[7]; uncompressed_size <<= 8;
15113 uncompressed_size += start[8]; uncompressed_size <<= 8;
15114 uncompressed_size += start[9]; uncompressed_size <<= 8;
15115 uncompressed_size += start[10]; uncompressed_size <<= 8;
15116 uncompressed_size += start[11];
15117 start += 12;
15118 new_size -= 12;
15119 }
15120
1835f746
NC
15121 if (uncompressed_size)
15122 {
15123 if (uncompress_section_contents (& start,
15124 uncompressed_size, & new_size))
15125 num_bytes = new_size;
15126 else
15127 {
15128 error (_("Unable to decompress section %s\n"),
dda8d76d 15129 printable_section_name (filedata, section));
f761cb13 15130 goto error_out;
1835f746
NC
15131 }
15132 }
bc303e5d
NC
15133 else
15134 start = real_start;
0e602686 15135 }
fd8008d8 15136
cf13d699
NC
15137 /* If the section being dumped has relocations against it the user might
15138 be expecting these relocations to have been applied. Check for this
15139 case and issue a warning message in order to avoid confusion.
15140 FIXME: Maybe we ought to have an option that dumps a section with
15141 relocs applied ? */
dda8d76d
NC
15142 for (relsec = filedata->section_headers;
15143 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15144 ++relsec)
15145 {
15146 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15147 || relsec->sh_info >= filedata->file_header.e_shnum
15148 || filedata->section_headers + relsec->sh_info != section
cf13d699 15149 || relsec->sh_size == 0
dda8d76d 15150 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15151 continue;
15152
15153 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15154 break;
15155 }
15156
cf13d699
NC
15157 data = start;
15158 end = start + num_bytes;
015dc7e1 15159 some_strings_shown = false;
cf13d699 15160
ba3265d0
NC
15161#ifdef HAVE_MBSTATE_T
15162 mbstate_t state;
15163 /* Initialise the multibyte conversion state. */
15164 memset (& state, 0, sizeof (state));
15165#endif
15166
015dc7e1 15167 bool continuing = false;
ba3265d0 15168
cf13d699
NC
15169 while (data < end)
15170 {
15171 while (!ISPRINT (* data))
15172 if (++ data >= end)
15173 break;
15174
15175 if (data < end)
15176 {
071436c6
NC
15177 size_t maxlen = end - data;
15178
ba3265d0
NC
15179 if (continuing)
15180 {
15181 printf (" ");
015dc7e1 15182 continuing = false;
ba3265d0
NC
15183 }
15184 else
15185 {
d1ce973e 15186 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15187 }
15188
4082ef84
NC
15189 if (maxlen > 0)
15190 {
f3da8a96 15191 char c = 0;
ba3265d0
NC
15192
15193 while (maxlen)
15194 {
15195 c = *data++;
15196
15197 if (c == 0)
15198 break;
15199
15200 /* PR 25543: Treat new-lines as string-ending characters. */
15201 if (c == '\n')
15202 {
15203 printf ("\\n\n");
15204 if (*data != 0)
015dc7e1 15205 continuing = true;
ba3265d0
NC
15206 break;
15207 }
15208
15209 /* Do not print control characters directly as they can affect terminal
15210 settings. Such characters usually appear in the names generated
15211 by the assembler for local labels. */
15212 if (ISCNTRL (c))
15213 {
15214 printf ("^%c", c + 0x40);
15215 }
15216 else if (ISPRINT (c))
15217 {
15218 putchar (c);
15219 }
15220 else
15221 {
15222 size_t n;
15223#ifdef HAVE_MBSTATE_T
15224 wchar_t w;
15225#endif
15226 /* Let printf do the hard work of displaying multibyte characters. */
15227 printf ("%.1s", data - 1);
15228#ifdef HAVE_MBSTATE_T
15229 /* Try to find out how many bytes made up the character that was
15230 just printed. Advance the symbol pointer past the bytes that
15231 were displayed. */
15232 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15233#else
15234 n = 1;
15235#endif
15236 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15237 data += (n - 1);
15238 }
15239 }
15240
15241 if (c != '\n')
15242 putchar ('\n');
4082ef84
NC
15243 }
15244 else
15245 {
15246 printf (_("<corrupt>\n"));
15247 data = end;
15248 }
015dc7e1 15249 some_strings_shown = true;
cf13d699
NC
15250 }
15251 }
15252
15253 if (! some_strings_shown)
15254 printf (_(" No strings found in this section."));
15255
0e602686 15256 free (real_start);
cf13d699
NC
15257
15258 putchar ('\n');
015dc7e1 15259 return true;
f761cb13
AM
15260
15261error_out:
15262 free (real_start);
015dc7e1 15263 return false;
cf13d699
NC
15264}
15265
015dc7e1
AM
15266static bool
15267dump_section_as_bytes (Elf_Internal_Shdr *section,
15268 Filedata *filedata,
15269 bool relocate)
cf13d699
NC
15270{
15271 Elf_Internal_Shdr * relsec;
0e602686
NC
15272 bfd_size_type bytes;
15273 bfd_size_type section_size;
15274 bfd_vma addr;
15275 unsigned char * data;
15276 unsigned char * real_start;
15277 unsigned char * start;
15278
dda8d76d 15279 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15280 if (start == NULL)
c6b78c96 15281 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15282 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15283
0e602686 15284 section_size = section->sh_size;
cf13d699 15285
835f2fae
NC
15286 if (filedata->is_separate)
15287 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15288 printable_section_name (filedata, section),
15289 filedata->file_name);
15290 else
15291 printf (_("\nHex dump of section '%s':\n"),
15292 printable_section_name (filedata, section));
cf13d699 15293
0e602686
NC
15294 if (decompress_dumps)
15295 {
15296 dwarf_size_type new_size = section_size;
15297 dwarf_size_type uncompressed_size = 0;
15298
15299 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15300 {
15301 Elf_Internal_Chdr chdr;
15302 unsigned int compression_header_size
ebdf1ebf 15303 = get_compression_header (& chdr, start, section_size);
0e602686 15304
5844b465
NC
15305 if (compression_header_size == 0)
15306 /* An error message will have already been generated
15307 by get_compression_header. */
15308 goto error_out;
15309
813dabb9 15310 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15311 {
813dabb9 15312 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15313 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15314 goto error_out;
0e602686 15315 }
813dabb9
L
15316 uncompressed_size = chdr.ch_size;
15317 start += compression_header_size;
15318 new_size -= compression_header_size;
0e602686
NC
15319 }
15320 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15321 {
15322 /* Read the zlib header. In this case, it should be "ZLIB"
15323 followed by the uncompressed section size, 8 bytes in
15324 big-endian order. */
15325 uncompressed_size = start[4]; uncompressed_size <<= 8;
15326 uncompressed_size += start[5]; uncompressed_size <<= 8;
15327 uncompressed_size += start[6]; uncompressed_size <<= 8;
15328 uncompressed_size += start[7]; uncompressed_size <<= 8;
15329 uncompressed_size += start[8]; uncompressed_size <<= 8;
15330 uncompressed_size += start[9]; uncompressed_size <<= 8;
15331 uncompressed_size += start[10]; uncompressed_size <<= 8;
15332 uncompressed_size += start[11];
15333 start += 12;
15334 new_size -= 12;
15335 }
15336
f055032e
NC
15337 if (uncompressed_size)
15338 {
15339 if (uncompress_section_contents (& start, uncompressed_size,
15340 & new_size))
bc303e5d
NC
15341 {
15342 section_size = new_size;
15343 }
f055032e
NC
15344 else
15345 {
15346 error (_("Unable to decompress section %s\n"),
dda8d76d 15347 printable_section_name (filedata, section));
bc303e5d 15348 /* FIXME: Print the section anyway ? */
f761cb13 15349 goto error_out;
f055032e
NC
15350 }
15351 }
bc303e5d
NC
15352 else
15353 start = real_start;
0e602686 15354 }
14ae95f2 15355
cf13d699
NC
15356 if (relocate)
15357 {
dda8d76d 15358 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15359 goto error_out;
cf13d699
NC
15360 }
15361 else
15362 {
15363 /* If the section being dumped has relocations against it the user might
15364 be expecting these relocations to have been applied. Check for this
15365 case and issue a warning message in order to avoid confusion.
15366 FIXME: Maybe we ought to have an option that dumps a section with
15367 relocs applied ? */
dda8d76d
NC
15368 for (relsec = filedata->section_headers;
15369 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15370 ++relsec)
15371 {
15372 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15373 || relsec->sh_info >= filedata->file_header.e_shnum
15374 || filedata->section_headers + relsec->sh_info != section
cf13d699 15375 || relsec->sh_size == 0
dda8d76d 15376 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15377 continue;
15378
15379 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15380 break;
15381 }
15382 }
15383
15384 addr = section->sh_addr;
0e602686 15385 bytes = section_size;
cf13d699
NC
15386 data = start;
15387
15388 while (bytes)
15389 {
15390 int j;
15391 int k;
15392 int lbytes;
15393
15394 lbytes = (bytes > 16 ? 16 : bytes);
15395
15396 printf (" 0x%8.8lx ", (unsigned long) addr);
15397
15398 for (j = 0; j < 16; j++)
15399 {
15400 if (j < lbytes)
15401 printf ("%2.2x", data[j]);
15402 else
15403 printf (" ");
15404
15405 if ((j & 3) == 3)
15406 printf (" ");
15407 }
15408
15409 for (j = 0; j < lbytes; j++)
15410 {
15411 k = data[j];
15412 if (k >= ' ' && k < 0x7f)
15413 printf ("%c", k);
15414 else
15415 printf (".");
15416 }
15417
15418 putchar ('\n');
15419
15420 data += lbytes;
15421 addr += lbytes;
15422 bytes -= lbytes;
15423 }
15424
0e602686 15425 free (real_start);
cf13d699
NC
15426
15427 putchar ('\n');
015dc7e1 15428 return true;
f761cb13
AM
15429
15430 error_out:
15431 free (real_start);
015dc7e1 15432 return false;
cf13d699
NC
15433}
15434
094e34f2 15435#ifdef ENABLE_LIBCTF
7d9813f1
NA
15436static ctf_sect_t *
15437shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15438{
84714f86 15439 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15440 buf->cts_size = shdr->sh_size;
15441 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15442
15443 return buf;
15444}
15445
15446/* Formatting callback function passed to ctf_dump. Returns either the pointer
15447 it is passed, or a pointer to newly-allocated storage, in which case
15448 dump_ctf() will free it when it no longer needs it. */
15449
2f6ecaed
NA
15450static char *
15451dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15452 char *s, void *arg)
7d9813f1 15453{
3e50a591 15454 const char *blanks = arg;
7d9813f1
NA
15455 char *new_s;
15456
3e50a591 15457 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15458 return s;
15459 return new_s;
15460}
15461
926c9e76
NA
15462/* Dump CTF errors/warnings. */
15463static void
139633c3 15464dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15465{
15466 ctf_next_t *it = NULL;
15467 char *errtext;
15468 int is_warning;
15469 int err;
15470
15471 /* Dump accumulated errors and warnings. */
15472 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15473 {
5e9b84f7 15474 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15475 errtext);
15476 free (errtext);
15477 }
15478 if (err != ECTF_NEXT_END)
15479 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15480}
15481
2f6ecaed
NA
15482/* Dump one CTF archive member. */
15483
80b56fad
NA
15484static void
15485dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15486 size_t member)
2f6ecaed 15487{
2f6ecaed
NA
15488 const char *things[] = {"Header", "Labels", "Data objects",
15489 "Function objects", "Variables", "Types", "Strings",
15490 ""};
15491 const char **thing;
15492 size_t i;
15493
80b56fad
NA
15494 /* Don't print out the name of the default-named archive member if it appears
15495 first in the list. The name .ctf appears everywhere, even for things that
15496 aren't really archives, so printing it out is liable to be confusing; also,
15497 the common case by far is for only one archive member to exist, and hiding
15498 it in that case seems worthwhile. */
2f6ecaed 15499
80b56fad
NA
15500 if (strcmp (name, ".ctf") != 0 || member != 0)
15501 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15502
80b56fad
NA
15503 if (ctf_parent_name (ctf) != NULL)
15504 ctf_import (ctf, parent);
2f6ecaed
NA
15505
15506 for (i = 0, thing = things; *thing[0]; thing++, i++)
15507 {
15508 ctf_dump_state_t *s = NULL;
15509 char *item;
15510
15511 printf ("\n %s:\n", *thing);
15512 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15513 (void *) " ")) != NULL)
15514 {
15515 printf ("%s\n", item);
15516 free (item);
15517 }
15518
15519 if (ctf_errno (ctf))
15520 {
15521 error (_("Iteration failed: %s, %s\n"), *thing,
15522 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15523 break;
2f6ecaed
NA
15524 }
15525 }
8b37e7b6 15526
926c9e76 15527 dump_ctf_errs (ctf);
2f6ecaed
NA
15528}
15529
015dc7e1 15530static bool
7d9813f1
NA
15531dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15532{
7d9813f1
NA
15533 Elf_Internal_Shdr * symtab_sec = NULL;
15534 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15535 void * data = NULL;
15536 void * symdata = NULL;
15537 void * strdata = NULL;
80b56fad 15538 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15539 ctf_sect_t * symsectp = NULL;
15540 ctf_sect_t * strsectp = NULL;
2f6ecaed 15541 ctf_archive_t * ctfa = NULL;
139633c3 15542 ctf_dict_t * parent = NULL;
80b56fad 15543 ctf_dict_t * fp;
7d9813f1 15544
80b56fad
NA
15545 ctf_next_t *i = NULL;
15546 const char *name;
15547 size_t member = 0;
7d9813f1 15548 int err;
015dc7e1 15549 bool ret = false;
7d9813f1
NA
15550
15551 shdr_to_ctf_sect (&ctfsect, section, filedata);
15552 data = get_section_contents (section, filedata);
15553 ctfsect.cts_data = data;
15554
616febde 15555 if (!dump_ctf_symtab_name)
3d16b64e 15556 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15557
15558 if (!dump_ctf_strtab_name)
3d16b64e 15559 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15560
15561 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15562 {
15563 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15564 {
15565 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15566 goto fail;
15567 }
15568 if ((symdata = (void *) get_data (NULL, filedata,
15569 symtab_sec->sh_offset, 1,
15570 symtab_sec->sh_size,
15571 _("symbols"))) == NULL)
15572 goto fail;
15573 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15574 symsect.cts_data = symdata;
15575 }
835f2fae 15576
df16e041 15577 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15578 {
15579 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15580 {
15581 error (_("No string table section named %s\n"),
15582 dump_ctf_strtab_name);
15583 goto fail;
15584 }
15585 if ((strdata = (void *) get_data (NULL, filedata,
15586 strtab_sec->sh_offset, 1,
15587 strtab_sec->sh_size,
15588 _("strings"))) == NULL)
15589 goto fail;
15590 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15591 strsect.cts_data = strdata;
15592 }
835f2fae 15593
2f6ecaed
NA
15594 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15595 libctf papers over the difference, so we can pretend it is always an
80b56fad 15596 archive. */
7d9813f1 15597
2f6ecaed 15598 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15599 {
926c9e76 15600 dump_ctf_errs (NULL);
7d9813f1
NA
15601 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15602 goto fail;
15603 }
15604
96c61be5
NA
15605 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15606 != ELFDATA2MSB);
15607
80b56fad
NA
15608 /* Preload the parent dict, since it will need to be imported into every
15609 child in turn. */
15610 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15611 {
926c9e76 15612 dump_ctf_errs (NULL);
2f6ecaed
NA
15613 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15614 goto fail;
7d9813f1
NA
15615 }
15616
015dc7e1 15617 ret = true;
7d9813f1 15618
835f2fae
NC
15619 if (filedata->is_separate)
15620 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15621 printable_section_name (filedata, section),
15622 filedata->file_name);
15623 else
15624 printf (_("\nDump of CTF section '%s':\n"),
15625 printable_section_name (filedata, section));
7d9813f1 15626
80b56fad
NA
15627 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15628 dump_ctf_archive_member (fp, name, parent, member++);
15629 if (err != ECTF_NEXT_END)
15630 {
15631 dump_ctf_errs (NULL);
15632 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15633 ret = false;
15634 }
7d9813f1
NA
15635
15636 fail:
139633c3 15637 ctf_dict_close (parent);
2f6ecaed 15638 ctf_close (ctfa);
7d9813f1
NA
15639 free (data);
15640 free (symdata);
15641 free (strdata);
15642 return ret;
15643}
094e34f2 15644#endif
7d9813f1 15645
015dc7e1 15646static bool
dda8d76d
NC
15647load_specific_debug_section (enum dwarf_section_display_enum debug,
15648 const Elf_Internal_Shdr * sec,
15649 void * data)
1007acb3 15650{
2cf0635d 15651 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15652 char buf [64];
dda8d76d 15653 Filedata * filedata = (Filedata *) data;
9abca702 15654
19e6b90e 15655 if (section->start != NULL)
dda8d76d
NC
15656 {
15657 /* If it is already loaded, do nothing. */
15658 if (streq (section->filename, filedata->file_name))
015dc7e1 15659 return true;
dda8d76d
NC
15660 free (section->start);
15661 }
1007acb3 15662
19e6b90e
L
15663 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15664 section->address = sec->sh_addr;
dda8d76d
NC
15665 section->filename = filedata->file_name;
15666 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15667 sec->sh_offset, 1,
15668 sec->sh_size, buf);
59245841
NC
15669 if (section->start == NULL)
15670 section->size = 0;
15671 else
15672 {
77115a4a
L
15673 unsigned char *start = section->start;
15674 dwarf_size_type size = sec->sh_size;
dab394de 15675 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15676
15677 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15678 {
15679 Elf_Internal_Chdr chdr;
d8024a91
NC
15680 unsigned int compression_header_size;
15681
f53be977
L
15682 if (size < (is_32bit_elf
15683 ? sizeof (Elf32_External_Chdr)
15684 : sizeof (Elf64_External_Chdr)))
d8024a91 15685 {
55be8fd0 15686 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15687 section->name);
015dc7e1 15688 return false;
d8024a91
NC
15689 }
15690
ebdf1ebf 15691 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15692 if (compression_header_size == 0)
15693 /* An error message will have already been generated
15694 by get_compression_header. */
015dc7e1 15695 return false;
d8024a91 15696
813dabb9
L
15697 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15698 {
15699 warn (_("section '%s' has unsupported compress type: %d\n"),
15700 section->name, chdr.ch_type);
015dc7e1 15701 return false;
813dabb9 15702 }
dab394de 15703 uncompressed_size = chdr.ch_size;
77115a4a
L
15704 start += compression_header_size;
15705 size -= compression_header_size;
15706 }
dab394de
L
15707 else if (size > 12 && streq ((char *) start, "ZLIB"))
15708 {
15709 /* Read the zlib header. In this case, it should be "ZLIB"
15710 followed by the uncompressed section size, 8 bytes in
15711 big-endian order. */
15712 uncompressed_size = start[4]; uncompressed_size <<= 8;
15713 uncompressed_size += start[5]; uncompressed_size <<= 8;
15714 uncompressed_size += start[6]; uncompressed_size <<= 8;
15715 uncompressed_size += start[7]; uncompressed_size <<= 8;
15716 uncompressed_size += start[8]; uncompressed_size <<= 8;
15717 uncompressed_size += start[9]; uncompressed_size <<= 8;
15718 uncompressed_size += start[10]; uncompressed_size <<= 8;
15719 uncompressed_size += start[11];
15720 start += 12;
15721 size -= 12;
15722 }
15723
1835f746 15724 if (uncompressed_size)
77115a4a 15725 {
1835f746
NC
15726 if (uncompress_section_contents (&start, uncompressed_size,
15727 &size))
15728 {
15729 /* Free the compressed buffer, update the section buffer
15730 and the section size if uncompress is successful. */
15731 free (section->start);
15732 section->start = start;
15733 }
15734 else
15735 {
15736 error (_("Unable to decompress section %s\n"),
dda8d76d 15737 printable_section_name (filedata, sec));
015dc7e1 15738 return false;
1835f746 15739 }
77115a4a 15740 }
bc303e5d 15741
77115a4a 15742 section->size = size;
59245841 15743 }
4a114e3e 15744
1b315056 15745 if (section->start == NULL)
015dc7e1 15746 return false;
1b315056 15747
19e6b90e 15748 if (debug_displays [debug].relocate)
32ec8896 15749 {
dda8d76d 15750 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15751 & section->reloc_info, & section->num_relocs))
015dc7e1 15752 return false;
32ec8896 15753 }
d1c4b12b
NC
15754 else
15755 {
15756 section->reloc_info = NULL;
15757 section->num_relocs = 0;
15758 }
1007acb3 15759
015dc7e1 15760 return true;
1007acb3
L
15761}
15762
301a9420
AM
15763#if HAVE_LIBDEBUGINFOD
15764/* Return a hex string representation of the build-id. */
15765unsigned char *
15766get_build_id (void * data)
15767{
ca0e11aa 15768 Filedata * filedata = (Filedata *) data;
301a9420
AM
15769 Elf_Internal_Shdr * shdr;
15770 unsigned long i;
15771
55be8fd0
NC
15772 /* Iterate through notes to find note.gnu.build-id.
15773 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15774 for (i = 0, shdr = filedata->section_headers;
15775 i < filedata->file_header.e_shnum && shdr != NULL;
15776 i++, shdr++)
15777 {
15778 if (shdr->sh_type != SHT_NOTE)
15779 continue;
15780
15781 char * next;
15782 char * end;
15783 size_t data_remaining;
15784 size_t min_notesz;
15785 Elf_External_Note * enote;
15786 Elf_Internal_Note inote;
15787
15788 bfd_vma offset = shdr->sh_offset;
15789 bfd_vma align = shdr->sh_addralign;
15790 bfd_vma length = shdr->sh_size;
15791
15792 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15793 if (enote == NULL)
15794 continue;
15795
15796 if (align < 4)
15797 align = 4;
15798 else if (align != 4 && align != 8)
f761cb13
AM
15799 {
15800 free (enote);
15801 continue;
15802 }
301a9420
AM
15803
15804 end = (char *) enote + length;
15805 data_remaining = end - (char *) enote;
15806
15807 if (!is_ia64_vms (filedata))
15808 {
15809 min_notesz = offsetof (Elf_External_Note, name);
15810 if (data_remaining < min_notesz)
15811 {
55be8fd0
NC
15812 warn (_("\
15813malformed note encountered in section %s whilst scanning for build-id note\n"),
15814 printable_section_name (filedata, shdr));
f761cb13 15815 free (enote);
55be8fd0 15816 continue;
301a9420
AM
15817 }
15818 data_remaining -= min_notesz;
15819
15820 inote.type = BYTE_GET (enote->type);
15821 inote.namesz = BYTE_GET (enote->namesz);
15822 inote.namedata = enote->name;
15823 inote.descsz = BYTE_GET (enote->descsz);
15824 inote.descdata = ((char *) enote
15825 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15826 inote.descpos = offset + (inote.descdata - (char *) enote);
15827 next = ((char *) enote
15828 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15829 }
15830 else
15831 {
15832 Elf64_External_VMS_Note *vms_enote;
15833
15834 /* PR binutils/15191
15835 Make sure that there is enough data to read. */
15836 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15837 if (data_remaining < min_notesz)
15838 {
55be8fd0
NC
15839 warn (_("\
15840malformed note encountered in section %s whilst scanning for build-id note\n"),
15841 printable_section_name (filedata, shdr));
f761cb13 15842 free (enote);
55be8fd0 15843 continue;
301a9420
AM
15844 }
15845 data_remaining -= min_notesz;
15846
15847 vms_enote = (Elf64_External_VMS_Note *) enote;
15848 inote.type = BYTE_GET (vms_enote->type);
15849 inote.namesz = BYTE_GET (vms_enote->namesz);
15850 inote.namedata = vms_enote->name;
15851 inote.descsz = BYTE_GET (vms_enote->descsz);
15852 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15853 inote.descpos = offset + (inote.descdata - (char *) enote);
15854 next = inote.descdata + align_power (inote.descsz, 3);
15855 }
15856
15857 /* Skip malformed notes. */
15858 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15859 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15860 || (size_t) (next - inote.descdata) < inote.descsz
15861 || ((size_t) (next - inote.descdata)
15862 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15863 {
55be8fd0
NC
15864 warn (_("\
15865malformed note encountered in section %s whilst scanning for build-id note\n"),
15866 printable_section_name (filedata, shdr));
f761cb13 15867 free (enote);
301a9420
AM
15868 continue;
15869 }
15870
15871 /* Check if this is the build-id note. If so then convert the build-id
15872 bytes to a hex string. */
15873 if (inote.namesz > 0
24d127aa 15874 && startswith (inote.namedata, "GNU")
301a9420
AM
15875 && inote.type == NT_GNU_BUILD_ID)
15876 {
15877 unsigned long j;
15878 char * build_id;
15879
15880 build_id = malloc (inote.descsz * 2 + 1);
15881 if (build_id == NULL)
f761cb13
AM
15882 {
15883 free (enote);
15884 return NULL;
15885 }
301a9420
AM
15886
15887 for (j = 0; j < inote.descsz; ++j)
15888 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15889 build_id[inote.descsz * 2] = '\0';
f761cb13 15890 free (enote);
301a9420 15891
55be8fd0 15892 return (unsigned char *) build_id;
301a9420 15893 }
f761cb13 15894 free (enote);
301a9420
AM
15895 }
15896
15897 return NULL;
15898}
15899#endif /* HAVE_LIBDEBUGINFOD */
15900
657d0d47
CC
15901/* If this is not NULL, load_debug_section will only look for sections
15902 within the list of sections given here. */
32ec8896 15903static unsigned int * section_subset = NULL;
657d0d47 15904
015dc7e1 15905bool
dda8d76d 15906load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15907{
2cf0635d
NC
15908 struct dwarf_section * section = &debug_displays [debug].section;
15909 Elf_Internal_Shdr * sec;
dda8d76d
NC
15910 Filedata * filedata = (Filedata *) data;
15911
f425ec66
NC
15912 /* Without section headers we cannot find any sections. */
15913 if (filedata->section_headers == NULL)
015dc7e1 15914 return false;
f425ec66 15915
9c1ce108
AM
15916 if (filedata->string_table == NULL
15917 && filedata->file_header.e_shstrndx != SHN_UNDEF
15918 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15919 {
15920 Elf_Internal_Shdr * strs;
15921
15922 /* Read in the string table, so that we have section names to scan. */
15923 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15924
4dff97b2 15925 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15926 {
9c1ce108
AM
15927 filedata->string_table
15928 = (char *) get_data (NULL, filedata, strs->sh_offset,
15929 1, strs->sh_size, _("string table"));
dda8d76d 15930
9c1ce108
AM
15931 filedata->string_table_length
15932 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15933 }
15934 }
d966045b
DJ
15935
15936 /* Locate the debug section. */
dda8d76d 15937 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15938 if (sec != NULL)
15939 section->name = section->uncompressed_name;
15940 else
15941 {
dda8d76d 15942 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15943 if (sec != NULL)
15944 section->name = section->compressed_name;
15945 }
15946 if (sec == NULL)
015dc7e1 15947 return false;
d966045b 15948
657d0d47
CC
15949 /* If we're loading from a subset of sections, and we've loaded
15950 a section matching this name before, it's likely that it's a
15951 different one. */
15952 if (section_subset != NULL)
15953 free_debug_section (debug);
15954
dda8d76d 15955 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15956}
15957
19e6b90e
L
15958void
15959free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15960{
2cf0635d 15961 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15962
19e6b90e
L
15963 if (section->start == NULL)
15964 return;
1007acb3 15965
19e6b90e
L
15966 free ((char *) section->start);
15967 section->start = NULL;
15968 section->address = 0;
15969 section->size = 0;
a788aedd 15970
9db70fc3
AM
15971 free (section->reloc_info);
15972 section->reloc_info = NULL;
15973 section->num_relocs = 0;
1007acb3
L
15974}
15975
015dc7e1 15976static bool
dda8d76d 15977display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15978{
84714f86
AM
15979 const char *name = (section_name_valid (filedata, section)
15980 ? section_name (filedata, section) : "");
15981 const char *print_name = printable_section_name (filedata, section);
19e6b90e 15982 bfd_size_type length;
015dc7e1 15983 bool result = true;
3f5e193b 15984 int i;
1007acb3 15985
19e6b90e
L
15986 length = section->sh_size;
15987 if (length == 0)
1007acb3 15988 {
74e1a04b 15989 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15990 return true;
1007acb3 15991 }
5dff79d8
NC
15992 if (section->sh_type == SHT_NOBITS)
15993 {
15994 /* There is no point in dumping the contents of a debugging section
15995 which has the NOBITS type - the bits in the file will be random.
15996 This can happen when a file containing a .eh_frame section is
15997 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15998 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15999 print_name);
015dc7e1 16000 return false;
5dff79d8 16001 }
1007acb3 16002
24d127aa 16003 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16004 name = ".debug_info";
1007acb3 16005
19e6b90e
L
16006 /* See if we know how to display the contents of this section. */
16007 for (i = 0; i < max; i++)
d85bf2ba
NC
16008 {
16009 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16010 struct dwarf_section_display * display = debug_displays + i;
16011 struct dwarf_section * sec = & display->section;
d966045b 16012
d85bf2ba 16013 if (streq (sec->uncompressed_name, name)
24d127aa 16014 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16015 || streq (sec->compressed_name, name))
16016 {
015dc7e1 16017 bool secondary = (section != find_section (filedata, name));
1007acb3 16018
d85bf2ba
NC
16019 if (secondary)
16020 free_debug_section (id);
dda8d76d 16021
24d127aa 16022 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16023 sec->name = name;
16024 else if (streq (sec->uncompressed_name, name))
16025 sec->name = sec->uncompressed_name;
16026 else
16027 sec->name = sec->compressed_name;
657d0d47 16028
d85bf2ba
NC
16029 if (load_specific_debug_section (id, section, filedata))
16030 {
16031 /* If this debug section is part of a CU/TU set in a .dwp file,
16032 restrict load_debug_section to the sections in that set. */
16033 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16034
d85bf2ba 16035 result &= display->display (sec, filedata);
657d0d47 16036
d85bf2ba 16037 section_subset = NULL;
1007acb3 16038
44266f36 16039 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16040 free_debug_section (id);
16041 }
16042 break;
16043 }
16044 }
1007acb3 16045
19e6b90e 16046 if (i == max)
1007acb3 16047 {
74e1a04b 16048 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16049 result = false;
1007acb3
L
16050 }
16051
19e6b90e 16052 return result;
5b18a4bc 16053}
103f02d3 16054
aef1f6d0
DJ
16055/* Set DUMP_SECTS for all sections where dumps were requested
16056 based on section name. */
16057
16058static void
dda8d76d 16059initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16060{
2cf0635d 16061 struct dump_list_entry * cur;
aef1f6d0
DJ
16062
16063 for (cur = dump_sects_byname; cur; cur = cur->next)
16064 {
16065 unsigned int i;
015dc7e1 16066 bool any = false;
aef1f6d0 16067
dda8d76d 16068 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16069 if (section_name_valid (filedata, filedata->section_headers + i)
16070 && streq (section_name (filedata, filedata->section_headers + i),
16071 cur->name))
aef1f6d0 16072 {
6431e409 16073 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16074 any = true;
aef1f6d0
DJ
16075 }
16076
835f2fae
NC
16077 if (!any && !filedata->is_separate)
16078 warn (_("Section '%s' was not dumped because it does not exist\n"),
16079 cur->name);
aef1f6d0
DJ
16080 }
16081}
16082
015dc7e1 16083static bool
dda8d76d 16084process_section_contents (Filedata * filedata)
5b18a4bc 16085{
2cf0635d 16086 Elf_Internal_Shdr * section;
19e6b90e 16087 unsigned int i;
015dc7e1 16088 bool res = true;
103f02d3 16089
19e6b90e 16090 if (! do_dump)
015dc7e1 16091 return true;
103f02d3 16092
dda8d76d 16093 initialise_dumps_byname (filedata);
aef1f6d0 16094
dda8d76d 16095 for (i = 0, section = filedata->section_headers;
6431e409 16096 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16097 i++, section++)
16098 {
6431e409 16099 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16100
d6bfbc39
NC
16101 if (filedata->is_separate && ! process_links)
16102 dump &= DEBUG_DUMP;
047c3dbf 16103
19e6b90e 16104#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16105 if (dump & DISASS_DUMP)
16106 {
16107 if (! disassemble_section (section, filedata))
015dc7e1 16108 res = false;
dda8d76d 16109 }
19e6b90e 16110#endif
dda8d76d 16111 if (dump & HEX_DUMP)
32ec8896 16112 {
015dc7e1
AM
16113 if (! dump_section_as_bytes (section, filedata, false))
16114 res = false;
32ec8896 16115 }
103f02d3 16116
dda8d76d 16117 if (dump & RELOC_DUMP)
32ec8896 16118 {
015dc7e1
AM
16119 if (! dump_section_as_bytes (section, filedata, true))
16120 res = false;
32ec8896 16121 }
09c11c86 16122
dda8d76d 16123 if (dump & STRING_DUMP)
32ec8896 16124 {
dda8d76d 16125 if (! dump_section_as_strings (section, filedata))
015dc7e1 16126 res = false;
32ec8896 16127 }
cf13d699 16128
dda8d76d 16129 if (dump & DEBUG_DUMP)
32ec8896 16130 {
dda8d76d 16131 if (! display_debug_section (i, section, filedata))
015dc7e1 16132 res = false;
32ec8896 16133 }
7d9813f1 16134
094e34f2 16135#ifdef ENABLE_LIBCTF
7d9813f1
NA
16136 if (dump & CTF_DUMP)
16137 {
16138 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16139 res = false;
7d9813f1 16140 }
094e34f2 16141#endif
5b18a4bc 16142 }
103f02d3 16143
835f2fae 16144 if (! filedata->is_separate)
0ee3043f 16145 {
835f2fae
NC
16146 /* Check to see if the user requested a
16147 dump of a section that does not exist. */
16148 for (; i < filedata->dump.num_dump_sects; i++)
16149 if (filedata->dump.dump_sects[i])
16150 {
ca0e11aa 16151 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16152 res = false;
835f2fae 16153 }
0ee3043f 16154 }
32ec8896
NC
16155
16156 return res;
5b18a4bc 16157}
103f02d3 16158
5b18a4bc 16159static void
19e6b90e 16160process_mips_fpe_exception (int mask)
5b18a4bc 16161{
19e6b90e
L
16162 if (mask)
16163 {
015dc7e1 16164 bool first = true;
32ec8896 16165
19e6b90e 16166 if (mask & OEX_FPU_INEX)
015dc7e1 16167 fputs ("INEX", stdout), first = false;
19e6b90e 16168 if (mask & OEX_FPU_UFLO)
015dc7e1 16169 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16170 if (mask & OEX_FPU_OFLO)
015dc7e1 16171 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16172 if (mask & OEX_FPU_DIV0)
015dc7e1 16173 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16174 if (mask & OEX_FPU_INVAL)
16175 printf ("%sINVAL", first ? "" : "|");
16176 }
5b18a4bc 16177 else
19e6b90e 16178 fputs ("0", stdout);
5b18a4bc 16179}
103f02d3 16180
f6f0e17b
NC
16181/* Display's the value of TAG at location P. If TAG is
16182 greater than 0 it is assumed to be an unknown tag, and
16183 a message is printed to this effect. Otherwise it is
16184 assumed that a message has already been printed.
16185
16186 If the bottom bit of TAG is set it assumed to have a
16187 string value, otherwise it is assumed to have an integer
16188 value.
16189
16190 Returns an updated P pointing to the first unread byte
16191 beyond the end of TAG's value.
16192
16193 Reads at or beyond END will not be made. */
16194
16195static unsigned char *
60abdbed 16196display_tag_value (signed int tag,
f6f0e17b
NC
16197 unsigned char * p,
16198 const unsigned char * const end)
16199{
16200 unsigned long val;
16201
16202 if (tag > 0)
16203 printf (" Tag_unknown_%d: ", tag);
16204
16205 if (p >= end)
16206 {
4082ef84 16207 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16208 }
16209 else if (tag & 1)
16210 {
071436c6
NC
16211 /* PR 17531 file: 027-19978-0.004. */
16212 size_t maxlen = (end - p) - 1;
16213
16214 putchar ('"');
4082ef84
NC
16215 if (maxlen > 0)
16216 {
16217 print_symbol ((int) maxlen, (const char *) p);
16218 p += strnlen ((char *) p, maxlen) + 1;
16219 }
16220 else
16221 {
16222 printf (_("<corrupt string tag>"));
16223 p = (unsigned char *) end;
16224 }
071436c6 16225 printf ("\"\n");
f6f0e17b
NC
16226 }
16227 else
16228 {
cd30bcef 16229 READ_ULEB (val, p, end);
f6f0e17b
NC
16230 printf ("%ld (0x%lx)\n", val, val);
16231 }
16232
4082ef84 16233 assert (p <= end);
f6f0e17b
NC
16234 return p;
16235}
16236
53a346d8
CZ
16237/* ARC ABI attributes section. */
16238
16239static unsigned char *
16240display_arc_attribute (unsigned char * p,
16241 const unsigned char * const end)
16242{
16243 unsigned int tag;
53a346d8
CZ
16244 unsigned int val;
16245
cd30bcef 16246 READ_ULEB (tag, p, end);
53a346d8
CZ
16247
16248 switch (tag)
16249 {
16250 case Tag_ARC_PCS_config:
cd30bcef 16251 READ_ULEB (val, p, end);
53a346d8
CZ
16252 printf (" Tag_ARC_PCS_config: ");
16253 switch (val)
16254 {
16255 case 0:
16256 printf (_("Absent/Non standard\n"));
16257 break;
16258 case 1:
16259 printf (_("Bare metal/mwdt\n"));
16260 break;
16261 case 2:
16262 printf (_("Bare metal/newlib\n"));
16263 break;
16264 case 3:
16265 printf (_("Linux/uclibc\n"));
16266 break;
16267 case 4:
16268 printf (_("Linux/glibc\n"));
16269 break;
16270 default:
16271 printf (_("Unknown\n"));
16272 break;
16273 }
16274 break;
16275
16276 case Tag_ARC_CPU_base:
cd30bcef 16277 READ_ULEB (val, p, end);
53a346d8
CZ
16278 printf (" Tag_ARC_CPU_base: ");
16279 switch (val)
16280 {
16281 default:
16282 case TAG_CPU_NONE:
16283 printf (_("Absent\n"));
16284 break;
16285 case TAG_CPU_ARC6xx:
16286 printf ("ARC6xx\n");
16287 break;
16288 case TAG_CPU_ARC7xx:
16289 printf ("ARC7xx\n");
16290 break;
16291 case TAG_CPU_ARCEM:
16292 printf ("ARCEM\n");
16293 break;
16294 case TAG_CPU_ARCHS:
16295 printf ("ARCHS\n");
16296 break;
16297 }
16298 break;
16299
16300 case Tag_ARC_CPU_variation:
cd30bcef 16301 READ_ULEB (val, p, end);
53a346d8
CZ
16302 printf (" Tag_ARC_CPU_variation: ");
16303 switch (val)
16304 {
16305 default:
16306 if (val > 0 && val < 16)
53a346d8 16307 printf ("Core%d\n", val);
d8cbc93b
JL
16308 else
16309 printf ("Unknown\n");
16310 break;
16311
53a346d8
CZ
16312 case 0:
16313 printf (_("Absent\n"));
16314 break;
16315 }
16316 break;
16317
16318 case Tag_ARC_CPU_name:
16319 printf (" Tag_ARC_CPU_name: ");
16320 p = display_tag_value (-1, p, end);
16321 break;
16322
16323 case Tag_ARC_ABI_rf16:
cd30bcef 16324 READ_ULEB (val, p, end);
53a346d8
CZ
16325 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16326 break;
16327
16328 case Tag_ARC_ABI_osver:
cd30bcef 16329 READ_ULEB (val, p, end);
53a346d8
CZ
16330 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16331 break;
16332
16333 case Tag_ARC_ABI_pic:
16334 case Tag_ARC_ABI_sda:
cd30bcef 16335 READ_ULEB (val, p, end);
53a346d8
CZ
16336 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16337 : " Tag_ARC_ABI_pic: ");
16338 switch (val)
16339 {
16340 case 0:
16341 printf (_("Absent\n"));
16342 break;
16343 case 1:
16344 printf ("MWDT\n");
16345 break;
16346 case 2:
16347 printf ("GNU\n");
16348 break;
16349 default:
16350 printf (_("Unknown\n"));
16351 break;
16352 }
16353 break;
16354
16355 case Tag_ARC_ABI_tls:
cd30bcef 16356 READ_ULEB (val, p, end);
53a346d8
CZ
16357 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16358 break;
16359
16360 case Tag_ARC_ABI_enumsize:
cd30bcef 16361 READ_ULEB (val, p, end);
53a346d8
CZ
16362 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16363 _("smallest"));
16364 break;
16365
16366 case Tag_ARC_ABI_exceptions:
cd30bcef 16367 READ_ULEB (val, p, end);
53a346d8
CZ
16368 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16369 : _("default"));
16370 break;
16371
16372 case Tag_ARC_ABI_double_size:
cd30bcef 16373 READ_ULEB (val, p, end);
53a346d8
CZ
16374 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16375 break;
16376
16377 case Tag_ARC_ISA_config:
16378 printf (" Tag_ARC_ISA_config: ");
16379 p = display_tag_value (-1, p, end);
16380 break;
16381
16382 case Tag_ARC_ISA_apex:
16383 printf (" Tag_ARC_ISA_apex: ");
16384 p = display_tag_value (-1, p, end);
16385 break;
16386
16387 case Tag_ARC_ISA_mpy_option:
cd30bcef 16388 READ_ULEB (val, p, end);
53a346d8
CZ
16389 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16390 break;
16391
db1e1b45 16392 case Tag_ARC_ATR_version:
cd30bcef 16393 READ_ULEB (val, p, end);
db1e1b45 16394 printf (" Tag_ARC_ATR_version: %d\n", val);
16395 break;
16396
53a346d8
CZ
16397 default:
16398 return display_tag_value (tag & 1, p, end);
16399 }
16400
16401 return p;
16402}
16403
11c1ff18
PB
16404/* ARM EABI attributes section. */
16405typedef struct
16406{
70e99720 16407 unsigned int tag;
2cf0635d 16408 const char * name;
11c1ff18 16409 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16410 unsigned int type;
288f0ba2 16411 const char *const *table;
11c1ff18
PB
16412} arm_attr_public_tag;
16413
288f0ba2 16414static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16415 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16416 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16417 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16418 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16419static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16420static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16421 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16422static const char *const arm_attr_tag_FP_arch[] =
bca38921 16423 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16424 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16425static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16426static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16427 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16428 "NEON for ARMv8.1"};
288f0ba2 16429static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16430 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16431 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16432static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16433 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16434static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16435 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16436static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16437 {"Absolute", "PC-relative", "None"};
288f0ba2 16438static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16439 {"None", "direct", "GOT-indirect"};
288f0ba2 16440static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16441 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16442static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16443static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16444 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16445static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16446static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16447static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16448 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16449static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16450 {"Unused", "small", "int", "forced to int"};
288f0ba2 16451static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16452 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16453static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16454 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16455static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16456 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16457static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16458 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16459 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16460static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16461 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16462 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16463static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16464static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16465 {"Not Allowed", "Allowed"};
288f0ba2 16466static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16467 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16468static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16469 {"Follow architecture", "Allowed"};
288f0ba2 16470static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16471 {"Not Allowed", "Allowed"};
288f0ba2 16472static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16473 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16474 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16475static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16476static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16477 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16478 "TrustZone and Virtualization Extensions"};
288f0ba2 16479static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16480 {"Not Allowed", "Allowed"};
11c1ff18 16481
288f0ba2 16482static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16483 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16484
99db83d0
AC
16485static const char * arm_attr_tag_PAC_extension[] =
16486 {"No PAC/AUT instructions",
16487 "PAC/AUT instructions permitted in the NOP space",
16488 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16489
4b535030
AC
16490static const char * arm_attr_tag_BTI_extension[] =
16491 {"BTI instructions not permitted",
16492 "BTI instructions permitted in the NOP space",
16493 "BTI instructions permitted in the NOP and in the non-NOP space"};
16494
b81ee92f
AC
16495static const char * arm_attr_tag_BTI_use[] =
16496 {"Compiled without branch target enforcement",
16497 "Compiled with branch target enforcement"};
16498
c9fed665
AC
16499static const char * arm_attr_tag_PACRET_use[] =
16500 {"Compiled without return address signing and authentication",
16501 "Compiled with return address signing and authentication"};
16502
11c1ff18
PB
16503#define LOOKUP(id, name) \
16504 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16505static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16506{
16507 {4, "CPU_raw_name", 1, NULL},
16508 {5, "CPU_name", 1, NULL},
16509 LOOKUP(6, CPU_arch),
16510 {7, "CPU_arch_profile", 0, NULL},
16511 LOOKUP(8, ARM_ISA_use),
16512 LOOKUP(9, THUMB_ISA_use),
75375b3e 16513 LOOKUP(10, FP_arch),
11c1ff18 16514 LOOKUP(11, WMMX_arch),
f5f53991
AS
16515 LOOKUP(12, Advanced_SIMD_arch),
16516 LOOKUP(13, PCS_config),
11c1ff18
PB
16517 LOOKUP(14, ABI_PCS_R9_use),
16518 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16519 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16520 LOOKUP(17, ABI_PCS_GOT_use),
16521 LOOKUP(18, ABI_PCS_wchar_t),
16522 LOOKUP(19, ABI_FP_rounding),
16523 LOOKUP(20, ABI_FP_denormal),
16524 LOOKUP(21, ABI_FP_exceptions),
16525 LOOKUP(22, ABI_FP_user_exceptions),
16526 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16527 {24, "ABI_align_needed", 0, NULL},
16528 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16529 LOOKUP(26, ABI_enum_size),
16530 LOOKUP(27, ABI_HardFP_use),
16531 LOOKUP(28, ABI_VFP_args),
16532 LOOKUP(29, ABI_WMMX_args),
16533 LOOKUP(30, ABI_optimization_goals),
16534 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16535 {32, "compatibility", 0, NULL},
f5f53991 16536 LOOKUP(34, CPU_unaligned_access),
75375b3e 16537 LOOKUP(36, FP_HP_extension),
8e79c3df 16538 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16539 LOOKUP(42, MPextension_use),
16540 LOOKUP(44, DIV_use),
15afaa63 16541 LOOKUP(46, DSP_extension),
a7ad558c 16542 LOOKUP(48, MVE_arch),
99db83d0 16543 LOOKUP(50, PAC_extension),
4b535030 16544 LOOKUP(52, BTI_extension),
b81ee92f 16545 LOOKUP(74, BTI_use),
c9fed665 16546 LOOKUP(76, PACRET_use),
f5f53991
AS
16547 {64, "nodefaults", 0, NULL},
16548 {65, "also_compatible_with", 0, NULL},
16549 LOOKUP(66, T2EE_use),
16550 {67, "conformance", 1, NULL},
16551 LOOKUP(68, Virtualization_use),
cd21e546 16552 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16553};
16554#undef LOOKUP
16555
11c1ff18 16556static unsigned char *
f6f0e17b
NC
16557display_arm_attribute (unsigned char * p,
16558 const unsigned char * const end)
11c1ff18 16559{
70e99720 16560 unsigned int tag;
70e99720 16561 unsigned int val;
2cf0635d 16562 arm_attr_public_tag * attr;
11c1ff18 16563 unsigned i;
70e99720 16564 unsigned int type;
11c1ff18 16565
cd30bcef 16566 READ_ULEB (tag, p, end);
11c1ff18 16567 attr = NULL;
2cf0635d 16568 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16569 {
16570 if (arm_attr_public_tags[i].tag == tag)
16571 {
16572 attr = &arm_attr_public_tags[i];
16573 break;
16574 }
16575 }
16576
16577 if (attr)
16578 {
16579 printf (" Tag_%s: ", attr->name);
16580 switch (attr->type)
16581 {
16582 case 0:
16583 switch (tag)
16584 {
16585 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16586 READ_ULEB (val, p, end);
11c1ff18
PB
16587 switch (val)
16588 {
2b692964
NC
16589 case 0: printf (_("None\n")); break;
16590 case 'A': printf (_("Application\n")); break;
16591 case 'R': printf (_("Realtime\n")); break;
16592 case 'M': printf (_("Microcontroller\n")); break;
16593 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16594 default: printf ("??? (%d)\n", val); break;
16595 }
16596 break;
16597
75375b3e 16598 case 24: /* Tag_align_needed. */
cd30bcef 16599 READ_ULEB (val, p, end);
75375b3e
MGD
16600 switch (val)
16601 {
2b692964
NC
16602 case 0: printf (_("None\n")); break;
16603 case 1: printf (_("8-byte\n")); break;
16604 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16605 case 3: printf ("??? 3\n"); break;
16606 default:
16607 if (val <= 12)
dd24e3da 16608 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16609 1 << val);
16610 else
16611 printf ("??? (%d)\n", val);
16612 break;
16613 }
16614 break;
16615
16616 case 25: /* Tag_align_preserved. */
cd30bcef 16617 READ_ULEB (val, p, end);
75375b3e
MGD
16618 switch (val)
16619 {
2b692964
NC
16620 case 0: printf (_("None\n")); break;
16621 case 1: printf (_("8-byte, except leaf SP\n")); break;
16622 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16623 case 3: printf ("??? 3\n"); break;
16624 default:
16625 if (val <= 12)
dd24e3da 16626 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16627 1 << val);
16628 else
16629 printf ("??? (%d)\n", val);
16630 break;
16631 }
16632 break;
16633
11c1ff18 16634 case 32: /* Tag_compatibility. */
071436c6 16635 {
cd30bcef 16636 READ_ULEB (val, p, end);
071436c6 16637 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16638 if (p < end - 1)
16639 {
16640 size_t maxlen = (end - p) - 1;
16641
16642 print_symbol ((int) maxlen, (const char *) p);
16643 p += strnlen ((char *) p, maxlen) + 1;
16644 }
16645 else
16646 {
16647 printf (_("<corrupt>"));
16648 p = (unsigned char *) end;
16649 }
071436c6 16650 putchar ('\n');
071436c6 16651 }
11c1ff18
PB
16652 break;
16653
f5f53991 16654 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16655 /* PR 17531: file: 001-505008-0.01. */
16656 if (p < end)
16657 p++;
2b692964 16658 printf (_("True\n"));
f5f53991
AS
16659 break;
16660
16661 case 65: /* Tag_also_compatible_with. */
cd30bcef 16662 READ_ULEB (val, p, end);
f5f53991
AS
16663 if (val == 6 /* Tag_CPU_arch. */)
16664 {
cd30bcef 16665 READ_ULEB (val, p, end);
071436c6 16666 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16667 printf ("??? (%d)\n", val);
16668 else
16669 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16670 }
16671 else
16672 printf ("???\n");
071436c6
NC
16673 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16674 ;
f5f53991
AS
16675 break;
16676
11c1ff18 16677 default:
bee0ee85
NC
16678 printf (_("<unknown: %d>\n"), tag);
16679 break;
11c1ff18
PB
16680 }
16681 return p;
16682
16683 case 1:
f6f0e17b 16684 return display_tag_value (-1, p, end);
11c1ff18 16685 case 2:
f6f0e17b 16686 return display_tag_value (0, p, end);
11c1ff18
PB
16687
16688 default:
16689 assert (attr->type & 0x80);
cd30bcef 16690 READ_ULEB (val, p, end);
11c1ff18
PB
16691 type = attr->type & 0x7f;
16692 if (val >= type)
16693 printf ("??? (%d)\n", val);
16694 else
16695 printf ("%s\n", attr->table[val]);
16696 return p;
16697 }
16698 }
11c1ff18 16699
f6f0e17b 16700 return display_tag_value (tag, p, end);
11c1ff18
PB
16701}
16702
104d59d1 16703static unsigned char *
60bca95a 16704display_gnu_attribute (unsigned char * p,
60abdbed 16705 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16706 const unsigned char * const end)
104d59d1 16707{
cd30bcef 16708 unsigned int tag;
60abdbed 16709 unsigned int val;
104d59d1 16710
cd30bcef 16711 READ_ULEB (tag, p, end);
104d59d1
JM
16712
16713 /* Tag_compatibility is the only generic GNU attribute defined at
16714 present. */
16715 if (tag == 32)
16716 {
cd30bcef 16717 READ_ULEB (val, p, end);
071436c6
NC
16718
16719 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16720 if (p == end)
16721 {
071436c6 16722 printf (_("<corrupt>\n"));
f6f0e17b
NC
16723 warn (_("corrupt vendor attribute\n"));
16724 }
16725 else
16726 {
4082ef84
NC
16727 if (p < end - 1)
16728 {
16729 size_t maxlen = (end - p) - 1;
071436c6 16730
4082ef84
NC
16731 print_symbol ((int) maxlen, (const char *) p);
16732 p += strnlen ((char *) p, maxlen) + 1;
16733 }
16734 else
16735 {
16736 printf (_("<corrupt>"));
16737 p = (unsigned char *) end;
16738 }
071436c6 16739 putchar ('\n');
f6f0e17b 16740 }
104d59d1
JM
16741 return p;
16742 }
16743
16744 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16745 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16746
f6f0e17b 16747 return display_tag_value (tag, p, end);
104d59d1
JM
16748}
16749
85f7484a
PB
16750static unsigned char *
16751display_m68k_gnu_attribute (unsigned char * p,
16752 unsigned int tag,
16753 const unsigned char * const end)
16754{
16755 unsigned int val;
16756
16757 if (tag == Tag_GNU_M68K_ABI_FP)
16758 {
16759 printf (" Tag_GNU_M68K_ABI_FP: ");
16760 if (p == end)
16761 {
16762 printf (_("<corrupt>\n"));
16763 return p;
16764 }
16765 READ_ULEB (val, p, end);
16766
16767 if (val > 3)
16768 printf ("(%#x), ", val);
16769
16770 switch (val & 3)
16771 {
16772 case 0:
16773 printf (_("unspecified hard/soft float\n"));
16774 break;
16775 case 1:
16776 printf (_("hard float\n"));
16777 break;
16778 case 2:
16779 printf (_("soft float\n"));
16780 break;
16781 }
16782 return p;
16783 }
16784
16785 return display_tag_value (tag & 1, p, end);
16786}
16787
34c8bcba 16788static unsigned char *
f6f0e17b 16789display_power_gnu_attribute (unsigned char * p,
60abdbed 16790 unsigned int tag,
f6f0e17b 16791 const unsigned char * const end)
34c8bcba 16792{
005d79fd 16793 unsigned int val;
34c8bcba
JM
16794
16795 if (tag == Tag_GNU_Power_ABI_FP)
16796 {
34c8bcba 16797 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16798 if (p == end)
005d79fd
AM
16799 {
16800 printf (_("<corrupt>\n"));
16801 return p;
16802 }
cd30bcef 16803 READ_ULEB (val, p, end);
60bca95a 16804
005d79fd
AM
16805 if (val > 15)
16806 printf ("(%#x), ", val);
16807
16808 switch (val & 3)
34c8bcba
JM
16809 {
16810 case 0:
005d79fd 16811 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16812 break;
16813 case 1:
005d79fd 16814 printf (_("hard float, "));
34c8bcba
JM
16815 break;
16816 case 2:
005d79fd 16817 printf (_("soft float, "));
34c8bcba 16818 break;
3c7b9897 16819 case 3:
005d79fd 16820 printf (_("single-precision hard float, "));
3c7b9897 16821 break;
005d79fd
AM
16822 }
16823
16824 switch (val & 0xC)
16825 {
16826 case 0:
16827 printf (_("unspecified long double\n"));
16828 break;
16829 case 4:
16830 printf (_("128-bit IBM long double\n"));
16831 break;
16832 case 8:
16833 printf (_("64-bit long double\n"));
16834 break;
16835 case 12:
16836 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16837 break;
16838 }
16839 return p;
005d79fd 16840 }
34c8bcba 16841
c6e65352
DJ
16842 if (tag == Tag_GNU_Power_ABI_Vector)
16843 {
c6e65352 16844 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16845 if (p == end)
005d79fd
AM
16846 {
16847 printf (_("<corrupt>\n"));
16848 return p;
16849 }
cd30bcef 16850 READ_ULEB (val, p, end);
005d79fd
AM
16851
16852 if (val > 3)
16853 printf ("(%#x), ", val);
16854
16855 switch (val & 3)
c6e65352
DJ
16856 {
16857 case 0:
005d79fd 16858 printf (_("unspecified\n"));
c6e65352
DJ
16859 break;
16860 case 1:
005d79fd 16861 printf (_("generic\n"));
c6e65352
DJ
16862 break;
16863 case 2:
16864 printf ("AltiVec\n");
16865 break;
16866 case 3:
16867 printf ("SPE\n");
16868 break;
c6e65352
DJ
16869 }
16870 return p;
005d79fd 16871 }
c6e65352 16872
f82e0623
NF
16873 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16874 {
005d79fd 16875 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16876 if (p == end)
f6f0e17b 16877 {
005d79fd 16878 printf (_("<corrupt>\n"));
f6f0e17b
NC
16879 return p;
16880 }
cd30bcef 16881 READ_ULEB (val, p, end);
0b4362b0 16882
005d79fd
AM
16883 if (val > 2)
16884 printf ("(%#x), ", val);
16885
16886 switch (val & 3)
16887 {
16888 case 0:
16889 printf (_("unspecified\n"));
16890 break;
16891 case 1:
16892 printf ("r3/r4\n");
16893 break;
16894 case 2:
16895 printf (_("memory\n"));
16896 break;
16897 case 3:
16898 printf ("???\n");
16899 break;
16900 }
f82e0623
NF
16901 return p;
16902 }
16903
f6f0e17b 16904 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16905}
16906
643f7afb
AK
16907static unsigned char *
16908display_s390_gnu_attribute (unsigned char * p,
60abdbed 16909 unsigned int tag,
643f7afb
AK
16910 const unsigned char * const end)
16911{
cd30bcef 16912 unsigned int val;
643f7afb
AK
16913
16914 if (tag == Tag_GNU_S390_ABI_Vector)
16915 {
643f7afb 16916 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16917 READ_ULEB (val, p, end);
643f7afb
AK
16918
16919 switch (val)
16920 {
16921 case 0:
16922 printf (_("any\n"));
16923 break;
16924 case 1:
16925 printf (_("software\n"));
16926 break;
16927 case 2:
16928 printf (_("hardware\n"));
16929 break;
16930 default:
16931 printf ("??? (%d)\n", val);
16932 break;
16933 }
16934 return p;
16935 }
16936
16937 return display_tag_value (tag & 1, p, end);
16938}
16939
9e8c70f9 16940static void
60abdbed 16941display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16942{
16943 if (mask)
16944 {
015dc7e1 16945 bool first = true;
071436c6 16946
9e8c70f9 16947 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16948 fputs ("mul32", stdout), first = false;
9e8c70f9 16949 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16950 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16951 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16952 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16953 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16954 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16955 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16956 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16957 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16958 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16959 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16960 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16961 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16962 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16963 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16964 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16965 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16966 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16967 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16968 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16969 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16970 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16971 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16972 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16973 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16974 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16975 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16976 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16977 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16978 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16979 }
16980 else
071436c6
NC
16981 fputc ('0', stdout);
16982 fputc ('\n', stdout);
9e8c70f9
DM
16983}
16984
3d68f91c 16985static void
60abdbed 16986display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16987{
16988 if (mask)
16989 {
015dc7e1 16990 bool first = true;
071436c6 16991
3d68f91c 16992 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16993 fputs ("fjathplus", stdout), first = false;
3d68f91c 16994 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16995 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16996 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16997 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16998 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16999 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17000 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17001 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17002 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17003 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17004 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17005 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17006 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17007 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17008 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17009 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17010 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17011 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17012 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17013 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17014 }
17015 else
071436c6
NC
17016 fputc ('0', stdout);
17017 fputc ('\n', stdout);
3d68f91c
JM
17018}
17019
9e8c70f9 17020static unsigned char *
f6f0e17b 17021display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17022 unsigned int tag,
f6f0e17b 17023 const unsigned char * const end)
9e8c70f9 17024{
cd30bcef 17025 unsigned int val;
3d68f91c 17026
9e8c70f9
DM
17027 if (tag == Tag_GNU_Sparc_HWCAPS)
17028 {
cd30bcef 17029 READ_ULEB (val, p, end);
9e8c70f9 17030 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17031 display_sparc_hwcaps (val);
17032 return p;
3d68f91c
JM
17033 }
17034 if (tag == Tag_GNU_Sparc_HWCAPS2)
17035 {
cd30bcef 17036 READ_ULEB (val, p, end);
3d68f91c
JM
17037 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17038 display_sparc_hwcaps2 (val);
17039 return p;
17040 }
9e8c70f9 17041
f6f0e17b 17042 return display_tag_value (tag, p, end);
9e8c70f9
DM
17043}
17044
351cdf24 17045static void
32ec8896 17046print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17047{
17048 switch (val)
17049 {
17050 case Val_GNU_MIPS_ABI_FP_ANY:
17051 printf (_("Hard or soft float\n"));
17052 break;
17053 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17054 printf (_("Hard float (double precision)\n"));
17055 break;
17056 case Val_GNU_MIPS_ABI_FP_SINGLE:
17057 printf (_("Hard float (single precision)\n"));
17058 break;
17059 case Val_GNU_MIPS_ABI_FP_SOFT:
17060 printf (_("Soft float\n"));
17061 break;
17062 case Val_GNU_MIPS_ABI_FP_OLD_64:
17063 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17064 break;
17065 case Val_GNU_MIPS_ABI_FP_XX:
17066 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17067 break;
17068 case Val_GNU_MIPS_ABI_FP_64:
17069 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17070 break;
17071 case Val_GNU_MIPS_ABI_FP_64A:
17072 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17073 break;
3350cc01
CM
17074 case Val_GNU_MIPS_ABI_FP_NAN2008:
17075 printf (_("NaN 2008 compatibility\n"));
17076 break;
351cdf24
MF
17077 default:
17078 printf ("??? (%d)\n", val);
17079 break;
17080 }
17081}
17082
2cf19d5c 17083static unsigned char *
f6f0e17b 17084display_mips_gnu_attribute (unsigned char * p,
60abdbed 17085 unsigned int tag,
f6f0e17b 17086 const unsigned char * const end)
2cf19d5c 17087{
2cf19d5c
JM
17088 if (tag == Tag_GNU_MIPS_ABI_FP)
17089 {
32ec8896 17090 unsigned int val;
f6f0e17b 17091
2cf19d5c 17092 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17093 READ_ULEB (val, p, end);
351cdf24 17094 print_mips_fp_abi_value (val);
2cf19d5c
JM
17095 return p;
17096 }
17097
a9f58168
CF
17098 if (tag == Tag_GNU_MIPS_ABI_MSA)
17099 {
32ec8896 17100 unsigned int val;
a9f58168 17101
a9f58168 17102 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17103 READ_ULEB (val, p, end);
a9f58168
CF
17104
17105 switch (val)
17106 {
17107 case Val_GNU_MIPS_ABI_MSA_ANY:
17108 printf (_("Any MSA or not\n"));
17109 break;
17110 case Val_GNU_MIPS_ABI_MSA_128:
17111 printf (_("128-bit MSA\n"));
17112 break;
17113 default:
17114 printf ("??? (%d)\n", val);
17115 break;
17116 }
17117 return p;
17118 }
17119
f6f0e17b 17120 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17121}
17122
59e6276b 17123static unsigned char *
f6f0e17b
NC
17124display_tic6x_attribute (unsigned char * p,
17125 const unsigned char * const end)
59e6276b 17126{
60abdbed 17127 unsigned int tag;
cd30bcef 17128 unsigned int val;
59e6276b 17129
cd30bcef 17130 READ_ULEB (tag, p, end);
59e6276b
JM
17131
17132 switch (tag)
17133 {
75fa6dc1 17134 case Tag_ISA:
75fa6dc1 17135 printf (" Tag_ISA: ");
cd30bcef 17136 READ_ULEB (val, p, end);
59e6276b
JM
17137
17138 switch (val)
17139 {
75fa6dc1 17140 case C6XABI_Tag_ISA_none:
59e6276b
JM
17141 printf (_("None\n"));
17142 break;
75fa6dc1 17143 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17144 printf ("C62x\n");
17145 break;
75fa6dc1 17146 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17147 printf ("C67x\n");
17148 break;
75fa6dc1 17149 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17150 printf ("C67x+\n");
17151 break;
75fa6dc1 17152 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17153 printf ("C64x\n");
17154 break;
75fa6dc1 17155 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17156 printf ("C64x+\n");
17157 break;
75fa6dc1 17158 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17159 printf ("C674x\n");
17160 break;
17161 default:
17162 printf ("??? (%d)\n", val);
17163 break;
17164 }
17165 return p;
17166
87779176 17167 case Tag_ABI_wchar_t:
87779176 17168 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17169 READ_ULEB (val, p, end);
87779176
JM
17170 switch (val)
17171 {
17172 case 0:
17173 printf (_("Not used\n"));
17174 break;
17175 case 1:
17176 printf (_("2 bytes\n"));
17177 break;
17178 case 2:
17179 printf (_("4 bytes\n"));
17180 break;
17181 default:
17182 printf ("??? (%d)\n", val);
17183 break;
17184 }
17185 return p;
17186
17187 case Tag_ABI_stack_align_needed:
87779176 17188 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17189 READ_ULEB (val, p, end);
87779176
JM
17190 switch (val)
17191 {
17192 case 0:
17193 printf (_("8-byte\n"));
17194 break;
17195 case 1:
17196 printf (_("16-byte\n"));
17197 break;
17198 default:
17199 printf ("??? (%d)\n", val);
17200 break;
17201 }
17202 return p;
17203
17204 case Tag_ABI_stack_align_preserved:
cd30bcef 17205 READ_ULEB (val, p, end);
87779176
JM
17206 printf (" Tag_ABI_stack_align_preserved: ");
17207 switch (val)
17208 {
17209 case 0:
17210 printf (_("8-byte\n"));
17211 break;
17212 case 1:
17213 printf (_("16-byte\n"));
17214 break;
17215 default:
17216 printf ("??? (%d)\n", val);
17217 break;
17218 }
17219 return p;
17220
b5593623 17221 case Tag_ABI_DSBT:
cd30bcef 17222 READ_ULEB (val, p, end);
b5593623
JM
17223 printf (" Tag_ABI_DSBT: ");
17224 switch (val)
17225 {
17226 case 0:
17227 printf (_("DSBT addressing not used\n"));
17228 break;
17229 case 1:
17230 printf (_("DSBT addressing used\n"));
17231 break;
17232 default:
17233 printf ("??? (%d)\n", val);
17234 break;
17235 }
17236 return p;
17237
87779176 17238 case Tag_ABI_PID:
cd30bcef 17239 READ_ULEB (val, p, end);
87779176
JM
17240 printf (" Tag_ABI_PID: ");
17241 switch (val)
17242 {
17243 case 0:
17244 printf (_("Data addressing position-dependent\n"));
17245 break;
17246 case 1:
17247 printf (_("Data addressing position-independent, GOT near DP\n"));
17248 break;
17249 case 2:
17250 printf (_("Data addressing position-independent, GOT far from DP\n"));
17251 break;
17252 default:
17253 printf ("??? (%d)\n", val);
17254 break;
17255 }
17256 return p;
17257
17258 case Tag_ABI_PIC:
cd30bcef 17259 READ_ULEB (val, p, end);
87779176
JM
17260 printf (" Tag_ABI_PIC: ");
17261 switch (val)
17262 {
17263 case 0:
17264 printf (_("Code addressing position-dependent\n"));
17265 break;
17266 case 1:
17267 printf (_("Code addressing position-independent\n"));
17268 break;
17269 default:
17270 printf ("??? (%d)\n", val);
17271 break;
17272 }
17273 return p;
17274
17275 case Tag_ABI_array_object_alignment:
cd30bcef 17276 READ_ULEB (val, p, end);
87779176
JM
17277 printf (" Tag_ABI_array_object_alignment: ");
17278 switch (val)
17279 {
17280 case 0:
17281 printf (_("8-byte\n"));
17282 break;
17283 case 1:
17284 printf (_("4-byte\n"));
17285 break;
17286 case 2:
17287 printf (_("16-byte\n"));
17288 break;
17289 default:
17290 printf ("??? (%d)\n", val);
17291 break;
17292 }
17293 return p;
17294
17295 case Tag_ABI_array_object_align_expected:
cd30bcef 17296 READ_ULEB (val, p, end);
87779176
JM
17297 printf (" Tag_ABI_array_object_align_expected: ");
17298 switch (val)
17299 {
17300 case 0:
17301 printf (_("8-byte\n"));
17302 break;
17303 case 1:
17304 printf (_("4-byte\n"));
17305 break;
17306 case 2:
17307 printf (_("16-byte\n"));
17308 break;
17309 default:
17310 printf ("??? (%d)\n", val);
17311 break;
17312 }
17313 return p;
17314
3cbd1c06 17315 case Tag_ABI_compatibility:
071436c6 17316 {
cd30bcef 17317 READ_ULEB (val, p, end);
071436c6 17318 printf (" Tag_ABI_compatibility: ");
071436c6 17319 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17320 if (p < end - 1)
17321 {
17322 size_t maxlen = (end - p) - 1;
17323
17324 print_symbol ((int) maxlen, (const char *) p);
17325 p += strnlen ((char *) p, maxlen) + 1;
17326 }
17327 else
17328 {
17329 printf (_("<corrupt>"));
17330 p = (unsigned char *) end;
17331 }
071436c6 17332 putchar ('\n');
071436c6
NC
17333 return p;
17334 }
87779176
JM
17335
17336 case Tag_ABI_conformance:
071436c6 17337 {
4082ef84
NC
17338 printf (" Tag_ABI_conformance: \"");
17339 if (p < end - 1)
17340 {
17341 size_t maxlen = (end - p) - 1;
071436c6 17342
4082ef84
NC
17343 print_symbol ((int) maxlen, (const char *) p);
17344 p += strnlen ((char *) p, maxlen) + 1;
17345 }
17346 else
17347 {
17348 printf (_("<corrupt>"));
17349 p = (unsigned char *) end;
17350 }
071436c6 17351 printf ("\"\n");
071436c6
NC
17352 return p;
17353 }
59e6276b
JM
17354 }
17355
f6f0e17b
NC
17356 return display_tag_value (tag, p, end);
17357}
59e6276b 17358
f6f0e17b 17359static void
60abdbed 17360display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17361{
17362 unsigned long addr = 0;
17363 size_t bytes = end - p;
17364
feceaa59 17365 assert (end >= p);
f6f0e17b 17366 while (bytes)
87779176 17367 {
f6f0e17b
NC
17368 int j;
17369 int k;
17370 int lbytes = (bytes > 16 ? 16 : bytes);
17371
17372 printf (" 0x%8.8lx ", addr);
17373
17374 for (j = 0; j < 16; j++)
17375 {
17376 if (j < lbytes)
17377 printf ("%2.2x", p[j]);
17378 else
17379 printf (" ");
17380
17381 if ((j & 3) == 3)
17382 printf (" ");
17383 }
17384
17385 for (j = 0; j < lbytes; j++)
17386 {
17387 k = p[j];
17388 if (k >= ' ' && k < 0x7f)
17389 printf ("%c", k);
17390 else
17391 printf (".");
17392 }
17393
17394 putchar ('\n');
17395
17396 p += lbytes;
17397 bytes -= lbytes;
17398 addr += lbytes;
87779176 17399 }
59e6276b 17400
f6f0e17b 17401 putchar ('\n');
59e6276b
JM
17402}
17403
13761a11 17404static unsigned char *
b0191216 17405display_msp430_attribute (unsigned char * p,
13761a11
NC
17406 const unsigned char * const end)
17407{
60abdbed
NC
17408 unsigned int val;
17409 unsigned int tag;
13761a11 17410
cd30bcef 17411 READ_ULEB (tag, p, end);
0b4362b0 17412
13761a11
NC
17413 switch (tag)
17414 {
17415 case OFBA_MSPABI_Tag_ISA:
13761a11 17416 printf (" Tag_ISA: ");
cd30bcef 17417 READ_ULEB (val, p, end);
13761a11
NC
17418 switch (val)
17419 {
17420 case 0: printf (_("None\n")); break;
17421 case 1: printf (_("MSP430\n")); break;
17422 case 2: printf (_("MSP430X\n")); break;
17423 default: printf ("??? (%d)\n", val); break;
17424 }
17425 break;
17426
17427 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17428 printf (" Tag_Code_Model: ");
cd30bcef 17429 READ_ULEB (val, p, end);
13761a11
NC
17430 switch (val)
17431 {
17432 case 0: printf (_("None\n")); break;
17433 case 1: printf (_("Small\n")); break;
17434 case 2: printf (_("Large\n")); break;
17435 default: printf ("??? (%d)\n", val); break;
17436 }
17437 break;
17438
17439 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17440 printf (" Tag_Data_Model: ");
cd30bcef 17441 READ_ULEB (val, p, end);
13761a11
NC
17442 switch (val)
17443 {
17444 case 0: printf (_("None\n")); break;
17445 case 1: printf (_("Small\n")); break;
17446 case 2: printf (_("Large\n")); break;
17447 case 3: printf (_("Restricted Large\n")); break;
17448 default: printf ("??? (%d)\n", val); break;
17449 }
17450 break;
17451
17452 default:
17453 printf (_(" <unknown tag %d>: "), tag);
17454
17455 if (tag & 1)
17456 {
071436c6 17457 putchar ('"');
4082ef84
NC
17458 if (p < end - 1)
17459 {
17460 size_t maxlen = (end - p) - 1;
17461
17462 print_symbol ((int) maxlen, (const char *) p);
17463 p += strnlen ((char *) p, maxlen) + 1;
17464 }
17465 else
17466 {
17467 printf (_("<corrupt>"));
17468 p = (unsigned char *) end;
17469 }
071436c6 17470 printf ("\"\n");
13761a11
NC
17471 }
17472 else
17473 {
cd30bcef 17474 READ_ULEB (val, p, end);
13761a11
NC
17475 printf ("%d (0x%x)\n", val, val);
17476 }
17477 break;
17478 }
17479
4082ef84 17480 assert (p <= end);
13761a11
NC
17481 return p;
17482}
17483
c0ea7c52
JL
17484static unsigned char *
17485display_msp430_gnu_attribute (unsigned char * p,
17486 unsigned int tag,
17487 const unsigned char * const end)
17488{
17489 if (tag == Tag_GNU_MSP430_Data_Region)
17490 {
cd30bcef 17491 unsigned int val;
c0ea7c52 17492
c0ea7c52 17493 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17494 READ_ULEB (val, p, end);
c0ea7c52
JL
17495
17496 switch (val)
17497 {
17498 case Val_GNU_MSP430_Data_Region_Any:
17499 printf (_("Any Region\n"));
17500 break;
17501 case Val_GNU_MSP430_Data_Region_Lower:
17502 printf (_("Lower Region Only\n"));
17503 break;
17504 default:
cd30bcef 17505 printf ("??? (%u)\n", val);
c0ea7c52
JL
17506 }
17507 return p;
17508 }
17509 return display_tag_value (tag & 1, p, end);
17510}
17511
2dc8dd17
JW
17512struct riscv_attr_tag_t {
17513 const char *name;
cd30bcef 17514 unsigned int tag;
2dc8dd17
JW
17515};
17516
17517static struct riscv_attr_tag_t riscv_attr_tag[] =
17518{
17519#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17520 T(arch),
17521 T(priv_spec),
17522 T(priv_spec_minor),
17523 T(priv_spec_revision),
17524 T(unaligned_access),
17525 T(stack_align),
17526#undef T
17527};
17528
17529static unsigned char *
17530display_riscv_attribute (unsigned char *p,
17531 const unsigned char * const end)
17532{
cd30bcef
AM
17533 unsigned int val;
17534 unsigned int tag;
2dc8dd17
JW
17535 struct riscv_attr_tag_t *attr = NULL;
17536 unsigned i;
17537
cd30bcef 17538 READ_ULEB (tag, p, end);
2dc8dd17
JW
17539
17540 /* Find the name of attribute. */
17541 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17542 {
17543 if (riscv_attr_tag[i].tag == tag)
17544 {
17545 attr = &riscv_attr_tag[i];
17546 break;
17547 }
17548 }
17549
17550 if (attr)
17551 printf (" %s: ", attr->name);
17552 else
17553 return display_tag_value (tag, p, end);
17554
17555 switch (tag)
17556 {
17557 case Tag_RISCV_priv_spec:
17558 case Tag_RISCV_priv_spec_minor:
17559 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17560 READ_ULEB (val, p, end);
17561 printf (_("%u\n"), val);
2dc8dd17
JW
17562 break;
17563 case Tag_RISCV_unaligned_access:
cd30bcef 17564 READ_ULEB (val, p, end);
2dc8dd17
JW
17565 switch (val)
17566 {
17567 case 0:
17568 printf (_("No unaligned access\n"));
17569 break;
17570 case 1:
17571 printf (_("Unaligned access\n"));
17572 break;
17573 }
17574 break;
17575 case Tag_RISCV_stack_align:
cd30bcef
AM
17576 READ_ULEB (val, p, end);
17577 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17578 break;
17579 case Tag_RISCV_arch:
17580 p = display_tag_value (-1, p, end);
17581 break;
17582 default:
17583 return display_tag_value (tag, p, end);
17584 }
17585
17586 return p;
17587}
17588
0861f561
CQ
17589static unsigned char *
17590display_csky_attribute (unsigned char * p,
17591 const unsigned char * const end)
17592{
17593 unsigned int tag;
17594 unsigned int val;
17595 READ_ULEB (tag, p, end);
17596
17597 if (tag >= Tag_CSKY_MAX)
17598 {
17599 return display_tag_value (-1, p, end);
17600 }
17601
17602 switch (tag)
17603 {
17604 case Tag_CSKY_ARCH_NAME:
17605 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17606 return display_tag_value (-1, p, end);
17607 case Tag_CSKY_CPU_NAME:
17608 printf (" Tag_CSKY_CPU_NAME:\t\t");
17609 return display_tag_value (-1, p, end);
17610
17611 case Tag_CSKY_ISA_FLAGS:
17612 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17613 return display_tag_value (0, p, end);
17614 case Tag_CSKY_ISA_EXT_FLAGS:
17615 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17616 return display_tag_value (0, p, end);
17617
17618 case Tag_CSKY_DSP_VERSION:
17619 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17620 READ_ULEB (val, p, end);
17621 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17622 printf ("DSP Extension\n");
17623 else if (val == VAL_CSKY_DSP_VERSION_2)
17624 printf ("DSP 2.0\n");
17625 break;
17626
17627 case Tag_CSKY_VDSP_VERSION:
17628 printf (" Tag_CSKY_VDSP_VERSION:\t");
17629 READ_ULEB (val, p, end);
17630 printf ("VDSP Version %d\n", val);
17631 break;
17632
17633 case Tag_CSKY_FPU_VERSION:
17634 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17635 READ_ULEB (val, p, end);
17636 if (val == VAL_CSKY_FPU_VERSION_1)
17637 printf ("ABIV1 FPU Version 1\n");
17638 else if (val == VAL_CSKY_FPU_VERSION_2)
17639 printf ("FPU Version 2\n");
17640 break;
17641
17642 case Tag_CSKY_FPU_ABI:
17643 printf (" Tag_CSKY_FPU_ABI:\t\t");
17644 READ_ULEB (val, p, end);
17645 if (val == VAL_CSKY_FPU_ABI_HARD)
17646 printf ("Hard\n");
17647 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17648 printf ("SoftFP\n");
17649 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17650 printf ("Soft\n");
17651 break;
17652 case Tag_CSKY_FPU_ROUNDING:
17653 READ_ULEB (val, p, end);
f253158f
NC
17654 if (val == 1)
17655 {
17656 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17657 printf ("Needed\n");
17658 }
0861f561
CQ
17659 break;
17660 case Tag_CSKY_FPU_DENORMAL:
17661 READ_ULEB (val, p, end);
f253158f
NC
17662 if (val == 1)
17663 {
17664 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17665 printf ("Needed\n");
17666 }
0861f561
CQ
17667 break;
17668 case Tag_CSKY_FPU_Exception:
17669 READ_ULEB (val, p, end);
f253158f
NC
17670 if (val == 1)
17671 {
17672 printf (" Tag_CSKY_FPU_Exception:\t");
17673 printf ("Needed\n");
17674 }
0861f561
CQ
17675 break;
17676 case Tag_CSKY_FPU_NUMBER_MODULE:
17677 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17678 return display_tag_value (-1, p, end);
17679 case Tag_CSKY_FPU_HARDFP:
17680 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17681 READ_ULEB (val, p, end);
17682 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17683 printf (" Half");
17684 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17685 printf (" Single");
17686 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17687 printf (" Double");
17688 printf ("\n");
17689 break;
17690 default:
17691 return display_tag_value (tag, p, end);
17692 }
17693 return p;
17694}
17695
015dc7e1 17696static bool
dda8d76d 17697process_attributes (Filedata * filedata,
60bca95a 17698 const char * public_name,
104d59d1 17699 unsigned int proc_type,
f6f0e17b 17700 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17701 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17702{
2cf0635d 17703 Elf_Internal_Shdr * sect;
11c1ff18 17704 unsigned i;
015dc7e1 17705 bool res = true;
11c1ff18
PB
17706
17707 /* Find the section header so that we get the size. */
dda8d76d
NC
17708 for (i = 0, sect = filedata->section_headers;
17709 i < filedata->file_header.e_shnum;
11c1ff18
PB
17710 i++, sect++)
17711 {
071436c6
NC
17712 unsigned char * contents;
17713 unsigned char * p;
17714
104d59d1 17715 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17716 continue;
17717
dda8d76d 17718 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17719 sect->sh_size, _("attributes"));
60bca95a 17720 if (contents == NULL)
32ec8896 17721 {
015dc7e1 17722 res = false;
32ec8896
NC
17723 continue;
17724 }
60bca95a 17725
11c1ff18 17726 p = contents;
60abdbed
NC
17727 /* The first character is the version of the attributes.
17728 Currently only version 1, (aka 'A') is recognised here. */
17729 if (*p != 'A')
32ec8896
NC
17730 {
17731 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17732 res = false;
32ec8896 17733 }
60abdbed 17734 else
11c1ff18 17735 {
071436c6
NC
17736 bfd_vma section_len;
17737
17738 section_len = sect->sh_size - 1;
11c1ff18 17739 p++;
60bca95a 17740
071436c6 17741 while (section_len > 0)
11c1ff18 17742 {
071436c6 17743 bfd_vma attr_len;
e9847026 17744 unsigned int namelen;
015dc7e1
AM
17745 bool public_section;
17746 bool gnu_section;
11c1ff18 17747
071436c6 17748 if (section_len <= 4)
e0a31db1
NC
17749 {
17750 error (_("Tag section ends prematurely\n"));
015dc7e1 17751 res = false;
e0a31db1
NC
17752 break;
17753 }
071436c6 17754 attr_len = byte_get (p, 4);
11c1ff18 17755 p += 4;
60bca95a 17756
071436c6 17757 if (attr_len > section_len)
11c1ff18 17758 {
071436c6
NC
17759 error (_("Bad attribute length (%u > %u)\n"),
17760 (unsigned) attr_len, (unsigned) section_len);
17761 attr_len = section_len;
015dc7e1 17762 res = false;
11c1ff18 17763 }
74e1a04b 17764 /* PR 17531: file: 001-101425-0.004 */
071436c6 17765 else if (attr_len < 5)
74e1a04b 17766 {
071436c6 17767 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17768 res = false;
74e1a04b
NC
17769 break;
17770 }
e9847026 17771
071436c6
NC
17772 section_len -= attr_len;
17773 attr_len -= 4;
17774
17775 namelen = strnlen ((char *) p, attr_len) + 1;
17776 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17777 {
17778 error (_("Corrupt attribute section name\n"));
015dc7e1 17779 res = false;
e9847026
NC
17780 break;
17781 }
17782
071436c6
NC
17783 printf (_("Attribute Section: "));
17784 print_symbol (INT_MAX, (const char *) p);
17785 putchar ('\n');
60bca95a
NC
17786
17787 if (public_name && streq ((char *) p, public_name))
015dc7e1 17788 public_section = true;
11c1ff18 17789 else
015dc7e1 17790 public_section = false;
60bca95a
NC
17791
17792 if (streq ((char *) p, "gnu"))
015dc7e1 17793 gnu_section = true;
104d59d1 17794 else
015dc7e1 17795 gnu_section = false;
60bca95a 17796
11c1ff18 17797 p += namelen;
071436c6 17798 attr_len -= namelen;
e0a31db1 17799
071436c6 17800 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17801 {
e0a31db1 17802 int tag;
cd30bcef 17803 unsigned int val;
11c1ff18 17804 bfd_vma size;
071436c6 17805 unsigned char * end;
60bca95a 17806
e0a31db1 17807 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17808 if (attr_len < 6)
e0a31db1
NC
17809 {
17810 error (_("Unused bytes at end of section\n"));
015dc7e1 17811 res = false;
e0a31db1
NC
17812 section_len = 0;
17813 break;
17814 }
17815
17816 tag = *(p++);
11c1ff18 17817 size = byte_get (p, 4);
071436c6 17818 if (size > attr_len)
11c1ff18 17819 {
e9847026 17820 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17821 (unsigned) size, (unsigned) attr_len);
015dc7e1 17822 res = false;
071436c6 17823 size = attr_len;
11c1ff18 17824 }
e0a31db1
NC
17825 /* PR binutils/17531: Safe handling of corrupt files. */
17826 if (size < 6)
17827 {
17828 error (_("Bad subsection length (%u < 6)\n"),
17829 (unsigned) size);
015dc7e1 17830 res = false;
e0a31db1
NC
17831 section_len = 0;
17832 break;
17833 }
60bca95a 17834
071436c6 17835 attr_len -= size;
11c1ff18 17836 end = p + size - 1;
071436c6 17837 assert (end <= contents + sect->sh_size);
11c1ff18 17838 p += 4;
60bca95a 17839
11c1ff18
PB
17840 switch (tag)
17841 {
17842 case 1:
2b692964 17843 printf (_("File Attributes\n"));
11c1ff18
PB
17844 break;
17845 case 2:
2b692964 17846 printf (_("Section Attributes:"));
11c1ff18
PB
17847 goto do_numlist;
17848 case 3:
2b692964 17849 printf (_("Symbol Attributes:"));
1a0670f3 17850 /* Fall through. */
11c1ff18
PB
17851 do_numlist:
17852 for (;;)
17853 {
cd30bcef 17854 READ_ULEB (val, p, end);
11c1ff18
PB
17855 if (val == 0)
17856 break;
17857 printf (" %d", val);
17858 }
17859 printf ("\n");
17860 break;
17861 default:
2b692964 17862 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17863 public_section = false;
11c1ff18
PB
17864 break;
17865 }
60bca95a 17866
071436c6 17867 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17868 {
17869 while (p < end)
f6f0e17b 17870 p = display_pub_attribute (p, end);
60abdbed 17871 assert (p == end);
104d59d1 17872 }
071436c6 17873 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17874 {
17875 while (p < end)
17876 p = display_gnu_attribute (p,
f6f0e17b
NC
17877 display_proc_gnu_attribute,
17878 end);
60abdbed 17879 assert (p == end);
11c1ff18 17880 }
071436c6 17881 else if (p < end)
11c1ff18 17882 {
071436c6 17883 printf (_(" Unknown attribute:\n"));
f6f0e17b 17884 display_raw_attribute (p, end);
11c1ff18
PB
17885 p = end;
17886 }
071436c6
NC
17887 else
17888 attr_len = 0;
11c1ff18
PB
17889 }
17890 }
17891 }
d70c5fc7 17892
60bca95a 17893 free (contents);
11c1ff18 17894 }
32ec8896
NC
17895
17896 return res;
11c1ff18
PB
17897}
17898
ccb4c951
RS
17899/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17900 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17901 and return the VMA of the next entry, or -1 if there was a problem.
17902 Does not read from DATA_END or beyond. */
ccb4c951
RS
17903
17904static bfd_vma
82b1b41b
NC
17905print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17906 unsigned char * data_end)
ccb4c951
RS
17907{
17908 printf (" ");
17909 print_vma (addr, LONG_HEX);
17910 printf (" ");
17911 if (addr < pltgot + 0xfff0)
17912 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17913 else
17914 printf ("%10s", "");
17915 printf (" ");
17916 if (data == NULL)
2b692964 17917 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17918 else
17919 {
17920 bfd_vma entry;
82b1b41b 17921 unsigned char * from = data + addr - pltgot;
ccb4c951 17922
82b1b41b
NC
17923 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17924 {
17925 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17926 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17927 return (bfd_vma) -1;
17928 }
17929 else
17930 {
17931 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17932 print_vma (entry, LONG_HEX);
17933 }
ccb4c951
RS
17934 }
17935 return addr + (is_32bit_elf ? 4 : 8);
17936}
17937
861fb55a
DJ
17938/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17939 PLTGOT. Print the Address and Initial fields of an entry at VMA
17940 ADDR and return the VMA of the next entry. */
17941
17942static bfd_vma
2cf0635d 17943print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17944{
17945 printf (" ");
17946 print_vma (addr, LONG_HEX);
17947 printf (" ");
17948 if (data == NULL)
2b692964 17949 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17950 else
17951 {
17952 bfd_vma entry;
17953
17954 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17955 print_vma (entry, LONG_HEX);
17956 }
17957 return addr + (is_32bit_elf ? 4 : 8);
17958}
17959
351cdf24
MF
17960static void
17961print_mips_ases (unsigned int mask)
17962{
17963 if (mask & AFL_ASE_DSP)
17964 fputs ("\n\tDSP ASE", stdout);
17965 if (mask & AFL_ASE_DSPR2)
17966 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17967 if (mask & AFL_ASE_DSPR3)
17968 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17969 if (mask & AFL_ASE_EVA)
17970 fputs ("\n\tEnhanced VA Scheme", stdout);
17971 if (mask & AFL_ASE_MCU)
17972 fputs ("\n\tMCU (MicroController) ASE", stdout);
17973 if (mask & AFL_ASE_MDMX)
17974 fputs ("\n\tMDMX ASE", stdout);
17975 if (mask & AFL_ASE_MIPS3D)
17976 fputs ("\n\tMIPS-3D ASE", stdout);
17977 if (mask & AFL_ASE_MT)
17978 fputs ("\n\tMT ASE", stdout);
17979 if (mask & AFL_ASE_SMARTMIPS)
17980 fputs ("\n\tSmartMIPS ASE", stdout);
17981 if (mask & AFL_ASE_VIRT)
17982 fputs ("\n\tVZ ASE", stdout);
17983 if (mask & AFL_ASE_MSA)
17984 fputs ("\n\tMSA ASE", stdout);
17985 if (mask & AFL_ASE_MIPS16)
17986 fputs ("\n\tMIPS16 ASE", stdout);
17987 if (mask & AFL_ASE_MICROMIPS)
17988 fputs ("\n\tMICROMIPS ASE", stdout);
17989 if (mask & AFL_ASE_XPA)
17990 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17991 if (mask & AFL_ASE_MIPS16E2)
17992 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17993 if (mask & AFL_ASE_CRC)
17994 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17995 if (mask & AFL_ASE_GINV)
17996 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17997 if (mask & AFL_ASE_LOONGSON_MMI)
17998 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17999 if (mask & AFL_ASE_LOONGSON_CAM)
18000 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18001 if (mask & AFL_ASE_LOONGSON_EXT)
18002 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18003 if (mask & AFL_ASE_LOONGSON_EXT2)
18004 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18005 if (mask == 0)
18006 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18007 else if ((mask & ~AFL_ASE_MASK) != 0)
18008 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18009}
18010
18011static void
18012print_mips_isa_ext (unsigned int isa_ext)
18013{
18014 switch (isa_ext)
18015 {
18016 case 0:
18017 fputs (_("None"), stdout);
18018 break;
18019 case AFL_EXT_XLR:
18020 fputs ("RMI XLR", stdout);
18021 break;
2c629856
N
18022 case AFL_EXT_OCTEON3:
18023 fputs ("Cavium Networks Octeon3", stdout);
18024 break;
351cdf24
MF
18025 case AFL_EXT_OCTEON2:
18026 fputs ("Cavium Networks Octeon2", stdout);
18027 break;
18028 case AFL_EXT_OCTEONP:
18029 fputs ("Cavium Networks OcteonP", stdout);
18030 break;
351cdf24
MF
18031 case AFL_EXT_OCTEON:
18032 fputs ("Cavium Networks Octeon", stdout);
18033 break;
18034 case AFL_EXT_5900:
18035 fputs ("Toshiba R5900", stdout);
18036 break;
18037 case AFL_EXT_4650:
18038 fputs ("MIPS R4650", stdout);
18039 break;
18040 case AFL_EXT_4010:
18041 fputs ("LSI R4010", stdout);
18042 break;
18043 case AFL_EXT_4100:
18044 fputs ("NEC VR4100", stdout);
18045 break;
18046 case AFL_EXT_3900:
18047 fputs ("Toshiba R3900", stdout);
18048 break;
18049 case AFL_EXT_10000:
18050 fputs ("MIPS R10000", stdout);
18051 break;
18052 case AFL_EXT_SB1:
18053 fputs ("Broadcom SB-1", stdout);
18054 break;
18055 case AFL_EXT_4111:
18056 fputs ("NEC VR4111/VR4181", stdout);
18057 break;
18058 case AFL_EXT_4120:
18059 fputs ("NEC VR4120", stdout);
18060 break;
18061 case AFL_EXT_5400:
18062 fputs ("NEC VR5400", stdout);
18063 break;
18064 case AFL_EXT_5500:
18065 fputs ("NEC VR5500", stdout);
18066 break;
18067 case AFL_EXT_LOONGSON_2E:
18068 fputs ("ST Microelectronics Loongson 2E", stdout);
18069 break;
18070 case AFL_EXT_LOONGSON_2F:
18071 fputs ("ST Microelectronics Loongson 2F", stdout);
18072 break;
38bf472a
MR
18073 case AFL_EXT_INTERAPTIV_MR2:
18074 fputs ("Imagination interAptiv MR2", stdout);
18075 break;
351cdf24 18076 default:
00ac7aa0 18077 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18078 }
18079}
18080
32ec8896 18081static signed int
351cdf24
MF
18082get_mips_reg_size (int reg_size)
18083{
18084 return (reg_size == AFL_REG_NONE) ? 0
18085 : (reg_size == AFL_REG_32) ? 32
18086 : (reg_size == AFL_REG_64) ? 64
18087 : (reg_size == AFL_REG_128) ? 128
18088 : -1;
18089}
18090
015dc7e1 18091static bool
dda8d76d 18092process_mips_specific (Filedata * filedata)
5b18a4bc 18093{
2cf0635d 18094 Elf_Internal_Dyn * entry;
351cdf24 18095 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18096 size_t liblist_offset = 0;
18097 size_t liblistno = 0;
18098 size_t conflictsno = 0;
18099 size_t options_offset = 0;
18100 size_t conflicts_offset = 0;
861fb55a
DJ
18101 size_t pltrelsz = 0;
18102 size_t pltrel = 0;
ccb4c951 18103 bfd_vma pltgot = 0;
861fb55a
DJ
18104 bfd_vma mips_pltgot = 0;
18105 bfd_vma jmprel = 0;
ccb4c951
RS
18106 bfd_vma local_gotno = 0;
18107 bfd_vma gotsym = 0;
18108 bfd_vma symtabno = 0;
015dc7e1 18109 bool res = true;
103f02d3 18110
dda8d76d 18111 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18112 display_mips_gnu_attribute))
015dc7e1 18113 res = false;
2cf19d5c 18114
dda8d76d 18115 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18116
18117 if (sect != NULL)
18118 {
18119 Elf_External_ABIFlags_v0 *abiflags_ext;
18120 Elf_Internal_ABIFlags_v0 abiflags_in;
18121
18122 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18123 {
18124 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18125 res = false;
32ec8896 18126 }
351cdf24
MF
18127 else
18128 {
dda8d76d 18129 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18130 sect->sh_size, _("MIPS ABI Flags section"));
18131 if (abiflags_ext)
18132 {
18133 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18134 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18135 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18136 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18137 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18138 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18139 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18140 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18141 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18142 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18143 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18144
18145 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18146 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18147 if (abiflags_in.isa_rev > 1)
18148 printf ("r%d", abiflags_in.isa_rev);
18149 printf ("\nGPR size: %d",
18150 get_mips_reg_size (abiflags_in.gpr_size));
18151 printf ("\nCPR1 size: %d",
18152 get_mips_reg_size (abiflags_in.cpr1_size));
18153 printf ("\nCPR2 size: %d",
18154 get_mips_reg_size (abiflags_in.cpr2_size));
18155 fputs ("\nFP ABI: ", stdout);
18156 print_mips_fp_abi_value (abiflags_in.fp_abi);
18157 fputs ("ISA Extension: ", stdout);
18158 print_mips_isa_ext (abiflags_in.isa_ext);
18159 fputs ("\nASEs:", stdout);
18160 print_mips_ases (abiflags_in.ases);
18161 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18162 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18163 fputc ('\n', stdout);
18164 free (abiflags_ext);
18165 }
18166 }
18167 }
18168
19e6b90e 18169 /* We have a lot of special sections. Thanks SGI! */
978c4450 18170 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18171 {
18172 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18173 sect = find_section (filedata, ".got");
bbdd9a68
MR
18174 if (sect != NULL)
18175 {
18176 unsigned char *data_end;
18177 unsigned char *data;
18178 bfd_vma ent, end;
18179 int addr_size;
18180
18181 pltgot = sect->sh_addr;
18182
18183 ent = pltgot;
18184 addr_size = (is_32bit_elf ? 4 : 8);
18185 end = pltgot + sect->sh_size;
18186
dda8d76d 18187 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18188 end - pltgot, 1,
18189 _("Global Offset Table data"));
18190 /* PR 12855: Null data is handled gracefully throughout. */
18191 data_end = data + (end - pltgot);
18192
18193 printf (_("\nStatic GOT:\n"));
18194 printf (_(" Canonical gp value: "));
18195 print_vma (ent + 0x7ff0, LONG_HEX);
18196 printf ("\n\n");
18197
18198 /* In a dynamic binary GOT[0] is reserved for the dynamic
18199 loader to store the lazy resolver pointer, however in
18200 a static binary it may well have been omitted and GOT
18201 reduced to a table of addresses.
18202 PR 21344: Check for the entry being fully available
18203 before fetching it. */
18204 if (data
18205 && data + ent - pltgot + addr_size <= data_end
18206 && byte_get (data + ent - pltgot, addr_size) == 0)
18207 {
18208 printf (_(" Reserved entries:\n"));
18209 printf (_(" %*s %10s %*s\n"),
18210 addr_size * 2, _("Address"), _("Access"),
18211 addr_size * 2, _("Value"));
18212 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18213 printf ("\n");
18214 if (ent == (bfd_vma) -1)
18215 goto sgot_print_fail;
18216
18217 /* Check for the MSB of GOT[1] being set, identifying a
18218 GNU object. This entry will be used by some runtime
18219 loaders, to store the module pointer. Otherwise this
18220 is an ordinary local entry.
18221 PR 21344: Check for the entry being fully available
18222 before fetching it. */
18223 if (data
18224 && data + ent - pltgot + addr_size <= data_end
18225 && (byte_get (data + ent - pltgot, addr_size)
18226 >> (addr_size * 8 - 1)) != 0)
18227 {
18228 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18229 printf ("\n");
18230 if (ent == (bfd_vma) -1)
18231 goto sgot_print_fail;
18232 }
18233 printf ("\n");
18234 }
18235
f17e9d8a 18236 if (data != NULL && ent < end)
bbdd9a68
MR
18237 {
18238 printf (_(" Local entries:\n"));
18239 printf (" %*s %10s %*s\n",
18240 addr_size * 2, _("Address"), _("Access"),
18241 addr_size * 2, _("Value"));
18242 while (ent < end)
18243 {
18244 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18245 printf ("\n");
18246 if (ent == (bfd_vma) -1)
18247 goto sgot_print_fail;
18248 }
18249 printf ("\n");
18250 }
18251
18252 sgot_print_fail:
9db70fc3 18253 free (data);
bbdd9a68
MR
18254 }
18255 return res;
18256 }
252b5132 18257
978c4450 18258 for (entry = filedata->dynamic_section;
071436c6 18259 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18260 (entry < filedata->dynamic_section + filedata->dynamic_nent
18261 && entry->d_tag != DT_NULL);
071436c6 18262 ++entry)
252b5132
RH
18263 switch (entry->d_tag)
18264 {
18265 case DT_MIPS_LIBLIST:
d93f0186 18266 liblist_offset
dda8d76d 18267 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18268 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18269 break;
18270 case DT_MIPS_LIBLISTNO:
18271 liblistno = entry->d_un.d_val;
18272 break;
18273 case DT_MIPS_OPTIONS:
dda8d76d 18274 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18275 break;
18276 case DT_MIPS_CONFLICT:
d93f0186 18277 conflicts_offset
dda8d76d 18278 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18279 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18280 break;
18281 case DT_MIPS_CONFLICTNO:
18282 conflictsno = entry->d_un.d_val;
18283 break;
ccb4c951 18284 case DT_PLTGOT:
861fb55a
DJ
18285 pltgot = entry->d_un.d_ptr;
18286 break;
ccb4c951
RS
18287 case DT_MIPS_LOCAL_GOTNO:
18288 local_gotno = entry->d_un.d_val;
18289 break;
18290 case DT_MIPS_GOTSYM:
18291 gotsym = entry->d_un.d_val;
18292 break;
18293 case DT_MIPS_SYMTABNO:
18294 symtabno = entry->d_un.d_val;
18295 break;
861fb55a
DJ
18296 case DT_MIPS_PLTGOT:
18297 mips_pltgot = entry->d_un.d_ptr;
18298 break;
18299 case DT_PLTREL:
18300 pltrel = entry->d_un.d_val;
18301 break;
18302 case DT_PLTRELSZ:
18303 pltrelsz = entry->d_un.d_val;
18304 break;
18305 case DT_JMPREL:
18306 jmprel = entry->d_un.d_ptr;
18307 break;
252b5132
RH
18308 default:
18309 break;
18310 }
18311
18312 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18313 {
2cf0635d 18314 Elf32_External_Lib * elib;
252b5132
RH
18315 size_t cnt;
18316
dda8d76d 18317 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18318 sizeof (Elf32_External_Lib),
18319 liblistno,
18320 _("liblist section data"));
a6e9f9df 18321 if (elib)
252b5132 18322 {
d3a49aa8
AM
18323 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18324 "\nSection '.liblist' contains %lu entries:\n",
18325 (unsigned long) liblistno),
a6e9f9df 18326 (unsigned long) liblistno);
2b692964 18327 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18328 stdout);
18329
18330 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18331 {
a6e9f9df 18332 Elf32_Lib liblist;
91d6fa6a 18333 time_t atime;
d5b07ef4 18334 char timebuf[128];
2cf0635d 18335 struct tm * tmp;
a6e9f9df
AM
18336
18337 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18338 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18339 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18340 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18341 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18342
91d6fa6a 18343 tmp = gmtime (&atime);
e9e44622
JJ
18344 snprintf (timebuf, sizeof (timebuf),
18345 "%04u-%02u-%02uT%02u:%02u:%02u",
18346 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18347 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18348
31104126 18349 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18350 if (valid_dynamic_name (filedata, liblist.l_name))
18351 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18352 else
2b692964 18353 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18354 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18355 liblist.l_version);
a6e9f9df
AM
18356
18357 if (liblist.l_flags == 0)
2b692964 18358 puts (_(" NONE"));
a6e9f9df
AM
18359 else
18360 {
18361 static const struct
252b5132 18362 {
2cf0635d 18363 const char * name;
a6e9f9df 18364 int bit;
252b5132 18365 }
a6e9f9df
AM
18366 l_flags_vals[] =
18367 {
18368 { " EXACT_MATCH", LL_EXACT_MATCH },
18369 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18370 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18371 { " EXPORTS", LL_EXPORTS },
18372 { " DELAY_LOAD", LL_DELAY_LOAD },
18373 { " DELTA", LL_DELTA }
18374 };
18375 int flags = liblist.l_flags;
18376 size_t fcnt;
18377
60bca95a 18378 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18379 if ((flags & l_flags_vals[fcnt].bit) != 0)
18380 {
18381 fputs (l_flags_vals[fcnt].name, stdout);
18382 flags ^= l_flags_vals[fcnt].bit;
18383 }
18384 if (flags != 0)
18385 printf (" %#x", (unsigned int) flags);
252b5132 18386
a6e9f9df
AM
18387 puts ("");
18388 }
252b5132 18389 }
252b5132 18390
a6e9f9df
AM
18391 free (elib);
18392 }
32ec8896 18393 else
015dc7e1 18394 res = false;
252b5132
RH
18395 }
18396
18397 if (options_offset != 0)
18398 {
2cf0635d 18399 Elf_External_Options * eopt;
252b5132
RH
18400 size_t offset;
18401 int cnt;
18402
18403 /* Find the section header so that we get the size. */
dda8d76d 18404 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18405 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18406 if (sect == NULL)
18407 {
18408 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18409 return false;
071436c6 18410 }
7fc0c668
NC
18411 /* PR 24243 */
18412 if (sect->sh_size < sizeof (* eopt))
18413 {
18414 error (_("The MIPS options section is too small.\n"));
015dc7e1 18415 return false;
7fc0c668 18416 }
252b5132 18417
dda8d76d 18418 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18419 sect->sh_size, _("options"));
a6e9f9df 18420 if (eopt)
252b5132 18421 {
fd17d1e6 18422 Elf_Internal_Options option;
76da6bbe 18423
a6e9f9df 18424 offset = cnt = 0;
82b1b41b 18425 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18426 {
2cf0635d 18427 Elf_External_Options * eoption;
fd17d1e6 18428 unsigned int optsize;
252b5132 18429
a6e9f9df 18430 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18431
fd17d1e6 18432 optsize = BYTE_GET (eoption->size);
76da6bbe 18433
82b1b41b 18434 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18435 if (optsize < sizeof (* eopt)
18436 || optsize > sect->sh_size - offset)
82b1b41b 18437 {
645f43a8 18438 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18439 optsize);
645f43a8 18440 free (eopt);
015dc7e1 18441 return false;
82b1b41b 18442 }
fd17d1e6 18443 offset += optsize;
a6e9f9df
AM
18444 ++cnt;
18445 }
252b5132 18446
d3a49aa8
AM
18447 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18448 "\nSection '%s' contains %d entries:\n",
18449 cnt),
dda8d76d 18450 printable_section_name (filedata, sect), cnt);
76da6bbe 18451
82b1b41b 18452 offset = 0;
a6e9f9df 18453 while (cnt-- > 0)
252b5132 18454 {
a6e9f9df 18455 size_t len;
fd17d1e6
AM
18456 Elf_External_Options * eoption;
18457
18458 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18459
18460 option.kind = BYTE_GET (eoption->kind);
18461 option.size = BYTE_GET (eoption->size);
18462 option.section = BYTE_GET (eoption->section);
18463 option.info = BYTE_GET (eoption->info);
a6e9f9df 18464
fd17d1e6 18465 switch (option.kind)
252b5132 18466 {
a6e9f9df
AM
18467 case ODK_NULL:
18468 /* This shouldn't happen. */
d0c4e780 18469 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18470 option.section, option.info);
a6e9f9df 18471 break;
2e6be59c 18472
a6e9f9df
AM
18473 case ODK_REGINFO:
18474 printf (" REGINFO ");
dda8d76d 18475 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18476 {
2cf0635d 18477 Elf32_External_RegInfo * ereg;
b34976b6 18478 Elf32_RegInfo reginfo;
a6e9f9df 18479
2e6be59c 18480 /* 32bit form. */
fd17d1e6
AM
18481 if (option.size < (sizeof (Elf_External_Options)
18482 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18483 {
18484 printf (_("<corrupt>\n"));
18485 error (_("Truncated MIPS REGINFO option\n"));
18486 cnt = 0;
18487 break;
18488 }
18489
fd17d1e6 18490 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18491
a6e9f9df
AM
18492 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18493 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18494 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18495 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18496 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18497 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18498
d0c4e780
AM
18499 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18500 reginfo.ri_gprmask, reginfo.ri_gp_value);
18501 printf (" "
18502 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18503 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18504 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18505 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18506 }
18507 else
18508 {
18509 /* 64 bit form. */
2cf0635d 18510 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18511 Elf64_Internal_RegInfo reginfo;
18512
fd17d1e6
AM
18513 if (option.size < (sizeof (Elf_External_Options)
18514 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18515 {
18516 printf (_("<corrupt>\n"));
18517 error (_("Truncated MIPS REGINFO option\n"));
18518 cnt = 0;
18519 break;
18520 }
18521
fd17d1e6 18522 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18523 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18524 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18525 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18526 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18527 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18528 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18529
d0c4e780
AM
18530 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18531 reginfo.ri_gprmask, reginfo.ri_gp_value);
18532 printf (" "
18533 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18534 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18535 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18536 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18537 }
fd17d1e6 18538 offset += option.size;
a6e9f9df 18539 continue;
2e6be59c 18540
a6e9f9df
AM
18541 case ODK_EXCEPTIONS:
18542 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18543 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18544 fputs (") fpe_max(", stdout);
fd17d1e6 18545 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18546 fputs (")", stdout);
18547
fd17d1e6 18548 if (option.info & OEX_PAGE0)
a6e9f9df 18549 fputs (" PAGE0", stdout);
fd17d1e6 18550 if (option.info & OEX_SMM)
a6e9f9df 18551 fputs (" SMM", stdout);
fd17d1e6 18552 if (option.info & OEX_FPDBUG)
a6e9f9df 18553 fputs (" FPDBUG", stdout);
fd17d1e6 18554 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18555 fputs (" DISMISS", stdout);
18556 break;
2e6be59c 18557
a6e9f9df
AM
18558 case ODK_PAD:
18559 fputs (" PAD ", stdout);
fd17d1e6 18560 if (option.info & OPAD_PREFIX)
a6e9f9df 18561 fputs (" PREFIX", stdout);
fd17d1e6 18562 if (option.info & OPAD_POSTFIX)
a6e9f9df 18563 fputs (" POSTFIX", stdout);
fd17d1e6 18564 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18565 fputs (" SYMBOL", stdout);
18566 break;
2e6be59c 18567
a6e9f9df
AM
18568 case ODK_HWPATCH:
18569 fputs (" HWPATCH ", stdout);
fd17d1e6 18570 if (option.info & OHW_R4KEOP)
a6e9f9df 18571 fputs (" R4KEOP", stdout);
fd17d1e6 18572 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18573 fputs (" R8KPFETCH", stdout);
fd17d1e6 18574 if (option.info & OHW_R5KEOP)
a6e9f9df 18575 fputs (" R5KEOP", stdout);
fd17d1e6 18576 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18577 fputs (" R5KCVTL", stdout);
18578 break;
2e6be59c 18579
a6e9f9df
AM
18580 case ODK_FILL:
18581 fputs (" FILL ", stdout);
18582 /* XXX Print content of info word? */
18583 break;
2e6be59c 18584
a6e9f9df
AM
18585 case ODK_TAGS:
18586 fputs (" TAGS ", stdout);
18587 /* XXX Print content of info word? */
18588 break;
2e6be59c 18589
a6e9f9df
AM
18590 case ODK_HWAND:
18591 fputs (" HWAND ", stdout);
fd17d1e6 18592 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18593 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18594 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18595 fputs (" R4KEOP_CLEAN", stdout);
18596 break;
2e6be59c 18597
a6e9f9df
AM
18598 case ODK_HWOR:
18599 fputs (" HWOR ", stdout);
fd17d1e6 18600 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18601 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18602 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18603 fputs (" R4KEOP_CLEAN", stdout);
18604 break;
2e6be59c 18605
a6e9f9df 18606 case ODK_GP_GROUP:
d0c4e780 18607 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18608 option.info & OGP_GROUP,
18609 (option.info & OGP_SELF) >> 16);
a6e9f9df 18610 break;
2e6be59c 18611
a6e9f9df 18612 case ODK_IDENT:
d0c4e780 18613 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18614 option.info & OGP_GROUP,
18615 (option.info & OGP_SELF) >> 16);
a6e9f9df 18616 break;
2e6be59c 18617
a6e9f9df
AM
18618 default:
18619 /* This shouldn't happen. */
d0c4e780 18620 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18621 option.kind, option.section, option.info);
a6e9f9df 18622 break;
252b5132 18623 }
a6e9f9df 18624
2cf0635d 18625 len = sizeof (* eopt);
fd17d1e6 18626 while (len < option.size)
82b1b41b 18627 {
fd17d1e6 18628 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18629
82b1b41b
NC
18630 if (ISPRINT (datum))
18631 printf ("%c", datum);
18632 else
18633 printf ("\\%03o", datum);
18634 len ++;
18635 }
a6e9f9df 18636 fputs ("\n", stdout);
82b1b41b 18637
fd17d1e6 18638 offset += option.size;
252b5132 18639 }
a6e9f9df 18640 free (eopt);
252b5132 18641 }
32ec8896 18642 else
015dc7e1 18643 res = false;
252b5132
RH
18644 }
18645
18646 if (conflicts_offset != 0 && conflictsno != 0)
18647 {
2cf0635d 18648 Elf32_Conflict * iconf;
252b5132
RH
18649 size_t cnt;
18650
978c4450 18651 if (filedata->dynamic_symbols == NULL)
252b5132 18652 {
591a748a 18653 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18654 return false;
252b5132
RH
18655 }
18656
7296a62a
NC
18657 /* PR 21345 - print a slightly more helpful error message
18658 if we are sure that the cmalloc will fail. */
645f43a8 18659 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18660 {
18661 error (_("Overlarge number of conflicts detected: %lx\n"),
18662 (long) conflictsno);
015dc7e1 18663 return false;
7296a62a
NC
18664 }
18665
3f5e193b 18666 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18667 if (iconf == NULL)
18668 {
8b73c356 18669 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18670 return false;
252b5132
RH
18671 }
18672
9ea033b2 18673 if (is_32bit_elf)
252b5132 18674 {
2cf0635d 18675 Elf32_External_Conflict * econf32;
a6e9f9df 18676
3f5e193b 18677 econf32 = (Elf32_External_Conflict *)
95099889
AM
18678 get_data (NULL, filedata, conflicts_offset,
18679 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18680 if (!econf32)
5a814d6d
AM
18681 {
18682 free (iconf);
015dc7e1 18683 return false;
5a814d6d 18684 }
252b5132
RH
18685
18686 for (cnt = 0; cnt < conflictsno; ++cnt)
18687 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18688
18689 free (econf32);
252b5132
RH
18690 }
18691 else
18692 {
2cf0635d 18693 Elf64_External_Conflict * econf64;
a6e9f9df 18694
3f5e193b 18695 econf64 = (Elf64_External_Conflict *)
95099889
AM
18696 get_data (NULL, filedata, conflicts_offset,
18697 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18698 if (!econf64)
5a814d6d
AM
18699 {
18700 free (iconf);
015dc7e1 18701 return false;
5a814d6d 18702 }
252b5132
RH
18703
18704 for (cnt = 0; cnt < conflictsno; ++cnt)
18705 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18706
18707 free (econf64);
252b5132
RH
18708 }
18709
d3a49aa8
AM
18710 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18711 "\nSection '.conflict' contains %lu entries:\n",
18712 (unsigned long) conflictsno),
c7e7ca54 18713 (unsigned long) conflictsno);
252b5132
RH
18714 puts (_(" Num: Index Value Name"));
18715
18716 for (cnt = 0; cnt < conflictsno; ++cnt)
18717 {
b34976b6 18718 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18719
978c4450 18720 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18721 printf (_("<corrupt symbol index>"));
d79b3d50 18722 else
e0a31db1
NC
18723 {
18724 Elf_Internal_Sym * psym;
18725
978c4450 18726 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18727 print_vma (psym->st_value, FULL_HEX);
18728 putchar (' ');
84714f86
AM
18729 if (valid_dynamic_name (filedata, psym->st_name))
18730 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18731 else
18732 printf (_("<corrupt: %14ld>"), psym->st_name);
18733 }
31104126 18734 putchar ('\n');
252b5132
RH
18735 }
18736
252b5132
RH
18737 free (iconf);
18738 }
18739
ccb4c951
RS
18740 if (pltgot != 0 && local_gotno != 0)
18741 {
91d6fa6a 18742 bfd_vma ent, local_end, global_end;
bbeee7ea 18743 size_t i, offset;
2cf0635d 18744 unsigned char * data;
82b1b41b 18745 unsigned char * data_end;
bbeee7ea 18746 int addr_size;
ccb4c951 18747
91d6fa6a 18748 ent = pltgot;
ccb4c951
RS
18749 addr_size = (is_32bit_elf ? 4 : 8);
18750 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18751
74e1a04b
NC
18752 /* PR binutils/17533 file: 012-111227-0.004 */
18753 if (symtabno < gotsym)
18754 {
18755 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18756 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18757 return false;
74e1a04b 18758 }
82b1b41b 18759
74e1a04b 18760 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18761 /* PR 17531: file: 54c91a34. */
18762 if (global_end < local_end)
18763 {
18764 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18765 return false;
82b1b41b 18766 }
948f632f 18767
dda8d76d
NC
18768 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18769 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18770 global_end - pltgot, 1,
18771 _("Global Offset Table data"));
919383ac 18772 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18773 data_end = data + (global_end - pltgot);
59245841 18774
ccb4c951
RS
18775 printf (_("\nPrimary GOT:\n"));
18776 printf (_(" Canonical gp value: "));
18777 print_vma (pltgot + 0x7ff0, LONG_HEX);
18778 printf ("\n\n");
18779
18780 printf (_(" Reserved entries:\n"));
18781 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18782 addr_size * 2, _("Address"), _("Access"),
18783 addr_size * 2, _("Initial"));
82b1b41b 18784 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18785 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18786 if (ent == (bfd_vma) -1)
18787 goto got_print_fail;
75ec1fdb 18788
c4ab9505
MR
18789 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18790 This entry will be used by some runtime loaders, to store the
18791 module pointer. Otherwise this is an ordinary local entry.
18792 PR 21344: Check for the entry being fully available before
18793 fetching it. */
18794 if (data
18795 && data + ent - pltgot + addr_size <= data_end
18796 && (byte_get (data + ent - pltgot, addr_size)
18797 >> (addr_size * 8 - 1)) != 0)
18798 {
18799 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18800 printf (_(" Module pointer (GNU extension)\n"));
18801 if (ent == (bfd_vma) -1)
18802 goto got_print_fail;
ccb4c951
RS
18803 }
18804 printf ("\n");
18805
f17e9d8a 18806 if (data != NULL && ent < local_end)
ccb4c951
RS
18807 {
18808 printf (_(" Local entries:\n"));
cc5914eb 18809 printf (" %*s %10s %*s\n",
2b692964
NC
18810 addr_size * 2, _("Address"), _("Access"),
18811 addr_size * 2, _("Initial"));
91d6fa6a 18812 while (ent < local_end)
ccb4c951 18813 {
82b1b41b 18814 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18815 printf ("\n");
82b1b41b
NC
18816 if (ent == (bfd_vma) -1)
18817 goto got_print_fail;
ccb4c951
RS
18818 }
18819 printf ("\n");
18820 }
18821
f17e9d8a 18822 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18823 {
18824 int sym_width;
18825
18826 printf (_(" Global entries:\n"));
cc5914eb 18827 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18828 addr_size * 2, _("Address"),
18829 _("Access"),
2b692964 18830 addr_size * 2, _("Initial"),
9cf03b7e
NC
18831 addr_size * 2, _("Sym.Val."),
18832 _("Type"),
18833 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18834 _("Ndx"), _("Name"));
0b4362b0 18835
ccb4c951 18836 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18837
ccb4c951
RS
18838 for (i = gotsym; i < symtabno; i++)
18839 {
82b1b41b 18840 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18841 printf (" ");
e0a31db1 18842
978c4450 18843 if (filedata->dynamic_symbols == NULL)
e0a31db1 18844 printf (_("<no dynamic symbols>"));
978c4450 18845 else if (i < filedata->num_dynamic_syms)
e0a31db1 18846 {
978c4450 18847 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18848
18849 print_vma (psym->st_value, LONG_HEX);
18850 printf (" %-7s %3s ",
dda8d76d
NC
18851 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18852 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18853
84714f86 18854 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18855 print_symbol (sym_width,
84714f86 18856 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18857 else
18858 printf (_("<corrupt: %14ld>"), psym->st_name);
18859 }
ccb4c951 18860 else
7fc5ac57
JBG
18861 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18862 (unsigned long) i);
e0a31db1 18863
ccb4c951 18864 printf ("\n");
82b1b41b
NC
18865 if (ent == (bfd_vma) -1)
18866 break;
ccb4c951
RS
18867 }
18868 printf ("\n");
18869 }
18870
82b1b41b 18871 got_print_fail:
9db70fc3 18872 free (data);
ccb4c951
RS
18873 }
18874
861fb55a
DJ
18875 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18876 {
91d6fa6a 18877 bfd_vma ent, end;
861fb55a
DJ
18878 size_t offset, rel_offset;
18879 unsigned long count, i;
2cf0635d 18880 unsigned char * data;
861fb55a 18881 int addr_size, sym_width;
2cf0635d 18882 Elf_Internal_Rela * rels;
861fb55a 18883
dda8d76d 18884 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18885 if (pltrel == DT_RELA)
18886 {
dda8d76d 18887 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18888 return false;
861fb55a
DJ
18889 }
18890 else
18891 {
dda8d76d 18892 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18893 return false;
861fb55a
DJ
18894 }
18895
91d6fa6a 18896 ent = mips_pltgot;
861fb55a
DJ
18897 addr_size = (is_32bit_elf ? 4 : 8);
18898 end = mips_pltgot + (2 + count) * addr_size;
18899
dda8d76d
NC
18900 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18901 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18902 1, _("Procedure Linkage Table data"));
59245841 18903 if (data == NULL)
288f0ba2
AM
18904 {
18905 free (rels);
015dc7e1 18906 return false;
288f0ba2 18907 }
59245841 18908
9cf03b7e 18909 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18910 printf (_(" Reserved entries:\n"));
18911 printf (_(" %*s %*s Purpose\n"),
2b692964 18912 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18913 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18914 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18915 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18916 printf (_(" Module pointer\n"));
861fb55a
DJ
18917 printf ("\n");
18918
18919 printf (_(" Entries:\n"));
cc5914eb 18920 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18921 addr_size * 2, _("Address"),
18922 addr_size * 2, _("Initial"),
18923 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18924 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18925 for (i = 0; i < count; i++)
18926 {
df97ab2a 18927 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18928
91d6fa6a 18929 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18930 printf (" ");
e0a31db1 18931
978c4450 18932 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18933 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18934 else
e0a31db1 18935 {
978c4450 18936 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18937
18938 print_vma (psym->st_value, LONG_HEX);
18939 printf (" %-7s %3s ",
dda8d76d
NC
18940 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18941 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 18942 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18943 print_symbol (sym_width,
84714f86 18944 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18945 else
18946 printf (_("<corrupt: %14ld>"), psym->st_name);
18947 }
861fb55a
DJ
18948 printf ("\n");
18949 }
18950 printf ("\n");
18951
9db70fc3 18952 free (data);
861fb55a
DJ
18953 free (rels);
18954 }
18955
32ec8896 18956 return res;
252b5132
RH
18957}
18958
015dc7e1 18959static bool
dda8d76d 18960process_nds32_specific (Filedata * filedata)
35c08157
KLC
18961{
18962 Elf_Internal_Shdr *sect = NULL;
18963
dda8d76d 18964 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18965 if (sect != NULL && sect->sh_size >= 4)
35c08157 18966 {
9c7b8e9b
AM
18967 unsigned char *buf;
18968 unsigned int flag;
35c08157
KLC
18969
18970 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18971 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18972 _("NDS32 elf flags section"));
35c08157 18973
9c7b8e9b 18974 if (buf == NULL)
015dc7e1 18975 return false;
32ec8896 18976
9c7b8e9b
AM
18977 flag = byte_get (buf, 4);
18978 free (buf);
18979 switch (flag & 0x3)
35c08157
KLC
18980 {
18981 case 0:
18982 printf ("(VEC_SIZE):\tNo entry.\n");
18983 break;
18984 case 1:
18985 printf ("(VEC_SIZE):\t4 bytes\n");
18986 break;
18987 case 2:
18988 printf ("(VEC_SIZE):\t16 bytes\n");
18989 break;
18990 case 3:
18991 printf ("(VEC_SIZE):\treserved\n");
18992 break;
18993 }
18994 }
18995
015dc7e1 18996 return true;
35c08157
KLC
18997}
18998
015dc7e1 18999static bool
dda8d76d 19000process_gnu_liblist (Filedata * filedata)
047b2264 19001{
2cf0635d
NC
19002 Elf_Internal_Shdr * section;
19003 Elf_Internal_Shdr * string_sec;
19004 Elf32_External_Lib * elib;
19005 char * strtab;
c256ffe7 19006 size_t strtab_size;
047b2264 19007 size_t cnt;
d3a49aa8 19008 unsigned long num_liblist;
047b2264 19009 unsigned i;
015dc7e1 19010 bool res = true;
047b2264
JJ
19011
19012 if (! do_arch)
015dc7e1 19013 return true;
047b2264 19014
dda8d76d
NC
19015 for (i = 0, section = filedata->section_headers;
19016 i < filedata->file_header.e_shnum;
b34976b6 19017 i++, section++)
047b2264
JJ
19018 {
19019 switch (section->sh_type)
19020 {
19021 case SHT_GNU_LIBLIST:
dda8d76d 19022 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19023 break;
19024
3f5e193b 19025 elib = (Elf32_External_Lib *)
dda8d76d 19026 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19027 _("liblist section data"));
047b2264
JJ
19028
19029 if (elib == NULL)
32ec8896 19030 {
015dc7e1 19031 res = false;
32ec8896
NC
19032 break;
19033 }
047b2264 19034
dda8d76d
NC
19035 string_sec = filedata->section_headers + section->sh_link;
19036 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19037 string_sec->sh_size,
19038 _("liblist string table"));
047b2264
JJ
19039 if (strtab == NULL
19040 || section->sh_entsize != sizeof (Elf32_External_Lib))
19041 {
19042 free (elib);
2842702f 19043 free (strtab);
015dc7e1 19044 res = false;
047b2264
JJ
19045 break;
19046 }
59245841 19047 strtab_size = string_sec->sh_size;
047b2264 19048
d3a49aa8
AM
19049 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19050 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19051 "\nLibrary list section '%s' contains %lu entries:\n",
19052 num_liblist),
dda8d76d 19053 printable_section_name (filedata, section),
d3a49aa8 19054 num_liblist);
047b2264 19055
2b692964 19056 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19057
19058 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19059 ++cnt)
19060 {
19061 Elf32_Lib liblist;
91d6fa6a 19062 time_t atime;
d5b07ef4 19063 char timebuf[128];
2cf0635d 19064 struct tm * tmp;
047b2264
JJ
19065
19066 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19067 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19068 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19069 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19070 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19071
91d6fa6a 19072 tmp = gmtime (&atime);
e9e44622
JJ
19073 snprintf (timebuf, sizeof (timebuf),
19074 "%04u-%02u-%02uT%02u:%02u:%02u",
19075 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19076 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19077
19078 printf ("%3lu: ", (unsigned long) cnt);
19079 if (do_wide)
c256ffe7 19080 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19081 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19082 else
c256ffe7 19083 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19084 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19085 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19086 liblist.l_version, liblist.l_flags);
19087 }
19088
19089 free (elib);
2842702f 19090 free (strtab);
047b2264
JJ
19091 }
19092 }
19093
32ec8896 19094 return res;
047b2264
JJ
19095}
19096
9437c45b 19097static const char *
dda8d76d 19098get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19099{
19100 static char buff[64];
103f02d3 19101
dda8d76d 19102 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19103 switch (e_type)
19104 {
57346661 19105 case NT_AUXV:
1ec5cd37 19106 return _("NT_AUXV (auxiliary vector)");
57346661 19107 case NT_PRSTATUS:
1ec5cd37 19108 return _("NT_PRSTATUS (prstatus structure)");
57346661 19109 case NT_FPREGSET:
1ec5cd37 19110 return _("NT_FPREGSET (floating point registers)");
57346661 19111 case NT_PRPSINFO:
1ec5cd37 19112 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19113 case NT_TASKSTRUCT:
1ec5cd37 19114 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19115 case NT_GDB_TDESC:
19116 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19117 case NT_PRXFPREG:
1ec5cd37 19118 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19119 case NT_PPC_VMX:
19120 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19121 case NT_PPC_VSX:
19122 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19123 case NT_PPC_TAR:
19124 return _("NT_PPC_TAR (ppc TAR register)");
19125 case NT_PPC_PPR:
19126 return _("NT_PPC_PPR (ppc PPR register)");
19127 case NT_PPC_DSCR:
19128 return _("NT_PPC_DSCR (ppc DSCR register)");
19129 case NT_PPC_EBB:
19130 return _("NT_PPC_EBB (ppc EBB registers)");
19131 case NT_PPC_PMU:
19132 return _("NT_PPC_PMU (ppc PMU registers)");
19133 case NT_PPC_TM_CGPR:
19134 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19135 case NT_PPC_TM_CFPR:
19136 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19137 case NT_PPC_TM_CVMX:
19138 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19139 case NT_PPC_TM_CVSX:
3fd21718 19140 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19141 case NT_PPC_TM_SPR:
19142 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19143 case NT_PPC_TM_CTAR:
19144 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19145 case NT_PPC_TM_CPPR:
19146 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19147 case NT_PPC_TM_CDSCR:
19148 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19149 case NT_386_TLS:
19150 return _("NT_386_TLS (x86 TLS information)");
19151 case NT_386_IOPERM:
19152 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19153 case NT_X86_XSTATE:
19154 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19155 case NT_X86_CET:
19156 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19157 case NT_S390_HIGH_GPRS:
19158 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19159 case NT_S390_TIMER:
19160 return _("NT_S390_TIMER (s390 timer register)");
19161 case NT_S390_TODCMP:
19162 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19163 case NT_S390_TODPREG:
19164 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19165 case NT_S390_CTRS:
19166 return _("NT_S390_CTRS (s390 control registers)");
19167 case NT_S390_PREFIX:
19168 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19169 case NT_S390_LAST_BREAK:
19170 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19171 case NT_S390_SYSTEM_CALL:
19172 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19173 case NT_S390_TDB:
19174 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19175 case NT_S390_VXRS_LOW:
19176 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19177 case NT_S390_VXRS_HIGH:
19178 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19179 case NT_S390_GS_CB:
19180 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19181 case NT_S390_GS_BC:
19182 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19183 case NT_ARM_VFP:
19184 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19185 case NT_ARM_TLS:
19186 return _("NT_ARM_TLS (AArch TLS registers)");
19187 case NT_ARM_HW_BREAK:
19188 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19189 case NT_ARM_HW_WATCH:
19190 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
19191 case NT_ARM_SVE:
19192 return _("NT_ARM_SVE (AArch SVE registers)");
19193 case NT_ARM_PAC_MASK:
19194 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19195 case NT_ARM_PACA_KEYS:
19196 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19197 case NT_ARM_PACG_KEYS:
19198 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19199 case NT_ARM_TAGGED_ADDR_CTRL:
19200 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19201 case NT_ARM_PAC_ENABLED_KEYS:
19202 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19203 case NT_ARC_V2:
19204 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19205 case NT_RISCV_CSR:
19206 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19207 case NT_PSTATUS:
1ec5cd37 19208 return _("NT_PSTATUS (pstatus structure)");
57346661 19209 case NT_FPREGS:
1ec5cd37 19210 return _("NT_FPREGS (floating point registers)");
57346661 19211 case NT_PSINFO:
1ec5cd37 19212 return _("NT_PSINFO (psinfo structure)");
57346661 19213 case NT_LWPSTATUS:
1ec5cd37 19214 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19215 case NT_LWPSINFO:
1ec5cd37 19216 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19217 case NT_WIN32PSTATUS:
1ec5cd37 19218 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19219 case NT_SIGINFO:
19220 return _("NT_SIGINFO (siginfo_t data)");
19221 case NT_FILE:
19222 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19223 default:
19224 break;
19225 }
19226 else
19227 switch (e_type)
19228 {
19229 case NT_VERSION:
19230 return _("NT_VERSION (version)");
19231 case NT_ARCH:
19232 return _("NT_ARCH (architecture)");
9ef920e9 19233 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19234 return _("OPEN");
9ef920e9 19235 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19236 return _("func");
c8795e1f
NC
19237 case NT_GO_BUILDID:
19238 return _("GO BUILDID");
1ec5cd37
NC
19239 default:
19240 break;
19241 }
19242
e9e44622 19243 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19244 return buff;
779fe533
NC
19245}
19246
015dc7e1 19247static bool
9ece1fa9
TT
19248print_core_note (Elf_Internal_Note *pnote)
19249{
19250 unsigned int addr_size = is_32bit_elf ? 4 : 8;
19251 bfd_vma count, page_size;
19252 unsigned char *descdata, *filenames, *descend;
19253
19254 if (pnote->type != NT_FILE)
04ac15ab
AS
19255 {
19256 if (do_wide)
19257 printf ("\n");
015dc7e1 19258 return true;
04ac15ab 19259 }
9ece1fa9
TT
19260
19261#ifndef BFD64
19262 if (!is_32bit_elf)
19263 {
19264 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19265 /* Still "successful". */
015dc7e1 19266 return true;
9ece1fa9
TT
19267 }
19268#endif
19269
19270 if (pnote->descsz < 2 * addr_size)
19271 {
32ec8896 19272 error (_(" Malformed note - too short for header\n"));
015dc7e1 19273 return false;
9ece1fa9
TT
19274 }
19275
19276 descdata = (unsigned char *) pnote->descdata;
19277 descend = descdata + pnote->descsz;
19278
19279 if (descdata[pnote->descsz - 1] != '\0')
19280 {
32ec8896 19281 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19282 return false;
9ece1fa9
TT
19283 }
19284
19285 count = byte_get (descdata, addr_size);
19286 descdata += addr_size;
19287
19288 page_size = byte_get (descdata, addr_size);
19289 descdata += addr_size;
19290
5396a86e
AM
19291 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
19292 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19293 {
32ec8896 19294 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19295 return false;
9ece1fa9
TT
19296 }
19297
19298 printf (_(" Page size: "));
19299 print_vma (page_size, DEC);
19300 printf ("\n");
19301
19302 printf (_(" %*s%*s%*s\n"),
19303 (int) (2 + 2 * addr_size), _("Start"),
19304 (int) (4 + 2 * addr_size), _("End"),
19305 (int) (4 + 2 * addr_size), _("Page Offset"));
19306 filenames = descdata + count * 3 * addr_size;
595712bb 19307 while (count-- > 0)
9ece1fa9
TT
19308 {
19309 bfd_vma start, end, file_ofs;
19310
19311 if (filenames == descend)
19312 {
32ec8896 19313 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19314 return false;
9ece1fa9
TT
19315 }
19316
19317 start = byte_get (descdata, addr_size);
19318 descdata += addr_size;
19319 end = byte_get (descdata, addr_size);
19320 descdata += addr_size;
19321 file_ofs = byte_get (descdata, addr_size);
19322 descdata += addr_size;
19323
19324 printf (" ");
19325 print_vma (start, FULL_HEX);
19326 printf (" ");
19327 print_vma (end, FULL_HEX);
19328 printf (" ");
19329 print_vma (file_ofs, FULL_HEX);
19330 printf ("\n %s\n", filenames);
19331
19332 filenames += 1 + strlen ((char *) filenames);
19333 }
19334
015dc7e1 19335 return true;
9ece1fa9
TT
19336}
19337
1118d252
RM
19338static const char *
19339get_gnu_elf_note_type (unsigned e_type)
19340{
1449284b 19341 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19342 switch (e_type)
19343 {
19344 case NT_GNU_ABI_TAG:
19345 return _("NT_GNU_ABI_TAG (ABI version tag)");
19346 case NT_GNU_HWCAP:
19347 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19348 case NT_GNU_BUILD_ID:
19349 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19350 case NT_GNU_GOLD_VERSION:
19351 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19352 case NT_GNU_PROPERTY_TYPE_0:
19353 return _("NT_GNU_PROPERTY_TYPE_0");
19354 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19355 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19356 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19357 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19358 default:
1449284b
NC
19359 {
19360 static char buff[64];
1118d252 19361
1449284b
NC
19362 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19363 return buff;
19364 }
19365 }
1118d252
RM
19366}
19367
a9eafb08
L
19368static void
19369decode_x86_compat_isa (unsigned int bitmask)
19370{
19371 while (bitmask)
19372 {
19373 unsigned int bit = bitmask & (- bitmask);
19374
19375 bitmask &= ~ bit;
19376 switch (bit)
19377 {
19378 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19379 printf ("i486");
19380 break;
19381 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19382 printf ("586");
19383 break;
19384 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19385 printf ("686");
19386 break;
19387 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19388 printf ("SSE");
19389 break;
19390 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19391 printf ("SSE2");
19392 break;
19393 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19394 printf ("SSE3");
19395 break;
19396 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19397 printf ("SSSE3");
19398 break;
19399 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19400 printf ("SSE4_1");
19401 break;
19402 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19403 printf ("SSE4_2");
19404 break;
19405 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19406 printf ("AVX");
19407 break;
19408 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19409 printf ("AVX2");
19410 break;
19411 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19412 printf ("AVX512F");
19413 break;
19414 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19415 printf ("AVX512CD");
19416 break;
19417 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19418 printf ("AVX512ER");
19419 break;
19420 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19421 printf ("AVX512PF");
19422 break;
19423 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19424 printf ("AVX512VL");
19425 break;
19426 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19427 printf ("AVX512DQ");
19428 break;
19429 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19430 printf ("AVX512BW");
19431 break;
65b3d26e
L
19432 default:
19433 printf (_("<unknown: %x>"), bit);
19434 break;
a9eafb08
L
19435 }
19436 if (bitmask)
19437 printf (", ");
19438 }
19439}
19440
9ef920e9 19441static void
32930e4e 19442decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19443{
0a59decb 19444 if (!bitmask)
90c745dc
L
19445 {
19446 printf (_("<None>"));
19447 return;
19448 }
90c745dc 19449
9ef920e9
NC
19450 while (bitmask)
19451 {
1fc87489 19452 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19453
19454 bitmask &= ~ bit;
19455 switch (bit)
19456 {
32930e4e 19457 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19458 printf ("CMOV");
19459 break;
32930e4e 19460 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19461 printf ("SSE");
19462 break;
32930e4e 19463 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19464 printf ("SSE2");
19465 break;
32930e4e 19466 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19467 printf ("SSE3");
19468 break;
32930e4e 19469 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19470 printf ("SSSE3");
19471 break;
32930e4e 19472 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19473 printf ("SSE4_1");
19474 break;
32930e4e 19475 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19476 printf ("SSE4_2");
19477 break;
32930e4e 19478 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19479 printf ("AVX");
19480 break;
32930e4e 19481 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19482 printf ("AVX2");
19483 break;
32930e4e 19484 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19485 printf ("FMA");
19486 break;
32930e4e 19487 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19488 printf ("AVX512F");
19489 break;
32930e4e 19490 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19491 printf ("AVX512CD");
19492 break;
32930e4e 19493 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19494 printf ("AVX512ER");
19495 break;
32930e4e 19496 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19497 printf ("AVX512PF");
19498 break;
32930e4e 19499 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19500 printf ("AVX512VL");
19501 break;
32930e4e 19502 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19503 printf ("AVX512DQ");
19504 break;
32930e4e 19505 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19506 printf ("AVX512BW");
19507 break;
32930e4e 19508 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19509 printf ("AVX512_4FMAPS");
19510 break;
32930e4e 19511 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19512 printf ("AVX512_4VNNIW");
19513 break;
32930e4e 19514 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19515 printf ("AVX512_BITALG");
19516 break;
32930e4e 19517 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19518 printf ("AVX512_IFMA");
19519 break;
32930e4e 19520 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19521 printf ("AVX512_VBMI");
19522 break;
32930e4e 19523 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19524 printf ("AVX512_VBMI2");
19525 break;
32930e4e 19526 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19527 printf ("AVX512_VNNI");
19528 break;
32930e4e 19529 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19530 printf ("AVX512_BF16");
19531 break;
65b3d26e
L
19532 default:
19533 printf (_("<unknown: %x>"), bit);
19534 break;
9ef920e9
NC
19535 }
19536 if (bitmask)
19537 printf (", ");
19538 }
19539}
19540
32930e4e
L
19541static void
19542decode_x86_isa (unsigned int bitmask)
19543{
32930e4e
L
19544 while (bitmask)
19545 {
19546 unsigned int bit = bitmask & (- bitmask);
19547
19548 bitmask &= ~ bit;
19549 switch (bit)
19550 {
b0ab0693
L
19551 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19552 printf ("x86-64-baseline");
19553 break;
32930e4e
L
19554 case GNU_PROPERTY_X86_ISA_1_V2:
19555 printf ("x86-64-v2");
19556 break;
19557 case GNU_PROPERTY_X86_ISA_1_V3:
19558 printf ("x86-64-v3");
19559 break;
19560 case GNU_PROPERTY_X86_ISA_1_V4:
19561 printf ("x86-64-v4");
19562 break;
19563 default:
19564 printf (_("<unknown: %x>"), bit);
19565 break;
19566 }
19567 if (bitmask)
19568 printf (", ");
19569 }
19570}
19571
ee2fdd6f 19572static void
a9eafb08 19573decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19574{
0a59decb 19575 if (!bitmask)
90c745dc
L
19576 {
19577 printf (_("<None>"));
19578 return;
19579 }
90c745dc 19580
ee2fdd6f
L
19581 while (bitmask)
19582 {
19583 unsigned int bit = bitmask & (- bitmask);
19584
19585 bitmask &= ~ bit;
19586 switch (bit)
19587 {
19588 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19589 printf ("IBT");
ee2fdd6f 19590 break;
48580982 19591 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19592 printf ("SHSTK");
48580982 19593 break;
279d901e
L
19594 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19595 printf ("LAM_U48");
19596 break;
19597 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19598 printf ("LAM_U57");
19599 break;
ee2fdd6f
L
19600 default:
19601 printf (_("<unknown: %x>"), bit);
19602 break;
19603 }
19604 if (bitmask)
19605 printf (", ");
19606 }
19607}
19608
a9eafb08
L
19609static void
19610decode_x86_feature_2 (unsigned int bitmask)
19611{
0a59decb 19612 if (!bitmask)
90c745dc
L
19613 {
19614 printf (_("<None>"));
19615 return;
19616 }
90c745dc 19617
a9eafb08
L
19618 while (bitmask)
19619 {
19620 unsigned int bit = bitmask & (- bitmask);
19621
19622 bitmask &= ~ bit;
19623 switch (bit)
19624 {
19625 case GNU_PROPERTY_X86_FEATURE_2_X86:
19626 printf ("x86");
19627 break;
19628 case GNU_PROPERTY_X86_FEATURE_2_X87:
19629 printf ("x87");
19630 break;
19631 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19632 printf ("MMX");
19633 break;
19634 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19635 printf ("XMM");
19636 break;
19637 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19638 printf ("YMM");
19639 break;
19640 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19641 printf ("ZMM");
19642 break;
a308b89d
L
19643 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19644 printf ("TMM");
19645 break;
32930e4e
L
19646 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19647 printf ("MASK");
19648 break;
a9eafb08
L
19649 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19650 printf ("FXSR");
19651 break;
19652 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19653 printf ("XSAVE");
19654 break;
19655 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19656 printf ("XSAVEOPT");
19657 break;
19658 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19659 printf ("XSAVEC");
19660 break;
65b3d26e
L
19661 default:
19662 printf (_("<unknown: %x>"), bit);
19663 break;
a9eafb08
L
19664 }
19665 if (bitmask)
19666 printf (", ");
19667 }
19668}
19669
cd702818
SD
19670static void
19671decode_aarch64_feature_1_and (unsigned int bitmask)
19672{
19673 while (bitmask)
19674 {
19675 unsigned int bit = bitmask & (- bitmask);
19676
19677 bitmask &= ~ bit;
19678 switch (bit)
19679 {
19680 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19681 printf ("BTI");
19682 break;
19683
19684 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19685 printf ("PAC");
19686 break;
19687
19688 default:
19689 printf (_("<unknown: %x>"), bit);
19690 break;
19691 }
19692 if (bitmask)
19693 printf (", ");
19694 }
19695}
19696
6320fd00
L
19697static void
19698decode_1_needed (unsigned int bitmask)
19699{
19700 while (bitmask)
19701 {
19702 unsigned int bit = bitmask & (- bitmask);
19703
19704 bitmask &= ~ bit;
19705 switch (bit)
19706 {
19707 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19708 printf ("indirect external access");
19709 break;
19710 default:
19711 printf (_("<unknown: %x>"), bit);
19712 break;
19713 }
19714 if (bitmask)
19715 printf (", ");
19716 }
19717}
19718
9ef920e9 19719static void
dda8d76d 19720print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19721{
19722 unsigned char * ptr = (unsigned char *) pnote->descdata;
19723 unsigned char * ptr_end = ptr + pnote->descsz;
19724 unsigned int size = is_32bit_elf ? 4 : 8;
19725
19726 printf (_(" Properties: "));
19727
1fc87489 19728 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19729 {
19730 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19731 return;
19732 }
19733
6ab2c4ed 19734 while (ptr < ptr_end)
9ef920e9 19735 {
1fc87489 19736 unsigned int j;
6ab2c4ed
MC
19737 unsigned int type;
19738 unsigned int datasz;
19739
19740 if ((size_t) (ptr_end - ptr) < 8)
19741 {
19742 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19743 break;
19744 }
19745
19746 type = byte_get (ptr, 4);
19747 datasz = byte_get (ptr + 4, 4);
9ef920e9 19748
1fc87489 19749 ptr += 8;
9ef920e9 19750
6ab2c4ed 19751 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19752 {
1fc87489
L
19753 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19754 type, datasz);
9ef920e9 19755 break;
1fc87489 19756 }
9ef920e9 19757
1fc87489
L
19758 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19759 {
dda8d76d
NC
19760 if (filedata->file_header.e_machine == EM_X86_64
19761 || filedata->file_header.e_machine == EM_IAMCU
19762 || filedata->file_header.e_machine == EM_386)
1fc87489 19763 {
aa7bca9b
L
19764 unsigned int bitmask;
19765
19766 if (datasz == 4)
0a59decb 19767 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19768 else
19769 bitmask = 0;
19770
1fc87489
L
19771 switch (type)
19772 {
19773 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19774 if (datasz != 4)
aa7bca9b
L
19775 printf (_("x86 ISA used: <corrupt length: %#x> "),
19776 datasz);
1fc87489 19777 else
aa7bca9b
L
19778 {
19779 printf ("x86 ISA used: ");
19780 decode_x86_isa (bitmask);
19781 }
1fc87489 19782 goto next;
9ef920e9 19783
1fc87489 19784 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19785 if (datasz != 4)
aa7bca9b
L
19786 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19787 datasz);
1fc87489 19788 else
aa7bca9b
L
19789 {
19790 printf ("x86 ISA needed: ");
19791 decode_x86_isa (bitmask);
19792 }
1fc87489 19793 goto next;
9ef920e9 19794
ee2fdd6f 19795 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19796 if (datasz != 4)
aa7bca9b
L
19797 printf (_("x86 feature: <corrupt length: %#x> "),
19798 datasz);
ee2fdd6f 19799 else
aa7bca9b
L
19800 {
19801 printf ("x86 feature: ");
a9eafb08
L
19802 decode_x86_feature_1 (bitmask);
19803 }
19804 goto next;
19805
19806 case GNU_PROPERTY_X86_FEATURE_2_USED:
19807 if (datasz != 4)
19808 printf (_("x86 feature used: <corrupt length: %#x> "),
19809 datasz);
19810 else
19811 {
19812 printf ("x86 feature used: ");
19813 decode_x86_feature_2 (bitmask);
19814 }
19815 goto next;
19816
19817 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19818 if (datasz != 4)
19819 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19820 else
19821 {
19822 printf ("x86 feature needed: ");
19823 decode_x86_feature_2 (bitmask);
19824 }
19825 goto next;
19826
19827 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19828 if (datasz != 4)
19829 printf (_("x86 ISA used: <corrupt length: %#x> "),
19830 datasz);
19831 else
19832 {
19833 printf ("x86 ISA used: ");
19834 decode_x86_compat_isa (bitmask);
19835 }
19836 goto next;
19837
19838 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19839 if (datasz != 4)
19840 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19841 datasz);
19842 else
19843 {
19844 printf ("x86 ISA needed: ");
19845 decode_x86_compat_isa (bitmask);
aa7bca9b 19846 }
ee2fdd6f
L
19847 goto next;
19848
32930e4e
L
19849 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19850 if (datasz != 4)
19851 printf (_("x86 ISA used: <corrupt length: %#x> "),
19852 datasz);
19853 else
19854 {
19855 printf ("x86 ISA used: ");
19856 decode_x86_compat_2_isa (bitmask);
19857 }
19858 goto next;
19859
19860 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19861 if (datasz != 4)
19862 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19863 datasz);
19864 else
19865 {
19866 printf ("x86 ISA needed: ");
19867 decode_x86_compat_2_isa (bitmask);
19868 }
19869 goto next;
19870
1fc87489
L
19871 default:
19872 break;
19873 }
19874 }
cd702818
SD
19875 else if (filedata->file_header.e_machine == EM_AARCH64)
19876 {
19877 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19878 {
19879 printf ("AArch64 feature: ");
19880 if (datasz != 4)
19881 printf (_("<corrupt length: %#x> "), datasz);
19882 else
19883 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19884 goto next;
19885 }
19886 }
1fc87489
L
19887 }
19888 else
19889 {
19890 switch (type)
9ef920e9 19891 {
1fc87489
L
19892 case GNU_PROPERTY_STACK_SIZE:
19893 printf (_("stack size: "));
19894 if (datasz != size)
19895 printf (_("<corrupt length: %#x> "), datasz);
19896 else
19897 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19898 goto next;
19899
19900 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19901 printf ("no copy on protected ");
19902 if (datasz)
19903 printf (_("<corrupt length: %#x> "), datasz);
19904 goto next;
19905
19906 default:
5a767724
L
19907 if ((type >= GNU_PROPERTY_UINT32_AND_LO
19908 && type <= GNU_PROPERTY_UINT32_AND_HI)
19909 || (type >= GNU_PROPERTY_UINT32_OR_LO
19910 && type <= GNU_PROPERTY_UINT32_OR_HI))
19911 {
6320fd00
L
19912 switch (type)
19913 {
19914 case GNU_PROPERTY_1_NEEDED:
19915 if (datasz != 4)
19916 printf (_("1_needed: <corrupt length: %#x> "),
19917 datasz);
19918 else
19919 {
19920 unsigned int bitmask = byte_get (ptr, 4);
19921 printf ("1_needed: ");
19922 decode_1_needed (bitmask);
19923 }
19924 goto next;
19925
19926 default:
19927 break;
19928 }
5a767724
L
19929 if (type <= GNU_PROPERTY_UINT32_AND_HI)
19930 printf (_("UINT32_AND (%#x): "), type);
19931 else
19932 printf (_("UINT32_OR (%#x): "), type);
19933 if (datasz != 4)
19934 printf (_("<corrupt length: %#x> "), datasz);
19935 else
19936 printf ("%#x", (unsigned int) byte_get (ptr, 4));
19937 goto next;
19938 }
9ef920e9
NC
19939 break;
19940 }
9ef920e9
NC
19941 }
19942
1fc87489
L
19943 if (type < GNU_PROPERTY_LOPROC)
19944 printf (_("<unknown type %#x data: "), type);
19945 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19946 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19947 else
19948 printf (_("<application-specific type %#x data: "), type);
19949 for (j = 0; j < datasz; ++j)
19950 printf ("%02x ", ptr[j] & 0xff);
19951 printf (">");
19952
dc1e8a47 19953 next:
9ef920e9 19954 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19955 if (ptr == ptr_end)
19956 break;
1fc87489 19957
6ab2c4ed
MC
19958 if (do_wide)
19959 printf (", ");
19960 else
19961 printf ("\n\t");
9ef920e9
NC
19962 }
19963
19964 printf ("\n");
19965}
19966
015dc7e1 19967static bool
dda8d76d 19968print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19969{
1449284b 19970 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19971 switch (pnote->type)
19972 {
19973 case NT_GNU_BUILD_ID:
19974 {
19975 unsigned long i;
19976
19977 printf (_(" Build ID: "));
19978 for (i = 0; i < pnote->descsz; ++i)
19979 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19980 printf ("\n");
664f90a3
TT
19981 }
19982 break;
19983
19984 case NT_GNU_ABI_TAG:
19985 {
19986 unsigned long os, major, minor, subminor;
19987 const char *osname;
19988
3102e897
NC
19989 /* PR 17531: file: 030-599401-0.004. */
19990 if (pnote->descsz < 16)
19991 {
19992 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19993 break;
19994 }
19995
664f90a3
TT
19996 os = byte_get ((unsigned char *) pnote->descdata, 4);
19997 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19998 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19999 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20000
20001 switch (os)
20002 {
20003 case GNU_ABI_TAG_LINUX:
20004 osname = "Linux";
20005 break;
20006 case GNU_ABI_TAG_HURD:
20007 osname = "Hurd";
20008 break;
20009 case GNU_ABI_TAG_SOLARIS:
20010 osname = "Solaris";
20011 break;
20012 case GNU_ABI_TAG_FREEBSD:
20013 osname = "FreeBSD";
20014 break;
20015 case GNU_ABI_TAG_NETBSD:
20016 osname = "NetBSD";
20017 break;
14ae95f2
RM
20018 case GNU_ABI_TAG_SYLLABLE:
20019 osname = "Syllable";
20020 break;
20021 case GNU_ABI_TAG_NACL:
20022 osname = "NaCl";
20023 break;
664f90a3
TT
20024 default:
20025 osname = "Unknown";
20026 break;
20027 }
20028
20029 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20030 major, minor, subminor);
20031 }
20032 break;
926c5385
CC
20033
20034 case NT_GNU_GOLD_VERSION:
20035 {
20036 unsigned long i;
20037
20038 printf (_(" Version: "));
20039 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20040 printf ("%c", pnote->descdata[i]);
20041 printf ("\n");
20042 }
20043 break;
1449284b
NC
20044
20045 case NT_GNU_HWCAP:
20046 {
20047 unsigned long num_entries, mask;
20048
20049 /* Hardware capabilities information. Word 0 is the number of entries.
20050 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20051 is a series of entries, where each entry is a single byte followed
20052 by a nul terminated string. The byte gives the bit number to test
20053 if enabled in the bitmask. */
20054 printf (_(" Hardware Capabilities: "));
20055 if (pnote->descsz < 8)
20056 {
32ec8896 20057 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20058 return false;
1449284b
NC
20059 }
20060 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20061 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20062 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20063 /* FIXME: Add code to display the entries... */
20064 }
20065 break;
20066
9ef920e9 20067 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20068 print_gnu_property_note (filedata, pnote);
9ef920e9 20069 break;
9abca702 20070
1449284b
NC
20071 default:
20072 /* Handle unrecognised types. An error message should have already been
20073 created by get_gnu_elf_note_type(), so all that we need to do is to
20074 display the data. */
20075 {
20076 unsigned long i;
20077
20078 printf (_(" Description data: "));
20079 for (i = 0; i < pnote->descsz; ++i)
20080 printf ("%02x ", pnote->descdata[i] & 0xff);
20081 printf ("\n");
20082 }
20083 break;
664f90a3
TT
20084 }
20085
015dc7e1 20086 return true;
664f90a3
TT
20087}
20088
685080f2
NC
20089static const char *
20090get_v850_elf_note_type (enum v850_notes n_type)
20091{
20092 static char buff[64];
20093
20094 switch (n_type)
20095 {
20096 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20097 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20098 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20099 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20100 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20101 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20102 default:
20103 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20104 return buff;
20105 }
20106}
20107
015dc7e1 20108static bool
685080f2
NC
20109print_v850_note (Elf_Internal_Note * pnote)
20110{
20111 unsigned int val;
20112
20113 if (pnote->descsz != 4)
015dc7e1 20114 return false;
32ec8896 20115
685080f2
NC
20116 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20117
20118 if (val == 0)
20119 {
20120 printf (_("not set\n"));
015dc7e1 20121 return true;
685080f2
NC
20122 }
20123
20124 switch (pnote->type)
20125 {
20126 case V850_NOTE_ALIGNMENT:
20127 switch (val)
20128 {
015dc7e1
AM
20129 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20130 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20131 }
20132 break;
14ae95f2 20133
685080f2
NC
20134 case V850_NOTE_DATA_SIZE:
20135 switch (val)
20136 {
015dc7e1
AM
20137 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20138 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20139 }
20140 break;
14ae95f2 20141
685080f2
NC
20142 case V850_NOTE_FPU_INFO:
20143 switch (val)
20144 {
015dc7e1
AM
20145 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20146 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20147 }
20148 break;
14ae95f2 20149
685080f2
NC
20150 case V850_NOTE_MMU_INFO:
20151 case V850_NOTE_CACHE_INFO:
20152 case V850_NOTE_SIMD_INFO:
20153 if (val == EF_RH850_SIMD)
20154 {
20155 printf (_("yes\n"));
015dc7e1 20156 return true;
685080f2
NC
20157 }
20158 break;
20159
20160 default:
20161 /* An 'unknown note type' message will already have been displayed. */
20162 break;
20163 }
20164
20165 printf (_("unknown value: %x\n"), val);
015dc7e1 20166 return false;
685080f2
NC
20167}
20168
015dc7e1 20169static bool
c6056a74
SF
20170process_netbsd_elf_note (Elf_Internal_Note * pnote)
20171{
20172 unsigned int version;
20173
20174 switch (pnote->type)
20175 {
20176 case NT_NETBSD_IDENT:
b966f55f
AM
20177 if (pnote->descsz < 1)
20178 break;
c6056a74
SF
20179 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20180 if ((version / 10000) % 100)
b966f55f 20181 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20182 version, version / 100000000, (version / 1000000) % 100,
20183 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20184 'A' + (version / 10000) % 26);
c6056a74
SF
20185 else
20186 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20187 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20188 (version / 100) % 100);
015dc7e1 20189 return true;
c6056a74
SF
20190
20191 case NT_NETBSD_MARCH:
9abca702 20192 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20193 pnote->descdata);
015dc7e1 20194 return true;
c6056a74 20195
9abca702 20196 case NT_NETBSD_PAX:
b966f55f
AM
20197 if (pnote->descsz < 1)
20198 break;
9abca702
CZ
20199 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20200 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20201 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20202 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20203 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20204 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20205 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20206 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20207 return true;
c6056a74 20208 }
b966f55f
AM
20209
20210 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20211 pnote->descsz, pnote->type);
015dc7e1 20212 return false;
c6056a74
SF
20213}
20214
f4ddf30f 20215static const char *
dda8d76d 20216get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20217{
f4ddf30f
JB
20218 switch (e_type)
20219 {
20220 case NT_FREEBSD_THRMISC:
20221 return _("NT_THRMISC (thrmisc structure)");
20222 case NT_FREEBSD_PROCSTAT_PROC:
20223 return _("NT_PROCSTAT_PROC (proc data)");
20224 case NT_FREEBSD_PROCSTAT_FILES:
20225 return _("NT_PROCSTAT_FILES (files data)");
20226 case NT_FREEBSD_PROCSTAT_VMMAP:
20227 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20228 case NT_FREEBSD_PROCSTAT_GROUPS:
20229 return _("NT_PROCSTAT_GROUPS (groups data)");
20230 case NT_FREEBSD_PROCSTAT_UMASK:
20231 return _("NT_PROCSTAT_UMASK (umask data)");
20232 case NT_FREEBSD_PROCSTAT_RLIMIT:
20233 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20234 case NT_FREEBSD_PROCSTAT_OSREL:
20235 return _("NT_PROCSTAT_OSREL (osreldate data)");
20236 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20237 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20238 case NT_FREEBSD_PROCSTAT_AUXV:
20239 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20240 case NT_FREEBSD_PTLWPINFO:
20241 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 20242 }
dda8d76d 20243 return get_note_type (filedata, e_type);
f4ddf30f
JB
20244}
20245
9437c45b 20246static const char *
dda8d76d 20247get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20248{
20249 static char buff[64];
20250
540e6170
CZ
20251 switch (e_type)
20252 {
20253 case NT_NETBSDCORE_PROCINFO:
20254 /* NetBSD core "procinfo" structure. */
20255 return _("NetBSD procinfo structure");
9437c45b 20256
540e6170
CZ
20257 case NT_NETBSDCORE_AUXV:
20258 return _("NetBSD ELF auxiliary vector data");
9437c45b 20259
06d949ec
KR
20260 case NT_NETBSDCORE_LWPSTATUS:
20261 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20262
540e6170 20263 default:
06d949ec 20264 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20265 defined for NetBSD core files. If the note type is less
20266 than the start of the machine-dependent note types, we don't
20267 understand it. */
20268
20269 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20270 {
20271 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20272 return buff;
20273 }
20274 break;
9437c45b
JT
20275 }
20276
dda8d76d 20277 switch (filedata->file_header.e_machine)
9437c45b
JT
20278 {
20279 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20280 and PT_GETFPREGS == mach+2. */
20281
20282 case EM_OLD_ALPHA:
20283 case EM_ALPHA:
20284 case EM_SPARC:
20285 case EM_SPARC32PLUS:
20286 case EM_SPARCV9:
20287 switch (e_type)
20288 {
2b692964 20289 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20290 return _("PT_GETREGS (reg structure)");
2b692964 20291 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20292 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20293 default:
20294 break;
20295 }
20296 break;
20297
c0d38b0e
CZ
20298 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20299 There's also old PT___GETREGS40 == mach + 1 for old reg
20300 structure which lacks GBR. */
20301 case EM_SH:
20302 switch (e_type)
20303 {
20304 case NT_NETBSDCORE_FIRSTMACH + 1:
20305 return _("PT___GETREGS40 (old reg structure)");
20306 case NT_NETBSDCORE_FIRSTMACH + 3:
20307 return _("PT_GETREGS (reg structure)");
20308 case NT_NETBSDCORE_FIRSTMACH + 5:
20309 return _("PT_GETFPREGS (fpreg structure)");
20310 default:
20311 break;
20312 }
20313 break;
20314
9437c45b
JT
20315 /* On all other arch's, PT_GETREGS == mach+1 and
20316 PT_GETFPREGS == mach+3. */
20317 default:
20318 switch (e_type)
20319 {
2b692964 20320 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20321 return _("PT_GETREGS (reg structure)");
2b692964 20322 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20323 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20324 default:
20325 break;
20326 }
20327 }
20328
9cf03b7e 20329 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20330 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20331 return buff;
20332}
20333
98ca73af
FC
20334static const char *
20335get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20336{
20337 switch (e_type)
20338 {
20339 case NT_OPENBSD_PROCINFO:
20340 return _("OpenBSD procinfo structure");
20341 case NT_OPENBSD_AUXV:
20342 return _("OpenBSD ELF auxiliary vector data");
20343 case NT_OPENBSD_REGS:
20344 return _("OpenBSD regular registers");
20345 case NT_OPENBSD_FPREGS:
20346 return _("OpenBSD floating point registers");
20347 case NT_OPENBSD_WCOOKIE:
20348 return _("OpenBSD window cookie");
20349 }
20350
20351 return get_note_type (filedata, e_type);
20352}
20353
70616151
TT
20354static const char *
20355get_stapsdt_note_type (unsigned e_type)
20356{
20357 static char buff[64];
20358
20359 switch (e_type)
20360 {
20361 case NT_STAPSDT:
20362 return _("NT_STAPSDT (SystemTap probe descriptors)");
20363
20364 default:
20365 break;
20366 }
20367
20368 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20369 return buff;
20370}
20371
015dc7e1 20372static bool
c6a9fc58
TT
20373print_stapsdt_note (Elf_Internal_Note *pnote)
20374{
3ca60c57
NC
20375 size_t len, maxlen;
20376 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20377 char *data = pnote->descdata;
20378 char *data_end = pnote->descdata + pnote->descsz;
20379 bfd_vma pc, base_addr, semaphore;
20380 char *provider, *probe, *arg_fmt;
20381
3ca60c57
NC
20382 if (pnote->descsz < (addr_size * 3))
20383 goto stapdt_note_too_small;
20384
c6a9fc58
TT
20385 pc = byte_get ((unsigned char *) data, addr_size);
20386 data += addr_size;
3ca60c57 20387
c6a9fc58
TT
20388 base_addr = byte_get ((unsigned char *) data, addr_size);
20389 data += addr_size;
3ca60c57 20390
c6a9fc58
TT
20391 semaphore = byte_get ((unsigned char *) data, addr_size);
20392 data += addr_size;
20393
3ca60c57
NC
20394 if (data >= data_end)
20395 goto stapdt_note_too_small;
20396 maxlen = data_end - data;
20397 len = strnlen (data, maxlen);
20398 if (len < maxlen)
20399 {
20400 provider = data;
20401 data += len + 1;
20402 }
20403 else
20404 goto stapdt_note_too_small;
20405
20406 if (data >= data_end)
20407 goto stapdt_note_too_small;
20408 maxlen = data_end - data;
20409 len = strnlen (data, maxlen);
20410 if (len < maxlen)
20411 {
20412 probe = data;
20413 data += len + 1;
20414 }
20415 else
20416 goto stapdt_note_too_small;
9abca702 20417
3ca60c57
NC
20418 if (data >= data_end)
20419 goto stapdt_note_too_small;
20420 maxlen = data_end - data;
20421 len = strnlen (data, maxlen);
20422 if (len < maxlen)
20423 {
20424 arg_fmt = data;
20425 data += len + 1;
20426 }
20427 else
20428 goto stapdt_note_too_small;
c6a9fc58
TT
20429
20430 printf (_(" Provider: %s\n"), provider);
20431 printf (_(" Name: %s\n"), probe);
20432 printf (_(" Location: "));
20433 print_vma (pc, FULL_HEX);
20434 printf (_(", Base: "));
20435 print_vma (base_addr, FULL_HEX);
20436 printf (_(", Semaphore: "));
20437 print_vma (semaphore, FULL_HEX);
9cf03b7e 20438 printf ("\n");
c6a9fc58
TT
20439 printf (_(" Arguments: %s\n"), arg_fmt);
20440
20441 return data == data_end;
3ca60c57
NC
20442
20443 stapdt_note_too_small:
20444 printf (_(" <corrupt - note is too small>\n"));
20445 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20446 return false;
c6a9fc58
TT
20447}
20448
00e98fc7
TG
20449static const char *
20450get_ia64_vms_note_type (unsigned e_type)
20451{
20452 static char buff[64];
20453
20454 switch (e_type)
20455 {
20456 case NT_VMS_MHD:
20457 return _("NT_VMS_MHD (module header)");
20458 case NT_VMS_LNM:
20459 return _("NT_VMS_LNM (language name)");
20460 case NT_VMS_SRC:
20461 return _("NT_VMS_SRC (source files)");
20462 case NT_VMS_TITLE:
9cf03b7e 20463 return "NT_VMS_TITLE";
00e98fc7
TG
20464 case NT_VMS_EIDC:
20465 return _("NT_VMS_EIDC (consistency check)");
20466 case NT_VMS_FPMODE:
20467 return _("NT_VMS_FPMODE (FP mode)");
20468 case NT_VMS_LINKTIME:
9cf03b7e 20469 return "NT_VMS_LINKTIME";
00e98fc7
TG
20470 case NT_VMS_IMGNAM:
20471 return _("NT_VMS_IMGNAM (image name)");
20472 case NT_VMS_IMGID:
20473 return _("NT_VMS_IMGID (image id)");
20474 case NT_VMS_LINKID:
20475 return _("NT_VMS_LINKID (link id)");
20476 case NT_VMS_IMGBID:
20477 return _("NT_VMS_IMGBID (build id)");
20478 case NT_VMS_GSTNAM:
20479 return _("NT_VMS_GSTNAM (sym table name)");
20480 case NT_VMS_ORIG_DYN:
9cf03b7e 20481 return "NT_VMS_ORIG_DYN";
00e98fc7 20482 case NT_VMS_PATCHTIME:
9cf03b7e 20483 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20484 default:
20485 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20486 return buff;
20487 }
20488}
20489
015dc7e1 20490static bool
00e98fc7
TG
20491print_ia64_vms_note (Elf_Internal_Note * pnote)
20492{
8d18bf79
NC
20493 int maxlen = pnote->descsz;
20494
20495 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20496 goto desc_size_fail;
20497
00e98fc7
TG
20498 switch (pnote->type)
20499 {
20500 case NT_VMS_MHD:
8d18bf79
NC
20501 if (maxlen <= 36)
20502 goto desc_size_fail;
20503
20504 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20505
20506 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20507 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20508 if (l + 34 < maxlen)
20509 {
20510 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20511 if (l + 35 < maxlen)
20512 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20513 else
20514 printf (_(" Module version : <missing>\n"));
20515 }
00e98fc7 20516 else
8d18bf79
NC
20517 {
20518 printf (_(" Module name : <missing>\n"));
20519 printf (_(" Module version : <missing>\n"));
20520 }
00e98fc7 20521 break;
8d18bf79 20522
00e98fc7 20523 case NT_VMS_LNM:
8d18bf79 20524 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20525 break;
8d18bf79 20526
00e98fc7
TG
20527#ifdef BFD64
20528 case NT_VMS_FPMODE:
9cf03b7e 20529 printf (_(" Floating Point mode: "));
8d18bf79
NC
20530 if (maxlen < 8)
20531 goto desc_size_fail;
20532 /* FIXME: Generate an error if descsz > 8 ? */
20533
4a5cb34f 20534 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 20535 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 20536 break;
8d18bf79 20537
00e98fc7
TG
20538 case NT_VMS_LINKTIME:
20539 printf (_(" Link time: "));
8d18bf79
NC
20540 if (maxlen < 8)
20541 goto desc_size_fail;
20542 /* FIXME: Generate an error if descsz > 8 ? */
20543
00e98fc7 20544 print_vms_time
8d18bf79 20545 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20546 printf ("\n");
20547 break;
8d18bf79 20548
00e98fc7
TG
20549 case NT_VMS_PATCHTIME:
20550 printf (_(" Patch time: "));
8d18bf79
NC
20551 if (maxlen < 8)
20552 goto desc_size_fail;
20553 /* FIXME: Generate an error if descsz > 8 ? */
20554
00e98fc7 20555 print_vms_time
8d18bf79 20556 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20557 printf ("\n");
20558 break;
8d18bf79 20559
00e98fc7 20560 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20561 if (maxlen < 34)
20562 goto desc_size_fail;
20563
00e98fc7
TG
20564 printf (_(" Major id: %u, minor id: %u\n"),
20565 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20566 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20567 printf (_(" Last modified : "));
00e98fc7
TG
20568 print_vms_time
20569 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20570 printf (_("\n Link flags : "));
4a5cb34f 20571 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20572 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20573 printf (_(" Header flags: 0x%08x\n"),
948f632f 20574 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20575 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20576 break;
20577#endif
8d18bf79 20578
00e98fc7 20579 case NT_VMS_IMGNAM:
8d18bf79 20580 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20581 break;
8d18bf79 20582
00e98fc7 20583 case NT_VMS_GSTNAM:
8d18bf79 20584 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20585 break;
8d18bf79 20586
00e98fc7 20587 case NT_VMS_IMGID:
8d18bf79 20588 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20589 break;
8d18bf79 20590
00e98fc7 20591 case NT_VMS_LINKID:
8d18bf79 20592 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20593 break;
8d18bf79 20594
00e98fc7 20595 default:
015dc7e1 20596 return false;
00e98fc7 20597 }
8d18bf79 20598
015dc7e1 20599 return true;
8d18bf79
NC
20600
20601 desc_size_fail:
20602 printf (_(" <corrupt - data size is too small>\n"));
20603 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20604 return false;
00e98fc7
TG
20605}
20606
fd486f32
AM
20607struct build_attr_cache {
20608 Filedata *filedata;
20609 char *strtab;
20610 unsigned long strtablen;
20611 Elf_Internal_Sym *symtab;
20612 unsigned long nsyms;
20613} ba_cache;
20614
6f156d7a
NC
20615/* Find the symbol associated with a build attribute that is attached
20616 to address OFFSET. If PNAME is non-NULL then store the name of
20617 the symbol (if found) in the provided pointer, Returns NULL if a
20618 symbol could not be found. */
c799a79d 20619
6f156d7a 20620static Elf_Internal_Sym *
015dc7e1
AM
20621get_symbol_for_build_attribute (Filedata *filedata,
20622 unsigned long offset,
20623 bool is_open_attr,
20624 const char **pname)
9ef920e9 20625{
fd486f32
AM
20626 Elf_Internal_Sym *saved_sym = NULL;
20627 Elf_Internal_Sym *sym;
9ef920e9 20628
dda8d76d 20629 if (filedata->section_headers != NULL
fd486f32 20630 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20631 {
c799a79d 20632 Elf_Internal_Shdr * symsec;
9ef920e9 20633
fd486f32
AM
20634 free (ba_cache.strtab);
20635 ba_cache.strtab = NULL;
20636 free (ba_cache.symtab);
20637 ba_cache.symtab = NULL;
20638
c799a79d 20639 /* Load the symbol and string sections. */
dda8d76d
NC
20640 for (symsec = filedata->section_headers;
20641 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20642 symsec ++)
9ef920e9 20643 {
28d13567
AM
20644 if (symsec->sh_type == SHT_SYMTAB
20645 && get_symtab (filedata, symsec,
20646 &ba_cache.symtab, &ba_cache.nsyms,
20647 &ba_cache.strtab, &ba_cache.strtablen))
20648 break;
9ef920e9 20649 }
fd486f32 20650 ba_cache.filedata = filedata;
9ef920e9
NC
20651 }
20652
fd486f32 20653 if (ba_cache.symtab == NULL)
6f156d7a 20654 return NULL;
9ef920e9 20655
c799a79d 20656 /* Find a symbol whose value matches offset. */
fd486f32 20657 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20658 if (sym->st_value == offset)
20659 {
fd486f32 20660 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20661 /* Huh ? This should not happen. */
20662 continue;
9ef920e9 20663
fd486f32 20664 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20665 continue;
9ef920e9 20666
9b9b1092 20667 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20668 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20669 if (ba_cache.strtab[sym->st_name] == '$'
20670 && ba_cache.strtab[sym->st_name + 1] != 0
20671 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20672 continue;
20673
c799a79d
NC
20674 if (is_open_attr)
20675 {
20676 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20677 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20678 FUNC symbols entirely. */
20679 switch (ELF_ST_TYPE (sym->st_info))
20680 {
c799a79d 20681 case STT_OBJECT:
6f156d7a 20682 case STT_FILE:
c799a79d 20683 saved_sym = sym;
6f156d7a
NC
20684 if (sym->st_size)
20685 {
20686 /* If the symbol has a size associated
20687 with it then we can stop searching. */
fd486f32 20688 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20689 }
c799a79d 20690 continue;
9ef920e9 20691
c799a79d
NC
20692 case STT_FUNC:
20693 /* Ignore function symbols. */
20694 continue;
20695
20696 default:
20697 break;
20698 }
20699
20700 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20701 {
c799a79d
NC
20702 case STB_GLOBAL:
20703 if (saved_sym == NULL
20704 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20705 saved_sym = sym;
20706 break;
c871dade 20707
c799a79d
NC
20708 case STB_LOCAL:
20709 if (saved_sym == NULL)
20710 saved_sym = sym;
20711 break;
20712
20713 default:
9ef920e9
NC
20714 break;
20715 }
20716 }
c799a79d
NC
20717 else
20718 {
20719 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20720 continue;
20721
20722 saved_sym = sym;
20723 break;
20724 }
20725 }
20726
6f156d7a 20727 if (saved_sym && pname)
fd486f32 20728 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20729
20730 return saved_sym;
c799a79d
NC
20731}
20732
d20e98ab
NC
20733/* Returns true iff addr1 and addr2 are in the same section. */
20734
015dc7e1 20735static bool
d20e98ab
NC
20736same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20737{
20738 Elf_Internal_Shdr * a1;
20739 Elf_Internal_Shdr * a2;
20740
20741 a1 = find_section_by_address (filedata, addr1);
20742 a2 = find_section_by_address (filedata, addr2);
9abca702 20743
d20e98ab
NC
20744 return a1 == a2 && a1 != NULL;
20745}
20746
015dc7e1 20747static bool
dda8d76d
NC
20748print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20749 Filedata * filedata)
c799a79d 20750{
015dc7e1
AM
20751 static unsigned long global_offset = 0;
20752 static unsigned long global_end = 0;
20753 static unsigned long func_offset = 0;
20754 static unsigned long func_end = 0;
c871dade 20755
015dc7e1
AM
20756 Elf_Internal_Sym *sym;
20757 const char *name;
20758 unsigned long start;
20759 unsigned long end;
20760 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20761
20762 switch (pnote->descsz)
c799a79d 20763 {
6f156d7a
NC
20764 case 0:
20765 /* A zero-length description means that the range of
20766 the previous note of the same type should be used. */
c799a79d 20767 if (is_open_attr)
c871dade 20768 {
6f156d7a
NC
20769 if (global_end > global_offset)
20770 printf (_(" Applies to region from %#lx to %#lx\n"),
20771 global_offset, global_end);
20772 else
20773 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20774 }
20775 else
20776 {
6f156d7a
NC
20777 if (func_end > func_offset)
20778 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20779 else
20780 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20781 }
015dc7e1 20782 return true;
9ef920e9 20783
6f156d7a
NC
20784 case 4:
20785 start = byte_get ((unsigned char *) pnote->descdata, 4);
20786 end = 0;
20787 break;
20788
20789 case 8:
c74147bb
NC
20790 start = byte_get ((unsigned char *) pnote->descdata, 4);
20791 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20792 break;
20793
20794 case 16:
20795 start = byte_get ((unsigned char *) pnote->descdata, 8);
20796 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20797 break;
9abca702 20798
6f156d7a 20799 default:
c799a79d
NC
20800 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20801 printf (_(" <invalid descsz>"));
015dc7e1 20802 return false;
c799a79d
NC
20803 }
20804
6f156d7a
NC
20805 name = NULL;
20806 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20807 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20808 in order to avoid them being confused with the start address of the
20809 first function in the file... */
20810 if (sym == NULL && is_open_attr)
20811 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20812 & name);
6f156d7a
NC
20813
20814 if (end == 0 && sym != NULL && sym->st_size > 0)
20815 end = start + sym->st_size;
c799a79d
NC
20816
20817 if (is_open_attr)
20818 {
d20e98ab
NC
20819 /* FIXME: Need to properly allow for section alignment.
20820 16 is just the alignment used on x86_64. */
20821 if (global_end > 0
20822 && start > BFD_ALIGN (global_end, 16)
20823 /* Build notes are not guaranteed to be organised in order of
20824 increasing address, but we should find the all of the notes
20825 for one section in the same place. */
20826 && same_section (filedata, start, global_end))
6f156d7a
NC
20827 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20828 global_end + 1, start - 1);
20829
20830 printf (_(" Applies to region from %#lx"), start);
20831 global_offset = start;
20832
20833 if (end)
20834 {
20835 printf (_(" to %#lx"), end);
20836 global_end = end;
20837 }
c799a79d
NC
20838 }
20839 else
20840 {
6f156d7a
NC
20841 printf (_(" Applies to region from %#lx"), start);
20842 func_offset = start;
20843
20844 if (end)
20845 {
20846 printf (_(" to %#lx"), end);
20847 func_end = end;
20848 }
c799a79d
NC
20849 }
20850
6f156d7a
NC
20851 if (sym && name)
20852 printf (_(" (%s)"), name);
20853
20854 printf ("\n");
015dc7e1 20855 return true;
9ef920e9
NC
20856}
20857
015dc7e1 20858static bool
9ef920e9
NC
20859print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20860{
1d15e434
NC
20861 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20862 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20863 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20864 char name_type;
20865 char name_attribute;
1d15e434 20866 const char * expected_types;
9ef920e9
NC
20867 const char * name = pnote->namedata;
20868 const char * text;
88305e1b 20869 signed int left;
9ef920e9
NC
20870
20871 if (name == NULL || pnote->namesz < 2)
20872 {
20873 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20874 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20875 return false;
9ef920e9
NC
20876 }
20877
6f156d7a
NC
20878 if (do_wide)
20879 left = 28;
20880 else
20881 left = 20;
88305e1b
NC
20882
20883 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20884 if (name[0] == 'G' && name[1] == 'A')
20885 {
6f156d7a
NC
20886 if (pnote->namesz < 4)
20887 {
20888 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20889 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20890 return false;
6f156d7a
NC
20891 }
20892
88305e1b
NC
20893 printf ("GA");
20894 name += 2;
20895 left -= 2;
20896 }
20897
9ef920e9
NC
20898 switch ((name_type = * name))
20899 {
20900 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20901 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20902 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20903 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20904 printf ("%c", * name);
88305e1b 20905 left --;
9ef920e9
NC
20906 break;
20907 default:
20908 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20909 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20910 return false;
9ef920e9
NC
20911 }
20912
9ef920e9
NC
20913 ++ name;
20914 text = NULL;
20915
20916 switch ((name_attribute = * name))
20917 {
20918 case GNU_BUILD_ATTRIBUTE_VERSION:
20919 text = _("<version>");
1d15e434 20920 expected_types = string_expected;
9ef920e9
NC
20921 ++ name;
20922 break;
20923 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20924 text = _("<stack prot>");
75d7d298 20925 expected_types = "!+*";
9ef920e9
NC
20926 ++ name;
20927 break;
20928 case GNU_BUILD_ATTRIBUTE_RELRO:
20929 text = _("<relro>");
1d15e434 20930 expected_types = bool_expected;
9ef920e9
NC
20931 ++ name;
20932 break;
20933 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20934 text = _("<stack size>");
1d15e434 20935 expected_types = number_expected;
9ef920e9
NC
20936 ++ name;
20937 break;
20938 case GNU_BUILD_ATTRIBUTE_TOOL:
20939 text = _("<tool>");
1d15e434 20940 expected_types = string_expected;
9ef920e9
NC
20941 ++ name;
20942 break;
20943 case GNU_BUILD_ATTRIBUTE_ABI:
20944 text = _("<ABI>");
20945 expected_types = "$*";
20946 ++ name;
20947 break;
20948 case GNU_BUILD_ATTRIBUTE_PIC:
20949 text = _("<PIC>");
1d15e434 20950 expected_types = number_expected;
9ef920e9
NC
20951 ++ name;
20952 break;
a8be5506
NC
20953 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20954 text = _("<short enum>");
1d15e434 20955 expected_types = bool_expected;
a8be5506
NC
20956 ++ name;
20957 break;
9ef920e9
NC
20958 default:
20959 if (ISPRINT (* name))
20960 {
20961 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20962
20963 if (len > left && ! do_wide)
20964 len = left;
75d7d298 20965 printf ("%.*s:", len, name);
9ef920e9 20966 left -= len;
0dd6ae21 20967 name += len;
9ef920e9
NC
20968 }
20969 else
20970 {
3e6b6445 20971 static char tmpbuf [128];
88305e1b 20972
3e6b6445
NC
20973 error (_("unrecognised byte in name field: %d\n"), * name);
20974 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20975 text = tmpbuf;
20976 name ++;
9ef920e9
NC
20977 }
20978 expected_types = "*$!+";
20979 break;
20980 }
20981
20982 if (text)
88305e1b 20983 left -= printf ("%s", text);
9ef920e9
NC
20984
20985 if (strchr (expected_types, name_type) == NULL)
75d7d298 20986 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20987
20988 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20989 {
20990 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20991 (unsigned long) pnote->namesz,
20992 (long) (name - pnote->namedata));
015dc7e1 20993 return false;
9ef920e9
NC
20994 }
20995
20996 if (left < 1 && ! do_wide)
015dc7e1 20997 return true;
9ef920e9
NC
20998
20999 switch (name_type)
21000 {
21001 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21002 {
b06b2c92 21003 unsigned int bytes;
ddef72cd
NC
21004 unsigned long long val = 0;
21005 unsigned int shift = 0;
21006 char * decoded = NULL;
21007
b06b2c92
NC
21008 bytes = pnote->namesz - (name - pnote->namedata);
21009 if (bytes > 0)
21010 /* The -1 is because the name field is always 0 terminated, and we
21011 want to be able to ensure that the shift in the while loop below
21012 will not overflow. */
21013 -- bytes;
21014
ddef72cd
NC
21015 if (bytes > sizeof (val))
21016 {
3e6b6445
NC
21017 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21018 bytes);
21019 bytes = sizeof (val);
ddef72cd 21020 }
3e6b6445
NC
21021 /* We do not bother to warn if bytes == 0 as this can
21022 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21023
21024 while (bytes --)
21025 {
54b8331d 21026 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21027
21028 val |= byte << shift;
9ef920e9
NC
21029 shift += 8;
21030 }
21031
75d7d298 21032 switch (name_attribute)
9ef920e9 21033 {
75d7d298 21034 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21035 switch (val)
21036 {
75d7d298
NC
21037 case 0: decoded = "static"; break;
21038 case 1: decoded = "pic"; break;
21039 case 2: decoded = "PIC"; break;
21040 case 3: decoded = "pie"; break;
21041 case 4: decoded = "PIE"; break;
21042 default: break;
9ef920e9 21043 }
75d7d298
NC
21044 break;
21045 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21046 switch (val)
9ef920e9 21047 {
75d7d298
NC
21048 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21049 case 0: decoded = "off"; break;
21050 case 1: decoded = "on"; break;
21051 case 2: decoded = "all"; break;
21052 case 3: decoded = "strong"; break;
21053 case 4: decoded = "explicit"; break;
21054 default: break;
9ef920e9 21055 }
75d7d298
NC
21056 break;
21057 default:
21058 break;
9ef920e9
NC
21059 }
21060
75d7d298 21061 if (decoded != NULL)
3e6b6445
NC
21062 {
21063 print_symbol (-left, decoded);
21064 left = 0;
21065 }
21066 else if (val == 0)
21067 {
21068 printf ("0x0");
21069 left -= 3;
21070 }
9ef920e9 21071 else
75d7d298
NC
21072 {
21073 if (do_wide)
ddef72cd 21074 left -= printf ("0x%llx", val);
75d7d298 21075 else
ddef72cd 21076 left -= printf ("0x%-.*llx", left, val);
75d7d298 21077 }
9ef920e9
NC
21078 }
21079 break;
21080 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21081 left -= print_symbol (- left, name);
21082 break;
21083 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21084 left -= print_symbol (- left, "true");
21085 break;
21086 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21087 left -= print_symbol (- left, "false");
21088 break;
21089 }
21090
21091 if (do_wide && left > 0)
21092 printf ("%-*s", left, " ");
9abca702 21093
015dc7e1 21094 return true;
9ef920e9
NC
21095}
21096
6d118b09
NC
21097/* Note that by the ELF standard, the name field is already null byte
21098 terminated, and namesz includes the terminating null byte.
21099 I.E. the value of namesz for the name "FSF" is 4.
21100
e3c8793a 21101 If the value of namesz is zero, there is no name present. */
9ef920e9 21102
015dc7e1 21103static bool
9ef920e9 21104process_note (Elf_Internal_Note * pnote,
dda8d76d 21105 Filedata * filedata)
779fe533 21106{
2cf0635d
NC
21107 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21108 const char * nt;
9437c45b
JT
21109
21110 if (pnote->namesz == 0)
1ec5cd37
NC
21111 /* If there is no note name, then use the default set of
21112 note type strings. */
dda8d76d 21113 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21114
24d127aa 21115 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21116 /* GNU-specific object file notes. */
21117 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21118
24d127aa 21119 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21120 /* FreeBSD-specific core file notes. */
dda8d76d 21121 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21122
24d127aa 21123 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21124 /* NetBSD-specific core file notes. */
dda8d76d 21125 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21126
24d127aa 21127 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21128 /* NetBSD-specific core file notes. */
21129 return process_netbsd_elf_note (pnote);
21130
24d127aa 21131 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21132 /* NetBSD-specific core file notes. */
21133 return process_netbsd_elf_note (pnote);
21134
98ca73af
FC
21135 else if (startswith (pnote->namedata, "OpenBSD"))
21136 /* OpenBSD-specific core file notes. */
21137 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21138
e9b095a5 21139 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21140 {
21141 /* SPU-specific core file notes. */
21142 nt = pnote->namedata + 4;
21143 name = "SPU";
21144 }
21145
24d127aa 21146 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21147 /* VMS/ia64-specific file notes. */
21148 nt = get_ia64_vms_note_type (pnote->type);
21149
24d127aa 21150 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21151 nt = get_stapsdt_note_type (pnote->type);
21152
9437c45b 21153 else
1ec5cd37
NC
21154 /* Don't recognize this note name; just use the default set of
21155 note type strings. */
dda8d76d 21156 nt = get_note_type (filedata, pnote->type);
9437c45b 21157
1449284b 21158 printf (" ");
9ef920e9 21159
24d127aa 21160 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21161 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21162 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21163 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21164 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21165 print_gnu_build_attribute_name (pnote);
21166 else
21167 print_symbol (-20, name);
21168
21169 if (do_wide)
21170 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21171 else
21172 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21173
24d127aa 21174 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21175 return print_ia64_vms_note (pnote);
24d127aa 21176 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21177 return print_gnu_note (filedata, pnote);
24d127aa 21178 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21179 return print_stapsdt_note (pnote);
24d127aa 21180 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21181 return print_core_note (pnote);
24d127aa 21182 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21183 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21184 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21185 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21186 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21187 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 21188
9ef920e9 21189 if (pnote->descsz)
1449284b
NC
21190 {
21191 unsigned long i;
21192
21193 printf (_(" description data: "));
21194 for (i = 0; i < pnote->descsz; i++)
178d8719 21195 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
21196 if (!do_wide)
21197 printf ("\n");
1449284b
NC
21198 }
21199
9ef920e9
NC
21200 if (do_wide)
21201 printf ("\n");
21202
015dc7e1 21203 return true;
1449284b 21204}
6d118b09 21205
015dc7e1 21206static bool
dda8d76d
NC
21207process_notes_at (Filedata * filedata,
21208 Elf_Internal_Shdr * section,
21209 bfd_vma offset,
82ed9683
L
21210 bfd_vma length,
21211 bfd_vma align)
779fe533 21212{
015dc7e1
AM
21213 Elf_External_Note *pnotes;
21214 Elf_External_Note *external;
21215 char *end;
21216 bool res = true;
103f02d3 21217
779fe533 21218 if (length <= 0)
015dc7e1 21219 return false;
103f02d3 21220
1449284b
NC
21221 if (section)
21222 {
dda8d76d 21223 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21224 if (pnotes)
32ec8896 21225 {
dda8d76d 21226 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21227 {
21228 free (pnotes);
015dc7e1 21229 return false;
f761cb13 21230 }
32ec8896 21231 }
1449284b
NC
21232 }
21233 else
82ed9683 21234 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21235 _("notes"));
4dff97b2 21236
dd24e3da 21237 if (pnotes == NULL)
015dc7e1 21238 return false;
779fe533 21239
103f02d3 21240 external = pnotes;
103f02d3 21241
ca0e11aa
NC
21242 if (filedata->is_separate)
21243 printf (_("In linked file '%s': "), filedata->file_name);
21244 else
21245 printf ("\n");
1449284b 21246 if (section)
ca0e11aa 21247 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21248 else
ca0e11aa 21249 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21250 (unsigned long) offset, (unsigned long) length);
21251
82ed9683
L
21252 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21253 specifies that notes should be aligned to 4 bytes in 32-bit
21254 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21255 we also support 4 byte alignment in 64-bit objects. If section
21256 alignment is less than 4, we treate alignment as 4 bytes. */
21257 if (align < 4)
21258 align = 4;
21259 else if (align != 4 && align != 8)
21260 {
21261 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21262 (long) align);
a788aedd 21263 free (pnotes);
015dc7e1 21264 return false;
82ed9683
L
21265 }
21266
dbe15e4e 21267 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21268
c8071705
NC
21269 end = (char *) pnotes + length;
21270 while ((char *) external < end)
779fe533 21271 {
b34976b6 21272 Elf_Internal_Note inote;
15b42fb0 21273 size_t min_notesz;
4dff97b2 21274 char * next;
2cf0635d 21275 char * temp = NULL;
c8071705 21276 size_t data_remaining = end - (char *) external;
6d118b09 21277
dda8d76d 21278 if (!is_ia64_vms (filedata))
15b42fb0 21279 {
9dd3a467
NC
21280 /* PR binutils/15191
21281 Make sure that there is enough data to read. */
15b42fb0
AM
21282 min_notesz = offsetof (Elf_External_Note, name);
21283 if (data_remaining < min_notesz)
9dd3a467 21284 {
d3a49aa8
AM
21285 warn (ngettext ("Corrupt note: only %ld byte remains, "
21286 "not enough for a full note\n",
21287 "Corrupt note: only %ld bytes remain, "
21288 "not enough for a full note\n",
21289 data_remaining),
21290 (long) data_remaining);
9dd3a467
NC
21291 break;
21292 }
5396a86e
AM
21293 data_remaining -= min_notesz;
21294
15b42fb0
AM
21295 inote.type = BYTE_GET (external->type);
21296 inote.namesz = BYTE_GET (external->namesz);
21297 inote.namedata = external->name;
21298 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21299 inote.descdata = ((char *) external
4dff97b2 21300 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21301 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21302 next = ((char *) external
4dff97b2 21303 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21304 }
00e98fc7 21305 else
15b42fb0
AM
21306 {
21307 Elf64_External_VMS_Note *vms_external;
00e98fc7 21308
9dd3a467
NC
21309 /* PR binutils/15191
21310 Make sure that there is enough data to read. */
15b42fb0
AM
21311 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21312 if (data_remaining < min_notesz)
9dd3a467 21313 {
d3a49aa8
AM
21314 warn (ngettext ("Corrupt note: only %ld byte remains, "
21315 "not enough for a full note\n",
21316 "Corrupt note: only %ld bytes remain, "
21317 "not enough for a full note\n",
21318 data_remaining),
21319 (long) data_remaining);
9dd3a467
NC
21320 break;
21321 }
5396a86e 21322 data_remaining -= min_notesz;
3e55a963 21323
15b42fb0
AM
21324 vms_external = (Elf64_External_VMS_Note *) external;
21325 inote.type = BYTE_GET (vms_external->type);
21326 inote.namesz = BYTE_GET (vms_external->namesz);
21327 inote.namedata = vms_external->name;
21328 inote.descsz = BYTE_GET (vms_external->descsz);
21329 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21330 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21331 next = inote.descdata + align_power (inote.descsz, 3);
21332 }
21333
5396a86e
AM
21334 /* PR 17531: file: 3443835e. */
21335 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21336 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21337 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21338 || (size_t) (next - inote.descdata) < inote.descsz
21339 || ((size_t) (next - inote.descdata)
21340 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21341 {
15b42fb0 21342 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21343 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21344 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21345 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21346 break;
21347 }
21348
15b42fb0 21349 external = (Elf_External_Note *) next;
dd24e3da 21350
6d118b09
NC
21351 /* Verify that name is null terminated. It appears that at least
21352 one version of Linux (RedHat 6.0) generates corefiles that don't
21353 comply with the ELF spec by failing to include the null byte in
21354 namesz. */
18344509 21355 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21356 {
5396a86e 21357 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21358 {
5396a86e
AM
21359 temp = (char *) malloc (inote.namesz + 1);
21360 if (temp == NULL)
21361 {
21362 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21363 res = false;
5396a86e
AM
21364 break;
21365 }
76da6bbe 21366
5396a86e
AM
21367 memcpy (temp, inote.namedata, inote.namesz);
21368 inote.namedata = temp;
21369 }
21370 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21371 }
21372
dda8d76d 21373 if (! process_note (& inote, filedata))
015dc7e1 21374 res = false;
103f02d3 21375
9db70fc3
AM
21376 free (temp);
21377 temp = NULL;
779fe533
NC
21378 }
21379
21380 free (pnotes);
103f02d3 21381
779fe533
NC
21382 return res;
21383}
21384
015dc7e1 21385static bool
dda8d76d 21386process_corefile_note_segments (Filedata * filedata)
779fe533 21387{
015dc7e1 21388 Elf_Internal_Phdr *segment;
b34976b6 21389 unsigned int i;
015dc7e1 21390 bool res = true;
103f02d3 21391
dda8d76d 21392 if (! get_program_headers (filedata))
015dc7e1 21393 return true;
103f02d3 21394
dda8d76d
NC
21395 for (i = 0, segment = filedata->program_headers;
21396 i < filedata->file_header.e_phnum;
b34976b6 21397 i++, segment++)
779fe533
NC
21398 {
21399 if (segment->p_type == PT_NOTE)
dda8d76d 21400 if (! process_notes_at (filedata, NULL,
32ec8896 21401 (bfd_vma) segment->p_offset,
82ed9683
L
21402 (bfd_vma) segment->p_filesz,
21403 (bfd_vma) segment->p_align))
015dc7e1 21404 res = false;
779fe533 21405 }
103f02d3 21406
779fe533
NC
21407 return res;
21408}
21409
015dc7e1 21410static bool
dda8d76d 21411process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21412{
21413 Elf_External_Note * pnotes;
21414 Elf_External_Note * external;
c8071705 21415 char * end;
015dc7e1 21416 bool res = true;
685080f2
NC
21417
21418 if (length <= 0)
015dc7e1 21419 return false;
685080f2 21420
dda8d76d 21421 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21422 _("v850 notes"));
21423 if (pnotes == NULL)
015dc7e1 21424 return false;
685080f2
NC
21425
21426 external = pnotes;
c8071705 21427 end = (char*) pnotes + length;
685080f2
NC
21428
21429 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21430 (unsigned long) offset, (unsigned long) length);
21431
c8071705 21432 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21433 {
21434 Elf_External_Note * next;
21435 Elf_Internal_Note inote;
21436
21437 inote.type = BYTE_GET (external->type);
21438 inote.namesz = BYTE_GET (external->namesz);
21439 inote.namedata = external->name;
21440 inote.descsz = BYTE_GET (external->descsz);
21441 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21442 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21443
c8071705
NC
21444 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21445 {
21446 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21447 inote.descdata = inote.namedata;
21448 inote.namesz = 0;
21449 }
21450
685080f2
NC
21451 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21452
c8071705 21453 if ( ((char *) next > end)
685080f2
NC
21454 || ((char *) next < (char *) pnotes))
21455 {
21456 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21457 (unsigned long) ((char *) external - (char *) pnotes));
21458 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21459 inote.type, inote.namesz, inote.descsz);
21460 break;
21461 }
21462
21463 external = next;
21464
21465 /* Prevent out-of-bounds indexing. */
c8071705 21466 if ( inote.namedata + inote.namesz > end
685080f2
NC
21467 || inote.namedata + inote.namesz < inote.namedata)
21468 {
21469 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21470 (unsigned long) ((char *) external - (char *) pnotes));
21471 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21472 inote.type, inote.namesz, inote.descsz);
21473 break;
21474 }
21475
21476 printf (" %s: ", get_v850_elf_note_type (inote.type));
21477
21478 if (! print_v850_note (& inote))
21479 {
015dc7e1 21480 res = false;
685080f2
NC
21481 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21482 inote.namesz, inote.descsz);
21483 }
21484 }
21485
21486 free (pnotes);
21487
21488 return res;
21489}
21490
015dc7e1 21491static bool
dda8d76d 21492process_note_sections (Filedata * filedata)
1ec5cd37 21493{
015dc7e1 21494 Elf_Internal_Shdr *section;
1ec5cd37 21495 unsigned long i;
32ec8896 21496 unsigned int n = 0;
015dc7e1 21497 bool res = true;
1ec5cd37 21498
dda8d76d
NC
21499 for (i = 0, section = filedata->section_headers;
21500 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21501 i++, section++)
685080f2
NC
21502 {
21503 if (section->sh_type == SHT_NOTE)
21504 {
dda8d76d 21505 if (! process_notes_at (filedata, section,
32ec8896 21506 (bfd_vma) section->sh_offset,
82ed9683
L
21507 (bfd_vma) section->sh_size,
21508 (bfd_vma) section->sh_addralign))
015dc7e1 21509 res = false;
685080f2
NC
21510 n++;
21511 }
21512
dda8d76d
NC
21513 if (( filedata->file_header.e_machine == EM_V800
21514 || filedata->file_header.e_machine == EM_V850
21515 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21516 && section->sh_type == SHT_RENESAS_INFO)
21517 {
dda8d76d 21518 if (! process_v850_notes (filedata,
32ec8896
NC
21519 (bfd_vma) section->sh_offset,
21520 (bfd_vma) section->sh_size))
015dc7e1 21521 res = false;
685080f2
NC
21522 n++;
21523 }
21524 }
df565f32
NC
21525
21526 if (n == 0)
21527 /* Try processing NOTE segments instead. */
dda8d76d 21528 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21529
21530 return res;
21531}
21532
015dc7e1 21533static bool
dda8d76d 21534process_notes (Filedata * filedata)
779fe533
NC
21535{
21536 /* If we have not been asked to display the notes then do nothing. */
21537 if (! do_notes)
015dc7e1 21538 return true;
103f02d3 21539
dda8d76d
NC
21540 if (filedata->file_header.e_type != ET_CORE)
21541 return process_note_sections (filedata);
103f02d3 21542
779fe533 21543 /* No program headers means no NOTE segment. */
dda8d76d
NC
21544 if (filedata->file_header.e_phnum > 0)
21545 return process_corefile_note_segments (filedata);
779fe533 21546
ca0e11aa
NC
21547 if (filedata->is_separate)
21548 printf (_("No notes found in linked file '%s'.\n"),
21549 filedata->file_name);
21550 else
21551 printf (_("No notes found file.\n"));
21552
015dc7e1 21553 return true;
779fe533
NC
21554}
21555
60abdbed
NC
21556static unsigned char *
21557display_public_gnu_attributes (unsigned char * start,
21558 const unsigned char * const end)
21559{
21560 printf (_(" Unknown GNU attribute: %s\n"), start);
21561
21562 start += strnlen ((char *) start, end - start);
21563 display_raw_attribute (start, end);
21564
21565 return (unsigned char *) end;
21566}
21567
21568static unsigned char *
21569display_generic_attribute (unsigned char * start,
21570 unsigned int tag,
21571 const unsigned char * const end)
21572{
21573 if (tag == 0)
21574 return (unsigned char *) end;
21575
21576 return display_tag_value (tag, start, end);
21577}
21578
015dc7e1 21579static bool
dda8d76d 21580process_arch_specific (Filedata * filedata)
252b5132 21581{
a952a375 21582 if (! do_arch)
015dc7e1 21583 return true;
a952a375 21584
dda8d76d 21585 switch (filedata->file_header.e_machine)
252b5132 21586 {
53a346d8
CZ
21587 case EM_ARC:
21588 case EM_ARC_COMPACT:
21589 case EM_ARC_COMPACT2:
dda8d76d 21590 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21591 display_arc_attribute,
21592 display_generic_attribute);
11c1ff18 21593 case EM_ARM:
dda8d76d 21594 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21595 display_arm_attribute,
21596 display_generic_attribute);
21597
252b5132 21598 case EM_MIPS:
4fe85591 21599 case EM_MIPS_RS3_LE:
dda8d76d 21600 return process_mips_specific (filedata);
60abdbed
NC
21601
21602 case EM_MSP430:
dda8d76d 21603 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21604 display_msp430_attribute,
c0ea7c52 21605 display_msp430_gnu_attribute);
60abdbed 21606
2dc8dd17
JW
21607 case EM_RISCV:
21608 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21609 display_riscv_attribute,
21610 display_generic_attribute);
21611
35c08157 21612 case EM_NDS32:
dda8d76d 21613 return process_nds32_specific (filedata);
60abdbed 21614
85f7484a
PB
21615 case EM_68K:
21616 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21617 display_m68k_gnu_attribute);
21618
34c8bcba 21619 case EM_PPC:
b82317dd 21620 case EM_PPC64:
dda8d76d 21621 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21622 display_power_gnu_attribute);
21623
643f7afb
AK
21624 case EM_S390:
21625 case EM_S390_OLD:
dda8d76d 21626 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21627 display_s390_gnu_attribute);
21628
9e8c70f9
DM
21629 case EM_SPARC:
21630 case EM_SPARC32PLUS:
21631 case EM_SPARCV9:
dda8d76d 21632 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21633 display_sparc_gnu_attribute);
21634
59e6276b 21635 case EM_TI_C6000:
dda8d76d 21636 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21637 display_tic6x_attribute,
21638 display_generic_attribute);
21639
0861f561
CQ
21640 case EM_CSKY:
21641 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21642 display_csky_attribute, NULL);
21643
252b5132 21644 default:
dda8d76d 21645 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21646 display_public_gnu_attributes,
21647 display_generic_attribute);
252b5132 21648 }
252b5132
RH
21649}
21650
015dc7e1 21651static bool
dda8d76d 21652get_file_header (Filedata * filedata)
252b5132 21653{
9ea033b2 21654 /* Read in the identity array. */
dda8d76d 21655 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21656 return false;
252b5132 21657
9ea033b2 21658 /* Determine how to read the rest of the header. */
dda8d76d 21659 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21660 {
1a0670f3
AM
21661 default:
21662 case ELFDATANONE:
adab8cdc
AO
21663 case ELFDATA2LSB:
21664 byte_get = byte_get_little_endian;
21665 byte_put = byte_put_little_endian;
21666 break;
21667 case ELFDATA2MSB:
21668 byte_get = byte_get_big_endian;
21669 byte_put = byte_put_big_endian;
21670 break;
9ea033b2
NC
21671 }
21672
21673 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21674 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21675
21676 /* Read in the rest of the header. */
21677 if (is_32bit_elf)
21678 {
21679 Elf32_External_Ehdr ehdr32;
252b5132 21680
dda8d76d 21681 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21682 return false;
103f02d3 21683
dda8d76d
NC
21684 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21685 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21686 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21687 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21688 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21689 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21690 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21691 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21692 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21693 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21694 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21695 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21696 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21697 }
252b5132 21698 else
9ea033b2
NC
21699 {
21700 Elf64_External_Ehdr ehdr64;
a952a375
NC
21701
21702 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21703 we will not be able to cope with the 64bit data found in
21704 64 ELF files. Detect this now and abort before we start
50c2245b 21705 overwriting things. */
a952a375
NC
21706 if (sizeof (bfd_vma) < 8)
21707 {
e3c8793a
NC
21708 error (_("This instance of readelf has been built without support for a\n\
2170964 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21710 return false;
a952a375 21711 }
103f02d3 21712
dda8d76d 21713 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21714 return false;
103f02d3 21715
dda8d76d
NC
21716 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21717 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21718 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21719 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21720 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21721 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21722 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21723 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21724 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21725 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21726 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21727 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21728 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21729 }
252b5132 21730
015dc7e1 21731 return true;
252b5132
RH
21732}
21733
13acb58d
AM
21734static void
21735free_filedata (Filedata *filedata)
21736{
21737 free (filedata->program_interpreter);
13acb58d 21738 free (filedata->program_headers);
13acb58d 21739 free (filedata->section_headers);
13acb58d 21740 free (filedata->string_table);
13acb58d 21741 free (filedata->dump.dump_sects);
13acb58d 21742 free (filedata->dynamic_strings);
13acb58d 21743 free (filedata->dynamic_symbols);
13acb58d 21744 free (filedata->dynamic_syminfo);
13acb58d 21745 free (filedata->dynamic_section);
13acb58d
AM
21746
21747 while (filedata->symtab_shndx_list != NULL)
21748 {
21749 elf_section_list *next = filedata->symtab_shndx_list->next;
21750 free (filedata->symtab_shndx_list);
21751 filedata->symtab_shndx_list = next;
21752 }
21753
21754 free (filedata->section_headers_groups);
13acb58d
AM
21755
21756 if (filedata->section_groups)
21757 {
21758 size_t i;
21759 struct group_list * g;
21760 struct group_list * next;
21761
21762 for (i = 0; i < filedata->group_count; i++)
21763 {
21764 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21765 {
21766 next = g->next;
21767 free (g);
21768 }
21769 }
21770
21771 free (filedata->section_groups);
13acb58d 21772 }
066f8fbe
AM
21773 memset (&filedata->section_headers, 0,
21774 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
21775}
21776
dda8d76d
NC
21777static void
21778close_file (Filedata * filedata)
21779{
21780 if (filedata)
21781 {
21782 if (filedata->handle)
21783 fclose (filedata->handle);
21784 free (filedata);
21785 }
21786}
21787
21788void
21789close_debug_file (void * data)
21790{
13acb58d 21791 free_filedata ((Filedata *) data);
dda8d76d
NC
21792 close_file ((Filedata *) data);
21793}
21794
21795static Filedata *
015dc7e1 21796open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21797{
21798 struct stat statbuf;
21799 Filedata * filedata = NULL;
21800
21801 if (stat (pathname, & statbuf) < 0
21802 || ! S_ISREG (statbuf.st_mode))
21803 goto fail;
21804
21805 filedata = calloc (1, sizeof * filedata);
21806 if (filedata == NULL)
21807 goto fail;
21808
21809 filedata->handle = fopen (pathname, "rb");
21810 if (filedata->handle == NULL)
21811 goto fail;
21812
21813 filedata->file_size = (bfd_size_type) statbuf.st_size;
21814 filedata->file_name = pathname;
ca0e11aa 21815 filedata->is_separate = is_separate;
dda8d76d
NC
21816
21817 if (! get_file_header (filedata))
21818 goto fail;
21819
4de91c10
AM
21820 if (!get_section_headers (filedata, false))
21821 goto fail;
dda8d76d
NC
21822
21823 return filedata;
21824
21825 fail:
21826 if (filedata)
21827 {
21828 if (filedata->handle)
21829 fclose (filedata->handle);
21830 free (filedata);
21831 }
21832 return NULL;
21833}
21834
21835void *
21836open_debug_file (const char * pathname)
21837{
015dc7e1 21838 return open_file (pathname, true);
dda8d76d
NC
21839}
21840
835f2fae
NC
21841static void
21842initialise_dump_sects (Filedata * filedata)
21843{
21844 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21845 Note we do this even if cmdline_dump_sects is empty because we
21846 must make sure that the dump_sets array is zeroed out before each
21847 object file is processed. */
21848 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21849 memset (filedata->dump.dump_sects, 0,
21850 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21851
21852 if (cmdline.num_dump_sects > 0)
21853 {
21854 if (filedata->dump.num_dump_sects == 0)
21855 /* A sneaky way of allocating the dump_sects array. */
21856 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21857
21858 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21859 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21860 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21861 }
21862}
21863
fb52b2f4
NC
21864/* Process one ELF object file according to the command line options.
21865 This file may actually be stored in an archive. The file is
32ec8896
NC
21866 positioned at the start of the ELF object. Returns TRUE if no
21867 problems were encountered, FALSE otherwise. */
fb52b2f4 21868
015dc7e1 21869static bool
dda8d76d 21870process_object (Filedata * filedata)
252b5132 21871{
015dc7e1 21872 bool have_separate_files;
252b5132 21873 unsigned int i;
015dc7e1 21874 bool res;
252b5132 21875
dda8d76d 21876 if (! get_file_header (filedata))
252b5132 21877 {
dda8d76d 21878 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21879 return false;
252b5132
RH
21880 }
21881
21882 /* Initialise per file variables. */
978c4450
AM
21883 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21884 filedata->version_info[i] = 0;
252b5132 21885
978c4450
AM
21886 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21887 filedata->dynamic_info[i] = 0;
21888 filedata->dynamic_info_DT_GNU_HASH = 0;
21889 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21890
21891 /* Process the file. */
21892 if (show_name)
dda8d76d 21893 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21894
835f2fae 21895 initialise_dump_sects (filedata);
d70c5fc7 21896
4de91c10
AM
21897 /* There may be some extensions in the first section header. Don't
21898 bomb if we can't read it. */
21899 get_section_headers (filedata, true);
21900
dda8d76d 21901 if (! process_file_header (filedata))
4de91c10
AM
21902 {
21903 res = false;
21904 goto out;
21905 }
252b5132 21906
e331b18d
AM
21907 /* Throw away the single section header read above, so that we
21908 re-read the entire set. */
21909 free (filedata->section_headers);
21910 filedata->section_headers = NULL;
21911
dda8d76d 21912 if (! process_section_headers (filedata))
2f62977e 21913 {
32ec8896 21914 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21915 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21916
2f62977e 21917 if (! do_using_dynamic)
015dc7e1 21918 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21919 }
252b5132 21920
dda8d76d 21921 if (! process_section_groups (filedata))
32ec8896 21922 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21923 do_unwind = false;
d1f5c6e3 21924
93df3340
AM
21925 process_program_headers (filedata);
21926
21927 res = process_dynamic_section (filedata);
252b5132 21928
dda8d76d 21929 if (! process_relocs (filedata))
015dc7e1 21930 res = false;
252b5132 21931
dda8d76d 21932 if (! process_unwind (filedata))
015dc7e1 21933 res = false;
4d6ed7c8 21934
dda8d76d 21935 if (! process_symbol_table (filedata))
015dc7e1 21936 res = false;
252b5132 21937
0f03783c 21938 if (! process_lto_symbol_tables (filedata))
015dc7e1 21939 res = false;
b9e920ec 21940
dda8d76d 21941 if (! process_syminfo (filedata))
015dc7e1 21942 res = false;
252b5132 21943
dda8d76d 21944 if (! process_version_sections (filedata))
015dc7e1 21945 res = false;
252b5132 21946
82ed9683 21947 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21948 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21949 else
015dc7e1 21950 have_separate_files = false;
dda8d76d
NC
21951
21952 if (! process_section_contents (filedata))
015dc7e1 21953 res = false;
f5842774 21954
24841daa 21955 if (have_separate_files)
dda8d76d 21956 {
24841daa
NC
21957 separate_info * d;
21958
21959 for (d = first_separate_info; d != NULL; d = d->next)
21960 {
835f2fae
NC
21961 initialise_dump_sects (d->handle);
21962
ca0e11aa 21963 if (process_links && ! process_file_header (d->handle))
015dc7e1 21964 res = false;
ca0e11aa 21965 else if (! process_section_headers (d->handle))
015dc7e1 21966 res = false;
d6bfbc39 21967 else if (! process_section_contents (d->handle))
015dc7e1 21968 res = false;
ca0e11aa
NC
21969 else if (process_links)
21970 {
ca0e11aa 21971 if (! process_section_groups (d->handle))
015dc7e1 21972 res = false;
93df3340 21973 process_program_headers (d->handle);
ca0e11aa 21974 if (! process_dynamic_section (d->handle))
015dc7e1 21975 res = false;
ca0e11aa 21976 if (! process_relocs (d->handle))
015dc7e1 21977 res = false;
ca0e11aa 21978 if (! process_unwind (d->handle))
015dc7e1 21979 res = false;
ca0e11aa 21980 if (! process_symbol_table (d->handle))
015dc7e1 21981 res = false;
ca0e11aa 21982 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21983 res = false;
ca0e11aa 21984 if (! process_syminfo (d->handle))
015dc7e1 21985 res = false;
ca0e11aa 21986 if (! process_version_sections (d->handle))
015dc7e1 21987 res = false;
ca0e11aa 21988 if (! process_notes (d->handle))
015dc7e1 21989 res = false;
ca0e11aa 21990 }
24841daa
NC
21991 }
21992
21993 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21994 }
21995
21996 if (! process_notes (filedata))
015dc7e1 21997 res = false;
103f02d3 21998
dda8d76d 21999 if (! process_gnu_liblist (filedata))
015dc7e1 22000 res = false;
047b2264 22001
dda8d76d 22002 if (! process_arch_specific (filedata))
015dc7e1 22003 res = false;
252b5132 22004
4de91c10 22005 out:
13acb58d 22006 free_filedata (filedata);
e4b17d5c 22007
19e6b90e 22008 free_debug_memory ();
18bd398b 22009
32ec8896 22010 return res;
252b5132
RH
22011}
22012
2cf0635d 22013/* Process an ELF archive.
32ec8896
NC
22014 On entry the file is positioned just after the ARMAG string.
22015 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22016
015dc7e1
AM
22017static bool
22018process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22019{
22020 struct archive_info arch;
22021 struct archive_info nested_arch;
22022 size_t got;
015dc7e1 22023 bool ret = true;
2cf0635d 22024
015dc7e1 22025 show_name = true;
2cf0635d
NC
22026
22027 /* The ARCH structure is used to hold information about this archive. */
22028 arch.file_name = NULL;
22029 arch.file = NULL;
22030 arch.index_array = NULL;
22031 arch.sym_table = NULL;
22032 arch.longnames = NULL;
22033
22034 /* The NESTED_ARCH structure is used as a single-item cache of information
22035 about a nested archive (when members of a thin archive reside within
22036 another regular archive file). */
22037 nested_arch.file_name = NULL;
22038 nested_arch.file = NULL;
22039 nested_arch.index_array = NULL;
22040 nested_arch.sym_table = NULL;
22041 nested_arch.longnames = NULL;
22042
dda8d76d 22043 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22044 filedata->file_size, is_thin_archive,
22045 do_archive_index) != 0)
2cf0635d 22046 {
015dc7e1 22047 ret = false;
2cf0635d 22048 goto out;
4145f1d5 22049 }
fb52b2f4 22050
4145f1d5
NC
22051 if (do_archive_index)
22052 {
2cf0635d 22053 if (arch.sym_table == NULL)
1cb7d8b1
AM
22054 error (_("%s: unable to dump the index as none was found\n"),
22055 filedata->file_name);
4145f1d5
NC
22056 else
22057 {
591f7597 22058 unsigned long i, l;
4145f1d5
NC
22059 unsigned long current_pos;
22060
1cb7d8b1
AM
22061 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22062 "in the symbol table)\n"),
22063 filedata->file_name, (unsigned long) arch.index_num,
22064 arch.sym_size);
dda8d76d
NC
22065
22066 current_pos = ftell (filedata->handle);
4145f1d5 22067
2cf0635d 22068 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22069 {
1cb7d8b1
AM
22070 if (i == 0
22071 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22072 {
22073 char * member_name
22074 = get_archive_member_name_at (&arch, arch.index_array[i],
22075 &nested_arch);
2cf0635d 22076
1cb7d8b1
AM
22077 if (member_name != NULL)
22078 {
22079 char * qualified_name
22080 = make_qualified_name (&arch, &nested_arch,
22081 member_name);
2cf0635d 22082
1cb7d8b1
AM
22083 if (qualified_name != NULL)
22084 {
22085 printf (_("Contents of binary %s at offset "),
22086 qualified_name);
c2a7d3f5
NC
22087 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22088 putchar ('\n');
1cb7d8b1
AM
22089 free (qualified_name);
22090 }
fd486f32 22091 free (member_name);
4145f1d5
NC
22092 }
22093 }
2cf0635d
NC
22094
22095 if (l >= arch.sym_size)
4145f1d5 22096 {
1cb7d8b1
AM
22097 error (_("%s: end of the symbol table reached "
22098 "before the end of the index\n"),
dda8d76d 22099 filedata->file_name);
015dc7e1 22100 ret = false;
cb8f3167 22101 break;
4145f1d5 22102 }
591f7597 22103 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22104 printf ("\t%.*s\n",
22105 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22106 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22107 }
22108
67ce483b 22109 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22110 l = (l + 7) & ~ 7;
22111 else
22112 l += l & 1;
22113
2cf0635d 22114 if (l < arch.sym_size)
32ec8896 22115 {
d3a49aa8
AM
22116 error (ngettext ("%s: %ld byte remains in the symbol table, "
22117 "but without corresponding entries in "
22118 "the index table\n",
22119 "%s: %ld bytes remain in the symbol table, "
22120 "but without corresponding entries in "
22121 "the index table\n",
22122 arch.sym_size - l),
dda8d76d 22123 filedata->file_name, arch.sym_size - l);
015dc7e1 22124 ret = false;
32ec8896 22125 }
4145f1d5 22126
dda8d76d 22127 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22128 {
1cb7d8b1
AM
22129 error (_("%s: failed to seek back to start of object files "
22130 "in the archive\n"),
dda8d76d 22131 filedata->file_name);
015dc7e1 22132 ret = false;
2cf0635d 22133 goto out;
4145f1d5 22134 }
fb52b2f4 22135 }
4145f1d5
NC
22136
22137 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22138 && !do_segments && !do_header && !do_dump && !do_version
22139 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22140 && !do_section_groups && !do_dyn_syms)
2cf0635d 22141 {
015dc7e1 22142 ret = true; /* Archive index only. */
2cf0635d
NC
22143 goto out;
22144 }
fb52b2f4
NC
22145 }
22146
fb52b2f4
NC
22147 while (1)
22148 {
2cf0635d
NC
22149 char * name;
22150 size_t namelen;
22151 char * qualified_name;
22152
22153 /* Read the next archive header. */
dda8d76d 22154 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22155 {
22156 error (_("%s: failed to seek to next archive header\n"),
22157 arch.file_name);
015dc7e1 22158 ret = false;
1cb7d8b1
AM
22159 break;
22160 }
dda8d76d 22161 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22162 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22163 {
22164 if (got == 0)
2cf0635d 22165 break;
28e817cc
NC
22166 /* PR 24049 - we cannot use filedata->file_name as this will
22167 have already been freed. */
22168 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22169
015dc7e1 22170 ret = false;
1cb7d8b1
AM
22171 break;
22172 }
2cf0635d 22173 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22174 {
22175 error (_("%s: did not find a valid archive header\n"),
22176 arch.file_name);
015dc7e1 22177 ret = false;
1cb7d8b1
AM
22178 break;
22179 }
2cf0635d
NC
22180
22181 arch.next_arhdr_offset += sizeof arch.arhdr;
22182
978c4450 22183 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22184
22185 name = get_archive_member_name (&arch, &nested_arch);
22186 if (name == NULL)
fb52b2f4 22187 {
28e817cc 22188 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22189 ret = false;
d989285c 22190 break;
fb52b2f4 22191 }
2cf0635d 22192 namelen = strlen (name);
fb52b2f4 22193
2cf0635d
NC
22194 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22195 if (qualified_name == NULL)
fb52b2f4 22196 {
28e817cc 22197 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22198 free (name);
015dc7e1 22199 ret = false;
d989285c 22200 break;
fb52b2f4
NC
22201 }
22202
2cf0635d 22203 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22204 {
22205 /* This is a proxy for an external member of a thin archive. */
22206 Filedata * member_filedata;
22207 char * member_file_name = adjust_relative_path
dda8d76d 22208 (filedata->file_name, name, namelen);
32ec8896 22209
fd486f32 22210 free (name);
1cb7d8b1
AM
22211 if (member_file_name == NULL)
22212 {
fd486f32 22213 free (qualified_name);
015dc7e1 22214 ret = false;
1cb7d8b1
AM
22215 break;
22216 }
2cf0635d 22217
015dc7e1 22218 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22219 if (member_filedata == NULL)
22220 {
22221 error (_("Input file '%s' is not readable.\n"), member_file_name);
22222 free (member_file_name);
fd486f32 22223 free (qualified_name);
015dc7e1 22224 ret = false;
1cb7d8b1
AM
22225 break;
22226 }
2cf0635d 22227
978c4450 22228 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22229 member_filedata->file_name = qualified_name;
2cf0635d 22230
75a2da57
AH
22231 /* The call to process_object() expects the file to be at the beginning. */
22232 rewind (member_filedata->handle);
22233
1cb7d8b1 22234 if (! process_object (member_filedata))
015dc7e1 22235 ret = false;
2cf0635d 22236
1cb7d8b1
AM
22237 close_file (member_filedata);
22238 free (member_file_name);
1cb7d8b1 22239 }
2cf0635d 22240 else if (is_thin_archive)
1cb7d8b1
AM
22241 {
22242 Filedata thin_filedata;
eb02c04d 22243
1cb7d8b1 22244 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22245
a043396b
NC
22246 /* PR 15140: Allow for corrupt thin archives. */
22247 if (nested_arch.file == NULL)
22248 {
22249 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22250 qualified_name, name);
fd486f32
AM
22251 free (qualified_name);
22252 free (name);
015dc7e1 22253 ret = false;
a043396b
NC
22254 break;
22255 }
fd486f32 22256 free (name);
a043396b 22257
1cb7d8b1 22258 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22259 filedata->archive_file_offset
22260 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22261
1cb7d8b1
AM
22262 /* The nested archive file will have been opened and setup by
22263 get_archive_member_name. */
978c4450
AM
22264 if (fseek (nested_arch.file, filedata->archive_file_offset,
22265 SEEK_SET) != 0)
1cb7d8b1
AM
22266 {
22267 error (_("%s: failed to seek to archive member.\n"),
22268 nested_arch.file_name);
fd486f32 22269 free (qualified_name);
015dc7e1 22270 ret = false;
1cb7d8b1
AM
22271 break;
22272 }
2cf0635d 22273
dda8d76d
NC
22274 thin_filedata.handle = nested_arch.file;
22275 thin_filedata.file_name = qualified_name;
9abca702 22276
1cb7d8b1 22277 if (! process_object (& thin_filedata))
015dc7e1 22278 ret = false;
1cb7d8b1 22279 }
2cf0635d 22280 else
1cb7d8b1 22281 {
fd486f32 22282 free (name);
978c4450 22283 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22284 filedata->file_name = qualified_name;
1cb7d8b1 22285 if (! process_object (filedata))
015dc7e1 22286 ret = false;
237877b8 22287 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22288 /* Stop looping with "negative" archive_file_size. */
978c4450 22289 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22290 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22291 }
fb52b2f4 22292
2cf0635d 22293 free (qualified_name);
fb52b2f4
NC
22294 }
22295
4145f1d5 22296 out:
2cf0635d
NC
22297 if (nested_arch.file != NULL)
22298 fclose (nested_arch.file);
22299 release_archive (&nested_arch);
22300 release_archive (&arch);
fb52b2f4 22301
d989285c 22302 return ret;
fb52b2f4
NC
22303}
22304
015dc7e1 22305static bool
2cf0635d 22306process_file (char * file_name)
fb52b2f4 22307{
dda8d76d 22308 Filedata * filedata = NULL;
fb52b2f4
NC
22309 struct stat statbuf;
22310 char armag[SARMAG];
015dc7e1 22311 bool ret = true;
fb52b2f4
NC
22312
22313 if (stat (file_name, &statbuf) < 0)
22314 {
f24ddbdd
NC
22315 if (errno == ENOENT)
22316 error (_("'%s': No such file\n"), file_name);
22317 else
22318 error (_("Could not locate '%s'. System error message: %s\n"),
22319 file_name, strerror (errno));
015dc7e1 22320 return false;
f24ddbdd
NC
22321 }
22322
22323 if (! S_ISREG (statbuf.st_mode))
22324 {
22325 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22326 return false;
fb52b2f4
NC
22327 }
22328
dda8d76d
NC
22329 filedata = calloc (1, sizeof * filedata);
22330 if (filedata == NULL)
22331 {
22332 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22333 return false;
dda8d76d
NC
22334 }
22335
22336 filedata->file_name = file_name;
22337 filedata->handle = fopen (file_name, "rb");
22338 if (filedata->handle == NULL)
fb52b2f4 22339 {
f24ddbdd 22340 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22341 free (filedata);
015dc7e1 22342 return false;
fb52b2f4
NC
22343 }
22344
dda8d76d 22345 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22346 {
4145f1d5 22347 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22348 fclose (filedata->handle);
22349 free (filedata);
015dc7e1 22350 return false;
fb52b2f4
NC
22351 }
22352
dda8d76d 22353 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 22354 filedata->is_separate = false;
f54498b4 22355
fb52b2f4 22356 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22357 {
015dc7e1
AM
22358 if (! process_archive (filedata, false))
22359 ret = false;
32ec8896 22360 }
2cf0635d 22361 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22362 {
015dc7e1
AM
22363 if ( ! process_archive (filedata, true))
22364 ret = false;
32ec8896 22365 }
fb52b2f4
NC
22366 else
22367 {
1b513401 22368 if (do_archive_index && !check_all)
4145f1d5
NC
22369 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22370 file_name);
22371
dda8d76d 22372 rewind (filedata->handle);
978c4450 22373 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22374
dda8d76d 22375 if (! process_object (filedata))
015dc7e1 22376 ret = false;
fb52b2f4
NC
22377 }
22378
dda8d76d 22379 fclose (filedata->handle);
8fb879cd
AM
22380 free (filedata->section_headers);
22381 free (filedata->program_headers);
22382 free (filedata->string_table);
6431e409 22383 free (filedata->dump.dump_sects);
dda8d76d 22384 free (filedata);
32ec8896 22385
fd486f32 22386 free (ba_cache.strtab);
1bd6175a 22387 ba_cache.strtab = NULL;
fd486f32 22388 free (ba_cache.symtab);
1bd6175a 22389 ba_cache.symtab = NULL;
fd486f32
AM
22390 ba_cache.filedata = NULL;
22391
fb52b2f4
NC
22392 return ret;
22393}
22394
252b5132
RH
22395#ifdef SUPPORT_DISASSEMBLY
22396/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22397 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22398 symbols. */
252b5132
RH
22399
22400void
2cf0635d 22401print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22402{
22403 fprintf (outfile,"0x%8.8x", addr);
22404}
22405
e3c8793a 22406/* Needed by the i386 disassembler. */
dda8d76d 22407
252b5132
RH
22408void
22409db_task_printsym (unsigned int addr)
22410{
22411 print_address (addr, stderr);
22412}
22413#endif
22414
22415int
2cf0635d 22416main (int argc, char ** argv)
252b5132 22417{
ff78d6d6
L
22418 int err;
22419
87b9f255 22420#ifdef HAVE_LC_MESSAGES
252b5132 22421 setlocale (LC_MESSAGES, "");
3882b010 22422#endif
3882b010 22423 setlocale (LC_CTYPE, "");
252b5132
RH
22424 bindtextdomain (PACKAGE, LOCALEDIR);
22425 textdomain (PACKAGE);
22426
869b9d07
MM
22427 expandargv (&argc, &argv);
22428
dda8d76d 22429 parse_args (& cmdline, argc, argv);
59f14fc0 22430
18bd398b 22431 if (optind < (argc - 1))
1b513401
NC
22432 /* When displaying information for more than one file,
22433 prefix the information with the file name. */
015dc7e1 22434 show_name = true;
5656ba2c
L
22435 else if (optind >= argc)
22436 {
1b513401 22437 /* Ensure that the warning is always displayed. */
015dc7e1 22438 do_checks = true;
1b513401 22439
5656ba2c
L
22440 warn (_("Nothing to do.\n"));
22441 usage (stderr);
22442 }
18bd398b 22443
015dc7e1 22444 err = false;
252b5132 22445 while (optind < argc)
32ec8896 22446 if (! process_file (argv[optind++]))
015dc7e1 22447 err = true;
252b5132 22448
9db70fc3 22449 free (cmdline.dump_sects);
252b5132 22450
7d9813f1
NA
22451 free (dump_ctf_symtab_name);
22452 free (dump_ctf_strtab_name);
22453 free (dump_ctf_parent_name);
22454
32ec8896 22455 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22456}