]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
sim: use program_transform_name for libsim
[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
252b5132 2445static const char *
dda8d76d 2446get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2447{
e9e44622 2448 static char buff[64];
252b5132
RH
2449
2450 switch (type)
2451 {
2452 case DT_NULL: return "NULL";
2453 case DT_NEEDED: return "NEEDED";
2454 case DT_PLTRELSZ: return "PLTRELSZ";
2455 case DT_PLTGOT: return "PLTGOT";
2456 case DT_HASH: return "HASH";
2457 case DT_STRTAB: return "STRTAB";
2458 case DT_SYMTAB: return "SYMTAB";
2459 case DT_RELA: return "RELA";
2460 case DT_RELASZ: return "RELASZ";
2461 case DT_RELAENT: return "RELAENT";
2462 case DT_STRSZ: return "STRSZ";
2463 case DT_SYMENT: return "SYMENT";
2464 case DT_INIT: return "INIT";
2465 case DT_FINI: return "FINI";
2466 case DT_SONAME: return "SONAME";
2467 case DT_RPATH: return "RPATH";
2468 case DT_SYMBOLIC: return "SYMBOLIC";
2469 case DT_REL: return "REL";
2470 case DT_RELSZ: return "RELSZ";
2471 case DT_RELENT: return "RELENT";
dd207c13
FS
2472 case DT_RELR: return "RELR";
2473 case DT_RELRSZ: return "RELRSZ";
2474 case DT_RELRENT: return "RELRENT";
252b5132
RH
2475 case DT_PLTREL: return "PLTREL";
2476 case DT_DEBUG: return "DEBUG";
2477 case DT_TEXTREL: return "TEXTREL";
2478 case DT_JMPREL: return "JMPREL";
2479 case DT_BIND_NOW: return "BIND_NOW";
2480 case DT_INIT_ARRAY: return "INIT_ARRAY";
2481 case DT_FINI_ARRAY: return "FINI_ARRAY";
2482 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2483 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2484 case DT_RUNPATH: return "RUNPATH";
2485 case DT_FLAGS: return "FLAGS";
2d0e6f43 2486
d1133906
NC
2487 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2488 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2489 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2490
05107a46 2491 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2492 case DT_PLTPADSZ: return "PLTPADSZ";
2493 case DT_MOVEENT: return "MOVEENT";
2494 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2495 case DT_FEATURE: return "FEATURE";
252b5132
RH
2496 case DT_POSFLAG_1: return "POSFLAG_1";
2497 case DT_SYMINSZ: return "SYMINSZ";
2498 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2499
252b5132 2500 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2501 case DT_CONFIG: return "CONFIG";
2502 case DT_DEPAUDIT: return "DEPAUDIT";
2503 case DT_AUDIT: return "AUDIT";
2504 case DT_PLTPAD: return "PLTPAD";
2505 case DT_MOVETAB: return "MOVETAB";
252b5132 2506 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2507
252b5132 2508 case DT_VERSYM: return "VERSYM";
103f02d3 2509
67a4f2b7
AO
2510 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2511 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2512 case DT_RELACOUNT: return "RELACOUNT";
2513 case DT_RELCOUNT: return "RELCOUNT";
2514 case DT_FLAGS_1: return "FLAGS_1";
2515 case DT_VERDEF: return "VERDEF";
2516 case DT_VERDEFNUM: return "VERDEFNUM";
2517 case DT_VERNEED: return "VERNEED";
2518 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2519
019148e4 2520 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2521 case DT_USED: return "USED";
2522 case DT_FILTER: return "FILTER";
103f02d3 2523
047b2264
JJ
2524 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2525 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2526 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2527 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2528 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2529 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2530 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2531
252b5132
RH
2532 default:
2533 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2534 {
2cf0635d 2535 const char * result;
103f02d3 2536
dda8d76d 2537 switch (filedata->file_header.e_machine)
252b5132 2538 {
37c18eed
SD
2539 case EM_AARCH64:
2540 result = get_aarch64_dynamic_type (type);
2541 break;
252b5132 2542 case EM_MIPS:
4fe85591 2543 case EM_MIPS_RS3_LE:
252b5132
RH
2544 result = get_mips_dynamic_type (type);
2545 break;
9a097730
RH
2546 case EM_SPARCV9:
2547 result = get_sparc64_dynamic_type (type);
2548 break;
7490d522
AM
2549 case EM_PPC:
2550 result = get_ppc_dynamic_type (type);
2551 break;
f1cb7e17
AM
2552 case EM_PPC64:
2553 result = get_ppc64_dynamic_type (type);
2554 break;
ecc51f48
NC
2555 case EM_IA_64:
2556 result = get_ia64_dynamic_type (type);
2557 break;
fabcb361
RH
2558 case EM_ALPHA:
2559 result = get_alpha_dynamic_type (type);
2560 break;
1c0d3aa6
NC
2561 case EM_SCORE:
2562 result = get_score_dynamic_type (type);
2563 break;
40b36596
JM
2564 case EM_TI_C6000:
2565 result = get_tic6x_dynamic_type (type);
2566 break;
36591ba1
SL
2567 case EM_ALTERA_NIOS2:
2568 result = get_nios2_dynamic_type (type);
2569 break;
252b5132 2570 default:
dda8d76d 2571 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2572 result = get_solaris_dynamic_type (type);
2573 else
2574 result = NULL;
252b5132
RH
2575 break;
2576 }
2577
2578 if (result != NULL)
2579 return result;
2580
e9e44622 2581 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2582 }
eec8f817 2583 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2584 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2585 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2586 {
2cf0635d 2587 const char * result;
103f02d3 2588
dda8d76d 2589 switch (filedata->file_header.e_machine)
103f02d3
UD
2590 {
2591 case EM_PARISC:
2592 result = get_parisc_dynamic_type (type);
2593 break;
148b93f2
NC
2594 case EM_IA_64:
2595 result = get_ia64_dynamic_type (type);
2596 break;
103f02d3 2597 default:
dda8d76d 2598 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2599 result = get_solaris_dynamic_type (type);
2600 else
2601 result = NULL;
103f02d3
UD
2602 break;
2603 }
2604
2605 if (result != NULL)
2606 return result;
2607
e9e44622
JJ
2608 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2609 type);
103f02d3 2610 }
252b5132 2611 else
e9e44622 2612 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2613
252b5132
RH
2614 return buff;
2615 }
2616}
2617
93df3340
AM
2618static bool get_program_headers (Filedata *);
2619static bool get_dynamic_section (Filedata *);
2620
2621static void
2622locate_dynamic_section (Filedata *filedata)
2623{
2624 unsigned long dynamic_addr = 0;
2625 bfd_size_type dynamic_size = 0;
2626
2627 if (filedata->file_header.e_phnum != 0
2628 && get_program_headers (filedata))
2629 {
2630 Elf_Internal_Phdr *segment;
2631 unsigned int i;
2632
2633 for (i = 0, segment = filedata->program_headers;
2634 i < filedata->file_header.e_phnum;
2635 i++, segment++)
2636 {
2637 if (segment->p_type == PT_DYNAMIC)
2638 {
2639 dynamic_addr = segment->p_offset;
2640 dynamic_size = segment->p_filesz;
2641
2642 if (filedata->section_headers != NULL)
2643 {
2644 Elf_Internal_Shdr *sec;
2645
2646 sec = find_section (filedata, ".dynamic");
2647 if (sec != NULL)
2648 {
2649 if (sec->sh_size == 0
2650 || sec->sh_type == SHT_NOBITS)
2651 {
2652 dynamic_addr = 0;
2653 dynamic_size = 0;
2654 }
2655 else
2656 {
2657 dynamic_addr = sec->sh_offset;
2658 dynamic_size = sec->sh_size;
2659 }
2660 }
2661 }
2662
2663 if (dynamic_addr > filedata->file_size
2664 || (dynamic_size > filedata->file_size - dynamic_addr))
2665 {
2666 dynamic_addr = 0;
2667 dynamic_size = 0;
2668 }
2669 break;
2670 }
2671 }
2672 }
2673 filedata->dynamic_addr = dynamic_addr;
2674 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2675}
2676
2677static bool
2678is_pie (Filedata *filedata)
2679{
2680 Elf_Internal_Dyn *entry;
2681
2682 if (filedata->dynamic_size == 0)
2683 locate_dynamic_section (filedata);
2684 if (filedata->dynamic_size <= 1)
2685 return false;
2686
2687 if (!get_dynamic_section (filedata))
2688 return false;
2689
2690 for (entry = filedata->dynamic_section;
2691 entry < filedata->dynamic_section + filedata->dynamic_nent;
2692 entry++)
2693 {
2694 if (entry->d_tag == DT_FLAGS_1)
2695 {
2696 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2697 return true;
2698 break;
2699 }
2700 }
2701 return false;
2702}
2703
252b5132 2704static char *
93df3340 2705get_file_type (Filedata *filedata)
252b5132 2706{
93df3340 2707 unsigned e_type = filedata->file_header.e_type;
89246a0e 2708 static char buff[64];
252b5132
RH
2709
2710 switch (e_type)
2711 {
32ec8896
NC
2712 case ET_NONE: return _("NONE (None)");
2713 case ET_REL: return _("REL (Relocatable file)");
2714 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2715 case ET_DYN:
2716 if (is_pie (filedata))
2717 return _("DYN (Position-Independent Executable file)");
2718 else
2719 return _("DYN (Shared object file)");
32ec8896 2720 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2721
2722 default:
2723 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2724 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2725 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2726 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2727 else
e9e44622 2728 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2729 return buff;
2730 }
2731}
2732
2733static char *
d3ba0551 2734get_machine_name (unsigned e_machine)
252b5132 2735{
b34976b6 2736 static char buff[64]; /* XXX */
252b5132
RH
2737
2738 switch (e_machine)
2739 {
55e22ca8
NC
2740 /* Please keep this switch table sorted by increasing EM_ value. */
2741 /* 0 */
c45021f2
NC
2742 case EM_NONE: return _("None");
2743 case EM_M32: return "WE32100";
2744 case EM_SPARC: return "Sparc";
2745 case EM_386: return "Intel 80386";
2746 case EM_68K: return "MC68000";
2747 case EM_88K: return "MC88000";
22abe556 2748 case EM_IAMCU: return "Intel MCU";
fb70ec17 2749 case EM_860: return "Intel 80860";
c45021f2
NC
2750 case EM_MIPS: return "MIPS R3000";
2751 case EM_S370: return "IBM System/370";
55e22ca8 2752 /* 10 */
7036c0e1 2753 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2754 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2755 case EM_PARISC: return "HPPA";
55e22ca8 2756 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2757 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2758 case EM_960: return "Intel 80960";
c45021f2 2759 case EM_PPC: return "PowerPC";
55e22ca8 2760 /* 20 */
285d1771 2761 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2762 case EM_S390_OLD:
2763 case EM_S390: return "IBM S/390";
2764 case EM_SPU: return "SPU";
2765 /* 30 */
2766 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2767 case EM_FR20: return "Fujitsu FR20";
2768 case EM_RH32: return "TRW RH32";
b34976b6 2769 case EM_MCORE: return "MCORE";
55e22ca8 2770 /* 40 */
7036c0e1
AJ
2771 case EM_ARM: return "ARM";
2772 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2773 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2774 case EM_SPARCV9: return "Sparc v9";
2775 case EM_TRICORE: return "Siemens Tricore";
584da044 2776 case EM_ARC: return "ARC";
c2dcd04e
NC
2777 case EM_H8_300: return "Renesas H8/300";
2778 case EM_H8_300H: return "Renesas H8/300H";
2779 case EM_H8S: return "Renesas H8S";
2780 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2781 /* 50 */
30800947 2782 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2783 case EM_MIPS_X: return "Stanford MIPS-X";
2784 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2785 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2786 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2787 case EM_PCP: return "Siemens PCP";
2788 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2789 case EM_NDR1: return "Denso NDR1 microprocesspr";
2790 case EM_STARCORE: return "Motorola Star*Core processor";
2791 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2792 /* 60 */
7036c0e1
AJ
2793 case EM_ST100: return "STMicroelectronics ST100 processor";
2794 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2795 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2796 case EM_PDSP: return "Sony DSP processor";
2797 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2798 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2799 case EM_FX66: return "Siemens FX66 microcontroller";
2800 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2801 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2802 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2803 /* 70 */
7036c0e1
AJ
2804 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2805 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2806 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2807 case EM_SVX: return "Silicon Graphics SVx";
2808 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2809 case EM_VAX: return "Digital VAX";
1b61cf92 2810 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2811 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2812 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2813 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2814 /* 80 */
b34976b6 2815 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2816 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2817 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2818 case EM_AVR_OLD:
2819 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2820 case EM_CYGNUS_FR30:
2821 case EM_FR30: return "Fujitsu FR30";
2822 case EM_CYGNUS_D10V:
2823 case EM_D10V: return "d10v";
2824 case EM_CYGNUS_D30V:
2825 case EM_D30V: return "d30v";
2826 case EM_CYGNUS_V850:
2827 case EM_V850: return "Renesas V850";
2828 case EM_CYGNUS_M32R:
2829 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2830 case EM_CYGNUS_MN10300:
2831 case EM_MN10300: return "mn10300";
2832 /* 90 */
2833 case EM_CYGNUS_MN10200:
2834 case EM_MN10200: return "mn10200";
2835 case EM_PJ: return "picoJava";
73589c9d 2836 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2837 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2838 case EM_XTENSA_OLD:
2839 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2840 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2841 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2842 case EM_NS32K: return "National Semiconductor 32000 series";
2843 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2844 case EM_SNP1K: return "Trebia SNP 1000 processor";
2845 /* 100 */
9abca702 2846 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2847 case EM_IP2K_OLD:
2848 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2849 case EM_MAX: return "MAX Processor";
2850 case EM_CR: return "National Semiconductor CompactRISC";
2851 case EM_F2MC16: return "Fujitsu F2MC16";
2852 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2853 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2854 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2855 case EM_SEP: return "Sharp embedded microprocessor";
2856 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2857 /* 110 */
11636f9e
JM
2858 case EM_UNICORE: return "Unicore";
2859 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2860 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2861 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2862 case EM_CRX: return "National Semiconductor CRX microprocessor";
2863 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2864 case EM_C166:
d70c5fc7 2865 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2866 case EM_M16C: return "Renesas M16C series microprocessors";
2867 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2868 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2869 /* 120 */
2870 case EM_M32C: return "Renesas M32c";
2871 /* 130 */
11636f9e
JM
2872 case EM_TSK3000: return "Altium TSK3000 core";
2873 case EM_RS08: return "Freescale RS08 embedded processor";
2874 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2875 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2876 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2877 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2878 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2879 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2880 /* 140 */
11636f9e
JM
2881 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2882 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2883 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2884 case EM_TI_PRU: return "TI PRU I/O processor";
2885 /* 160 */
11636f9e
JM
2886 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2887 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2888 case EM_R32C: return "Renesas R32C series microprocessors";
2889 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2890 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2891 case EM_8051: return "Intel 8051 and variants";
2892 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2893 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2894 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2895 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2896 /* 170 */
11636f9e
JM
2897 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2898 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2899 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2900 case EM_RX: return "Renesas RX";
a3c62988 2901 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2902 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2903 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2904 case EM_CR16:
2905 case EM_MICROBLAZE:
2906 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2907 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2908 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2909 /* 180 */
2910 case EM_L1OM: return "Intel L1OM";
2911 case EM_K1OM: return "Intel K1OM";
2912 case EM_INTEL182: return "Intel (reserved)";
2913 case EM_AARCH64: return "AArch64";
2914 case EM_ARM184: return "ARM (reserved)";
2915 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2916 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2917 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2918 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2919 /* 190 */
11636f9e 2920 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2921 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2922 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2923 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2924 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2925 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2926 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2927 case EM_RL78: return "Renesas RL78";
6d913794 2928 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2929 case EM_78K0R: return "Renesas 78K0R";
2930 /* 200 */
6d913794 2931 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2932 case EM_BA1: return "Beyond BA1 CPU architecture";
2933 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2934 case EM_XCORE: return "XMOS xCORE processor family";
2935 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2936 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2937 /* 210 */
6d913794
NC
2938 case EM_KM32: return "KM211 KM32 32-bit processor";
2939 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2940 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2941 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2942 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2943 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2944 case EM_COGE: return "Cognitive Smart Memory Processor";
2945 case EM_COOL: return "Bluechip Systems CoolEngine";
2946 case EM_NORC: return "Nanoradio Optimized RISC";
2947 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2948 /* 220 */
15f205b1 2949 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2950 case EM_VISIUM: return "CDS VISIUMcore processor";
2951 case EM_FT32: return "FTDI Chip FT32";
2952 case EM_MOXIE: return "Moxie";
2953 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2954 /* 230 (all reserved) */
2955 /* 240 */
55e22ca8
NC
2956 case EM_RISCV: return "RISC-V";
2957 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2958 case EM_CEVA: return "CEVA Processor Architecture Family";
2959 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2960 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2961 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2962 case EM_IMG1: return "Imagination Technologies";
2963 /* 250 */
fe944acf 2964 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2965 case EM_VE: return "NEC Vector Engine";
2966 case EM_CSKY: return "C-SKY";
2967 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2968 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2969 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2970 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2971 case EM_65816: return "WDC 65816/65C816";
01a8c731 2972 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2973 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2974
2975 /* Large numbers... */
2976 case EM_MT: return "Morpho Techologies MT processor";
2977 case EM_ALPHA: return "Alpha";
2978 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2979 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2980 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2981 case EM_IQ2000: return "Vitesse IQ2000";
2982 case EM_M32C_OLD:
2983 case EM_NIOS32: return "Altera Nios";
2984 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2985 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2986 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2987 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2988
252b5132 2989 default:
35d9dd2f 2990 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2991 return buff;
2992 }
2993}
2994
a9522a21
AB
2995static void
2996decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2997{
2998 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2999 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3000 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3001 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3002 architectures.
3003
3004 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3005 but also sets a specific architecture type in the e_flags field.
3006
3007 However, when decoding the flags we don't worry if we see an
3008 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3009 ARCEM architecture type. */
3010
3011 switch (e_flags & EF_ARC_MACH_MSK)
3012 {
3013 /* We only expect these to occur for EM_ARC_COMPACT2. */
3014 case EF_ARC_CPU_ARCV2EM:
3015 strcat (buf, ", ARC EM");
3016 break;
3017 case EF_ARC_CPU_ARCV2HS:
3018 strcat (buf, ", ARC HS");
3019 break;
3020
3021 /* We only expect these to occur for EM_ARC_COMPACT. */
3022 case E_ARC_MACH_ARC600:
3023 strcat (buf, ", ARC600");
3024 break;
3025 case E_ARC_MACH_ARC601:
3026 strcat (buf, ", ARC601");
3027 break;
3028 case E_ARC_MACH_ARC700:
3029 strcat (buf, ", ARC700");
3030 break;
3031
3032 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3033 new ELF with new architecture being read by an old version of
3034 readelf, or (c) An ELF built with non-GNU compiler that does not
3035 set the architecture in the e_flags. */
3036 default:
3037 if (e_machine == EM_ARC_COMPACT)
3038 strcat (buf, ", Unknown ARCompact");
3039 else
3040 strcat (buf, ", Unknown ARC");
3041 break;
3042 }
3043
3044 switch (e_flags & EF_ARC_OSABI_MSK)
3045 {
3046 case E_ARC_OSABI_ORIG:
3047 strcat (buf, ", (ABI:legacy)");
3048 break;
3049 case E_ARC_OSABI_V2:
3050 strcat (buf, ", (ABI:v2)");
3051 break;
3052 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3053 case E_ARC_OSABI_V3:
3054 strcat (buf, ", v3 no-legacy-syscalls ABI");
3055 break;
53a346d8
CZ
3056 case E_ARC_OSABI_V4:
3057 strcat (buf, ", v4 ABI");
3058 break;
a9522a21
AB
3059 default:
3060 strcat (buf, ", unrecognised ARC OSABI flag");
3061 break;
3062 }
3063}
3064
f3485b74 3065static void
d3ba0551 3066decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3067{
3068 unsigned eabi;
015dc7e1 3069 bool unknown = false;
f3485b74
NC
3070
3071 eabi = EF_ARM_EABI_VERSION (e_flags);
3072 e_flags &= ~ EF_ARM_EABIMASK;
3073
3074 /* Handle "generic" ARM flags. */
3075 if (e_flags & EF_ARM_RELEXEC)
3076 {
3077 strcat (buf, ", relocatable executable");
3078 e_flags &= ~ EF_ARM_RELEXEC;
3079 }
76da6bbe 3080
18a20338
CL
3081 if (e_flags & EF_ARM_PIC)
3082 {
3083 strcat (buf, ", position independent");
3084 e_flags &= ~ EF_ARM_PIC;
3085 }
3086
f3485b74
NC
3087 /* Now handle EABI specific flags. */
3088 switch (eabi)
3089 {
3090 default:
2c71103e 3091 strcat (buf, ", <unrecognized EABI>");
f3485b74 3092 if (e_flags)
015dc7e1 3093 unknown = true;
f3485b74
NC
3094 break;
3095
3096 case EF_ARM_EABI_VER1:
a5bcd848 3097 strcat (buf, ", Version1 EABI");
f3485b74
NC
3098 while (e_flags)
3099 {
3100 unsigned flag;
76da6bbe 3101
f3485b74
NC
3102 /* Process flags one bit at a time. */
3103 flag = e_flags & - e_flags;
3104 e_flags &= ~ flag;
76da6bbe 3105
f3485b74
NC
3106 switch (flag)
3107 {
a5bcd848 3108 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3109 strcat (buf, ", sorted symbol tables");
3110 break;
76da6bbe 3111
f3485b74 3112 default:
015dc7e1 3113 unknown = true;
f3485b74
NC
3114 break;
3115 }
3116 }
3117 break;
76da6bbe 3118
a5bcd848
PB
3119 case EF_ARM_EABI_VER2:
3120 strcat (buf, ", Version2 EABI");
3121 while (e_flags)
3122 {
3123 unsigned flag;
3124
3125 /* Process flags one bit at a time. */
3126 flag = e_flags & - e_flags;
3127 e_flags &= ~ flag;
3128
3129 switch (flag)
3130 {
3131 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3132 strcat (buf, ", sorted symbol tables");
3133 break;
3134
3135 case EF_ARM_DYNSYMSUSESEGIDX:
3136 strcat (buf, ", dynamic symbols use segment index");
3137 break;
3138
3139 case EF_ARM_MAPSYMSFIRST:
3140 strcat (buf, ", mapping symbols precede others");
3141 break;
3142
3143 default:
015dc7e1 3144 unknown = true;
a5bcd848
PB
3145 break;
3146 }
3147 }
3148 break;
3149
d507cf36
PB
3150 case EF_ARM_EABI_VER3:
3151 strcat (buf, ", Version3 EABI");
8cb51566
PB
3152 break;
3153
3154 case EF_ARM_EABI_VER4:
3155 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3156 while (e_flags)
3157 {
3158 unsigned flag;
3159
3160 /* Process flags one bit at a time. */
3161 flag = e_flags & - e_flags;
3162 e_flags &= ~ flag;
3163
3164 switch (flag)
3165 {
3166 case EF_ARM_BE8:
3167 strcat (buf, ", BE8");
3168 break;
3169
3170 case EF_ARM_LE8:
3171 strcat (buf, ", LE8");
3172 break;
3173
3174 default:
015dc7e1 3175 unknown = true;
3bfcb652
NC
3176 break;
3177 }
3bfcb652
NC
3178 }
3179 break;
3a4a14e9
PB
3180
3181 case EF_ARM_EABI_VER5:
3182 strcat (buf, ", Version5 EABI");
d507cf36
PB
3183 while (e_flags)
3184 {
3185 unsigned flag;
3186
3187 /* Process flags one bit at a time. */
3188 flag = e_flags & - e_flags;
3189 e_flags &= ~ flag;
3190
3191 switch (flag)
3192 {
3193 case EF_ARM_BE8:
3194 strcat (buf, ", BE8");
3195 break;
3196
3197 case EF_ARM_LE8:
3198 strcat (buf, ", LE8");
3199 break;
3200
3bfcb652
NC
3201 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3202 strcat (buf, ", soft-float ABI");
3203 break;
3204
3205 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3206 strcat (buf, ", hard-float ABI");
3207 break;
3208
d507cf36 3209 default:
015dc7e1 3210 unknown = true;
d507cf36
PB
3211 break;
3212 }
3213 }
3214 break;
3215
f3485b74 3216 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3217 strcat (buf, ", GNU EABI");
f3485b74
NC
3218 while (e_flags)
3219 {
3220 unsigned flag;
76da6bbe 3221
f3485b74
NC
3222 /* Process flags one bit at a time. */
3223 flag = e_flags & - e_flags;
3224 e_flags &= ~ flag;
76da6bbe 3225
f3485b74
NC
3226 switch (flag)
3227 {
a5bcd848 3228 case EF_ARM_INTERWORK:
f3485b74
NC
3229 strcat (buf, ", interworking enabled");
3230 break;
76da6bbe 3231
a5bcd848 3232 case EF_ARM_APCS_26:
f3485b74
NC
3233 strcat (buf, ", uses APCS/26");
3234 break;
76da6bbe 3235
a5bcd848 3236 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3237 strcat (buf, ", uses APCS/float");
3238 break;
76da6bbe 3239
a5bcd848 3240 case EF_ARM_PIC:
f3485b74
NC
3241 strcat (buf, ", position independent");
3242 break;
76da6bbe 3243
a5bcd848 3244 case EF_ARM_ALIGN8:
f3485b74
NC
3245 strcat (buf, ", 8 bit structure alignment");
3246 break;
76da6bbe 3247
a5bcd848 3248 case EF_ARM_NEW_ABI:
f3485b74
NC
3249 strcat (buf, ", uses new ABI");
3250 break;
76da6bbe 3251
a5bcd848 3252 case EF_ARM_OLD_ABI:
f3485b74
NC
3253 strcat (buf, ", uses old ABI");
3254 break;
76da6bbe 3255
a5bcd848 3256 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3257 strcat (buf, ", software FP");
3258 break;
76da6bbe 3259
90e01f86
ILT
3260 case EF_ARM_VFP_FLOAT:
3261 strcat (buf, ", VFP");
3262 break;
3263
fde78edd
NC
3264 case EF_ARM_MAVERICK_FLOAT:
3265 strcat (buf, ", Maverick FP");
3266 break;
3267
f3485b74 3268 default:
015dc7e1 3269 unknown = true;
f3485b74
NC
3270 break;
3271 }
3272 }
3273 }
f3485b74
NC
3274
3275 if (unknown)
2b692964 3276 strcat (buf,_(", <unknown>"));
f3485b74
NC
3277}
3278
343433df
AB
3279static void
3280decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3281{
3282 --size; /* Leave space for null terminator. */
3283
3284 switch (e_flags & EF_AVR_MACH)
3285 {
3286 case E_AVR_MACH_AVR1:
3287 strncat (buf, ", avr:1", size);
3288 break;
3289 case E_AVR_MACH_AVR2:
3290 strncat (buf, ", avr:2", size);
3291 break;
3292 case E_AVR_MACH_AVR25:
3293 strncat (buf, ", avr:25", size);
3294 break;
3295 case E_AVR_MACH_AVR3:
3296 strncat (buf, ", avr:3", size);
3297 break;
3298 case E_AVR_MACH_AVR31:
3299 strncat (buf, ", avr:31", size);
3300 break;
3301 case E_AVR_MACH_AVR35:
3302 strncat (buf, ", avr:35", size);
3303 break;
3304 case E_AVR_MACH_AVR4:
3305 strncat (buf, ", avr:4", size);
3306 break;
3307 case E_AVR_MACH_AVR5:
3308 strncat (buf, ", avr:5", size);
3309 break;
3310 case E_AVR_MACH_AVR51:
3311 strncat (buf, ", avr:51", size);
3312 break;
3313 case E_AVR_MACH_AVR6:
3314 strncat (buf, ", avr:6", size);
3315 break;
3316 case E_AVR_MACH_AVRTINY:
3317 strncat (buf, ", avr:100", size);
3318 break;
3319 case E_AVR_MACH_XMEGA1:
3320 strncat (buf, ", avr:101", size);
3321 break;
3322 case E_AVR_MACH_XMEGA2:
3323 strncat (buf, ", avr:102", size);
3324 break;
3325 case E_AVR_MACH_XMEGA3:
3326 strncat (buf, ", avr:103", size);
3327 break;
3328 case E_AVR_MACH_XMEGA4:
3329 strncat (buf, ", avr:104", size);
3330 break;
3331 case E_AVR_MACH_XMEGA5:
3332 strncat (buf, ", avr:105", size);
3333 break;
3334 case E_AVR_MACH_XMEGA6:
3335 strncat (buf, ", avr:106", size);
3336 break;
3337 case E_AVR_MACH_XMEGA7:
3338 strncat (buf, ", avr:107", size);
3339 break;
3340 default:
3341 strncat (buf, ", avr:<unknown>", size);
3342 break;
3343 }
3344
3345 size -= strlen (buf);
3346 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3347 strncat (buf, ", link-relax", size);
3348}
3349
35c08157
KLC
3350static void
3351decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3352{
3353 unsigned abi;
3354 unsigned arch;
3355 unsigned config;
3356 unsigned version;
015dc7e1 3357 bool has_fpu = false;
32ec8896 3358 unsigned int r = 0;
35c08157
KLC
3359
3360 static const char *ABI_STRINGS[] =
3361 {
3362 "ABI v0", /* use r5 as return register; only used in N1213HC */
3363 "ABI v1", /* use r0 as return register */
3364 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3365 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3366 "AABI",
3367 "ABI2 FP+"
35c08157
KLC
3368 };
3369 static const char *VER_STRINGS[] =
3370 {
3371 "Andes ELF V1.3 or older",
3372 "Andes ELF V1.3.1",
3373 "Andes ELF V1.4"
3374 };
3375 static const char *ARCH_STRINGS[] =
3376 {
3377 "",
3378 "Andes Star v1.0",
3379 "Andes Star v2.0",
3380 "Andes Star v3.0",
3381 "Andes Star v3.0m"
3382 };
3383
3384 abi = EF_NDS_ABI & e_flags;
3385 arch = EF_NDS_ARCH & e_flags;
3386 config = EF_NDS_INST & e_flags;
3387 version = EF_NDS32_ELF_VERSION & e_flags;
3388
3389 memset (buf, 0, size);
3390
3391 switch (abi)
3392 {
3393 case E_NDS_ABI_V0:
3394 case E_NDS_ABI_V1:
3395 case E_NDS_ABI_V2:
3396 case E_NDS_ABI_V2FP:
3397 case E_NDS_ABI_AABI:
40c7a7cb 3398 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3399 /* In case there are holes in the array. */
3400 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3401 break;
3402
3403 default:
3404 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3405 break;
3406 }
3407
3408 switch (version)
3409 {
3410 case E_NDS32_ELF_VER_1_2:
3411 case E_NDS32_ELF_VER_1_3:
3412 case E_NDS32_ELF_VER_1_4:
3413 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3414 break;
3415
3416 default:
3417 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3418 break;
3419 }
3420
3421 if (E_NDS_ABI_V0 == abi)
3422 {
3423 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3424 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3425 if (arch == E_NDS_ARCH_STAR_V1_0)
3426 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3427 return;
3428 }
3429
3430 switch (arch)
3431 {
3432 case E_NDS_ARCH_STAR_V1_0:
3433 case E_NDS_ARCH_STAR_V2_0:
3434 case E_NDS_ARCH_STAR_V3_0:
3435 case E_NDS_ARCH_STAR_V3_M:
3436 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3437 break;
3438
3439 default:
3440 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3441 /* ARCH version determines how the e_flags are interpreted.
3442 If it is unknown, we cannot proceed. */
3443 return;
3444 }
3445
3446 /* Newer ABI; Now handle architecture specific flags. */
3447 if (arch == E_NDS_ARCH_STAR_V1_0)
3448 {
3449 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3450 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3451
3452 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3453 r += snprintf (buf + r, size -r, ", MAC");
3454
3455 if (config & E_NDS32_HAS_DIV_INST)
3456 r += snprintf (buf + r, size -r, ", DIV");
3457
3458 if (config & E_NDS32_HAS_16BIT_INST)
3459 r += snprintf (buf + r, size -r, ", 16b");
3460 }
3461 else
3462 {
3463 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3464 {
3465 if (version <= E_NDS32_ELF_VER_1_3)
3466 r += snprintf (buf + r, size -r, ", [B8]");
3467 else
3468 r += snprintf (buf + r, size -r, ", EX9");
3469 }
3470
3471 if (config & E_NDS32_HAS_MAC_DX_INST)
3472 r += snprintf (buf + r, size -r, ", MAC_DX");
3473
3474 if (config & E_NDS32_HAS_DIV_DX_INST)
3475 r += snprintf (buf + r, size -r, ", DIV_DX");
3476
3477 if (config & E_NDS32_HAS_16BIT_INST)
3478 {
3479 if (version <= E_NDS32_ELF_VER_1_3)
3480 r += snprintf (buf + r, size -r, ", 16b");
3481 else
3482 r += snprintf (buf + r, size -r, ", IFC");
3483 }
3484 }
3485
3486 if (config & E_NDS32_HAS_EXT_INST)
3487 r += snprintf (buf + r, size -r, ", PERF1");
3488
3489 if (config & E_NDS32_HAS_EXT2_INST)
3490 r += snprintf (buf + r, size -r, ", PERF2");
3491
3492 if (config & E_NDS32_HAS_FPU_INST)
3493 {
015dc7e1 3494 has_fpu = true;
35c08157
KLC
3495 r += snprintf (buf + r, size -r, ", FPU_SP");
3496 }
3497
3498 if (config & E_NDS32_HAS_FPU_DP_INST)
3499 {
015dc7e1 3500 has_fpu = true;
35c08157
KLC
3501 r += snprintf (buf + r, size -r, ", FPU_DP");
3502 }
3503
3504 if (config & E_NDS32_HAS_FPU_MAC_INST)
3505 {
015dc7e1 3506 has_fpu = true;
35c08157
KLC
3507 r += snprintf (buf + r, size -r, ", FPU_MAC");
3508 }
3509
3510 if (has_fpu)
3511 {
3512 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3513 {
3514 case E_NDS32_FPU_REG_8SP_4DP:
3515 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3516 break;
3517 case E_NDS32_FPU_REG_16SP_8DP:
3518 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3519 break;
3520 case E_NDS32_FPU_REG_32SP_16DP:
3521 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3522 break;
3523 case E_NDS32_FPU_REG_32SP_32DP:
3524 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3525 break;
3526 }
3527 }
3528
3529 if (config & E_NDS32_HAS_AUDIO_INST)
3530 r += snprintf (buf + r, size -r, ", AUDIO");
3531
3532 if (config & E_NDS32_HAS_STRING_INST)
3533 r += snprintf (buf + r, size -r, ", STR");
3534
3535 if (config & E_NDS32_HAS_REDUCED_REGS)
3536 r += snprintf (buf + r, size -r, ", 16REG");
3537
3538 if (config & E_NDS32_HAS_VIDEO_INST)
3539 {
3540 if (version <= E_NDS32_ELF_VER_1_3)
3541 r += snprintf (buf + r, size -r, ", VIDEO");
3542 else
3543 r += snprintf (buf + r, size -r, ", SATURATION");
3544 }
3545
3546 if (config & E_NDS32_HAS_ENCRIPT_INST)
3547 r += snprintf (buf + r, size -r, ", ENCRP");
3548
3549 if (config & E_NDS32_HAS_L2C_INST)
3550 r += snprintf (buf + r, size -r, ", L2C");
3551}
3552
252b5132 3553static char *
dda8d76d 3554get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3555{
b34976b6 3556 static char buf[1024];
252b5132
RH
3557
3558 buf[0] = '\0';
76da6bbe 3559
252b5132
RH
3560 if (e_flags)
3561 {
3562 switch (e_machine)
3563 {
3564 default:
3565 break;
3566
886a2506 3567 case EM_ARC_COMPACT2:
886a2506 3568 case EM_ARC_COMPACT:
a9522a21
AB
3569 decode_ARC_machine_flags (e_flags, e_machine, buf);
3570 break;
886a2506 3571
f3485b74
NC
3572 case EM_ARM:
3573 decode_ARM_machine_flags (e_flags, buf);
3574 break;
76da6bbe 3575
343433df
AB
3576 case EM_AVR:
3577 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3578 break;
3579
781303ce
MF
3580 case EM_BLACKFIN:
3581 if (e_flags & EF_BFIN_PIC)
3582 strcat (buf, ", PIC");
3583
3584 if (e_flags & EF_BFIN_FDPIC)
3585 strcat (buf, ", FDPIC");
3586
3587 if (e_flags & EF_BFIN_CODE_IN_L1)
3588 strcat (buf, ", code in L1");
3589
3590 if (e_flags & EF_BFIN_DATA_IN_L1)
3591 strcat (buf, ", data in L1");
3592
3593 break;
3594
ec2dfb42
AO
3595 case EM_CYGNUS_FRV:
3596 switch (e_flags & EF_FRV_CPU_MASK)
3597 {
3598 case EF_FRV_CPU_GENERIC:
3599 break;
3600
3601 default:
3602 strcat (buf, ", fr???");
3603 break;
57346661 3604
ec2dfb42
AO
3605 case EF_FRV_CPU_FR300:
3606 strcat (buf, ", fr300");
3607 break;
3608
3609 case EF_FRV_CPU_FR400:
3610 strcat (buf, ", fr400");
3611 break;
3612 case EF_FRV_CPU_FR405:
3613 strcat (buf, ", fr405");
3614 break;
3615
3616 case EF_FRV_CPU_FR450:
3617 strcat (buf, ", fr450");
3618 break;
3619
3620 case EF_FRV_CPU_FR500:
3621 strcat (buf, ", fr500");
3622 break;
3623 case EF_FRV_CPU_FR550:
3624 strcat (buf, ", fr550");
3625 break;
3626
3627 case EF_FRV_CPU_SIMPLE:
3628 strcat (buf, ", simple");
3629 break;
3630 case EF_FRV_CPU_TOMCAT:
3631 strcat (buf, ", tomcat");
3632 break;
3633 }
1c877e87 3634 break;
ec2dfb42 3635
53c7db4b 3636 case EM_68K:
425c6cb0 3637 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3638 strcat (buf, ", m68000");
425c6cb0 3639 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3640 strcat (buf, ", cpu32");
3641 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3642 strcat (buf, ", fido_a");
425c6cb0 3643 else
266abb8f 3644 {
2cf0635d
NC
3645 char const * isa = _("unknown");
3646 char const * mac = _("unknown mac");
3647 char const * additional = NULL;
0112cd26 3648
c694fd50 3649 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3650 {
c694fd50 3651 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3652 isa = "A";
3653 additional = ", nodiv";
3654 break;
c694fd50 3655 case EF_M68K_CF_ISA_A:
266abb8f
NS
3656 isa = "A";
3657 break;
c694fd50 3658 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3659 isa = "A+";
3660 break;
c694fd50 3661 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3662 isa = "B";
3663 additional = ", nousp";
3664 break;
c694fd50 3665 case EF_M68K_CF_ISA_B:
266abb8f
NS
3666 isa = "B";
3667 break;
f608cd77
NS
3668 case EF_M68K_CF_ISA_C:
3669 isa = "C";
3670 break;
3671 case EF_M68K_CF_ISA_C_NODIV:
3672 isa = "C";
3673 additional = ", nodiv";
3674 break;
266abb8f
NS
3675 }
3676 strcat (buf, ", cf, isa ");
3677 strcat (buf, isa);
0b2e31dc
NS
3678 if (additional)
3679 strcat (buf, additional);
c694fd50 3680 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3681 strcat (buf, ", float");
c694fd50 3682 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3683 {
3684 case 0:
3685 mac = NULL;
3686 break;
c694fd50 3687 case EF_M68K_CF_MAC:
266abb8f
NS
3688 mac = "mac";
3689 break;
c694fd50 3690 case EF_M68K_CF_EMAC:
266abb8f
NS
3691 mac = "emac";
3692 break;
f608cd77
NS
3693 case EF_M68K_CF_EMAC_B:
3694 mac = "emac_b";
3695 break;
266abb8f
NS
3696 }
3697 if (mac)
3698 {
3699 strcat (buf, ", ");
3700 strcat (buf, mac);
3701 }
266abb8f 3702 }
53c7db4b 3703 break;
33c63f9d 3704
153a2776
NC
3705 case EM_CYGNUS_MEP:
3706 switch (e_flags & EF_MEP_CPU_MASK)
3707 {
3708 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3709 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3710 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3711 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3712 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3713 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3714 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3715 }
3716
3717 switch (e_flags & EF_MEP_COP_MASK)
3718 {
3719 case EF_MEP_COP_NONE: break;
3720 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3721 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3722 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3723 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3724 default: strcat (buf, _("<unknown MeP copro type>")); break;
3725 }
3726
3727 if (e_flags & EF_MEP_LIBRARY)
3728 strcat (buf, ", Built for Library");
3729
3730 if (e_flags & EF_MEP_INDEX_MASK)
3731 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3732 e_flags & EF_MEP_INDEX_MASK);
3733
3734 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3735 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3736 e_flags & ~ EF_MEP_ALL_FLAGS);
3737 break;
3738
252b5132
RH
3739 case EM_PPC:
3740 if (e_flags & EF_PPC_EMB)
3741 strcat (buf, ", emb");
3742
3743 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3744 strcat (buf, _(", relocatable"));
252b5132
RH
3745
3746 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3747 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3748 break;
3749
ee67d69a
AM
3750 case EM_PPC64:
3751 if (e_flags & EF_PPC64_ABI)
3752 {
3753 char abi[] = ", abiv0";
3754
3755 abi[6] += e_flags & EF_PPC64_ABI;
3756 strcat (buf, abi);
3757 }
3758 break;
3759
708e2187
NC
3760 case EM_V800:
3761 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3762 strcat (buf, ", RH850 ABI");
0b4362b0 3763
708e2187
NC
3764 if (e_flags & EF_V800_850E3)
3765 strcat (buf, ", V3 architecture");
3766
3767 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3768 strcat (buf, ", FPU not used");
3769
3770 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3771 strcat (buf, ", regmode: COMMON");
3772
3773 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3774 strcat (buf, ", r4 not used");
3775
3776 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3777 strcat (buf, ", r30 not used");
3778
3779 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3780 strcat (buf, ", r5 not used");
3781
3782 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3783 strcat (buf, ", r2 not used");
3784
3785 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3786 {
3787 switch (e_flags & - e_flags)
3788 {
3789 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3790 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3791 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3792 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3793 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3794 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3795 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3796 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3797 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3798 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3799 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3800 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3801 default: break;
3802 }
3803 }
3804 break;
3805
2b0337b0 3806 case EM_V850:
252b5132
RH
3807 case EM_CYGNUS_V850:
3808 switch (e_flags & EF_V850_ARCH)
3809 {
78c8d46c
NC
3810 case E_V850E3V5_ARCH:
3811 strcat (buf, ", v850e3v5");
3812 break;
1cd986c5
NC
3813 case E_V850E2V3_ARCH:
3814 strcat (buf, ", v850e2v3");
3815 break;
3816 case E_V850E2_ARCH:
3817 strcat (buf, ", v850e2");
3818 break;
3819 case E_V850E1_ARCH:
3820 strcat (buf, ", v850e1");
8ad30312 3821 break;
252b5132
RH
3822 case E_V850E_ARCH:
3823 strcat (buf, ", v850e");
3824 break;
252b5132
RH
3825 case E_V850_ARCH:
3826 strcat (buf, ", v850");
3827 break;
3828 default:
2b692964 3829 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3830 break;
3831 }
3832 break;
3833
2b0337b0 3834 case EM_M32R:
252b5132
RH
3835 case EM_CYGNUS_M32R:
3836 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3837 strcat (buf, ", m32r");
252b5132
RH
3838 break;
3839
3840 case EM_MIPS:
4fe85591 3841 case EM_MIPS_RS3_LE:
252b5132
RH
3842 if (e_flags & EF_MIPS_NOREORDER)
3843 strcat (buf, ", noreorder");
3844
3845 if (e_flags & EF_MIPS_PIC)
3846 strcat (buf, ", pic");
3847
3848 if (e_flags & EF_MIPS_CPIC)
3849 strcat (buf, ", cpic");
3850
d1bdd336
TS
3851 if (e_flags & EF_MIPS_UCODE)
3852 strcat (buf, ", ugen_reserved");
3853
252b5132
RH
3854 if (e_flags & EF_MIPS_ABI2)
3855 strcat (buf, ", abi2");
3856
43521d43
TS
3857 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3858 strcat (buf, ", odk first");
3859
a5d22d2a
TS
3860 if (e_flags & EF_MIPS_32BITMODE)
3861 strcat (buf, ", 32bitmode");
3862
ba92f887
MR
3863 if (e_flags & EF_MIPS_NAN2008)
3864 strcat (buf, ", nan2008");
3865
fef1b0b3
SE
3866 if (e_flags & EF_MIPS_FP64)
3867 strcat (buf, ", fp64");
3868
156c2f8b
NC
3869 switch ((e_flags & EF_MIPS_MACH))
3870 {
3871 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3872 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3873 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3874 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3875 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3876 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3877 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3878 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3879 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3880 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3881 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3882 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3883 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3884 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3885 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3886 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3887 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3888 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3889 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3890 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3891 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3892 case 0:
3893 /* We simply ignore the field in this case to avoid confusion:
3894 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3895 extension. */
3896 break;
2b692964 3897 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3898 }
43521d43
TS
3899
3900 switch ((e_flags & EF_MIPS_ABI))
3901 {
3902 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3903 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3904 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3905 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3906 case 0:
3907 /* We simply ignore the field in this case to avoid confusion:
3908 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3909 This means it is likely to be an o32 file, but not for
3910 sure. */
3911 break;
2b692964 3912 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3913 }
3914
3915 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3916 strcat (buf, ", mdmx");
3917
3918 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3919 strcat (buf, ", mips16");
3920
df58fc94
RS
3921 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3922 strcat (buf, ", micromips");
3923
43521d43
TS
3924 switch ((e_flags & EF_MIPS_ARCH))
3925 {
3926 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3927 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3928 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3929 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3930 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3931 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3932 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3933 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3934 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3935 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3936 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3937 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3938 }
252b5132 3939 break;
351b4b40 3940
35c08157
KLC
3941 case EM_NDS32:
3942 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3943 break;
3944
fe944acf
FT
3945 case EM_NFP:
3946 switch (EF_NFP_MACH (e_flags))
3947 {
3948 case E_NFP_MACH_3200:
3949 strcat (buf, ", NFP-32xx");
3950 break;
3951 case E_NFP_MACH_6000:
3952 strcat (buf, ", NFP-6xxx");
3953 break;
3954 }
3955 break;
3956
e23eba97
NC
3957 case EM_RISCV:
3958 if (e_flags & EF_RISCV_RVC)
3959 strcat (buf, ", RVC");
2922d21d 3960
7f999549
JW
3961 if (e_flags & EF_RISCV_RVE)
3962 strcat (buf, ", RVE");
3963
2922d21d
AW
3964 switch (e_flags & EF_RISCV_FLOAT_ABI)
3965 {
3966 case EF_RISCV_FLOAT_ABI_SOFT:
3967 strcat (buf, ", soft-float ABI");
3968 break;
3969
3970 case EF_RISCV_FLOAT_ABI_SINGLE:
3971 strcat (buf, ", single-float ABI");
3972 break;
3973
3974 case EF_RISCV_FLOAT_ABI_DOUBLE:
3975 strcat (buf, ", double-float ABI");
3976 break;
3977
3978 case EF_RISCV_FLOAT_ABI_QUAD:
3979 strcat (buf, ", quad-float ABI");
3980 break;
3981 }
e23eba97
NC
3982 break;
3983
ccde1100
AO
3984 case EM_SH:
3985 switch ((e_flags & EF_SH_MACH_MASK))
3986 {
3987 case EF_SH1: strcat (buf, ", sh1"); break;
3988 case EF_SH2: strcat (buf, ", sh2"); break;
3989 case EF_SH3: strcat (buf, ", sh3"); break;
3990 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3991 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3992 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3993 case EF_SH3E: strcat (buf, ", sh3e"); break;
3994 case EF_SH4: strcat (buf, ", sh4"); break;
3995 case EF_SH5: strcat (buf, ", sh5"); break;
3996 case EF_SH2E: strcat (buf, ", sh2e"); break;
3997 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3998 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3999 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4000 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4001 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4002 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4003 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4004 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4005 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4006 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4007 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4008 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4009 }
4010
cec6a5b8
MR
4011 if (e_flags & EF_SH_PIC)
4012 strcat (buf, ", pic");
4013
4014 if (e_flags & EF_SH_FDPIC)
4015 strcat (buf, ", fdpic");
ccde1100 4016 break;
948f632f 4017
73589c9d
CS
4018 case EM_OR1K:
4019 if (e_flags & EF_OR1K_NODELAY)
4020 strcat (buf, ", no delay");
4021 break;
57346661 4022
351b4b40
RH
4023 case EM_SPARCV9:
4024 if (e_flags & EF_SPARC_32PLUS)
4025 strcat (buf, ", v8+");
4026
4027 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4028 strcat (buf, ", ultrasparcI");
4029
4030 if (e_flags & EF_SPARC_SUN_US3)
4031 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4032
4033 if (e_flags & EF_SPARC_HAL_R1)
4034 strcat (buf, ", halr1");
4035
4036 if (e_flags & EF_SPARC_LEDATA)
4037 strcat (buf, ", ledata");
4038
4039 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4040 strcat (buf, ", tso");
4041
4042 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4043 strcat (buf, ", pso");
4044
4045 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4046 strcat (buf, ", rmo");
4047 break;
7d466069 4048
103f02d3
UD
4049 case EM_PARISC:
4050 switch (e_flags & EF_PARISC_ARCH)
4051 {
4052 case EFA_PARISC_1_0:
4053 strcpy (buf, ", PA-RISC 1.0");
4054 break;
4055 case EFA_PARISC_1_1:
4056 strcpy (buf, ", PA-RISC 1.1");
4057 break;
4058 case EFA_PARISC_2_0:
4059 strcpy (buf, ", PA-RISC 2.0");
4060 break;
4061 default:
4062 break;
4063 }
4064 if (e_flags & EF_PARISC_TRAPNIL)
4065 strcat (buf, ", trapnil");
4066 if (e_flags & EF_PARISC_EXT)
4067 strcat (buf, ", ext");
4068 if (e_flags & EF_PARISC_LSB)
4069 strcat (buf, ", lsb");
4070 if (e_flags & EF_PARISC_WIDE)
4071 strcat (buf, ", wide");
4072 if (e_flags & EF_PARISC_NO_KABP)
4073 strcat (buf, ", no kabp");
4074 if (e_flags & EF_PARISC_LAZYSWAP)
4075 strcat (buf, ", lazyswap");
30800947 4076 break;
76da6bbe 4077
7d466069 4078 case EM_PJ:
2b0337b0 4079 case EM_PJ_OLD:
7d466069
ILT
4080 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4081 strcat (buf, ", new calling convention");
4082
4083 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4084 strcat (buf, ", gnu calling convention");
4085 break;
4d6ed7c8
NC
4086
4087 case EM_IA_64:
4088 if ((e_flags & EF_IA_64_ABI64))
4089 strcat (buf, ", 64-bit");
4090 else
4091 strcat (buf, ", 32-bit");
4092 if ((e_flags & EF_IA_64_REDUCEDFP))
4093 strcat (buf, ", reduced fp model");
4094 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4095 strcat (buf, ", no function descriptors, constant gp");
4096 else if ((e_flags & EF_IA_64_CONS_GP))
4097 strcat (buf, ", constant gp");
4098 if ((e_flags & EF_IA_64_ABSOLUTE))
4099 strcat (buf, ", absolute");
dda8d76d 4100 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4101 {
4102 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4103 strcat (buf, ", vms_linkages");
4104 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4105 {
4106 case EF_IA_64_VMS_COMCOD_SUCCESS:
4107 break;
4108 case EF_IA_64_VMS_COMCOD_WARNING:
4109 strcat (buf, ", warning");
4110 break;
4111 case EF_IA_64_VMS_COMCOD_ERROR:
4112 strcat (buf, ", error");
4113 break;
4114 case EF_IA_64_VMS_COMCOD_ABORT:
4115 strcat (buf, ", abort");
4116 break;
4117 default:
bee0ee85
NC
4118 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4119 e_flags & EF_IA_64_VMS_COMCOD);
4120 strcat (buf, ", <unknown>");
28f997cf
TG
4121 }
4122 }
4d6ed7c8 4123 break;
179d3252
JT
4124
4125 case EM_VAX:
4126 if ((e_flags & EF_VAX_NONPIC))
4127 strcat (buf, ", non-PIC");
4128 if ((e_flags & EF_VAX_DFLOAT))
4129 strcat (buf, ", D-Float");
4130 if ((e_flags & EF_VAX_GFLOAT))
4131 strcat (buf, ", G-Float");
4132 break;
c7927a3c 4133
619ed720
EB
4134 case EM_VISIUM:
4135 if (e_flags & EF_VISIUM_ARCH_MCM)
4136 strcat (buf, ", mcm");
4137 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4138 strcat (buf, ", mcm24");
4139 if (e_flags & EF_VISIUM_ARCH_GR6)
4140 strcat (buf, ", gr6");
4141 break;
4142
4046d87a 4143 case EM_RL78:
1740ba0c
NC
4144 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4145 {
4146 case E_FLAG_RL78_ANY_CPU: break;
4147 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4148 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4149 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4150 }
856ea05c
KP
4151 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4152 strcat (buf, ", 64-bit doubles");
4046d87a 4153 break;
0b4362b0 4154
c7927a3c
NC
4155 case EM_RX:
4156 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4157 strcat (buf, ", 64-bit doubles");
4158 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4159 strcat (buf, ", dsp");
d4cb0ea0 4160 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4161 strcat (buf, ", pid");
708e2187
NC
4162 if (e_flags & E_FLAG_RX_ABI)
4163 strcat (buf, ", RX ABI");
3525236c
NC
4164 if (e_flags & E_FLAG_RX_SINSNS_SET)
4165 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4166 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4167 if (e_flags & E_FLAG_RX_V2)
4168 strcat (buf, ", V2");
f87673e0
YS
4169 if (e_flags & E_FLAG_RX_V3)
4170 strcat (buf, ", V3");
d4cb0ea0 4171 break;
55786da2
AK
4172
4173 case EM_S390:
4174 if (e_flags & EF_S390_HIGH_GPRS)
4175 strcat (buf, ", highgprs");
d4cb0ea0 4176 break;
40b36596
JM
4177
4178 case EM_TI_C6000:
4179 if ((e_flags & EF_C6000_REL))
4180 strcat (buf, ", relocatable module");
d4cb0ea0 4181 break;
13761a11
NC
4182
4183 case EM_MSP430:
4184 strcat (buf, _(": architecture variant: "));
4185 switch (e_flags & EF_MSP430_MACH)
4186 {
4187 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4188 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4189 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4190 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4191 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4192 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4193 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4194 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4195 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4196 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4197 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4198 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4199 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4200 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4201 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4202 default:
4203 strcat (buf, _(": unknown")); break;
4204 }
4205
4206 if (e_flags & ~ EF_MSP430_MACH)
4207 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4208 break;
4209
4210 case EM_Z80:
4211 switch (e_flags & EF_Z80_MACH_MSK)
4212 {
4213 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4214 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4215 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4216 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4217 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4218 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4219 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4220 default:
4221 strcat (buf, _(", unknown")); break;
4222 }
4223 break;
e9a0721f 4224 case EM_LOONGARCH:
4225 if (EF_LOONGARCH_IS_LP64 (e_flags))
4226 strcat (buf, ", LP64");
4227 else if (EF_LOONGARCH_IS_ILP32 (e_flags))
4228 strcat (buf, ", ILP32");
4229
4230 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4231 strcat (buf, ", SOFT-FLOAT");
4232 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4233 strcat (buf, ", SINGLE-FLOAT");
4234 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4235 strcat (buf, ", DOUBLE-FLOAT");
4236
4237 break;
252b5132
RH
4238 }
4239 }
4240
4241 return buf;
4242}
4243
252b5132 4244static const char *
dda8d76d 4245get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4246{
4247 static char buff[32];
4248
4249 switch (osabi)
4250 {
4251 case ELFOSABI_NONE: return "UNIX - System V";
4252 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4253 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4254 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4255 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4256 case ELFOSABI_AIX: return "UNIX - AIX";
4257 case ELFOSABI_IRIX: return "UNIX - IRIX";
4258 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4259 case ELFOSABI_TRU64: return "UNIX - TRU64";
4260 case ELFOSABI_MODESTO: return "Novell - Modesto";
4261 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4262 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4263 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4264 case ELFOSABI_AROS: return "AROS";
11636f9e 4265 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4266 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4267 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4268 default:
40b36596 4269 if (osabi >= 64)
dda8d76d 4270 switch (filedata->file_header.e_machine)
40b36596
JM
4271 {
4272 case EM_ARM:
4273 switch (osabi)
4274 {
4275 case ELFOSABI_ARM: return "ARM";
18a20338 4276 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4277 default:
4278 break;
4279 }
4280 break;
4281
4282 case EM_MSP430:
4283 case EM_MSP430_OLD:
619ed720 4284 case EM_VISIUM:
40b36596
JM
4285 switch (osabi)
4286 {
4287 case ELFOSABI_STANDALONE: return _("Standalone App");
4288 default:
4289 break;
4290 }
4291 break;
4292
4293 case EM_TI_C6000:
4294 switch (osabi)
4295 {
4296 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4297 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4298 default:
4299 break;
4300 }
4301 break;
4302
4303 default:
4304 break;
4305 }
e9e44622 4306 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4307 return buff;
4308 }
4309}
4310
a06ea964
NC
4311static const char *
4312get_aarch64_segment_type (unsigned long type)
4313{
4314 switch (type)
4315 {
32ec8896
NC
4316 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
4317 default: return NULL;
a06ea964 4318 }
a06ea964
NC
4319}
4320
b294bdf8
MM
4321static const char *
4322get_arm_segment_type (unsigned long type)
4323{
4324 switch (type)
4325 {
32ec8896
NC
4326 case PT_ARM_EXIDX: return "EXIDX";
4327 default: return NULL;
b294bdf8 4328 }
b294bdf8
MM
4329}
4330
b4cbbe8f
AK
4331static const char *
4332get_s390_segment_type (unsigned long type)
4333{
4334 switch (type)
4335 {
4336 case PT_S390_PGSTE: return "S390_PGSTE";
4337 default: return NULL;
4338 }
4339}
4340
d3ba0551
AM
4341static const char *
4342get_mips_segment_type (unsigned long type)
252b5132
RH
4343{
4344 switch (type)
4345 {
32ec8896
NC
4346 case PT_MIPS_REGINFO: return "REGINFO";
4347 case PT_MIPS_RTPROC: return "RTPROC";
4348 case PT_MIPS_OPTIONS: return "OPTIONS";
4349 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4350 default: return NULL;
252b5132 4351 }
252b5132
RH
4352}
4353
103f02d3 4354static const char *
d3ba0551 4355get_parisc_segment_type (unsigned long type)
103f02d3
UD
4356{
4357 switch (type)
4358 {
103f02d3
UD
4359 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4360 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4361 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4362 default: return NULL;
103f02d3 4363 }
103f02d3
UD
4364}
4365
4d6ed7c8 4366static const char *
d3ba0551 4367get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4368{
4369 switch (type)
4370 {
4371 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4372 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4373 default: return NULL;
4d6ed7c8 4374 }
4d6ed7c8
NC
4375}
4376
40b36596
JM
4377static const char *
4378get_tic6x_segment_type (unsigned long type)
4379{
4380 switch (type)
4381 {
32ec8896
NC
4382 case PT_C6000_PHATTR: return "C6000_PHATTR";
4383 default: return NULL;
40b36596 4384 }
40b36596
JM
4385}
4386
fbc95f1e
KC
4387static const char *
4388get_riscv_segment_type (unsigned long type)
4389{
4390 switch (type)
4391 {
4392 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4393 default: return NULL;
4394 }
4395}
4396
df3a023b
AM
4397static const char *
4398get_hpux_segment_type (unsigned long type, unsigned e_machine)
4399{
4400 if (e_machine == EM_PARISC)
4401 switch (type)
4402 {
4403 case PT_HP_TLS: return "HP_TLS";
4404 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4405 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4406 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4407 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4408 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4409 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4410 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4411 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4412 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4413 case PT_HP_PARALLEL: return "HP_PARALLEL";
4414 case PT_HP_FASTBIND: return "HP_FASTBIND";
4415 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4416 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4417 case PT_HP_STACK: return "HP_STACK";
4418 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4419 default: return NULL;
4420 }
4421
4422 if (e_machine == EM_IA_64)
4423 switch (type)
4424 {
4425 case PT_HP_TLS: return "HP_TLS";
4426 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4427 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4428 case PT_IA_64_HP_STACK: return "HP_STACK";
4429 default: return NULL;
4430 }
4431
4432 return NULL;
4433}
4434
5522f910
NC
4435static const char *
4436get_solaris_segment_type (unsigned long type)
4437{
4438 switch (type)
4439 {
4440 case 0x6464e550: return "PT_SUNW_UNWIND";
4441 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4442 case 0x6ffffff7: return "PT_LOSUNW";
4443 case 0x6ffffffa: return "PT_SUNWBSS";
4444 case 0x6ffffffb: return "PT_SUNWSTACK";
4445 case 0x6ffffffc: return "PT_SUNWDTRACE";
4446 case 0x6ffffffd: return "PT_SUNWCAP";
4447 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4448 default: return NULL;
5522f910
NC
4449 }
4450}
4451
252b5132 4452static const char *
dda8d76d 4453get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4454{
b34976b6 4455 static char buff[32];
252b5132
RH
4456
4457 switch (p_type)
4458 {
b34976b6
AM
4459 case PT_NULL: return "NULL";
4460 case PT_LOAD: return "LOAD";
252b5132 4461 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4462 case PT_INTERP: return "INTERP";
4463 case PT_NOTE: return "NOTE";
4464 case PT_SHLIB: return "SHLIB";
4465 case PT_PHDR: return "PHDR";
13ae64f3 4466 case PT_TLS: return "TLS";
32ec8896 4467 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4468 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4469 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4470 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4471
3eba3ef3
NC
4472 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4473 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4474 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4475
252b5132 4476 default:
df3a023b 4477 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4478 {
2cf0635d 4479 const char * result;
103f02d3 4480
dda8d76d 4481 switch (filedata->file_header.e_machine)
252b5132 4482 {
a06ea964
NC
4483 case EM_AARCH64:
4484 result = get_aarch64_segment_type (p_type);
4485 break;
b294bdf8
MM
4486 case EM_ARM:
4487 result = get_arm_segment_type (p_type);
4488 break;
252b5132 4489 case EM_MIPS:
4fe85591 4490 case EM_MIPS_RS3_LE:
252b5132
RH
4491 result = get_mips_segment_type (p_type);
4492 break;
103f02d3
UD
4493 case EM_PARISC:
4494 result = get_parisc_segment_type (p_type);
4495 break;
4d6ed7c8
NC
4496 case EM_IA_64:
4497 result = get_ia64_segment_type (p_type);
4498 break;
40b36596
JM
4499 case EM_TI_C6000:
4500 result = get_tic6x_segment_type (p_type);
4501 break;
b4cbbe8f
AK
4502 case EM_S390:
4503 case EM_S390_OLD:
4504 result = get_s390_segment_type (p_type);
4505 break;
fbc95f1e
KC
4506 case EM_RISCV:
4507 result = get_riscv_segment_type (p_type);
4508 break;
252b5132
RH
4509 default:
4510 result = NULL;
4511 break;
4512 }
103f02d3 4513
252b5132
RH
4514 if (result != NULL)
4515 return result;
103f02d3 4516
1a9ccd70 4517 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4518 }
4519 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4520 {
df3a023b 4521 const char * result = NULL;
103f02d3 4522
df3a023b 4523 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4524 {
df3a023b
AM
4525 case ELFOSABI_GNU:
4526 case ELFOSABI_FREEBSD:
4527 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4528 {
4529 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4530 result = buff;
4531 }
103f02d3 4532 break;
df3a023b
AM
4533 case ELFOSABI_HPUX:
4534 result = get_hpux_segment_type (p_type,
4535 filedata->file_header.e_machine);
4536 break;
4537 case ELFOSABI_SOLARIS:
4538 result = get_solaris_segment_type (p_type);
00428cca 4539 break;
103f02d3 4540 default:
103f02d3
UD
4541 break;
4542 }
103f02d3
UD
4543 if (result != NULL)
4544 return result;
4545
1a9ccd70 4546 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4547 }
252b5132 4548 else
e9e44622 4549 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4550
4551 return buff;
4552 }
4553}
4554
53a346d8
CZ
4555static const char *
4556get_arc_section_type_name (unsigned int sh_type)
4557{
4558 switch (sh_type)
4559 {
4560 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4561 default:
4562 break;
4563 }
4564 return NULL;
4565}
4566
252b5132 4567static const char *
d3ba0551 4568get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4569{
4570 switch (sh_type)
4571 {
b34976b6
AM
4572 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4573 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4574 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4575 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4576 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4577 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4578 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4579 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4580 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4581 case SHT_MIPS_RELD: return "MIPS_RELD";
4582 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4583 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4584 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4585 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4586 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4587 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4588 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4589 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4590 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4591 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4592 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4593 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4594 case SHT_MIPS_LINE: return "MIPS_LINE";
4595 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4596 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4597 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4598 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4599 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4600 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4601 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4602 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4603 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4604 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4605 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4606 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4607 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4608 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4609 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4610 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4611 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4612 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4613 default:
4614 break;
4615 }
4616 return NULL;
4617}
4618
103f02d3 4619static const char *
d3ba0551 4620get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4621{
4622 switch (sh_type)
4623 {
4624 case SHT_PARISC_EXT: return "PARISC_EXT";
4625 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4626 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4627 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4628 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4629 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4630 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4631 default: return NULL;
103f02d3 4632 }
103f02d3
UD
4633}
4634
4d6ed7c8 4635static const char *
dda8d76d 4636get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4637{
18bd398b 4638 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4639 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4640 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4641
4d6ed7c8
NC
4642 switch (sh_type)
4643 {
148b93f2
NC
4644 case SHT_IA_64_EXT: return "IA_64_EXT";
4645 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4646 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4647 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4648 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4649 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4650 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4651 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4652 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4653 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4654 default:
4655 break;
4656 }
4657 return NULL;
4658}
4659
d2b2c203
DJ
4660static const char *
4661get_x86_64_section_type_name (unsigned int sh_type)
4662{
4663 switch (sh_type)
4664 {
4665 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4666 default: return NULL;
d2b2c203 4667 }
d2b2c203
DJ
4668}
4669
a06ea964
NC
4670static const char *
4671get_aarch64_section_type_name (unsigned int sh_type)
4672{
4673 switch (sh_type)
4674 {
32ec8896
NC
4675 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4676 default: return NULL;
a06ea964 4677 }
a06ea964
NC
4678}
4679
40a18ebd
NC
4680static const char *
4681get_arm_section_type_name (unsigned int sh_type)
4682{
4683 switch (sh_type)
4684 {
7f6fed87
NC
4685 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4686 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4687 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4688 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4689 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4690 default: return NULL;
40a18ebd 4691 }
40a18ebd
NC
4692}
4693
40b36596
JM
4694static const char *
4695get_tic6x_section_type_name (unsigned int sh_type)
4696{
4697 switch (sh_type)
4698 {
32ec8896
NC
4699 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4700 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4701 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4702 case SHT_TI_ICODE: return "TI_ICODE";
4703 case SHT_TI_XREF: return "TI_XREF";
4704 case SHT_TI_HANDLER: return "TI_HANDLER";
4705 case SHT_TI_INITINFO: return "TI_INITINFO";
4706 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4707 default: return NULL;
40b36596 4708 }
40b36596
JM
4709}
4710
13761a11 4711static const char *
b0191216 4712get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4713{
4714 switch (sh_type)
4715 {
32ec8896
NC
4716 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4717 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4718 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4719 default: return NULL;
13761a11
NC
4720 }
4721}
4722
fe944acf
FT
4723static const char *
4724get_nfp_section_type_name (unsigned int sh_type)
4725{
4726 switch (sh_type)
4727 {
4728 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4729 case SHT_NFP_INITREG: return "NFP_INITREG";
4730 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4731 default: return NULL;
4732 }
4733}
4734
685080f2
NC
4735static const char *
4736get_v850_section_type_name (unsigned int sh_type)
4737{
4738 switch (sh_type)
4739 {
32ec8896
NC
4740 case SHT_V850_SCOMMON: return "V850 Small Common";
4741 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4742 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4743 case SHT_RENESAS_IOP: return "RENESAS IOP";
4744 case SHT_RENESAS_INFO: return "RENESAS INFO";
4745 default: return NULL;
685080f2
NC
4746 }
4747}
4748
2dc8dd17
JW
4749static const char *
4750get_riscv_section_type_name (unsigned int sh_type)
4751{
4752 switch (sh_type)
4753 {
4754 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4755 default: return NULL;
4756 }
4757}
4758
0861f561
CQ
4759static const char *
4760get_csky_section_type_name (unsigned int sh_type)
4761{
4762 switch (sh_type)
4763 {
4764 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4765 default: return NULL;
4766 }
4767}
4768
252b5132 4769static const char *
dda8d76d 4770get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4771{
b34976b6 4772 static char buff[32];
9fb71ee4 4773 const char * result;
252b5132
RH
4774
4775 switch (sh_type)
4776 {
4777 case SHT_NULL: return "NULL";
4778 case SHT_PROGBITS: return "PROGBITS";
4779 case SHT_SYMTAB: return "SYMTAB";
4780 case SHT_STRTAB: return "STRTAB";
4781 case SHT_RELA: return "RELA";
dd207c13 4782 case SHT_RELR: return "RELR";
252b5132
RH
4783 case SHT_HASH: return "HASH";
4784 case SHT_DYNAMIC: return "DYNAMIC";
4785 case SHT_NOTE: return "NOTE";
4786 case SHT_NOBITS: return "NOBITS";
4787 case SHT_REL: return "REL";
4788 case SHT_SHLIB: return "SHLIB";
4789 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4790 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4791 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4792 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4793 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4794 case SHT_GROUP: return "GROUP";
67ce483b 4795 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4796 case SHT_GNU_verdef: return "VERDEF";
4797 case SHT_GNU_verneed: return "VERNEED";
4798 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4799 case 0x6ffffff0: return "VERSYM";
4800 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4801 case 0x7ffffffd: return "AUXILIARY";
4802 case 0x7fffffff: return "FILTER";
047b2264 4803 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4804
4805 default:
4806 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4807 {
dda8d76d 4808 switch (filedata->file_header.e_machine)
252b5132 4809 {
53a346d8
CZ
4810 case EM_ARC:
4811 case EM_ARC_COMPACT:
4812 case EM_ARC_COMPACT2:
4813 result = get_arc_section_type_name (sh_type);
4814 break;
252b5132 4815 case EM_MIPS:
4fe85591 4816 case EM_MIPS_RS3_LE:
252b5132
RH
4817 result = get_mips_section_type_name (sh_type);
4818 break;
103f02d3
UD
4819 case EM_PARISC:
4820 result = get_parisc_section_type_name (sh_type);
4821 break;
4d6ed7c8 4822 case EM_IA_64:
dda8d76d 4823 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4824 break;
d2b2c203 4825 case EM_X86_64:
8a9036a4 4826 case EM_L1OM:
7a9068fe 4827 case EM_K1OM:
d2b2c203
DJ
4828 result = get_x86_64_section_type_name (sh_type);
4829 break;
a06ea964
NC
4830 case EM_AARCH64:
4831 result = get_aarch64_section_type_name (sh_type);
4832 break;
40a18ebd
NC
4833 case EM_ARM:
4834 result = get_arm_section_type_name (sh_type);
4835 break;
40b36596
JM
4836 case EM_TI_C6000:
4837 result = get_tic6x_section_type_name (sh_type);
4838 break;
13761a11 4839 case EM_MSP430:
b0191216 4840 result = get_msp430_section_type_name (sh_type);
13761a11 4841 break;
fe944acf
FT
4842 case EM_NFP:
4843 result = get_nfp_section_type_name (sh_type);
4844 break;
685080f2
NC
4845 case EM_V800:
4846 case EM_V850:
4847 case EM_CYGNUS_V850:
4848 result = get_v850_section_type_name (sh_type);
4849 break;
2dc8dd17
JW
4850 case EM_RISCV:
4851 result = get_riscv_section_type_name (sh_type);
4852 break;
0861f561
CQ
4853 case EM_CSKY:
4854 result = get_csky_section_type_name (sh_type);
4855 break;
252b5132
RH
4856 default:
4857 result = NULL;
4858 break;
4859 }
4860
4861 if (result != NULL)
4862 return result;
4863
9fb71ee4 4864 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4865 }
4866 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4867 {
dda8d76d 4868 switch (filedata->file_header.e_machine)
148b93f2
NC
4869 {
4870 case EM_IA_64:
dda8d76d 4871 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4872 break;
4873 default:
dda8d76d 4874 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4875 result = get_solaris_section_type (sh_type);
4876 else
1b4b80bf
NC
4877 {
4878 switch (sh_type)
4879 {
4880 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4881 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4882 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4883 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4884 default:
4885 result = NULL;
4886 break;
4887 }
4888 }
148b93f2
NC
4889 break;
4890 }
4891
4892 if (result != NULL)
4893 return result;
4894
9fb71ee4 4895 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4896 }
252b5132 4897 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4898 {
dda8d76d 4899 switch (filedata->file_header.e_machine)
685080f2
NC
4900 {
4901 case EM_V800:
4902 case EM_V850:
4903 case EM_CYGNUS_V850:
9fb71ee4 4904 result = get_v850_section_type_name (sh_type);
a9fb83be 4905 break;
685080f2 4906 default:
9fb71ee4 4907 result = NULL;
685080f2
NC
4908 break;
4909 }
4910
9fb71ee4
NC
4911 if (result != NULL)
4912 return result;
4913
4914 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4915 }
252b5132 4916 else
a7dbfd1c
NC
4917 /* This message is probably going to be displayed in a 15
4918 character wide field, so put the hex value first. */
4919 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4920
252b5132
RH
4921 return buff;
4922 }
4923}
4924
79bc120c
NC
4925enum long_option_values
4926{
4927 OPTION_DEBUG_DUMP = 512,
4928 OPTION_DYN_SYMS,
0f03783c 4929 OPTION_LTO_SYMS,
79bc120c
NC
4930 OPTION_DWARF_DEPTH,
4931 OPTION_DWARF_START,
4932 OPTION_DWARF_CHECK,
4933 OPTION_CTF_DUMP,
4934 OPTION_CTF_PARENT,
4935 OPTION_CTF_SYMBOLS,
4936 OPTION_CTF_STRINGS,
4937 OPTION_WITH_SYMBOL_VERSIONS,
4938 OPTION_RECURSE_LIMIT,
4939 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
4940 OPTION_NO_DEMANGLING,
4941 OPTION_SYM_BASE
79bc120c 4942};
2979dc34 4943
85b1c36d 4944static struct option options[] =
252b5132 4945{
79bc120c
NC
4946 /* Note - This table is alpha-sorted on the 'val'
4947 field in order to make adding new options easier. */
4948 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4949 {"all", no_argument, 0, 'a'},
79bc120c
NC
4950 {"demangle", optional_argument, 0, 'C'},
4951 {"archive-index", no_argument, 0, 'c'},
4952 {"use-dynamic", no_argument, 0, 'D'},
4953 {"dynamic", no_argument, 0, 'd'},
b34976b6 4954 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4955 {"section-groups", no_argument, 0, 'g'},
4956 {"help", no_argument, 0, 'H'},
4957 {"file-header", no_argument, 0, 'h'},
b34976b6 4958 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4959 {"lint", no_argument, 0, 'L'},
4960 {"enable-checks", no_argument, 0, 'L'},
4961 {"program-headers", no_argument, 0, 'l'},
b34976b6 4962 {"segments", no_argument, 0, 'l'},
595cf52e 4963 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4964 {"notes", no_argument, 0, 'n'},
ca0e11aa 4965 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4966 {"string-dump", required_argument, 0, 'p'},
4967 {"relocated-dump", required_argument, 0, 'R'},
4968 {"relocs", no_argument, 0, 'r'},
4969 {"section-headers", no_argument, 0, 'S'},
4970 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4971 {"symbols", no_argument, 0, 's'},
4972 {"syms", no_argument, 0, 's'},
79bc120c
NC
4973 {"silent-truncation",no_argument, 0, 'T'},
4974 {"section-details", no_argument, 0, 't'},
b3aa80b4 4975 {"unicode", required_argument, NULL, 'U'},
09c11c86 4976 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4977 {"version-info", no_argument, 0, 'V'},
4978 {"version", no_argument, 0, 'v'},
4979 {"wide", no_argument, 0, 'W'},
b34976b6 4980 {"hex-dump", required_argument, 0, 'x'},
0e602686 4981 {"decompress", no_argument, 0, 'z'},
252b5132 4982
79bc120c
NC
4983 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4984 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4985 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4986 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4987 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4988 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4989 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4990 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4991 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4992 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4993#ifdef ENABLE_LIBCTF
d344b407 4994 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4995 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4996 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4997 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4998#endif
047c3dbf 4999 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5000
b34976b6 5001 {0, no_argument, 0, 0}
252b5132
RH
5002};
5003
5004static void
2cf0635d 5005usage (FILE * stream)
252b5132 5006{
92f01d61
JM
5007 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5008 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5009 fprintf (stream, _(" Options are:\n"));
5010 fprintf (stream, _("\
5011 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5012 fprintf (stream, _("\
5013 -h --file-header Display the ELF file header\n"));
5014 fprintf (stream, _("\
5015 -l --program-headers Display the program headers\n"));
5016 fprintf (stream, _("\
5017 --segments An alias for --program-headers\n"));
5018 fprintf (stream, _("\
5019 -S --section-headers Display the sections' header\n"));
5020 fprintf (stream, _("\
5021 --sections An alias for --section-headers\n"));
5022 fprintf (stream, _("\
5023 -g --section-groups Display the section groups\n"));
5024 fprintf (stream, _("\
5025 -t --section-details Display the section details\n"));
5026 fprintf (stream, _("\
5027 -e --headers Equivalent to: -h -l -S\n"));
5028 fprintf (stream, _("\
5029 -s --syms Display the symbol table\n"));
5030 fprintf (stream, _("\
5031 --symbols An alias for --syms\n"));
5032 fprintf (stream, _("\
5033 --dyn-syms Display the dynamic symbol table\n"));
5034 fprintf (stream, _("\
5035 --lto-syms Display LTO symbol tables\n"));
5036 fprintf (stream, _("\
047c3dbf
NL
5037 --sym-base=[0|8|10|16] \n\
5038 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5039 mixed (the default), octal, decimal, hexadecimal.\n"));
5040 fprintf (stream, _("\
0d646226
AM
5041 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5042 display_demangler_styles (stream, _("\
5043 STYLE can be "));
d6249f5f
AM
5044 fprintf (stream, _("\
5045 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5046 fprintf (stream, _("\
5047 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5048 fprintf (stream, _("\
5049 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5050 fprintf (stream, _("\
5051 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5052 Display unicode characters as determined by the current locale\n\
5053 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5054 escape sequences, or treat them as invalid and display as\n\
5055 \"{hex sequences}\"\n"));
d6249f5f
AM
5056 fprintf (stream, _("\
5057 -n --notes Display the core notes (if present)\n"));
5058 fprintf (stream, _("\
5059 -r --relocs Display the relocations (if present)\n"));
5060 fprintf (stream, _("\
5061 -u --unwind Display the unwind info (if present)\n"));
5062 fprintf (stream, _("\
5063 -d --dynamic Display the dynamic section (if present)\n"));
5064 fprintf (stream, _("\
5065 -V --version-info Display the version sections (if present)\n"));
5066 fprintf (stream, _("\
5067 -A --arch-specific Display architecture specific information (if any)\n"));
5068 fprintf (stream, _("\
5069 -c --archive-index Display the symbol/file index in an archive\n"));
5070 fprintf (stream, _("\
5071 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5072 fprintf (stream, _("\
5073 -L --lint|--enable-checks\n\
5074 Display warning messages for possible problems\n"));
5075 fprintf (stream, _("\
09c11c86 5076 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5077 Dump the contents of section <number|name> as bytes\n"));
5078 fprintf (stream, _("\
09c11c86 5079 -p --string-dump=<number|name>\n\
d6249f5f
AM
5080 Dump the contents of section <number|name> as strings\n"));
5081 fprintf (stream, _("\
cf13d699 5082 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5083 Dump the relocated contents of section <number|name>\n"));
5084 fprintf (stream, _("\
5085 -z --decompress Decompress section before dumping it\n"));
5086 fprintf (stream, _("\
5087 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5088 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5089 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5090 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5091 U/=trace_info]\n\
5092 Display the contents of DWARF debug sections\n"));
5093 fprintf (stream, _("\
5094 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5095 debuginfo files\n"));
5096 fprintf (stream, _("\
5097 -P --process-links Display the contents of non-debug sections in separate\n\
5098 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5099#if DEFAULT_FOR_FOLLOW_LINKS
5100 fprintf (stream, _("\
d6249f5f
AM
5101 -wK --debug-dump=follow-links\n\
5102 Follow links to separate debug info files (default)\n"));
5103 fprintf (stream, _("\
5104 -wN --debug-dump=no-follow-links\n\
5105 Do not follow links to separate debug info files\n"));
c46b7066
NC
5106#else
5107 fprintf (stream, _("\
d6249f5f
AM
5108 -wK --debug-dump=follow-links\n\
5109 Follow links to separate debug info files\n"));
5110 fprintf (stream, _("\
5111 -wN --debug-dump=no-follow-links\n\
5112 Do not follow links to separate debug info files\n\
5113 (default)\n"));
c46b7066 5114#endif
fd2f0033 5115 fprintf (stream, _("\
d6249f5f
AM
5116 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5117 fprintf (stream, _("\
5118 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5119#ifdef ENABLE_LIBCTF
7d9813f1 5120 fprintf (stream, _("\
d6249f5f
AM
5121 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5122 fprintf (stream, _("\
80b56fad 5123 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5124 fprintf (stream, _("\
7d9813f1 5125 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5126 Use section <number|name> as the CTF external symtab\n"));
5127 fprintf (stream, _("\
7d9813f1 5128 --ctf-strings=<number|name>\n\
d6249f5f 5129 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5130#endif
7d9813f1 5131
252b5132 5132#ifdef SUPPORT_DISASSEMBLY
92f01d61 5133 fprintf (stream, _("\
09c11c86
NC
5134 -i --instruction-dump=<number|name>\n\
5135 Disassemble the contents of section <number|name>\n"));
252b5132 5136#endif
92f01d61 5137 fprintf (stream, _("\
d6249f5f
AM
5138 -I --histogram Display histogram of bucket list lengths\n"));
5139 fprintf (stream, _("\
5140 -W --wide Allow output width to exceed 80 characters\n"));
5141 fprintf (stream, _("\
5142 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5143 fprintf (stream, _("\
5144 @<file> Read options from <file>\n"));
5145 fprintf (stream, _("\
5146 -H --help Display this information\n"));
5147 fprintf (stream, _("\
8b53311e 5148 -v --version Display the version number of readelf\n"));
1118d252 5149
92f01d61
JM
5150 if (REPORT_BUGS_TO[0] && stream == stdout)
5151 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5152
92f01d61 5153 exit (stream == stdout ? 0 : 1);
252b5132
RH
5154}
5155
18bd398b
NC
5156/* Record the fact that the user wants the contents of section number
5157 SECTION to be displayed using the method(s) encoded as flags bits
5158 in TYPE. Note, TYPE can be zero if we are creating the array for
5159 the first time. */
5160
252b5132 5161static void
6431e409
AM
5162request_dump_bynumber (struct dump_data *dumpdata,
5163 unsigned int section, dump_type type)
252b5132 5164{
6431e409 5165 if (section >= dumpdata->num_dump_sects)
252b5132 5166 {
2cf0635d 5167 dump_type * new_dump_sects;
252b5132 5168
3f5e193b 5169 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5170 sizeof (* new_dump_sects));
252b5132
RH
5171
5172 if (new_dump_sects == NULL)
591a748a 5173 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5174 else
5175 {
6431e409 5176 if (dumpdata->dump_sects)
21b65bac
NC
5177 {
5178 /* Copy current flag settings. */
6431e409
AM
5179 memcpy (new_dump_sects, dumpdata->dump_sects,
5180 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5181
6431e409 5182 free (dumpdata->dump_sects);
21b65bac 5183 }
252b5132 5184
6431e409
AM
5185 dumpdata->dump_sects = new_dump_sects;
5186 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5187 }
5188 }
5189
6431e409
AM
5190 if (dumpdata->dump_sects)
5191 dumpdata->dump_sects[section] |= type;
252b5132
RH
5192}
5193
aef1f6d0
DJ
5194/* Request a dump by section name. */
5195
5196static void
2cf0635d 5197request_dump_byname (const char * section, dump_type type)
aef1f6d0 5198{
2cf0635d 5199 struct dump_list_entry * new_request;
aef1f6d0 5200
3f5e193b
NC
5201 new_request = (struct dump_list_entry *)
5202 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5203 if (!new_request)
591a748a 5204 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5205
5206 new_request->name = strdup (section);
5207 if (!new_request->name)
591a748a 5208 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5209
5210 new_request->type = type;
5211
5212 new_request->next = dump_sects_byname;
5213 dump_sects_byname = new_request;
5214}
5215
cf13d699 5216static inline void
6431e409 5217request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5218{
5219 int section;
5220 char * cp;
5221
015dc7e1 5222 do_dump = true;
cf13d699
NC
5223 section = strtoul (optarg, & cp, 0);
5224
5225 if (! *cp && section >= 0)
6431e409 5226 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5227 else
5228 request_dump_byname (optarg, type);
5229}
5230
252b5132 5231static void
6431e409 5232parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5233{
5234 int c;
5235
5236 if (argc < 2)
92f01d61 5237 usage (stderr);
252b5132
RH
5238
5239 while ((c = getopt_long
b3aa80b4 5240 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5241 {
252b5132
RH
5242 switch (c)
5243 {
5244 case 0:
5245 /* Long options. */
5246 break;
5247 case 'H':
92f01d61 5248 usage (stdout);
252b5132
RH
5249 break;
5250
5251 case 'a':
015dc7e1
AM
5252 do_syms = true;
5253 do_reloc = true;
5254 do_unwind = true;
5255 do_dynamic = true;
5256 do_header = true;
5257 do_sections = true;
5258 do_section_groups = true;
5259 do_segments = true;
5260 do_version = true;
5261 do_histogram = true;
5262 do_arch = true;
5263 do_notes = true;
252b5132 5264 break;
79bc120c 5265
f5842774 5266 case 'g':
015dc7e1 5267 do_section_groups = true;
f5842774 5268 break;
5477e8a0 5269 case 't':
595cf52e 5270 case 'N':
015dc7e1
AM
5271 do_sections = true;
5272 do_section_details = true;
595cf52e 5273 break;
252b5132 5274 case 'e':
015dc7e1
AM
5275 do_header = true;
5276 do_sections = true;
5277 do_segments = true;
252b5132 5278 break;
a952a375 5279 case 'A':
015dc7e1 5280 do_arch = true;
a952a375 5281 break;
252b5132 5282 case 'D':
015dc7e1 5283 do_using_dynamic = true;
252b5132
RH
5284 break;
5285 case 'r':
015dc7e1 5286 do_reloc = true;
252b5132 5287 break;
4d6ed7c8 5288 case 'u':
015dc7e1 5289 do_unwind = true;
4d6ed7c8 5290 break;
252b5132 5291 case 'h':
015dc7e1 5292 do_header = true;
252b5132
RH
5293 break;
5294 case 'l':
015dc7e1 5295 do_segments = true;
252b5132
RH
5296 break;
5297 case 's':
015dc7e1 5298 do_syms = true;
252b5132
RH
5299 break;
5300 case 'S':
015dc7e1 5301 do_sections = true;
252b5132
RH
5302 break;
5303 case 'd':
015dc7e1 5304 do_dynamic = true;
252b5132 5305 break;
a952a375 5306 case 'I':
015dc7e1 5307 do_histogram = true;
a952a375 5308 break;
779fe533 5309 case 'n':
015dc7e1 5310 do_notes = true;
779fe533 5311 break;
4145f1d5 5312 case 'c':
015dc7e1 5313 do_archive_index = true;
4145f1d5 5314 break;
1b513401 5315 case 'L':
015dc7e1 5316 do_checks = true;
1b513401 5317 break;
ca0e11aa 5318 case 'P':
015dc7e1
AM
5319 process_links = true;
5320 do_follow_links = true;
ca0e11aa 5321 break;
252b5132 5322 case 'x':
6431e409 5323 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5324 break;
09c11c86 5325 case 'p':
6431e409 5326 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5327 break;
5328 case 'R':
6431e409 5329 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5330 break;
0e602686 5331 case 'z':
015dc7e1 5332 decompress_dumps = true;
0e602686 5333 break;
252b5132 5334 case 'w':
015dc7e1 5335 do_dump = true;
0f03783c 5336 if (optarg == NULL)
613ff48b 5337 {
015dc7e1 5338 do_debugging = true;
613ff48b
CC
5339 dwarf_select_sections_all ();
5340 }
252b5132
RH
5341 else
5342 {
015dc7e1 5343 do_debugging = false;
4cb93e3b 5344 dwarf_select_sections_by_letters (optarg);
252b5132
RH
5345 }
5346 break;
2979dc34 5347 case OPTION_DEBUG_DUMP:
015dc7e1 5348 do_dump = true;
0f03783c 5349 if (optarg == NULL)
d6249f5f
AM
5350 {
5351 do_debugging = true;
5352 dwarf_select_sections_all ();
5353 }
2979dc34
JJ
5354 else
5355 {
015dc7e1 5356 do_debugging = false;
4cb93e3b 5357 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
5358 }
5359 break;
fd2f0033
TT
5360 case OPTION_DWARF_DEPTH:
5361 {
5362 char *cp;
5363
5364 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5365 }
5366 break;
5367 case OPTION_DWARF_START:
5368 {
5369 char *cp;
5370
5371 dwarf_start_die = strtoul (optarg, & cp, 0);
5372 }
5373 break;
4723351a 5374 case OPTION_DWARF_CHECK:
015dc7e1 5375 dwarf_check = true;
4723351a 5376 break;
7d9813f1 5377 case OPTION_CTF_DUMP:
015dc7e1 5378 do_ctf = true;
6431e409 5379 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5380 break;
5381 case OPTION_CTF_SYMBOLS:
df16e041 5382 free (dump_ctf_symtab_name);
7d9813f1
NA
5383 dump_ctf_symtab_name = strdup (optarg);
5384 break;
5385 case OPTION_CTF_STRINGS:
df16e041 5386 free (dump_ctf_strtab_name);
7d9813f1
NA
5387 dump_ctf_strtab_name = strdup (optarg);
5388 break;
5389 case OPTION_CTF_PARENT:
df16e041 5390 free (dump_ctf_parent_name);
7d9813f1
NA
5391 dump_ctf_parent_name = strdup (optarg);
5392 break;
2c610e4b 5393 case OPTION_DYN_SYMS:
015dc7e1 5394 do_dyn_syms = true;
2c610e4b 5395 break;
0f03783c 5396 case OPTION_LTO_SYMS:
015dc7e1 5397 do_lto_syms = true;
0f03783c 5398 break;
252b5132
RH
5399#ifdef SUPPORT_DISASSEMBLY
5400 case 'i':
6431e409 5401 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5402 break;
252b5132
RH
5403#endif
5404 case 'v':
5405 print_version (program_name);
5406 break;
5407 case 'V':
015dc7e1 5408 do_version = true;
252b5132 5409 break;
d974e256 5410 case 'W':
015dc7e1 5411 do_wide = true;
d974e256 5412 break;
0942c7ab 5413 case 'T':
015dc7e1 5414 do_not_show_symbol_truncation = true;
0942c7ab 5415 break;
79bc120c 5416 case 'C':
015dc7e1 5417 do_demangle = true;
79bc120c
NC
5418 if (optarg != NULL)
5419 {
5420 enum demangling_styles style;
5421
5422 style = cplus_demangle_name_to_style (optarg);
5423 if (style == unknown_demangling)
5424 error (_("unknown demangling style `%s'"), optarg);
5425
5426 cplus_demangle_set_style (style);
5427 }
5428 break;
5429 case OPTION_NO_DEMANGLING:
015dc7e1 5430 do_demangle = false;
79bc120c
NC
5431 break;
5432 case OPTION_RECURSE_LIMIT:
5433 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5434 break;
5435 case OPTION_NO_RECURSE_LIMIT:
5436 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5437 break;
5438 case OPTION_WITH_SYMBOL_VERSIONS:
5439 /* Ignored for backward compatibility. */
5440 break;
b9e920ec 5441
b3aa80b4
NC
5442 case 'U':
5443 if (optarg == NULL)
5444 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5445 else if (streq (optarg, "default") || streq (optarg, "d"))
5446 unicode_display = unicode_default;
5447 else if (streq (optarg, "locale") || streq (optarg, "l"))
5448 unicode_display = unicode_locale;
5449 else if (streq (optarg, "escape") || streq (optarg, "e"))
5450 unicode_display = unicode_escape;
5451 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5452 unicode_display = unicode_invalid;
5453 else if (streq (optarg, "hex") || streq (optarg, "x"))
5454 unicode_display = unicode_hex;
5455 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5456 unicode_display = unicode_highlight;
5457 else
5458 error (_("invalid argument to -U/--unicode: %s"), optarg);
5459 break;
5460
047c3dbf
NL
5461 case OPTION_SYM_BASE:
5462 sym_base = 0;
5463 if (optarg != NULL)
5464 {
5465 sym_base = strtoul (optarg, NULL, 0);
5466 switch (sym_base)
5467 {
5468 case 0:
5469 case 8:
5470 case 10:
5471 case 16:
5472 break;
5473
5474 default:
5475 sym_base = 0;
5476 break;
5477 }
5478 }
5479 break;
5480
252b5132 5481 default:
252b5132
RH
5482 /* xgettext:c-format */
5483 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5484 /* Fall through. */
252b5132 5485 case '?':
92f01d61 5486 usage (stderr);
252b5132
RH
5487 }
5488 }
5489
4d6ed7c8 5490 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5491 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5492 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5493 && !do_section_groups && !do_archive_index
0f03783c 5494 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5495 {
5496 if (do_checks)
5497 {
015dc7e1
AM
5498 check_all = true;
5499 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5500 do_segments = do_header = do_dump = do_version = true;
5501 do_histogram = do_debugging = do_arch = do_notes = true;
5502 do_section_groups = do_archive_index = do_dyn_syms = true;
5503 do_lto_syms = true;
1b513401
NC
5504 }
5505 else
5506 usage (stderr);
5507 }
252b5132
RH
5508}
5509
5510static const char *
d3ba0551 5511get_elf_class (unsigned int elf_class)
252b5132 5512{
b34976b6 5513 static char buff[32];
103f02d3 5514
252b5132
RH
5515 switch (elf_class)
5516 {
5517 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5518 case ELFCLASS32: return "ELF32";
5519 case ELFCLASS64: return "ELF64";
ab5e7794 5520 default:
e9e44622 5521 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5522 return buff;
252b5132
RH
5523 }
5524}
5525
5526static const char *
d3ba0551 5527get_data_encoding (unsigned int encoding)
252b5132 5528{
b34976b6 5529 static char buff[32];
103f02d3 5530
252b5132
RH
5531 switch (encoding)
5532 {
5533 case ELFDATANONE: return _("none");
33c63f9d
CM
5534 case ELFDATA2LSB: return _("2's complement, little endian");
5535 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5536 default:
e9e44622 5537 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5538 return buff;
252b5132
RH
5539 }
5540}
5541
dda8d76d 5542/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5543
015dc7e1 5544static bool
dda8d76d 5545process_file_header (Filedata * filedata)
252b5132 5546{
dda8d76d
NC
5547 Elf_Internal_Ehdr * header = & filedata->file_header;
5548
5549 if ( header->e_ident[EI_MAG0] != ELFMAG0
5550 || header->e_ident[EI_MAG1] != ELFMAG1
5551 || header->e_ident[EI_MAG2] != ELFMAG2
5552 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5553 {
5554 error
5555 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5556 return false;
252b5132
RH
5557 }
5558
ca0e11aa
NC
5559 if (! filedata->is_separate)
5560 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5561
252b5132
RH
5562 if (do_header)
5563 {
32ec8896 5564 unsigned i;
252b5132 5565
ca0e11aa
NC
5566 if (filedata->is_separate)
5567 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5568 else
5569 printf (_("ELF Header:\n"));
252b5132 5570 printf (_(" Magic: "));
b34976b6 5571 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5572 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5573 printf ("\n");
5574 printf (_(" Class: %s\n"),
dda8d76d 5575 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5576 printf (_(" Data: %s\n"),
dda8d76d 5577 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5578 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5579 header->e_ident[EI_VERSION],
5580 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5581 ? _(" (current)")
dda8d76d 5582 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5583 ? _(" <unknown>")
789be9f7 5584 : "")));
252b5132 5585 printf (_(" OS/ABI: %s\n"),
dda8d76d 5586 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5587 printf (_(" ABI Version: %d\n"),
dda8d76d 5588 header->e_ident[EI_ABIVERSION]);
252b5132 5589 printf (_(" Type: %s\n"),
93df3340 5590 get_file_type (filedata));
252b5132 5591 printf (_(" Machine: %s\n"),
dda8d76d 5592 get_machine_name (header->e_machine));
252b5132 5593 printf (_(" Version: 0x%lx\n"),
e8a64888 5594 header->e_version);
76da6bbe 5595
f7a99963 5596 printf (_(" Entry point address: "));
e8a64888 5597 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5598 printf (_("\n Start of program headers: "));
e8a64888 5599 print_vma (header->e_phoff, DEC);
f7a99963 5600 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5601 print_vma (header->e_shoff, DEC);
f7a99963 5602 printf (_(" (bytes into file)\n"));
76da6bbe 5603
252b5132 5604 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5605 header->e_flags,
dda8d76d 5606 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5607 printf (_(" Size of this header: %u (bytes)\n"),
5608 header->e_ehsize);
5609 printf (_(" Size of program headers: %u (bytes)\n"),
5610 header->e_phentsize);
5611 printf (_(" Number of program headers: %u"),
5612 header->e_phnum);
dda8d76d
NC
5613 if (filedata->section_headers != NULL
5614 && header->e_phnum == PN_XNUM
5615 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5616 {
5617 header->e_phnum = filedata->section_headers[0].sh_info;
5618 printf (" (%u)", header->e_phnum);
5619 }
2046a35d 5620 putc ('\n', stdout);
e8a64888
AM
5621 printf (_(" Size of section headers: %u (bytes)\n"),
5622 header->e_shentsize);
5623 printf (_(" Number of section headers: %u"),
5624 header->e_shnum);
dda8d76d 5625 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5626 {
5627 header->e_shnum = filedata->section_headers[0].sh_size;
5628 printf (" (%u)", header->e_shnum);
5629 }
560f3c1c 5630 putc ('\n', stdout);
e8a64888
AM
5631 printf (_(" Section header string table index: %u"),
5632 header->e_shstrndx);
dda8d76d
NC
5633 if (filedata->section_headers != NULL
5634 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5635 {
5636 header->e_shstrndx = filedata->section_headers[0].sh_link;
5637 printf (" (%u)", header->e_shstrndx);
5638 }
5639 if (header->e_shstrndx != SHN_UNDEF
5640 && header->e_shstrndx >= header->e_shnum)
5641 {
5642 header->e_shstrndx = SHN_UNDEF;
5643 printf (_(" <corrupt: out of range>"));
5644 }
560f3c1c
AM
5645 putc ('\n', stdout);
5646 }
5647
dda8d76d 5648 if (filedata->section_headers != NULL)
560f3c1c 5649 {
dda8d76d
NC
5650 if (header->e_phnum == PN_XNUM
5651 && filedata->section_headers[0].sh_info != 0)
5652 header->e_phnum = filedata->section_headers[0].sh_info;
5653 if (header->e_shnum == SHN_UNDEF)
5654 header->e_shnum = filedata->section_headers[0].sh_size;
5655 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5656 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5657 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5658 header->e_shstrndx = SHN_UNDEF;
252b5132 5659 }
103f02d3 5660
015dc7e1 5661 return true;
9ea033b2
NC
5662}
5663
dda8d76d
NC
5664/* Read in the program headers from FILEDATA and store them in PHEADERS.
5665 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5666
015dc7e1 5667static bool
dda8d76d 5668get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5669{
2cf0635d
NC
5670 Elf32_External_Phdr * phdrs;
5671 Elf32_External_Phdr * external;
5672 Elf_Internal_Phdr * internal;
b34976b6 5673 unsigned int i;
dda8d76d
NC
5674 unsigned int size = filedata->file_header.e_phentsize;
5675 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5676
5677 /* PR binutils/17531: Cope with unexpected section header sizes. */
5678 if (size == 0 || num == 0)
015dc7e1 5679 return false;
e0a31db1
NC
5680 if (size < sizeof * phdrs)
5681 {
5682 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5683 return false;
e0a31db1
NC
5684 }
5685 if (size > sizeof * phdrs)
5686 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5687
dda8d76d 5688 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5689 size, num, _("program headers"));
5690 if (phdrs == NULL)
015dc7e1 5691 return false;
9ea033b2 5692
91d6fa6a 5693 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5694 i < filedata->file_header.e_phnum;
b34976b6 5695 i++, internal++, external++)
252b5132 5696 {
9ea033b2
NC
5697 internal->p_type = BYTE_GET (external->p_type);
5698 internal->p_offset = BYTE_GET (external->p_offset);
5699 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5700 internal->p_paddr = BYTE_GET (external->p_paddr);
5701 internal->p_filesz = BYTE_GET (external->p_filesz);
5702 internal->p_memsz = BYTE_GET (external->p_memsz);
5703 internal->p_flags = BYTE_GET (external->p_flags);
5704 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5705 }
5706
9ea033b2 5707 free (phdrs);
015dc7e1 5708 return true;
252b5132
RH
5709}
5710
dda8d76d
NC
5711/* Read in the program headers from FILEDATA and store them in PHEADERS.
5712 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5713
015dc7e1 5714static bool
dda8d76d 5715get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5716{
2cf0635d
NC
5717 Elf64_External_Phdr * phdrs;
5718 Elf64_External_Phdr * external;
5719 Elf_Internal_Phdr * internal;
b34976b6 5720 unsigned int i;
dda8d76d
NC
5721 unsigned int size = filedata->file_header.e_phentsize;
5722 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5723
5724 /* PR binutils/17531: Cope with unexpected section header sizes. */
5725 if (size == 0 || num == 0)
015dc7e1 5726 return false;
e0a31db1
NC
5727 if (size < sizeof * phdrs)
5728 {
5729 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5730 return false;
e0a31db1
NC
5731 }
5732 if (size > sizeof * phdrs)
5733 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5734
dda8d76d 5735 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5736 size, num, _("program headers"));
a6e9f9df 5737 if (!phdrs)
015dc7e1 5738 return false;
9ea033b2 5739
91d6fa6a 5740 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5741 i < filedata->file_header.e_phnum;
b34976b6 5742 i++, internal++, external++)
9ea033b2
NC
5743 {
5744 internal->p_type = BYTE_GET (external->p_type);
5745 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5746 internal->p_offset = BYTE_GET (external->p_offset);
5747 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5748 internal->p_paddr = BYTE_GET (external->p_paddr);
5749 internal->p_filesz = BYTE_GET (external->p_filesz);
5750 internal->p_memsz = BYTE_GET (external->p_memsz);
5751 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5752 }
5753
5754 free (phdrs);
015dc7e1 5755 return true;
9ea033b2 5756}
252b5132 5757
32ec8896 5758/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5759
015dc7e1 5760static bool
dda8d76d 5761get_program_headers (Filedata * filedata)
d93f0186 5762{
2cf0635d 5763 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5764
5765 /* Check cache of prior read. */
dda8d76d 5766 if (filedata->program_headers != NULL)
015dc7e1 5767 return true;
d93f0186 5768
82156ab7
NC
5769 /* Be kind to memory checkers by looking for
5770 e_phnum values which we know must be invalid. */
dda8d76d 5771 if (filedata->file_header.e_phnum
82156ab7 5772 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5773 >= filedata->file_size)
82156ab7
NC
5774 {
5775 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5776 filedata->file_header.e_phnum);
015dc7e1 5777 return false;
82156ab7 5778 }
d93f0186 5779
dda8d76d 5780 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5781 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5782 if (phdrs == NULL)
5783 {
8b73c356 5784 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5785 filedata->file_header.e_phnum);
015dc7e1 5786 return false;
d93f0186
NC
5787 }
5788
5789 if (is_32bit_elf
dda8d76d
NC
5790 ? get_32bit_program_headers (filedata, phdrs)
5791 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5792 {
dda8d76d 5793 filedata->program_headers = phdrs;
015dc7e1 5794 return true;
d93f0186
NC
5795 }
5796
5797 free (phdrs);
015dc7e1 5798 return false;
d93f0186
NC
5799}
5800
93df3340 5801/* Print program header info and locate dynamic section. */
2f62977e 5802
93df3340 5803static void
dda8d76d 5804process_program_headers (Filedata * filedata)
252b5132 5805{
2cf0635d 5806 Elf_Internal_Phdr * segment;
b34976b6 5807 unsigned int i;
1a9ccd70 5808 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5809
dda8d76d 5810 if (filedata->file_header.e_phnum == 0)
252b5132 5811 {
82f2dbf7 5812 /* PR binutils/12467. */
dda8d76d 5813 if (filedata->file_header.e_phoff != 0)
93df3340
AM
5814 warn (_("possibly corrupt ELF header - it has a non-zero program"
5815 " header offset, but no program headers\n"));
82f2dbf7 5816 else if (do_segments)
ca0e11aa
NC
5817 {
5818 if (filedata->is_separate)
5819 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5820 filedata->file_name);
5821 else
5822 printf (_("\nThere are no program headers in this file.\n"));
5823 }
93df3340 5824 goto no_headers;
252b5132
RH
5825 }
5826
5827 if (do_segments && !do_header)
5828 {
ca0e11aa
NC
5829 if (filedata->is_separate)
5830 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 5831 filedata->file_name, get_file_type (filedata));
ca0e11aa 5832 else
93df3340 5833 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
dda8d76d 5834 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5835 printf (ngettext ("There is %d program header, starting at offset %s\n",
5836 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5837 filedata->file_header.e_phnum),
5838 filedata->file_header.e_phnum,
5839 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5840 }
5841
dda8d76d 5842 if (! get_program_headers (filedata))
93df3340 5843 goto no_headers;
103f02d3 5844
252b5132
RH
5845 if (do_segments)
5846 {
dda8d76d 5847 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5848 printf (_("\nProgram Headers:\n"));
5849 else
5850 printf (_("\nProgram Headers:\n"));
76da6bbe 5851
f7a99963
NC
5852 if (is_32bit_elf)
5853 printf
5854 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5855 else if (do_wide)
5856 printf
5857 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5858 else
5859 {
5860 printf
5861 (_(" Type Offset VirtAddr PhysAddr\n"));
5862 printf
5863 (_(" FileSiz MemSiz Flags Align\n"));
5864 }
252b5132
RH
5865 }
5866
93df3340
AM
5867 unsigned long dynamic_addr = 0;
5868 bfd_size_type dynamic_size = 0;
dda8d76d
NC
5869 for (i = 0, segment = filedata->program_headers;
5870 i < filedata->file_header.e_phnum;
b34976b6 5871 i++, segment++)
252b5132
RH
5872 {
5873 if (do_segments)
5874 {
dda8d76d 5875 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5876
5877 if (is_32bit_elf)
5878 {
5879 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5880 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5881 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5882 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5883 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5884 printf ("%c%c%c ",
5885 (segment->p_flags & PF_R ? 'R' : ' '),
5886 (segment->p_flags & PF_W ? 'W' : ' '),
5887 (segment->p_flags & PF_X ? 'E' : ' '));
5888 printf ("%#lx", (unsigned long) segment->p_align);
5889 }
d974e256
JJ
5890 else if (do_wide)
5891 {
5892 if ((unsigned long) segment->p_offset == segment->p_offset)
5893 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5894 else
5895 {
5896 print_vma (segment->p_offset, FULL_HEX);
5897 putchar (' ');
5898 }
5899
5900 print_vma (segment->p_vaddr, FULL_HEX);
5901 putchar (' ');
5902 print_vma (segment->p_paddr, FULL_HEX);
5903 putchar (' ');
5904
5905 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5906 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5907 else
5908 {
5909 print_vma (segment->p_filesz, FULL_HEX);
5910 putchar (' ');
5911 }
5912
5913 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5914 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5915 else
5916 {
f48e6c45 5917 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5918 }
5919
5920 printf (" %c%c%c ",
5921 (segment->p_flags & PF_R ? 'R' : ' '),
5922 (segment->p_flags & PF_W ? 'W' : ' '),
5923 (segment->p_flags & PF_X ? 'E' : ' '));
5924
5925 if ((unsigned long) segment->p_align == segment->p_align)
5926 printf ("%#lx", (unsigned long) segment->p_align);
5927 else
5928 {
5929 print_vma (segment->p_align, PREFIX_HEX);
5930 }
5931 }
f7a99963
NC
5932 else
5933 {
5934 print_vma (segment->p_offset, FULL_HEX);
5935 putchar (' ');
5936 print_vma (segment->p_vaddr, FULL_HEX);
5937 putchar (' ');
5938 print_vma (segment->p_paddr, FULL_HEX);
5939 printf ("\n ");
5940 print_vma (segment->p_filesz, FULL_HEX);
5941 putchar (' ');
5942 print_vma (segment->p_memsz, FULL_HEX);
5943 printf (" %c%c%c ",
5944 (segment->p_flags & PF_R ? 'R' : ' '),
5945 (segment->p_flags & PF_W ? 'W' : ' '),
5946 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5947 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5948 }
252b5132 5949
1a9ccd70
NC
5950 putc ('\n', stdout);
5951 }
f54498b4 5952
252b5132
RH
5953 switch (segment->p_type)
5954 {
1a9ccd70 5955 case PT_LOAD:
502d895c
NC
5956#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5957 required by the ELF standard, several programs, including the Linux
5958 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5959 if (previous_load
5960 && previous_load->p_vaddr > segment->p_vaddr)
5961 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5962#endif
1a9ccd70
NC
5963 if (segment->p_memsz < segment->p_filesz)
5964 error (_("the segment's file size is larger than its memory size\n"));
5965 previous_load = segment;
5966 break;
5967
5968 case PT_PHDR:
5969 /* PR 20815 - Verify that the program header is loaded into memory. */
5970 if (i > 0 && previous_load != NULL)
5971 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5972 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5973 {
5974 unsigned int j;
5975
dda8d76d 5976 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5977 {
5978 Elf_Internal_Phdr *load = filedata->program_headers + j;
5979 if (load->p_type == PT_LOAD
5980 && load->p_offset <= segment->p_offset
5981 && (load->p_offset + load->p_filesz
5982 >= segment->p_offset + segment->p_filesz)
5983 && load->p_vaddr <= segment->p_vaddr
5984 && (load->p_vaddr + load->p_filesz
5985 >= segment->p_vaddr + segment->p_filesz))
5986 break;
5987 }
dda8d76d 5988 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5989 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5990 }
5991 break;
5992
252b5132 5993 case PT_DYNAMIC:
93df3340 5994 if (dynamic_addr)
252b5132
RH
5995 error (_("more than one dynamic segment\n"));
5996
20737c13
AM
5997 /* By default, assume that the .dynamic section is the first
5998 section in the DYNAMIC segment. */
93df3340
AM
5999 dynamic_addr = segment->p_offset;
6000 dynamic_size = segment->p_filesz;
20737c13 6001
b2d38a17
NC
6002 /* Try to locate the .dynamic section. If there is
6003 a section header table, we can easily locate it. */
dda8d76d 6004 if (filedata->section_headers != NULL)
b2d38a17 6005 {
2cf0635d 6006 Elf_Internal_Shdr * sec;
b2d38a17 6007
dda8d76d 6008 sec = find_section (filedata, ".dynamic");
89fac5e3 6009 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6010 {
93df3340
AM
6011 /* A corresponding .dynamic section is expected, but on
6012 IA-64/OpenVMS it is OK for it to be missing. */
6013 if (!is_ia64_vms (filedata))
6014 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6015 break;
6016 }
6017
42bb2e33 6018 if (sec->sh_type == SHT_NOBITS)
20737c13 6019 {
93df3340
AM
6020 dynamic_addr = 0;
6021 dynamic_size = 0;
20737c13
AM
6022 break;
6023 }
42bb2e33 6024
93df3340
AM
6025 dynamic_addr = sec->sh_offset;
6026 dynamic_size = sec->sh_size;
b2d38a17 6027
8ac10c5b
L
6028 /* The PT_DYNAMIC segment, which is used by the run-time
6029 loader, should exactly match the .dynamic section. */
6030 if (do_checks
93df3340
AM
6031 && (dynamic_addr != segment->p_offset
6032 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6033 warn (_("\
6034the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6035 }
39e224f6
MW
6036
6037 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6038 segment. Check this after matching against the section headers
6039 so we don't warn on debuginfo file (which have NOBITS .dynamic
6040 sections). */
93df3340
AM
6041 if (dynamic_addr > filedata->file_size
6042 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6043 {
6044 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6045 dynamic_addr = 0;
6046 dynamic_size = 0;
39e224f6 6047 }
252b5132
RH
6048 break;
6049
6050 case PT_INTERP:
13acb58d
AM
6051 if (segment->p_offset >= filedata->file_size
6052 || segment->p_filesz > filedata->file_size - segment->p_offset
6053 || segment->p_filesz - 1 >= (size_t) -2
6054 || fseek (filedata->handle,
6055 filedata->archive_file_offset + (long) segment->p_offset,
6056 SEEK_SET))
252b5132
RH
6057 error (_("Unable to find program interpreter name\n"));
6058 else
6059 {
13acb58d
AM
6060 size_t len = segment->p_filesz;
6061 free (filedata->program_interpreter);
6062 filedata->program_interpreter = xmalloc (len + 1);
6063 len = fread (filedata->program_interpreter, 1, len,
6064 filedata->handle);
6065 filedata->program_interpreter[len] = 0;
252b5132
RH
6066
6067 if (do_segments)
f54498b4 6068 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6069 filedata->program_interpreter);
252b5132
RH
6070 }
6071 break;
6072 }
252b5132
RH
6073 }
6074
dda8d76d
NC
6075 if (do_segments
6076 && filedata->section_headers != NULL
6077 && filedata->string_table != NULL)
252b5132
RH
6078 {
6079 printf (_("\n Section to Segment mapping:\n"));
6080 printf (_(" Segment Sections...\n"));
6081
dda8d76d 6082 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6083 {
9ad5cbcf 6084 unsigned int j;
2cf0635d 6085 Elf_Internal_Shdr * section;
252b5132 6086
dda8d76d
NC
6087 segment = filedata->program_headers + i;
6088 section = filedata->section_headers + 1;
252b5132
RH
6089
6090 printf (" %2.2d ", i);
6091
dda8d76d 6092 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6093 {
f4638467
AM
6094 if (!ELF_TBSS_SPECIAL (section, segment)
6095 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6096 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6097 }
6098
6099 putc ('\n',stdout);
6100 }
6101 }
6102
93df3340
AM
6103 filedata->dynamic_addr = dynamic_addr;
6104 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6105 return;
6106
6107 no_headers:
6108 filedata->dynamic_addr = 0;
6109 filedata->dynamic_size = 1;
252b5132
RH
6110}
6111
6112
d93f0186
NC
6113/* Find the file offset corresponding to VMA by using the program headers. */
6114
6115static long
dda8d76d 6116offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 6117{
2cf0635d 6118 Elf_Internal_Phdr * seg;
d93f0186 6119
dda8d76d 6120 if (! get_program_headers (filedata))
d93f0186
NC
6121 {
6122 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6123 return (long) vma;
6124 }
6125
dda8d76d
NC
6126 for (seg = filedata->program_headers;
6127 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6128 ++seg)
6129 {
6130 if (seg->p_type != PT_LOAD)
6131 continue;
6132
6133 if (vma >= (seg->p_vaddr & -seg->p_align)
6134 && vma + size <= seg->p_vaddr + seg->p_filesz)
6135 return vma - seg->p_vaddr + seg->p_offset;
6136 }
6137
6138 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6139 (unsigned long) vma);
d93f0186
NC
6140 return (long) vma;
6141}
6142
6143
dda8d76d
NC
6144/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6145 If PROBE is true, this is just a probe and we do not generate any error
6146 messages if the load fails. */
049b0c3a 6147
015dc7e1
AM
6148static bool
6149get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6150{
2cf0635d
NC
6151 Elf32_External_Shdr * shdrs;
6152 Elf_Internal_Shdr * internal;
dda8d76d
NC
6153 unsigned int i;
6154 unsigned int size = filedata->file_header.e_shentsize;
6155 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6156
6157 /* PR binutils/17531: Cope with unexpected section header sizes. */
6158 if (size == 0 || num == 0)
015dc7e1 6159 return false;
049b0c3a
NC
6160 if (size < sizeof * shdrs)
6161 {
6162 if (! probe)
6163 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6164 return false;
049b0c3a
NC
6165 }
6166 if (!probe && size > sizeof * shdrs)
6167 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6168
dda8d76d 6169 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6170 size, num,
6171 probe ? NULL : _("section headers"));
6172 if (shdrs == NULL)
015dc7e1 6173 return false;
252b5132 6174
dda8d76d
NC
6175 filedata->section_headers = (Elf_Internal_Shdr *)
6176 cmalloc (num, sizeof (Elf_Internal_Shdr));
6177 if (filedata->section_headers == NULL)
252b5132 6178 {
049b0c3a 6179 if (!probe)
8b73c356 6180 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6181 free (shdrs);
015dc7e1 6182 return false;
252b5132
RH
6183 }
6184
dda8d76d 6185 for (i = 0, internal = filedata->section_headers;
560f3c1c 6186 i < num;
b34976b6 6187 i++, internal++)
252b5132
RH
6188 {
6189 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6190 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6191 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6192 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6193 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6194 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6195 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6196 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6197 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6198 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6199 if (!probe && internal->sh_link > num)
6200 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6201 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6202 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6203 }
6204
6205 free (shdrs);
015dc7e1 6206 return true;
252b5132
RH
6207}
6208
dda8d76d
NC
6209/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6210
015dc7e1
AM
6211static bool
6212get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6213{
dda8d76d
NC
6214 Elf64_External_Shdr * shdrs;
6215 Elf_Internal_Shdr * internal;
6216 unsigned int i;
6217 unsigned int size = filedata->file_header.e_shentsize;
6218 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6219
6220 /* PR binutils/17531: Cope with unexpected section header sizes. */
6221 if (size == 0 || num == 0)
015dc7e1 6222 return false;
dda8d76d 6223
049b0c3a
NC
6224 if (size < sizeof * shdrs)
6225 {
6226 if (! probe)
6227 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6228 return false;
049b0c3a 6229 }
dda8d76d 6230
049b0c3a
NC
6231 if (! probe && size > sizeof * shdrs)
6232 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6233
dda8d76d
NC
6234 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6235 filedata->file_header.e_shoff,
049b0c3a
NC
6236 size, num,
6237 probe ? NULL : _("section headers"));
6238 if (shdrs == NULL)
015dc7e1 6239 return false;
9ea033b2 6240
dda8d76d
NC
6241 filedata->section_headers = (Elf_Internal_Shdr *)
6242 cmalloc (num, sizeof (Elf_Internal_Shdr));
6243 if (filedata->section_headers == NULL)
9ea033b2 6244 {
049b0c3a 6245 if (! probe)
8b73c356 6246 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6247 free (shdrs);
015dc7e1 6248 return false;
9ea033b2
NC
6249 }
6250
dda8d76d 6251 for (i = 0, internal = filedata->section_headers;
560f3c1c 6252 i < num;
b34976b6 6253 i++, internal++)
9ea033b2
NC
6254 {
6255 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6256 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6257 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6258 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6259 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6260 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6261 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6262 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6263 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6264 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6265 if (!probe && internal->sh_link > num)
6266 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6267 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6268 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6269 }
6270
6271 free (shdrs);
015dc7e1 6272 return true;
9ea033b2
NC
6273}
6274
4de91c10
AM
6275static bool
6276get_section_headers (Filedata *filedata, bool probe)
6277{
6278 if (filedata->section_headers != NULL)
6279 return true;
6280
4de91c10
AM
6281 if (is_32bit_elf)
6282 return get_32bit_section_headers (filedata, probe);
6283 else
6284 return get_64bit_section_headers (filedata, probe);
6285}
6286
252b5132 6287static Elf_Internal_Sym *
dda8d76d
NC
6288get_32bit_elf_symbols (Filedata * filedata,
6289 Elf_Internal_Shdr * section,
6290 unsigned long * num_syms_return)
252b5132 6291{
ba5cdace 6292 unsigned long number = 0;
dd24e3da 6293 Elf32_External_Sym * esyms = NULL;
ba5cdace 6294 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6295 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6296 Elf_Internal_Sym * psym;
b34976b6 6297 unsigned int j;
e3d39609 6298 elf_section_list * entry;
252b5132 6299
c9c1d674
EG
6300 if (section->sh_size == 0)
6301 {
6302 if (num_syms_return != NULL)
6303 * num_syms_return = 0;
6304 return NULL;
6305 }
6306
dd24e3da 6307 /* Run some sanity checks first. */
c9c1d674 6308 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6309 {
c9c1d674 6310 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6311 printable_section_name (filedata, section),
6312 (unsigned long) section->sh_entsize);
ba5cdace 6313 goto exit_point;
dd24e3da
NC
6314 }
6315
dda8d76d 6316 if (section->sh_size > filedata->file_size)
f54498b4
NC
6317 {
6318 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6319 printable_section_name (filedata, section),
6320 (unsigned long) section->sh_size);
f54498b4
NC
6321 goto exit_point;
6322 }
6323
dd24e3da
NC
6324 number = section->sh_size / section->sh_entsize;
6325
6326 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6327 {
c9c1d674 6328 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6329 (unsigned long) section->sh_size,
dda8d76d 6330 printable_section_name (filedata, section),
8066deb1 6331 (unsigned long) section->sh_entsize);
ba5cdace 6332 goto exit_point;
dd24e3da
NC
6333 }
6334
dda8d76d 6335 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6336 section->sh_size, _("symbols"));
dd24e3da 6337 if (esyms == NULL)
ba5cdace 6338 goto exit_point;
252b5132 6339
e3d39609 6340 shndx = NULL;
978c4450 6341 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6342 {
6343 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6344 continue;
6345
6346 if (shndx != NULL)
6347 {
6348 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6349 free (shndx);
6350 }
6351
6352 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6353 entry->hdr->sh_offset,
6354 1, entry->hdr->sh_size,
6355 _("symbol table section indices"));
6356 if (shndx == NULL)
6357 goto exit_point;
6358
6359 /* PR17531: file: heap-buffer-overflow */
6360 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6361 {
6362 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6363 printable_section_name (filedata, entry->hdr),
6364 (unsigned long) entry->hdr->sh_size,
6365 (unsigned long) section->sh_size);
6366 goto exit_point;
c9c1d674 6367 }
e3d39609 6368 }
9ad5cbcf 6369
3f5e193b 6370 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6371
6372 if (isyms == NULL)
6373 {
8b73c356
NC
6374 error (_("Out of memory reading %lu symbols\n"),
6375 (unsigned long) number);
dd24e3da 6376 goto exit_point;
252b5132
RH
6377 }
6378
dd24e3da 6379 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6380 {
6381 psym->st_name = BYTE_GET (esyms[j].st_name);
6382 psym->st_value = BYTE_GET (esyms[j].st_value);
6383 psym->st_size = BYTE_GET (esyms[j].st_size);
6384 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6385 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6386 psym->st_shndx
6387 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6388 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6389 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6390 psym->st_info = BYTE_GET (esyms[j].st_info);
6391 psym->st_other = BYTE_GET (esyms[j].st_other);
6392 }
6393
dd24e3da 6394 exit_point:
e3d39609
NC
6395 free (shndx);
6396 free (esyms);
252b5132 6397
ba5cdace
NC
6398 if (num_syms_return != NULL)
6399 * num_syms_return = isyms == NULL ? 0 : number;
6400
252b5132
RH
6401 return isyms;
6402}
6403
9ea033b2 6404static Elf_Internal_Sym *
dda8d76d
NC
6405get_64bit_elf_symbols (Filedata * filedata,
6406 Elf_Internal_Shdr * section,
6407 unsigned long * num_syms_return)
9ea033b2 6408{
ba5cdace
NC
6409 unsigned long number = 0;
6410 Elf64_External_Sym * esyms = NULL;
6411 Elf_External_Sym_Shndx * shndx = NULL;
6412 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6413 Elf_Internal_Sym * psym;
b34976b6 6414 unsigned int j;
e3d39609 6415 elf_section_list * entry;
9ea033b2 6416
c9c1d674
EG
6417 if (section->sh_size == 0)
6418 {
6419 if (num_syms_return != NULL)
6420 * num_syms_return = 0;
6421 return NULL;
6422 }
6423
dd24e3da 6424 /* Run some sanity checks first. */
c9c1d674 6425 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6426 {
c9c1d674 6427 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6428 printable_section_name (filedata, section),
8066deb1 6429 (unsigned long) section->sh_entsize);
ba5cdace 6430 goto exit_point;
dd24e3da
NC
6431 }
6432
dda8d76d 6433 if (section->sh_size > filedata->file_size)
f54498b4
NC
6434 {
6435 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6436 printable_section_name (filedata, section),
8066deb1 6437 (unsigned long) section->sh_size);
f54498b4
NC
6438 goto exit_point;
6439 }
6440
dd24e3da
NC
6441 number = section->sh_size / section->sh_entsize;
6442
6443 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6444 {
c9c1d674 6445 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6446 (unsigned long) section->sh_size,
dda8d76d 6447 printable_section_name (filedata, section),
8066deb1 6448 (unsigned long) section->sh_entsize);
ba5cdace 6449 goto exit_point;
dd24e3da
NC
6450 }
6451
dda8d76d 6452 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6453 section->sh_size, _("symbols"));
a6e9f9df 6454 if (!esyms)
ba5cdace 6455 goto exit_point;
9ea033b2 6456
e3d39609 6457 shndx = NULL;
978c4450 6458 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6459 {
6460 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6461 continue;
6462
6463 if (shndx != NULL)
6464 {
6465 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6466 free (shndx);
c9c1d674 6467 }
e3d39609
NC
6468
6469 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6470 entry->hdr->sh_offset,
6471 1, entry->hdr->sh_size,
6472 _("symbol table section indices"));
6473 if (shndx == NULL)
6474 goto exit_point;
6475
6476 /* PR17531: file: heap-buffer-overflow */
6477 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6478 {
6479 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6480 printable_section_name (filedata, entry->hdr),
6481 (unsigned long) entry->hdr->sh_size,
6482 (unsigned long) section->sh_size);
6483 goto exit_point;
6484 }
6485 }
9ad5cbcf 6486
3f5e193b 6487 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6488
6489 if (isyms == NULL)
6490 {
8b73c356
NC
6491 error (_("Out of memory reading %lu symbols\n"),
6492 (unsigned long) number);
ba5cdace 6493 goto exit_point;
9ea033b2
NC
6494 }
6495
ba5cdace 6496 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6497 {
6498 psym->st_name = BYTE_GET (esyms[j].st_name);
6499 psym->st_info = BYTE_GET (esyms[j].st_info);
6500 psym->st_other = BYTE_GET (esyms[j].st_other);
6501 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6502
4fbb74a6 6503 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6504 psym->st_shndx
6505 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6506 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6507 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6508
66543521
AM
6509 psym->st_value = BYTE_GET (esyms[j].st_value);
6510 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6511 }
6512
ba5cdace 6513 exit_point:
e3d39609
NC
6514 free (shndx);
6515 free (esyms);
ba5cdace
NC
6516
6517 if (num_syms_return != NULL)
6518 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6519
6520 return isyms;
6521}
6522
4de91c10
AM
6523static Elf_Internal_Sym *
6524get_elf_symbols (Filedata *filedata,
6525 Elf_Internal_Shdr *section,
6526 unsigned long *num_syms_return)
6527{
6528 if (is_32bit_elf)
6529 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6530 else
6531 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6532}
6533
d1133906 6534static const char *
dda8d76d 6535get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6536{
5477e8a0 6537 static char buff[1024];
2cf0635d 6538 char * p = buff;
32ec8896
NC
6539 unsigned int field_size = is_32bit_elf ? 8 : 16;
6540 signed int sindex;
6541 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6542 bfd_vma os_flags = 0;
6543 bfd_vma proc_flags = 0;
6544 bfd_vma unknown_flags = 0;
148b93f2 6545 static const struct
5477e8a0 6546 {
2cf0635d 6547 const char * str;
32ec8896 6548 unsigned int len;
5477e8a0
L
6549 }
6550 flags [] =
6551 {
cfcac11d
NC
6552 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6553 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6554 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6555 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6556 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6557 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6558 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6559 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6560 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6561 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6562 /* IA-64 specific. */
6563 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6564 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6565 /* IA-64 OpenVMS specific. */
6566 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6567 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6568 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6569 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6570 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6571 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6572 /* Generic. */
cfcac11d 6573 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6574 /* SPARC specific. */
77115a4a 6575 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6576 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6577 /* ARM specific. */
6578 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6579 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6580 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6581 /* GNU specific. */
6582 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6583 /* VLE specific. */
6584 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6585 /* GNU specific. */
6586 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6587 };
6588
6589 if (do_section_details)
6590 {
8d5ff12c
L
6591 sprintf (buff, "[%*.*lx]: ",
6592 field_size, field_size, (unsigned long) sh_flags);
6593 p += field_size + 4;
5477e8a0 6594 }
76da6bbe 6595
d1133906
NC
6596 while (sh_flags)
6597 {
6598 bfd_vma flag;
6599
6600 flag = sh_flags & - sh_flags;
6601 sh_flags &= ~ flag;
76da6bbe 6602
5477e8a0 6603 if (do_section_details)
d1133906 6604 {
5477e8a0
L
6605 switch (flag)
6606 {
91d6fa6a
NC
6607 case SHF_WRITE: sindex = 0; break;
6608 case SHF_ALLOC: sindex = 1; break;
6609 case SHF_EXECINSTR: sindex = 2; break;
6610 case SHF_MERGE: sindex = 3; break;
6611 case SHF_STRINGS: sindex = 4; break;
6612 case SHF_INFO_LINK: sindex = 5; break;
6613 case SHF_LINK_ORDER: sindex = 6; break;
6614 case SHF_OS_NONCONFORMING: sindex = 7; break;
6615 case SHF_GROUP: sindex = 8; break;
6616 case SHF_TLS: sindex = 9; break;
18ae9cc1 6617 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6618 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6619
5477e8a0 6620 default:
91d6fa6a 6621 sindex = -1;
dda8d76d 6622 switch (filedata->file_header.e_machine)
148b93f2 6623 {
cfcac11d 6624 case EM_IA_64:
148b93f2 6625 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6626 sindex = 10;
148b93f2 6627 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6628 sindex = 11;
148b93f2 6629#ifdef BFD64
dda8d76d 6630 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6631 switch (flag)
6632 {
91d6fa6a
NC
6633 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6634 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6635 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6636 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6637 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6638 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6639 default: break;
6640 }
6641#endif
cfcac11d
NC
6642 break;
6643
caa83f8b 6644 case EM_386:
22abe556 6645 case EM_IAMCU:
caa83f8b 6646 case EM_X86_64:
7f502d6c 6647 case EM_L1OM:
7a9068fe 6648 case EM_K1OM:
cfcac11d
NC
6649 case EM_OLD_SPARCV9:
6650 case EM_SPARC32PLUS:
6651 case EM_SPARCV9:
6652 case EM_SPARC:
18ae9cc1 6653 if (flag == SHF_ORDERED)
91d6fa6a 6654 sindex = 19;
cfcac11d 6655 break;
ac4c9b04
MG
6656
6657 case EM_ARM:
6658 switch (flag)
6659 {
6660 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6661 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6662 case SHF_COMDEF: sindex = 23; break;
6663 default: break;
6664 }
6665 break;
83eef883
AFB
6666 case EM_PPC:
6667 if (flag == SHF_PPC_VLE)
6668 sindex = 25;
6669 break;
99fabbc9
JL
6670 default:
6671 break;
6672 }
ac4c9b04 6673
99fabbc9
JL
6674 switch (filedata->file_header.e_ident[EI_OSABI])
6675 {
6676 case ELFOSABI_GNU:
6677 case ELFOSABI_FREEBSD:
6678 if (flag == SHF_GNU_RETAIN)
6679 sindex = 26;
6680 /* Fall through */
6681 case ELFOSABI_NONE:
6682 if (flag == SHF_GNU_MBIND)
6683 /* We should not recognize SHF_GNU_MBIND for
6684 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6685 not set the EI_OSABI header byte. */
6686 sindex = 24;
6687 break;
cfcac11d
NC
6688 default:
6689 break;
148b93f2 6690 }
99fabbc9 6691 break;
5477e8a0
L
6692 }
6693
91d6fa6a 6694 if (sindex != -1)
5477e8a0 6695 {
8d5ff12c
L
6696 if (p != buff + field_size + 4)
6697 {
6698 if (size < (10 + 2))
bee0ee85
NC
6699 {
6700 warn (_("Internal error: not enough buffer room for section flag info"));
6701 return _("<unknown>");
6702 }
8d5ff12c
L
6703 size -= 2;
6704 *p++ = ',';
6705 *p++ = ' ';
6706 }
6707
91d6fa6a
NC
6708 size -= flags [sindex].len;
6709 p = stpcpy (p, flags [sindex].str);
5477e8a0 6710 }
3b22753a 6711 else if (flag & SHF_MASKOS)
8d5ff12c 6712 os_flags |= flag;
d1133906 6713 else if (flag & SHF_MASKPROC)
8d5ff12c 6714 proc_flags |= flag;
d1133906 6715 else
8d5ff12c 6716 unknown_flags |= flag;
5477e8a0
L
6717 }
6718 else
6719 {
6720 switch (flag)
6721 {
6722 case SHF_WRITE: *p = 'W'; break;
6723 case SHF_ALLOC: *p = 'A'; break;
6724 case SHF_EXECINSTR: *p = 'X'; break;
6725 case SHF_MERGE: *p = 'M'; break;
6726 case SHF_STRINGS: *p = 'S'; break;
6727 case SHF_INFO_LINK: *p = 'I'; break;
6728 case SHF_LINK_ORDER: *p = 'L'; break;
6729 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6730 case SHF_GROUP: *p = 'G'; break;
6731 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6732 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6733 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6734
6735 default:
dda8d76d
NC
6736 if ((filedata->file_header.e_machine == EM_X86_64
6737 || filedata->file_header.e_machine == EM_L1OM
6738 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6739 && flag == SHF_X86_64_LARGE)
6740 *p = 'l';
dda8d76d 6741 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6742 && flag == SHF_ARM_PURECODE)
99fabbc9 6743 *p = 'y';
dda8d76d 6744 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6745 && flag == SHF_PPC_VLE)
99fabbc9 6746 *p = 'v';
5477e8a0
L
6747 else if (flag & SHF_MASKOS)
6748 {
99fabbc9
JL
6749 switch (filedata->file_header.e_ident[EI_OSABI])
6750 {
6751 case ELFOSABI_GNU:
6752 case ELFOSABI_FREEBSD:
6753 if (flag == SHF_GNU_RETAIN)
6754 {
6755 *p = 'R';
6756 break;
6757 }
6758 /* Fall through */
6759 case ELFOSABI_NONE:
6760 if (flag == SHF_GNU_MBIND)
6761 {
6762 /* We should not recognize SHF_GNU_MBIND for
6763 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6764 not set the EI_OSABI header byte. */
6765 *p = 'D';
6766 break;
6767 }
6768 /* Fall through */
6769 default:
6770 *p = 'o';
6771 sh_flags &= ~SHF_MASKOS;
6772 break;
6773 }
5477e8a0
L
6774 }
6775 else if (flag & SHF_MASKPROC)
6776 {
6777 *p = 'p';
6778 sh_flags &= ~ SHF_MASKPROC;
6779 }
6780 else
6781 *p = 'x';
6782 break;
6783 }
6784 p++;
d1133906
NC
6785 }
6786 }
76da6bbe 6787
8d5ff12c
L
6788 if (do_section_details)
6789 {
6790 if (os_flags)
6791 {
6792 size -= 5 + field_size;
6793 if (p != buff + field_size + 4)
6794 {
6795 if (size < (2 + 1))
bee0ee85
NC
6796 {
6797 warn (_("Internal error: not enough buffer room for section flag info"));
6798 return _("<unknown>");
6799 }
8d5ff12c
L
6800 size -= 2;
6801 *p++ = ',';
6802 *p++ = ' ';
6803 }
6804 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6805 (unsigned long) os_flags);
6806 p += 5 + field_size;
6807 }
6808 if (proc_flags)
6809 {
6810 size -= 7 + field_size;
6811 if (p != buff + field_size + 4)
6812 {
6813 if (size < (2 + 1))
bee0ee85
NC
6814 {
6815 warn (_("Internal error: not enough buffer room for section flag info"));
6816 return _("<unknown>");
6817 }
8d5ff12c
L
6818 size -= 2;
6819 *p++ = ',';
6820 *p++ = ' ';
6821 }
6822 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6823 (unsigned long) proc_flags);
6824 p += 7 + field_size;
6825 }
6826 if (unknown_flags)
6827 {
6828 size -= 10 + field_size;
6829 if (p != buff + field_size + 4)
6830 {
6831 if (size < (2 + 1))
bee0ee85
NC
6832 {
6833 warn (_("Internal error: not enough buffer room for section flag info"));
6834 return _("<unknown>");
6835 }
8d5ff12c
L
6836 size -= 2;
6837 *p++ = ',';
6838 *p++ = ' ';
6839 }
2b692964 6840 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6841 (unsigned long) unknown_flags);
6842 p += 10 + field_size;
6843 }
6844 }
6845
e9e44622 6846 *p = '\0';
d1133906
NC
6847 return buff;
6848}
6849
5844b465 6850static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6851get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6852{
6853 if (is_32bit_elf)
6854 {
6855 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6856
ebdf1ebf
NC
6857 if (size < sizeof (* echdr))
6858 {
6859 error (_("Compressed section is too small even for a compression header\n"));
6860 return 0;
6861 }
6862
77115a4a
L
6863 chdr->ch_type = BYTE_GET (echdr->ch_type);
6864 chdr->ch_size = BYTE_GET (echdr->ch_size);
6865 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6866 return sizeof (*echdr);
6867 }
6868 else
6869 {
6870 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6871
ebdf1ebf
NC
6872 if (size < sizeof (* echdr))
6873 {
6874 error (_("Compressed section is too small even for a compression header\n"));
6875 return 0;
6876 }
6877
77115a4a
L
6878 chdr->ch_type = BYTE_GET (echdr->ch_type);
6879 chdr->ch_size = BYTE_GET (echdr->ch_size);
6880 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6881 return sizeof (*echdr);
6882 }
6883}
6884
015dc7e1 6885static bool
dda8d76d 6886process_section_headers (Filedata * filedata)
252b5132 6887{
2cf0635d 6888 Elf_Internal_Shdr * section;
b34976b6 6889 unsigned int i;
252b5132 6890
dda8d76d 6891 if (filedata->file_header.e_shnum == 0)
252b5132 6892 {
82f2dbf7 6893 /* PR binutils/12467. */
dda8d76d 6894 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6895 {
6896 warn (_("possibly corrupt ELF file header - it has a non-zero"
6897 " section header offset, but no section headers\n"));
015dc7e1 6898 return false;
32ec8896 6899 }
82f2dbf7 6900 else if (do_sections)
252b5132
RH
6901 printf (_("\nThere are no sections in this file.\n"));
6902
015dc7e1 6903 return true;
252b5132
RH
6904 }
6905
6906 if (do_sections && !do_header)
ca0e11aa
NC
6907 {
6908 if (filedata->is_separate && process_links)
6909 printf (_("In linked file '%s': "), filedata->file_name);
6910 if (! filedata->is_separate || process_links)
6911 printf (ngettext ("There is %d section header, "
6912 "starting at offset 0x%lx:\n",
6913 "There are %d section headers, "
6914 "starting at offset 0x%lx:\n",
6915 filedata->file_header.e_shnum),
6916 filedata->file_header.e_shnum,
6917 (unsigned long) filedata->file_header.e_shoff);
6918 }
252b5132 6919
4de91c10
AM
6920 if (!get_section_headers (filedata, false))
6921 return false;
252b5132
RH
6922
6923 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6924 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6925 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6926 {
dda8d76d 6927 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6928
c256ffe7
JJ
6929 if (section->sh_size != 0)
6930 {
dda8d76d
NC
6931 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6932 1, section->sh_size,
6933 _("string table"));
0de14b54 6934
dda8d76d 6935 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6936 }
252b5132
RH
6937 }
6938
6939 /* Scan the sections for the dynamic symbol table
e3c8793a 6940 and dynamic string table and debug sections. */
89fac5e3 6941 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6942 switch (filedata->file_header.e_machine)
89fac5e3
RS
6943 {
6944 case EM_MIPS:
6945 case EM_MIPS_RS3_LE:
6946 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6947 FDE addresses. However, the ABI also has a semi-official ILP32
6948 variant for which the normal FDE address size rules apply.
6949
6950 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6951 section, where XX is the size of longs in bits. Unfortunately,
6952 earlier compilers provided no way of distinguishing ILP32 objects
6953 from LP64 objects, so if there's any doubt, we should assume that
6954 the official LP64 form is being used. */
dda8d76d
NC
6955 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6956 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6957 eh_addr_size = 8;
6958 break;
0f56a26a
DD
6959
6960 case EM_H8_300:
6961 case EM_H8_300H:
dda8d76d 6962 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6963 {
6964 case E_H8_MACH_H8300:
6965 case E_H8_MACH_H8300HN:
6966 case E_H8_MACH_H8300SN:
6967 case E_H8_MACH_H8300SXN:
6968 eh_addr_size = 2;
6969 break;
6970 case E_H8_MACH_H8300H:
6971 case E_H8_MACH_H8300S:
6972 case E_H8_MACH_H8300SX:
6973 eh_addr_size = 4;
6974 break;
6975 }
f4236fe4
DD
6976 break;
6977
ff7eeb89 6978 case EM_M32C_OLD:
f4236fe4 6979 case EM_M32C:
dda8d76d 6980 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6981 {
6982 case EF_M32C_CPU_M16C:
6983 eh_addr_size = 2;
6984 break;
6985 }
6986 break;
89fac5e3
RS
6987 }
6988
76ca31c0
NC
6989#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6990 do \
6991 { \
6992 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6993 if (section->sh_entsize != expected_entsize) \
9dd3a467 6994 { \
76ca31c0
NC
6995 char buf[40]; \
6996 sprintf_vma (buf, section->sh_entsize); \
6997 /* Note: coded this way so that there is a single string for \
6998 translation. */ \
6999 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
7000 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
7001 (unsigned) expected_entsize); \
9dd3a467 7002 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7003 } \
7004 } \
08d8fa11 7005 while (0)
9dd3a467
NC
7006
7007#define CHECK_ENTSIZE(section, i, type) \
1b513401 7008 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7009 sizeof (Elf64_External_##type))
7010
dda8d76d
NC
7011 for (i = 0, section = filedata->section_headers;
7012 i < filedata->file_header.e_shnum;
b34976b6 7013 i++, section++)
252b5132 7014 {
84714f86 7015 const char *name = section_name_print (filedata, section);
252b5132 7016
1b513401
NC
7017 /* Run some sanity checks on the headers and
7018 possibly fill in some file data as well. */
7019 switch (section->sh_type)
252b5132 7020 {
1b513401 7021 case SHT_DYNSYM:
978c4450 7022 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7023 {
7024 error (_("File contains multiple dynamic symbol tables\n"));
7025 continue;
7026 }
7027
08d8fa11 7028 CHECK_ENTSIZE (section, i, Sym);
978c4450 7029 filedata->dynamic_symbols
4de91c10 7030 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7031 filedata->dynamic_symtab_section = section;
1b513401
NC
7032 break;
7033
7034 case SHT_STRTAB:
7035 if (streq (name, ".dynstr"))
252b5132 7036 {
1b513401
NC
7037 if (filedata->dynamic_strings != NULL)
7038 {
7039 error (_("File contains multiple dynamic string tables\n"));
7040 continue;
7041 }
7042
7043 filedata->dynamic_strings
7044 = (char *) get_data (NULL, filedata, section->sh_offset,
7045 1, section->sh_size, _("dynamic strings"));
7046 filedata->dynamic_strings_length
7047 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7048 filedata->dynamic_strtab_section = section;
252b5132 7049 }
1b513401
NC
7050 break;
7051
7052 case SHT_SYMTAB_SHNDX:
7053 {
7054 elf_section_list * entry = xmalloc (sizeof * entry);
7055
7056 entry->hdr = section;
7057 entry->next = filedata->symtab_shndx_list;
7058 filedata->symtab_shndx_list = entry;
7059 }
7060 break;
7061
7062 case SHT_SYMTAB:
7063 CHECK_ENTSIZE (section, i, Sym);
7064 break;
7065
7066 case SHT_GROUP:
7067 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7068 break;
252b5132 7069
1b513401
NC
7070 case SHT_REL:
7071 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7072 if (do_checks && section->sh_size == 0)
1b513401
NC
7073 warn (_("Section '%s': zero-sized relocation section\n"), name);
7074 break;
7075
7076 case SHT_RELA:
7077 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7078 if (do_checks && section->sh_size == 0)
1b513401
NC
7079 warn (_("Section '%s': zero-sized relocation section\n"), name);
7080 break;
7081
7082 case SHT_NOTE:
7083 case SHT_PROGBITS:
546cb2d8
NC
7084 /* Having a zero sized section is not illegal according to the
7085 ELF standard, but it might be an indication that something
7086 is wrong. So issue a warning if we are running in lint mode. */
7087 if (do_checks && section->sh_size == 0)
1b513401
NC
7088 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7089 break;
7090
7091 default:
7092 break;
7093 }
7094
7095 if ((do_debugging || do_debug_info || do_debug_abbrevs
7096 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7097 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7098 || do_debug_str || do_debug_str_offsets || do_debug_loc
7099 || do_debug_ranges
1b513401 7100 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7101 && (startswith (name, ".debug_")
7102 || startswith (name, ".zdebug_")))
252b5132 7103 {
1b315056
CS
7104 if (name[1] == 'z')
7105 name += sizeof (".zdebug_") - 1;
7106 else
7107 name += sizeof (".debug_") - 1;
252b5132
RH
7108
7109 if (do_debugging
24d127aa
ML
7110 || (do_debug_info && startswith (name, "info"))
7111 || (do_debug_info && startswith (name, "types"))
7112 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7113 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7114 || (do_debug_lines && startswith (name, "line."))
7115 || (do_debug_pubnames && startswith (name, "pubnames"))
7116 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7117 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7118 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7119 || (do_debug_aranges && startswith (name, "aranges"))
7120 || (do_debug_ranges && startswith (name, "ranges"))
7121 || (do_debug_ranges && startswith (name, "rnglists"))
7122 || (do_debug_frames && startswith (name, "frame"))
7123 || (do_debug_macinfo && startswith (name, "macinfo"))
7124 || (do_debug_macinfo && startswith (name, "macro"))
7125 || (do_debug_str && startswith (name, "str"))
7126 || (do_debug_links && startswith (name, "sup"))
7127 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7128 || (do_debug_loc && startswith (name, "loc"))
7129 || (do_debug_loc && startswith (name, "loclists"))
7130 || (do_debug_addr && startswith (name, "addr"))
7131 || (do_debug_cu_index && startswith (name, "cu_index"))
7132 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7133 )
6431e409 7134 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7135 }
a262ae96 7136 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7137 else if ((do_debugging || do_debug_info)
24d127aa 7138 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7139 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7140 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7141 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7142 else if (do_gdb_index && (streq (name, ".gdb_index")
7143 || streq (name, ".debug_names")))
6431e409 7144 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7145 /* Trace sections for Itanium VMS. */
7146 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7147 || do_trace_aranges)
24d127aa 7148 && startswith (name, ".trace_"))
6f875884
TG
7149 {
7150 name += sizeof (".trace_") - 1;
7151
7152 if (do_debugging
7153 || (do_trace_info && streq (name, "info"))
7154 || (do_trace_abbrevs && streq (name, "abbrev"))
7155 || (do_trace_aranges && streq (name, "aranges"))
7156 )
6431e409 7157 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7158 }
dda8d76d 7159 else if ((do_debugging || do_debug_links)
24d127aa
ML
7160 && (startswith (name, ".gnu_debuglink")
7161 || startswith (name, ".gnu_debugaltlink")))
6431e409 7162 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7163 }
7164
7165 if (! do_sections)
015dc7e1 7166 return true;
252b5132 7167
ca0e11aa 7168 if (filedata->is_separate && ! process_links)
015dc7e1 7169 return true;
ca0e11aa
NC
7170
7171 if (filedata->is_separate)
7172 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7173 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7174 printf (_("\nSection Headers:\n"));
7175 else
7176 printf (_("\nSection Header:\n"));
76da6bbe 7177
f7a99963 7178 if (is_32bit_elf)
595cf52e 7179 {
5477e8a0 7180 if (do_section_details)
595cf52e
L
7181 {
7182 printf (_(" [Nr] Name\n"));
5477e8a0 7183 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7184 }
7185 else
7186 printf
7187 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7188 }
d974e256 7189 else if (do_wide)
595cf52e 7190 {
5477e8a0 7191 if (do_section_details)
595cf52e
L
7192 {
7193 printf (_(" [Nr] Name\n"));
5477e8a0 7194 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7195 }
7196 else
7197 printf
7198 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7199 }
f7a99963
NC
7200 else
7201 {
5477e8a0 7202 if (do_section_details)
595cf52e
L
7203 {
7204 printf (_(" [Nr] Name\n"));
5477e8a0
L
7205 printf (_(" Type Address Offset Link\n"));
7206 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7207 }
7208 else
7209 {
7210 printf (_(" [Nr] Name Type Address Offset\n"));
7211 printf (_(" Size EntSize Flags Link Info Align\n"));
7212 }
f7a99963 7213 }
252b5132 7214
5477e8a0
L
7215 if (do_section_details)
7216 printf (_(" Flags\n"));
7217
dda8d76d
NC
7218 for (i = 0, section = filedata->section_headers;
7219 i < filedata->file_header.e_shnum;
b34976b6 7220 i++, section++)
252b5132 7221 {
dd905818
NC
7222 /* Run some sanity checks on the section header. */
7223
7224 /* Check the sh_link field. */
7225 switch (section->sh_type)
7226 {
285e3f99
AM
7227 case SHT_REL:
7228 case SHT_RELA:
7229 if (section->sh_link == 0
7230 && (filedata->file_header.e_type == ET_EXEC
7231 || filedata->file_header.e_type == ET_DYN))
7232 /* A dynamic relocation section where all entries use a
7233 zero symbol index need not specify a symtab section. */
7234 break;
7235 /* Fall through. */
dd905818
NC
7236 case SHT_SYMTAB_SHNDX:
7237 case SHT_GROUP:
7238 case SHT_HASH:
7239 case SHT_GNU_HASH:
7240 case SHT_GNU_versym:
285e3f99 7241 if (section->sh_link == 0
dda8d76d
NC
7242 || section->sh_link >= filedata->file_header.e_shnum
7243 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7244 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7245 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7246 i, section->sh_link);
7247 break;
7248
7249 case SHT_DYNAMIC:
7250 case SHT_SYMTAB:
7251 case SHT_DYNSYM:
7252 case SHT_GNU_verneed:
7253 case SHT_GNU_verdef:
7254 case SHT_GNU_LIBLIST:
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_STRTAB)
dd905818
NC
7258 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7259 i, section->sh_link);
7260 break;
7261
7262 case SHT_INIT_ARRAY:
7263 case SHT_FINI_ARRAY:
7264 case SHT_PREINIT_ARRAY:
7265 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7266 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7267 i, section->sh_link);
7268 break;
7269
7270 default:
7271 /* FIXME: Add support for target specific section types. */
7272#if 0 /* Currently we do not check other section types as there are too
7273 many special cases. Stab sections for example have a type
7274 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7275 section. */
7276 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7277 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7278 i, section->sh_link);
7279#endif
7280 break;
7281 }
7282
7283 /* Check the sh_info field. */
7284 switch (section->sh_type)
7285 {
7286 case SHT_REL:
7287 case SHT_RELA:
285e3f99
AM
7288 if (section->sh_info == 0
7289 && (filedata->file_header.e_type == ET_EXEC
7290 || filedata->file_header.e_type == ET_DYN))
7291 /* Dynamic relocations apply to segments, so they do not
7292 need to specify the section they relocate. */
7293 break;
7294 if (section->sh_info == 0
dda8d76d
NC
7295 || section->sh_info >= filedata->file_header.e_shnum
7296 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7297 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7298 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7299 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7300 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7301 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7302 /* FIXME: Are other section types valid ? */
dda8d76d 7303 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7304 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7305 i, section->sh_info);
dd905818
NC
7306 break;
7307
7308 case SHT_DYNAMIC:
7309 case SHT_HASH:
7310 case SHT_SYMTAB_SHNDX:
7311 case SHT_INIT_ARRAY:
7312 case SHT_FINI_ARRAY:
7313 case SHT_PREINIT_ARRAY:
7314 if (section->sh_info != 0)
7315 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7316 i, section->sh_info);
7317 break;
7318
7319 case SHT_GROUP:
7320 case SHT_SYMTAB:
7321 case SHT_DYNSYM:
7322 /* A symbol index - we assume that it is valid. */
7323 break;
7324
7325 default:
7326 /* FIXME: Add support for target specific section types. */
7327 if (section->sh_type == SHT_NOBITS)
7328 /* NOBITS section headers with non-zero sh_info fields can be
7329 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7330 information. The stripped sections have their headers
7331 preserved but their types set to SHT_NOBITS. So do not check
7332 this type of section. */
dd905818
NC
7333 ;
7334 else if (section->sh_flags & SHF_INFO_LINK)
7335 {
dda8d76d 7336 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7337 warn (_("[%2u]: Expected link to another section in info field"), i);
7338 }
a91e1603
L
7339 else if (section->sh_type < SHT_LOOS
7340 && (section->sh_flags & SHF_GNU_MBIND) == 0
7341 && section->sh_info != 0)
dd905818
NC
7342 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7343 i, section->sh_info);
7344 break;
7345 }
7346
3e6b6445 7347 /* Check the sh_size field. */
dda8d76d 7348 if (section->sh_size > filedata->file_size
3e6b6445
NC
7349 && section->sh_type != SHT_NOBITS
7350 && section->sh_type != SHT_NULL
7351 && section->sh_type < SHT_LOOS)
7352 warn (_("Size of section %u is larger than the entire file!\n"), i);
7353
7bfd842d 7354 printf (" [%2u] ", i);
5477e8a0 7355 if (do_section_details)
dda8d76d 7356 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7357 else
84714f86 7358 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7359
ea52a088 7360 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7361 get_section_type_name (filedata, section->sh_type));
0b4362b0 7362
f7a99963
NC
7363 if (is_32bit_elf)
7364 {
cfcac11d
NC
7365 const char * link_too_big = NULL;
7366
f7a99963 7367 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7368
f7a99963
NC
7369 printf ( " %6.6lx %6.6lx %2.2lx",
7370 (unsigned long) section->sh_offset,
7371 (unsigned long) section->sh_size,
7372 (unsigned long) section->sh_entsize);
d1133906 7373
5477e8a0
L
7374 if (do_section_details)
7375 fputs (" ", stdout);
7376 else
dda8d76d 7377 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7378
dda8d76d 7379 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7380 {
7381 link_too_big = "";
7382 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7383 an error but it can have special values in Solaris binaries. */
dda8d76d 7384 switch (filedata->file_header.e_machine)
cfcac11d 7385 {
caa83f8b 7386 case EM_386:
22abe556 7387 case EM_IAMCU:
caa83f8b 7388 case EM_X86_64:
7f502d6c 7389 case EM_L1OM:
7a9068fe 7390 case EM_K1OM:
cfcac11d
NC
7391 case EM_OLD_SPARCV9:
7392 case EM_SPARC32PLUS:
7393 case EM_SPARCV9:
7394 case EM_SPARC:
7395 if (section->sh_link == (SHN_BEFORE & 0xffff))
7396 link_too_big = "BEFORE";
7397 else if (section->sh_link == (SHN_AFTER & 0xffff))
7398 link_too_big = "AFTER";
7399 break;
7400 default:
7401 break;
7402 }
7403 }
7404
7405 if (do_section_details)
7406 {
7407 if (link_too_big != NULL && * link_too_big)
7408 printf ("<%s> ", link_too_big);
7409 else
7410 printf ("%2u ", section->sh_link);
7411 printf ("%3u %2lu\n", section->sh_info,
7412 (unsigned long) section->sh_addralign);
7413 }
7414 else
7415 printf ("%2u %3u %2lu\n",
7416 section->sh_link,
7417 section->sh_info,
7418 (unsigned long) section->sh_addralign);
7419
7420 if (link_too_big && ! * link_too_big)
7421 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7422 i, section->sh_link);
f7a99963 7423 }
d974e256
JJ
7424 else if (do_wide)
7425 {
7426 print_vma (section->sh_addr, LONG_HEX);
7427
7428 if ((long) section->sh_offset == section->sh_offset)
7429 printf (" %6.6lx", (unsigned long) section->sh_offset);
7430 else
7431 {
7432 putchar (' ');
7433 print_vma (section->sh_offset, LONG_HEX);
7434 }
7435
7436 if ((unsigned long) section->sh_size == section->sh_size)
7437 printf (" %6.6lx", (unsigned long) section->sh_size);
7438 else
7439 {
7440 putchar (' ');
7441 print_vma (section->sh_size, LONG_HEX);
7442 }
7443
7444 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7445 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7446 else
7447 {
7448 putchar (' ');
7449 print_vma (section->sh_entsize, LONG_HEX);
7450 }
7451
5477e8a0
L
7452 if (do_section_details)
7453 fputs (" ", stdout);
7454 else
dda8d76d 7455 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7456
72de5009 7457 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7458
7459 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7460 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7461 else
7462 {
7463 print_vma (section->sh_addralign, DEC);
7464 putchar ('\n');
7465 }
7466 }
5477e8a0 7467 else if (do_section_details)
595cf52e 7468 {
55cc53e9 7469 putchar (' ');
595cf52e
L
7470 print_vma (section->sh_addr, LONG_HEX);
7471 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7472 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7473 else
7474 {
7475 printf (" ");
7476 print_vma (section->sh_offset, LONG_HEX);
7477 }
72de5009 7478 printf (" %u\n ", section->sh_link);
595cf52e 7479 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7480 putchar (' ');
595cf52e
L
7481 print_vma (section->sh_entsize, LONG_HEX);
7482
72de5009
AM
7483 printf (" %-16u %lu\n",
7484 section->sh_info,
595cf52e
L
7485 (unsigned long) section->sh_addralign);
7486 }
f7a99963
NC
7487 else
7488 {
7489 putchar (' ');
7490 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7491 if ((long) section->sh_offset == section->sh_offset)
7492 printf (" %8.8lx", (unsigned long) section->sh_offset);
7493 else
7494 {
7495 printf (" ");
7496 print_vma (section->sh_offset, LONG_HEX);
7497 }
f7a99963
NC
7498 printf ("\n ");
7499 print_vma (section->sh_size, LONG_HEX);
7500 printf (" ");
7501 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7502
dda8d76d 7503 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7504
72de5009
AM
7505 printf (" %2u %3u %lu\n",
7506 section->sh_link,
7507 section->sh_info,
f7a99963
NC
7508 (unsigned long) section->sh_addralign);
7509 }
5477e8a0
L
7510
7511 if (do_section_details)
77115a4a 7512 {
dda8d76d 7513 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7514 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7515 {
7516 /* Minimum section size is 12 bytes for 32-bit compression
7517 header + 12 bytes for compressed data header. */
7518 unsigned char buf[24];
d8024a91 7519
77115a4a 7520 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7521 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7522 sizeof (buf), _("compression header")))
7523 {
7524 Elf_Internal_Chdr chdr;
d8024a91 7525
5844b465
NC
7526 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7527 printf (_(" [<corrupt>]\n"));
77115a4a 7528 else
5844b465
NC
7529 {
7530 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7531 printf (" ZLIB, ");
7532 else
7533 printf (_(" [<unknown>: 0x%x], "),
7534 chdr.ch_type);
7535 print_vma (chdr.ch_size, LONG_HEX);
7536 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7537 }
77115a4a
L
7538 }
7539 }
7540 }
252b5132
RH
7541 }
7542
5477e8a0 7543 if (!do_section_details)
3dbcc61d 7544 {
9fb71ee4
NC
7545 /* The ordering of the letters shown here matches the ordering of the
7546 corresponding SHF_xxx values, and hence the order in which these
7547 letters will be displayed to the user. */
7548 printf (_("Key to Flags:\n\
7549 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7550 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7551 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7552 switch (filedata->file_header.e_ident[EI_OSABI])
7553 {
7554 case ELFOSABI_GNU:
7555 case ELFOSABI_FREEBSD:
7556 printf (_("R (retain), "));
7557 /* Fall through */
7558 case ELFOSABI_NONE:
7559 printf (_("D (mbind), "));
7560 break;
7561 default:
7562 break;
7563 }
dda8d76d
NC
7564 if (filedata->file_header.e_machine == EM_X86_64
7565 || filedata->file_header.e_machine == EM_L1OM
7566 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7567 printf (_("l (large), "));
dda8d76d 7568 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7569 printf (_("y (purecode), "));
dda8d76d 7570 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7571 printf (_("v (VLE), "));
9fb71ee4 7572 printf ("p (processor specific)\n");
0b4362b0 7573 }
d1133906 7574
015dc7e1 7575 return true;
252b5132
RH
7576}
7577
015dc7e1 7578static bool
28d13567
AM
7579get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7580 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7581 char **strtab, unsigned long *strtablen)
7582{
7583 *strtab = NULL;
7584 *strtablen = 0;
4de91c10 7585 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7586
7587 if (*symtab == NULL)
015dc7e1 7588 return false;
28d13567
AM
7589
7590 if (symsec->sh_link != 0)
7591 {
7592 Elf_Internal_Shdr *strsec;
7593
7594 if (symsec->sh_link >= filedata->file_header.e_shnum)
7595 {
7596 error (_("Bad sh_link in symbol table section\n"));
7597 free (*symtab);
7598 *symtab = NULL;
7599 *nsyms = 0;
015dc7e1 7600 return false;
28d13567
AM
7601 }
7602
7603 strsec = filedata->section_headers + symsec->sh_link;
7604
7605 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7606 1, strsec->sh_size, _("string table"));
7607 if (*strtab == NULL)
7608 {
7609 free (*symtab);
7610 *symtab = NULL;
7611 *nsyms = 0;
015dc7e1 7612 return false;
28d13567
AM
7613 }
7614 *strtablen = strsec->sh_size;
7615 }
015dc7e1 7616 return true;
28d13567
AM
7617}
7618
f5842774
L
7619static const char *
7620get_group_flags (unsigned int flags)
7621{
1449284b 7622 static char buff[128];
220453ec 7623
6d913794
NC
7624 if (flags == 0)
7625 return "";
7626 else if (flags == GRP_COMDAT)
7627 return "COMDAT ";
f5842774 7628
89246a0e
AM
7629 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7630 flags,
7631 flags & GRP_MASKOS ? _("<OS specific>") : "",
7632 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7633 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7634 ? _("<unknown>") : ""));
6d913794 7635
f5842774
L
7636 return buff;
7637}
7638
015dc7e1 7639static bool
dda8d76d 7640process_section_groups (Filedata * filedata)
f5842774 7641{
2cf0635d 7642 Elf_Internal_Shdr * section;
f5842774 7643 unsigned int i;
2cf0635d
NC
7644 struct group * group;
7645 Elf_Internal_Shdr * symtab_sec;
7646 Elf_Internal_Shdr * strtab_sec;
7647 Elf_Internal_Sym * symtab;
ba5cdace 7648 unsigned long num_syms;
2cf0635d 7649 char * strtab;
c256ffe7 7650 size_t strtab_size;
d1f5c6e3
L
7651
7652 /* Don't process section groups unless needed. */
7653 if (!do_unwind && !do_section_groups)
015dc7e1 7654 return true;
f5842774 7655
dda8d76d 7656 if (filedata->file_header.e_shnum == 0)
f5842774
L
7657 {
7658 if (do_section_groups)
ca0e11aa
NC
7659 {
7660 if (filedata->is_separate)
7661 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7662 filedata->file_name);
7663 else
7664 printf (_("\nThere are no section groups in this file.\n"));
7665 }
015dc7e1 7666 return true;
f5842774
L
7667 }
7668
dda8d76d 7669 if (filedata->section_headers == NULL)
f5842774
L
7670 {
7671 error (_("Section headers are not available!\n"));
fa1908fd 7672 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7673 return false;
f5842774
L
7674 }
7675
978c4450
AM
7676 filedata->section_headers_groups
7677 = (struct group **) calloc (filedata->file_header.e_shnum,
7678 sizeof (struct group *));
e4b17d5c 7679
978c4450 7680 if (filedata->section_headers_groups == NULL)
e4b17d5c 7681 {
8b73c356 7682 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7683 filedata->file_header.e_shnum);
015dc7e1 7684 return false;
e4b17d5c
L
7685 }
7686
f5842774 7687 /* Scan the sections for the group section. */
978c4450 7688 filedata->group_count = 0;
dda8d76d
NC
7689 for (i = 0, section = filedata->section_headers;
7690 i < filedata->file_header.e_shnum;
f5842774 7691 i++, section++)
e4b17d5c 7692 if (section->sh_type == SHT_GROUP)
978c4450 7693 filedata->group_count++;
e4b17d5c 7694
978c4450 7695 if (filedata->group_count == 0)
d1f5c6e3
L
7696 {
7697 if (do_section_groups)
ca0e11aa
NC
7698 {
7699 if (filedata->is_separate)
7700 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7701 filedata->file_name);
7702 else
7703 printf (_("\nThere are no section groups in this file.\n"));
7704 }
d1f5c6e3 7705
015dc7e1 7706 return true;
d1f5c6e3
L
7707 }
7708
978c4450
AM
7709 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7710 sizeof (struct group));
e4b17d5c 7711
978c4450 7712 if (filedata->section_groups == NULL)
e4b17d5c 7713 {
8b73c356 7714 error (_("Out of memory reading %lu groups\n"),
978c4450 7715 (unsigned long) filedata->group_count);
015dc7e1 7716 return false;
e4b17d5c
L
7717 }
7718
d1f5c6e3
L
7719 symtab_sec = NULL;
7720 strtab_sec = NULL;
7721 symtab = NULL;
ba5cdace 7722 num_syms = 0;
d1f5c6e3 7723 strtab = NULL;
c256ffe7 7724 strtab_size = 0;
ca0e11aa
NC
7725
7726 if (filedata->is_separate)
7727 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7728
978c4450 7729 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7730 i < filedata->file_header.e_shnum;
e4b17d5c 7731 i++, section++)
f5842774
L
7732 {
7733 if (section->sh_type == SHT_GROUP)
7734 {
dda8d76d 7735 const char * name = printable_section_name (filedata, section);
74e1a04b 7736 const char * group_name;
2cf0635d
NC
7737 unsigned char * start;
7738 unsigned char * indices;
f5842774 7739 unsigned int entry, j, size;
2cf0635d
NC
7740 Elf_Internal_Shdr * sec;
7741 Elf_Internal_Sym * sym;
f5842774
L
7742
7743 /* Get the symbol table. */
dda8d76d
NC
7744 if (section->sh_link >= filedata->file_header.e_shnum
7745 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7746 != SHT_SYMTAB))
f5842774
L
7747 {
7748 error (_("Bad sh_link in group section `%s'\n"), name);
7749 continue;
7750 }
d1f5c6e3
L
7751
7752 if (symtab_sec != sec)
7753 {
7754 symtab_sec = sec;
9db70fc3 7755 free (symtab);
4de91c10 7756 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7757 }
f5842774 7758
dd24e3da
NC
7759 if (symtab == NULL)
7760 {
7761 error (_("Corrupt header in group section `%s'\n"), name);
7762 continue;
7763 }
7764
ba5cdace
NC
7765 if (section->sh_info >= num_syms)
7766 {
7767 error (_("Bad sh_info in group section `%s'\n"), name);
7768 continue;
7769 }
7770
f5842774
L
7771 sym = symtab + section->sh_info;
7772
7773 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7774 {
4fbb74a6 7775 if (sym->st_shndx == 0
dda8d76d 7776 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7777 {
7778 error (_("Bad sh_info in group section `%s'\n"), name);
7779 continue;
7780 }
ba2685cc 7781
84714f86
AM
7782 group_name = section_name_print (filedata,
7783 filedata->section_headers
b9e920ec 7784 + sym->st_shndx);
c256ffe7 7785 strtab_sec = NULL;
9db70fc3 7786 free (strtab);
f5842774 7787 strtab = NULL;
c256ffe7 7788 strtab_size = 0;
f5842774
L
7789 }
7790 else
7791 {
7792 /* Get the string table. */
dda8d76d 7793 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7794 {
7795 strtab_sec = NULL;
9db70fc3 7796 free (strtab);
c256ffe7
JJ
7797 strtab = NULL;
7798 strtab_size = 0;
7799 }
7800 else if (strtab_sec
dda8d76d 7801 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7802 {
7803 strtab_sec = sec;
9db70fc3 7804 free (strtab);
071436c6 7805
dda8d76d 7806 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7807 1, strtab_sec->sh_size,
7808 _("string table"));
c256ffe7 7809 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7810 }
c256ffe7 7811 group_name = sym->st_name < strtab_size
2b692964 7812 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7813 }
7814
c9c1d674
EG
7815 /* PR 17531: file: loop. */
7816 if (section->sh_entsize > section->sh_size)
7817 {
7818 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7819 printable_section_name (filedata, section),
8066deb1
AM
7820 (unsigned long) section->sh_entsize,
7821 (unsigned long) section->sh_size);
61dd8e19 7822 continue;
c9c1d674
EG
7823 }
7824
dda8d76d 7825 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7826 1, section->sh_size,
7827 _("section data"));
59245841
NC
7828 if (start == NULL)
7829 continue;
f5842774
L
7830
7831 indices = start;
7832 size = (section->sh_size / section->sh_entsize) - 1;
7833 entry = byte_get (indices, 4);
7834 indices += 4;
e4b17d5c
L
7835
7836 if (do_section_groups)
7837 {
2b692964 7838 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7839 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7840
e4b17d5c
L
7841 printf (_(" [Index] Name\n"));
7842 }
7843
7844 group->group_index = i;
7845
f5842774
L
7846 for (j = 0; j < size; j++)
7847 {
2cf0635d 7848 struct group_list * g;
e4b17d5c 7849
f5842774
L
7850 entry = byte_get (indices, 4);
7851 indices += 4;
7852
dda8d76d 7853 if (entry >= filedata->file_header.e_shnum)
391cb864 7854 {
57028622
NC
7855 static unsigned num_group_errors = 0;
7856
7857 if (num_group_errors ++ < 10)
7858 {
7859 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7860 entry, i, filedata->file_header.e_shnum - 1);
57028622 7861 if (num_group_errors == 10)
67ce483b 7862 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7863 }
391cb864
L
7864 continue;
7865 }
391cb864 7866
978c4450 7867 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7868 {
d1f5c6e3
L
7869 if (entry)
7870 {
57028622
NC
7871 static unsigned num_errs = 0;
7872
7873 if (num_errs ++ < 10)
7874 {
7875 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7876 entry, i,
978c4450 7877 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7878 if (num_errs == 10)
7879 warn (_("Further error messages about already contained group sections suppressed\n"));
7880 }
d1f5c6e3
L
7881 continue;
7882 }
7883 else
7884 {
7885 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7886 section group. We just warn it the first time
d1f5c6e3 7887 and ignore it afterwards. */
015dc7e1 7888 static bool warned = false;
d1f5c6e3
L
7889 if (!warned)
7890 {
7891 error (_("section 0 in group section [%5u]\n"),
978c4450 7892 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7893 warned = true;
d1f5c6e3
L
7894 }
7895 }
e4b17d5c
L
7896 }
7897
978c4450 7898 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7899
7900 if (do_section_groups)
7901 {
dda8d76d
NC
7902 sec = filedata->section_headers + entry;
7903 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7904 }
7905
3f5e193b 7906 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7907 g->section_index = entry;
7908 g->next = group->root;
7909 group->root = g;
f5842774
L
7910 }
7911
9db70fc3 7912 free (start);
e4b17d5c
L
7913
7914 group++;
f5842774
L
7915 }
7916 }
7917
9db70fc3
AM
7918 free (symtab);
7919 free (strtab);
015dc7e1 7920 return true;
f5842774
L
7921}
7922
28f997cf
TG
7923/* Data used to display dynamic fixups. */
7924
7925struct ia64_vms_dynfixup
7926{
7927 bfd_vma needed_ident; /* Library ident number. */
7928 bfd_vma needed; /* Index in the dstrtab of the library name. */
7929 bfd_vma fixup_needed; /* Index of the library. */
7930 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7931 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7932};
7933
7934/* Data used to display dynamic relocations. */
7935
7936struct ia64_vms_dynimgrela
7937{
7938 bfd_vma img_rela_cnt; /* Number of relocations. */
7939 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7940};
7941
7942/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7943 library). */
7944
015dc7e1 7945static bool
dda8d76d
NC
7946dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7947 struct ia64_vms_dynfixup * fixup,
7948 const char * strtab,
7949 unsigned int strtab_sz)
28f997cf 7950{
32ec8896 7951 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7952 long i;
32ec8896 7953 const char * lib_name;
28f997cf 7954
978c4450
AM
7955 imfs = get_data (NULL, filedata,
7956 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7957 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7958 _("dynamic section image fixups"));
7959 if (!imfs)
015dc7e1 7960 return false;
28f997cf
TG
7961
7962 if (fixup->needed < strtab_sz)
7963 lib_name = strtab + fixup->needed;
7964 else
7965 {
32ec8896 7966 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7967 (unsigned long) fixup->needed);
28f997cf
TG
7968 lib_name = "???";
7969 }
736990c4 7970
28f997cf
TG
7971 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7972 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7973 printf
7974 (_("Seg Offset Type SymVec DataType\n"));
7975
7976 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7977 {
7978 unsigned int type;
7979 const char *rtype;
7980
7981 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7982 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7983 type = BYTE_GET (imfs [i].type);
7984 rtype = elf_ia64_reloc_type (type);
7985 if (rtype == NULL)
7986 printf (" 0x%08x ", type);
7987 else
7988 printf (" %-32s ", rtype);
7989 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7990 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7991 }
7992
7993 free (imfs);
015dc7e1 7994 return true;
28f997cf
TG
7995}
7996
7997/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7998
015dc7e1 7999static bool
dda8d76d 8000dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8001{
8002 Elf64_External_VMS_IMAGE_RELA *imrs;
8003 long i;
8004
978c4450
AM
8005 imrs = get_data (NULL, filedata,
8006 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8007 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8008 _("dynamic section image relocations"));
28f997cf 8009 if (!imrs)
015dc7e1 8010 return false;
28f997cf
TG
8011
8012 printf (_("\nImage relocs\n"));
8013 printf
8014 (_("Seg Offset Type Addend Seg Sym Off\n"));
8015
8016 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8017 {
8018 unsigned int type;
8019 const char *rtype;
8020
8021 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
8022 printf ("%08" BFD_VMA_FMT "x ",
8023 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
8024 type = BYTE_GET (imrs [i].type);
8025 rtype = elf_ia64_reloc_type (type);
8026 if (rtype == NULL)
8027 printf ("0x%08x ", type);
8028 else
8029 printf ("%-31s ", rtype);
8030 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8031 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
8032 printf ("%08" BFD_VMA_FMT "x\n",
8033 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
8034 }
8035
8036 free (imrs);
015dc7e1 8037 return true;
28f997cf
TG
8038}
8039
8040/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8041
015dc7e1 8042static bool
dda8d76d 8043process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8044{
8045 struct ia64_vms_dynfixup fixup;
8046 struct ia64_vms_dynimgrela imgrela;
8047 Elf_Internal_Dyn *entry;
28f997cf
TG
8048 bfd_vma strtab_off = 0;
8049 bfd_vma strtab_sz = 0;
8050 char *strtab = NULL;
015dc7e1 8051 bool res = true;
28f997cf
TG
8052
8053 memset (&fixup, 0, sizeof (fixup));
8054 memset (&imgrela, 0, sizeof (imgrela));
8055
8056 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8057 for (entry = filedata->dynamic_section;
8058 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8059 entry++)
8060 {
8061 switch (entry->d_tag)
8062 {
8063 case DT_IA_64_VMS_STRTAB_OFFSET:
8064 strtab_off = entry->d_un.d_val;
8065 break;
8066 case DT_STRSZ:
8067 strtab_sz = entry->d_un.d_val;
8068 if (strtab == NULL)
978c4450
AM
8069 strtab = get_data (NULL, filedata,
8070 filedata->dynamic_addr + strtab_off,
28f997cf 8071 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8072 if (strtab == NULL)
8073 strtab_sz = 0;
28f997cf
TG
8074 break;
8075
8076 case DT_IA_64_VMS_NEEDED_IDENT:
8077 fixup.needed_ident = entry->d_un.d_val;
8078 break;
8079 case DT_NEEDED:
8080 fixup.needed = entry->d_un.d_val;
8081 break;
8082 case DT_IA_64_VMS_FIXUP_NEEDED:
8083 fixup.fixup_needed = entry->d_un.d_val;
8084 break;
8085 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8086 fixup.fixup_rela_cnt = entry->d_un.d_val;
8087 break;
8088 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8089 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8090 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8091 res = false;
28f997cf 8092 break;
28f997cf
TG
8093 case DT_IA_64_VMS_IMG_RELA_CNT:
8094 imgrela.img_rela_cnt = entry->d_un.d_val;
8095 break;
8096 case DT_IA_64_VMS_IMG_RELA_OFF:
8097 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8098 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8099 res = false;
28f997cf
TG
8100 break;
8101
8102 default:
8103 break;
8104 }
8105 }
8106
9db70fc3 8107 free (strtab);
28f997cf
TG
8108
8109 return res;
8110}
8111
85b1c36d 8112static struct
566b0d53 8113{
2cf0635d 8114 const char * name;
566b0d53
L
8115 int reloc;
8116 int size;
a7fd1186 8117 relocation_type rel_type;
32ec8896
NC
8118}
8119 dynamic_relocations [] =
566b0d53 8120{
a7fd1186
FS
8121 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8122 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8123 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8124 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8125};
8126
252b5132 8127/* Process the reloc section. */
18bd398b 8128
015dc7e1 8129static bool
dda8d76d 8130process_relocs (Filedata * filedata)
252b5132 8131{
b34976b6
AM
8132 unsigned long rel_size;
8133 unsigned long rel_offset;
252b5132 8134
252b5132 8135 if (!do_reloc)
015dc7e1 8136 return true;
252b5132
RH
8137
8138 if (do_using_dynamic)
8139 {
a7fd1186 8140 relocation_type rel_type;
2cf0635d 8141 const char * name;
015dc7e1 8142 bool has_dynamic_reloc;
566b0d53 8143 unsigned int i;
0de14b54 8144
015dc7e1 8145 has_dynamic_reloc = false;
252b5132 8146
566b0d53 8147 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8148 {
a7fd1186 8149 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8150 name = dynamic_relocations [i].name;
978c4450
AM
8151 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8152 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8153
32ec8896 8154 if (rel_size)
015dc7e1 8155 has_dynamic_reloc = true;
566b0d53 8156
a7fd1186 8157 if (rel_type == reltype_unknown)
aa903cfb 8158 {
566b0d53 8159 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8160 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8161 {
8162 case DT_REL:
a7fd1186 8163 rel_type = reltype_rel;
566b0d53
L
8164 break;
8165 case DT_RELA:
a7fd1186 8166 rel_type = reltype_rela;
566b0d53
L
8167 break;
8168 }
aa903cfb 8169 }
252b5132 8170
566b0d53
L
8171 if (rel_size)
8172 {
ca0e11aa
NC
8173 if (filedata->is_separate)
8174 printf
8175 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8176 filedata->file_name, name, rel_offset, rel_size);
8177 else
8178 printf
8179 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8180 name, rel_offset, rel_size);
252b5132 8181
dda8d76d
NC
8182 dump_relocations (filedata,
8183 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8184 rel_size,
978c4450
AM
8185 filedata->dynamic_symbols,
8186 filedata->num_dynamic_syms,
8187 filedata->dynamic_strings,
8188 filedata->dynamic_strings_length,
a7fd1186 8189 rel_type, true /* is_dynamic */);
566b0d53 8190 }
252b5132 8191 }
566b0d53 8192
dda8d76d
NC
8193 if (is_ia64_vms (filedata))
8194 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8195 has_dynamic_reloc = true;
28f997cf 8196
566b0d53 8197 if (! has_dynamic_reloc)
ca0e11aa
NC
8198 {
8199 if (filedata->is_separate)
8200 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8201 filedata->file_name);
8202 else
8203 printf (_("\nThere are no dynamic relocations in this file.\n"));
8204 }
252b5132
RH
8205 }
8206 else
8207 {
2cf0635d 8208 Elf_Internal_Shdr * section;
b34976b6 8209 unsigned long i;
015dc7e1 8210 bool found = false;
252b5132 8211
dda8d76d
NC
8212 for (i = 0, section = filedata->section_headers;
8213 i < filedata->file_header.e_shnum;
b34976b6 8214 i++, section++)
252b5132
RH
8215 {
8216 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8217 && section->sh_type != SHT_REL
8218 && section->sh_type != SHT_RELR)
252b5132
RH
8219 continue;
8220
8221 rel_offset = section->sh_offset;
8222 rel_size = section->sh_size;
8223
8224 if (rel_size)
8225 {
a7fd1186 8226 relocation_type rel_type;
d3a49aa8 8227 unsigned long num_rela;
103f02d3 8228
ca0e11aa
NC
8229 if (filedata->is_separate)
8230 printf (_("\nIn linked file '%s' relocation section "),
8231 filedata->file_name);
8232 else
8233 printf (_("\nRelocation section "));
252b5132 8234
dda8d76d 8235 if (filedata->string_table == NULL)
19936277 8236 printf ("%d", section->sh_name);
252b5132 8237 else
dda8d76d 8238 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8239
d3a49aa8
AM
8240 num_rela = rel_size / section->sh_entsize;
8241 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8242 " at offset 0x%lx contains %lu entries:\n",
8243 num_rela),
8244 rel_offset, num_rela);
252b5132 8245
a7fd1186
FS
8246 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8247 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8248
4fbb74a6 8249 if (section->sh_link != 0
dda8d76d 8250 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8251 {
2cf0635d
NC
8252 Elf_Internal_Shdr * symsec;
8253 Elf_Internal_Sym * symtab;
d79b3d50 8254 unsigned long nsyms;
c256ffe7 8255 unsigned long strtablen = 0;
2cf0635d 8256 char * strtab = NULL;
57346661 8257
dda8d76d 8258 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8259 if (symsec->sh_type != SHT_SYMTAB
8260 && symsec->sh_type != SHT_DYNSYM)
8261 continue;
8262
28d13567
AM
8263 if (!get_symtab (filedata, symsec,
8264 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8265 continue;
252b5132 8266
dda8d76d 8267 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8268 symtab, nsyms, strtab, strtablen,
a7fd1186 8269 rel_type,
bb4d2ac2 8270 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8271 free (strtab);
d79b3d50
NC
8272 free (symtab);
8273 }
8274 else
dda8d76d 8275 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8276 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8277
015dc7e1 8278 found = true;
252b5132
RH
8279 }
8280 }
8281
8282 if (! found)
45ac8f4f
NC
8283 {
8284 /* Users sometimes forget the -D option, so try to be helpful. */
8285 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8286 {
978c4450 8287 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8288 {
ca0e11aa
NC
8289 if (filedata->is_separate)
8290 printf (_("\nThere are no static relocations in linked file '%s'."),
8291 filedata->file_name);
8292 else
8293 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8294 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8295
8296 break;
8297 }
8298 }
8299 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8300 {
8301 if (filedata->is_separate)
8302 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8303 filedata->file_name);
8304 else
8305 printf (_("\nThere are no relocations in this file.\n"));
8306 }
45ac8f4f 8307 }
252b5132
RH
8308 }
8309
015dc7e1 8310 return true;
252b5132
RH
8311}
8312
4d6ed7c8
NC
8313/* An absolute address consists of a section and an offset. If the
8314 section is NULL, the offset itself is the address, otherwise, the
8315 address equals to LOAD_ADDRESS(section) + offset. */
8316
8317struct absaddr
948f632f
DA
8318{
8319 unsigned short section;
8320 bfd_vma offset;
8321};
4d6ed7c8 8322
948f632f
DA
8323/* Find the nearest symbol at or below ADDR. Returns the symbol
8324 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8325
4d6ed7c8 8326static void
dda8d76d
NC
8327find_symbol_for_address (Filedata * filedata,
8328 Elf_Internal_Sym * symtab,
8329 unsigned long nsyms,
8330 const char * strtab,
8331 unsigned long strtab_size,
8332 struct absaddr addr,
8333 const char ** symname,
8334 bfd_vma * offset)
4d6ed7c8 8335{
d3ba0551 8336 bfd_vma dist = 0x100000;
2cf0635d 8337 Elf_Internal_Sym * sym;
948f632f
DA
8338 Elf_Internal_Sym * beg;
8339 Elf_Internal_Sym * end;
2cf0635d 8340 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8341
0b6ae522 8342 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8343 beg = symtab;
8344 end = symtab + nsyms;
0b6ae522 8345
948f632f 8346 while (beg < end)
4d6ed7c8 8347 {
948f632f
DA
8348 bfd_vma value;
8349
8350 sym = beg + (end - beg) / 2;
0b6ae522 8351
948f632f 8352 value = sym->st_value;
0b6ae522
DJ
8353 REMOVE_ARCH_BITS (value);
8354
948f632f 8355 if (sym->st_name != 0
4d6ed7c8 8356 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8357 && addr.offset >= value
8358 && addr.offset - value < dist)
4d6ed7c8
NC
8359 {
8360 best = sym;
0b6ae522 8361 dist = addr.offset - value;
4d6ed7c8
NC
8362 if (!dist)
8363 break;
8364 }
948f632f
DA
8365
8366 if (addr.offset < value)
8367 end = sym;
8368 else
8369 beg = sym + 1;
4d6ed7c8 8370 }
1b31d05e 8371
4d6ed7c8
NC
8372 if (best)
8373 {
57346661 8374 *symname = (best->st_name >= strtab_size
2b692964 8375 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8376 *offset = dist;
8377 return;
8378 }
1b31d05e 8379
4d6ed7c8
NC
8380 *symname = NULL;
8381 *offset = addr.offset;
8382}
8383
32ec8896 8384static /* signed */ int
948f632f
DA
8385symcmp (const void *p, const void *q)
8386{
8387 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8388 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8389
8390 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8391}
8392
8393/* Process the unwind section. */
8394
8395#include "unwind-ia64.h"
8396
8397struct ia64_unw_table_entry
8398{
8399 struct absaddr start;
8400 struct absaddr end;
8401 struct absaddr info;
8402};
8403
8404struct ia64_unw_aux_info
8405{
32ec8896
NC
8406 struct ia64_unw_table_entry * table; /* Unwind table. */
8407 unsigned long table_len; /* Length of unwind table. */
8408 unsigned char * info; /* Unwind info. */
8409 unsigned long info_size; /* Size of unwind info. */
8410 bfd_vma info_addr; /* Starting address of unwind info. */
8411 bfd_vma seg_base; /* Starting address of segment. */
8412 Elf_Internal_Sym * symtab; /* The symbol table. */
8413 unsigned long nsyms; /* Number of symbols. */
8414 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8415 unsigned long nfuns; /* Number of entries in funtab. */
8416 char * strtab; /* The string table. */
8417 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8418};
8419
015dc7e1 8420static bool
dda8d76d 8421dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8422{
2cf0635d 8423 struct ia64_unw_table_entry * tp;
948f632f 8424 unsigned long j, nfuns;
4d6ed7c8 8425 int in_body;
015dc7e1 8426 bool res = true;
7036c0e1 8427
948f632f
DA
8428 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8429 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8430 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8431 aux->funtab[nfuns++] = aux->symtab[j];
8432 aux->nfuns = nfuns;
8433 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8434
4d6ed7c8
NC
8435 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8436 {
8437 bfd_vma stamp;
8438 bfd_vma offset;
2cf0635d
NC
8439 const unsigned char * dp;
8440 const unsigned char * head;
53774b7e 8441 const unsigned char * end;
2cf0635d 8442 const char * procname;
4d6ed7c8 8443
dda8d76d 8444 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8445 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8446
8447 fputs ("\n<", stdout);
8448
8449 if (procname)
8450 {
8451 fputs (procname, stdout);
8452
8453 if (offset)
8454 printf ("+%lx", (unsigned long) offset);
8455 }
8456
8457 fputs (">: [", stdout);
8458 print_vma (tp->start.offset, PREFIX_HEX);
8459 fputc ('-', stdout);
8460 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8461 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8462 (unsigned long) (tp->info.offset - aux->seg_base));
8463
53774b7e
NC
8464 /* PR 17531: file: 86232b32. */
8465 if (aux->info == NULL)
8466 continue;
8467
97c0a079
AM
8468 offset = tp->info.offset;
8469 if (tp->info.section)
8470 {
8471 if (tp->info.section >= filedata->file_header.e_shnum)
8472 {
8473 warn (_("Invalid section %u in table entry %ld\n"),
8474 tp->info.section, (long) (tp - aux->table));
015dc7e1 8475 res = false;
97c0a079
AM
8476 continue;
8477 }
8478 offset += filedata->section_headers[tp->info.section].sh_addr;
8479 }
8480 offset -= aux->info_addr;
53774b7e 8481 /* PR 17531: file: 0997b4d1. */
90679903
AM
8482 if (offset >= aux->info_size
8483 || aux->info_size - offset < 8)
53774b7e
NC
8484 {
8485 warn (_("Invalid offset %lx in table entry %ld\n"),
8486 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8487 res = false;
53774b7e
NC
8488 continue;
8489 }
8490
97c0a079 8491 head = aux->info + offset;
a4a00738 8492 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8493
86f55779 8494 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8495 (unsigned) UNW_VER (stamp),
8496 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8497 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8498 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8499 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8500
8501 if (UNW_VER (stamp) != 1)
8502 {
2b692964 8503 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8504 continue;
8505 }
8506
8507 in_body = 0;
53774b7e
NC
8508 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8509 /* PR 17531: file: 16ceda89. */
8510 if (end > aux->info + aux->info_size)
8511 end = aux->info + aux->info_size;
8512 for (dp = head + 8; dp < end;)
b4477bc8 8513 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8514 }
948f632f
DA
8515
8516 free (aux->funtab);
32ec8896
NC
8517
8518 return res;
4d6ed7c8
NC
8519}
8520
015dc7e1 8521static bool
dda8d76d
NC
8522slurp_ia64_unwind_table (Filedata * filedata,
8523 struct ia64_unw_aux_info * aux,
8524 Elf_Internal_Shdr * sec)
4d6ed7c8 8525{
89fac5e3 8526 unsigned long size, nrelas, i;
2cf0635d
NC
8527 Elf_Internal_Phdr * seg;
8528 struct ia64_unw_table_entry * tep;
8529 Elf_Internal_Shdr * relsec;
8530 Elf_Internal_Rela * rela;
8531 Elf_Internal_Rela * rp;
8532 unsigned char * table;
8533 unsigned char * tp;
8534 Elf_Internal_Sym * sym;
8535 const char * relname;
4d6ed7c8 8536
53774b7e
NC
8537 aux->table_len = 0;
8538
4d6ed7c8
NC
8539 /* First, find the starting address of the segment that includes
8540 this section: */
8541
dda8d76d 8542 if (filedata->file_header.e_phnum)
4d6ed7c8 8543 {
dda8d76d 8544 if (! get_program_headers (filedata))
015dc7e1 8545 return false;
4d6ed7c8 8546
dda8d76d
NC
8547 for (seg = filedata->program_headers;
8548 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8549 ++seg)
4d6ed7c8
NC
8550 {
8551 if (seg->p_type != PT_LOAD)
8552 continue;
8553
8554 if (sec->sh_addr >= seg->p_vaddr
8555 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8556 {
8557 aux->seg_base = seg->p_vaddr;
8558 break;
8559 }
8560 }
4d6ed7c8
NC
8561 }
8562
8563 /* Second, build the unwind table from the contents of the unwind section: */
8564 size = sec->sh_size;
dda8d76d 8565 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8566 _("unwind table"));
a6e9f9df 8567 if (!table)
015dc7e1 8568 return false;
4d6ed7c8 8569
53774b7e 8570 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8571 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8572 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8573 tep = aux->table;
53774b7e
NC
8574
8575 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8576 {
8577 tep->start.section = SHN_UNDEF;
8578 tep->end.section = SHN_UNDEF;
8579 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8580 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8581 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8582 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8583 tep->start.offset += aux->seg_base;
8584 tep->end.offset += aux->seg_base;
8585 tep->info.offset += aux->seg_base;
8586 }
8587 free (table);
8588
41e92641 8589 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8590 for (relsec = filedata->section_headers;
8591 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8592 ++relsec)
8593 {
8594 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8595 || relsec->sh_info >= filedata->file_header.e_shnum
8596 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8597 continue;
8598
dda8d76d 8599 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8600 & rela, & nrelas))
53774b7e
NC
8601 {
8602 free (aux->table);
8603 aux->table = NULL;
8604 aux->table_len = 0;
015dc7e1 8605 return false;
53774b7e 8606 }
4d6ed7c8
NC
8607
8608 for (rp = rela; rp < rela + nrelas; ++rp)
8609 {
4770fb94 8610 unsigned int sym_ndx;
726bd37d
AM
8611 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8612 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8613
82b1b41b
NC
8614 /* PR 17531: file: 9fa67536. */
8615 if (relname == NULL)
8616 {
726bd37d 8617 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8618 continue;
8619 }
948f632f 8620
24d127aa 8621 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8622 {
82b1b41b 8623 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8624 continue;
8625 }
8626
89fac5e3 8627 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8628
53774b7e
NC
8629 /* PR 17531: file: 5bc8d9bf. */
8630 if (i >= aux->table_len)
8631 {
8632 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8633 continue;
8634 }
8635
4770fb94
AM
8636 sym_ndx = get_reloc_symindex (rp->r_info);
8637 if (sym_ndx >= aux->nsyms)
8638 {
8639 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8640 sym_ndx);
8641 continue;
8642 }
8643 sym = aux->symtab + sym_ndx;
8644
53774b7e 8645 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8646 {
8647 case 0:
8648 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8649 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8650 break;
8651 case 1:
8652 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8653 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8654 break;
8655 case 2:
8656 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8657 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8658 break;
8659 default:
8660 break;
8661 }
8662 }
8663
8664 free (rela);
8665 }
8666
015dc7e1 8667 return true;
4d6ed7c8
NC
8668}
8669
015dc7e1 8670static bool
dda8d76d 8671ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8672{
2cf0635d
NC
8673 Elf_Internal_Shdr * sec;
8674 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8675 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8676 struct ia64_unw_aux_info aux;
015dc7e1 8677 bool res = true;
f1467e33 8678
4d6ed7c8
NC
8679 memset (& aux, 0, sizeof (aux));
8680
dda8d76d 8681 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8682 {
28d13567 8683 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8684 {
28d13567 8685 if (aux.symtab)
4082ef84 8686 {
28d13567
AM
8687 error (_("Multiple symbol tables encountered\n"));
8688 free (aux.symtab);
8689 aux.symtab = NULL;
4082ef84 8690 free (aux.strtab);
28d13567 8691 aux.strtab = NULL;
4082ef84 8692 }
28d13567
AM
8693 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8694 &aux.strtab, &aux.strtab_size))
015dc7e1 8695 return false;
4d6ed7c8
NC
8696 }
8697 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8698 unwcount++;
8699 }
8700
8701 if (!unwcount)
8702 printf (_("\nThere are no unwind sections in this file.\n"));
8703
8704 while (unwcount-- > 0)
8705 {
84714f86 8706 const char *suffix;
579f31ac
JJ
8707 size_t len, len2;
8708
dda8d76d
NC
8709 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8710 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8711 if (sec->sh_type == SHT_IA_64_UNWIND)
8712 {
8713 unwsec = sec;
8714 break;
8715 }
4082ef84
NC
8716 /* We have already counted the number of SHT_IA64_UNWIND
8717 sections so the loop above should never fail. */
8718 assert (unwsec != NULL);
579f31ac
JJ
8719
8720 unwstart = i + 1;
8721 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8722
e4b17d5c
L
8723 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8724 {
8725 /* We need to find which section group it is in. */
4082ef84 8726 struct group_list * g;
e4b17d5c 8727
978c4450
AM
8728 if (filedata->section_headers_groups == NULL
8729 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8730 i = filedata->file_header.e_shnum;
4082ef84 8731 else
e4b17d5c 8732 {
978c4450 8733 g = filedata->section_headers_groups[i]->root;
18bd398b 8734
4082ef84
NC
8735 for (; g != NULL; g = g->next)
8736 {
dda8d76d 8737 sec = filedata->section_headers + g->section_index;
e4b17d5c 8738
84714f86
AM
8739 if (section_name_valid (filedata, sec)
8740 && streq (section_name (filedata, sec),
8741 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8742 break;
8743 }
8744
8745 if (g == NULL)
dda8d76d 8746 i = filedata->file_header.e_shnum;
4082ef84 8747 }
e4b17d5c 8748 }
84714f86
AM
8749 else if (section_name_valid (filedata, unwsec)
8750 && startswith (section_name (filedata, unwsec),
e9b095a5 8751 ELF_STRING_ia64_unwind_once))
579f31ac 8752 {
18bd398b 8753 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8754 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8755 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8756 for (i = 0, sec = filedata->section_headers;
8757 i < filedata->file_header.e_shnum;
579f31ac 8758 ++i, ++sec)
84714f86
AM
8759 if (section_name_valid (filedata, sec)
8760 && startswith (section_name (filedata, sec),
e9b095a5 8761 ELF_STRING_ia64_unwind_info_once)
84714f86 8762 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8763 break;
8764 }
8765 else
8766 {
8767 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8768 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8769 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8770 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8771 suffix = "";
84714f86
AM
8772 if (section_name_valid (filedata, unwsec)
8773 && startswith (section_name (filedata, unwsec),
8774 ELF_STRING_ia64_unwind))
8775 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8776 for (i = 0, sec = filedata->section_headers;
8777 i < filedata->file_header.e_shnum;
579f31ac 8778 ++i, ++sec)
84714f86
AM
8779 if (section_name_valid (filedata, sec)
8780 && startswith (section_name (filedata, sec),
8781 ELF_STRING_ia64_unwind_info)
8782 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8783 break;
8784 }
8785
dda8d76d 8786 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8787 {
8788 printf (_("\nCould not find unwind info section for "));
8789
dda8d76d 8790 if (filedata->string_table == NULL)
579f31ac
JJ
8791 printf ("%d", unwsec->sh_name);
8792 else
dda8d76d 8793 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8794 }
8795 else
4d6ed7c8 8796 {
4d6ed7c8 8797 aux.info_addr = sec->sh_addr;
dda8d76d 8798 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8799 sec->sh_size,
8800 _("unwind info"));
59245841 8801 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8802
579f31ac 8803 printf (_("\nUnwind section "));
4d6ed7c8 8804
dda8d76d 8805 if (filedata->string_table == NULL)
579f31ac
JJ
8806 printf ("%d", unwsec->sh_name);
8807 else
dda8d76d 8808 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8809
579f31ac 8810 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8811 (unsigned long) unwsec->sh_offset,
89fac5e3 8812 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8813
dda8d76d 8814 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8815 && aux.table_len > 0)
dda8d76d 8816 dump_ia64_unwind (filedata, & aux);
579f31ac 8817
9db70fc3
AM
8818 free ((char *) aux.table);
8819 free ((char *) aux.info);
579f31ac
JJ
8820 aux.table = NULL;
8821 aux.info = NULL;
8822 }
4d6ed7c8 8823 }
4d6ed7c8 8824
9db70fc3
AM
8825 free (aux.symtab);
8826 free ((char *) aux.strtab);
32ec8896
NC
8827
8828 return res;
4d6ed7c8
NC
8829}
8830
3f5e193b 8831struct hppa_unw_table_entry
32ec8896
NC
8832{
8833 struct absaddr start;
8834 struct absaddr end;
8835 unsigned int Cannot_unwind:1; /* 0 */
8836 unsigned int Millicode:1; /* 1 */
8837 unsigned int Millicode_save_sr0:1; /* 2 */
8838 unsigned int Region_description:2; /* 3..4 */
8839 unsigned int reserved1:1; /* 5 */
8840 unsigned int Entry_SR:1; /* 6 */
8841 unsigned int Entry_FR:4; /* Number saved 7..10 */
8842 unsigned int Entry_GR:5; /* Number saved 11..15 */
8843 unsigned int Args_stored:1; /* 16 */
8844 unsigned int Variable_Frame:1; /* 17 */
8845 unsigned int Separate_Package_Body:1; /* 18 */
8846 unsigned int Frame_Extension_Millicode:1; /* 19 */
8847 unsigned int Stack_Overflow_Check:1; /* 20 */
8848 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8849 unsigned int Ada_Region:1; /* 22 */
8850 unsigned int cxx_info:1; /* 23 */
8851 unsigned int cxx_try_catch:1; /* 24 */
8852 unsigned int sched_entry_seq:1; /* 25 */
8853 unsigned int reserved2:1; /* 26 */
8854 unsigned int Save_SP:1; /* 27 */
8855 unsigned int Save_RP:1; /* 28 */
8856 unsigned int Save_MRP_in_frame:1; /* 29 */
8857 unsigned int extn_ptr_defined:1; /* 30 */
8858 unsigned int Cleanup_defined:1; /* 31 */
8859
8860 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8861 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8862 unsigned int Large_frame:1; /* 2 */
8863 unsigned int Pseudo_SP_Set:1; /* 3 */
8864 unsigned int reserved4:1; /* 4 */
8865 unsigned int Total_frame_size:27; /* 5..31 */
8866};
3f5e193b 8867
57346661 8868struct hppa_unw_aux_info
948f632f 8869{
32ec8896
NC
8870 struct hppa_unw_table_entry * table; /* Unwind table. */
8871 unsigned long table_len; /* Length of unwind table. */
8872 bfd_vma seg_base; /* Starting address of segment. */
8873 Elf_Internal_Sym * symtab; /* The symbol table. */
8874 unsigned long nsyms; /* Number of symbols. */
8875 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8876 unsigned long nfuns; /* Number of entries in funtab. */
8877 char * strtab; /* The string table. */
8878 unsigned long strtab_size; /* Size of string table. */
948f632f 8879};
57346661 8880
015dc7e1 8881static bool
dda8d76d 8882dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8883{
2cf0635d 8884 struct hppa_unw_table_entry * tp;
948f632f 8885 unsigned long j, nfuns;
015dc7e1 8886 bool res = true;
948f632f
DA
8887
8888 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8889 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8890 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8891 aux->funtab[nfuns++] = aux->symtab[j];
8892 aux->nfuns = nfuns;
8893 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8894
57346661
AM
8895 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8896 {
8897 bfd_vma offset;
2cf0635d 8898 const char * procname;
57346661 8899
dda8d76d 8900 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8901 aux->strtab_size, tp->start, &procname,
8902 &offset);
8903
8904 fputs ("\n<", stdout);
8905
8906 if (procname)
8907 {
8908 fputs (procname, stdout);
8909
8910 if (offset)
8911 printf ("+%lx", (unsigned long) offset);
8912 }
8913
8914 fputs (">: [", stdout);
8915 print_vma (tp->start.offset, PREFIX_HEX);
8916 fputc ('-', stdout);
8917 print_vma (tp->end.offset, PREFIX_HEX);
8918 printf ("]\n\t");
8919
18bd398b
NC
8920#define PF(_m) if (tp->_m) printf (#_m " ");
8921#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8922 PF(Cannot_unwind);
8923 PF(Millicode);
8924 PF(Millicode_save_sr0);
18bd398b 8925 /* PV(Region_description); */
57346661
AM
8926 PF(Entry_SR);
8927 PV(Entry_FR);
8928 PV(Entry_GR);
8929 PF(Args_stored);
8930 PF(Variable_Frame);
8931 PF(Separate_Package_Body);
8932 PF(Frame_Extension_Millicode);
8933 PF(Stack_Overflow_Check);
8934 PF(Two_Instruction_SP_Increment);
8935 PF(Ada_Region);
8936 PF(cxx_info);
8937 PF(cxx_try_catch);
8938 PF(sched_entry_seq);
8939 PF(Save_SP);
8940 PF(Save_RP);
8941 PF(Save_MRP_in_frame);
8942 PF(extn_ptr_defined);
8943 PF(Cleanup_defined);
8944 PF(MPE_XL_interrupt_marker);
8945 PF(HP_UX_interrupt_marker);
8946 PF(Large_frame);
8947 PF(Pseudo_SP_Set);
8948 PV(Total_frame_size);
8949#undef PF
8950#undef PV
8951 }
8952
18bd398b 8953 printf ("\n");
948f632f
DA
8954
8955 free (aux->funtab);
32ec8896
NC
8956
8957 return res;
57346661
AM
8958}
8959
015dc7e1 8960static bool
dda8d76d
NC
8961slurp_hppa_unwind_table (Filedata * filedata,
8962 struct hppa_unw_aux_info * aux,
8963 Elf_Internal_Shdr * sec)
57346661 8964{
1c0751b2 8965 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8966 Elf_Internal_Phdr * seg;
8967 struct hppa_unw_table_entry * tep;
8968 Elf_Internal_Shdr * relsec;
8969 Elf_Internal_Rela * rela;
8970 Elf_Internal_Rela * rp;
8971 unsigned char * table;
8972 unsigned char * tp;
8973 Elf_Internal_Sym * sym;
8974 const char * relname;
57346661 8975
57346661
AM
8976 /* First, find the starting address of the segment that includes
8977 this section. */
dda8d76d 8978 if (filedata->file_header.e_phnum)
57346661 8979 {
dda8d76d 8980 if (! get_program_headers (filedata))
015dc7e1 8981 return false;
57346661 8982
dda8d76d
NC
8983 for (seg = filedata->program_headers;
8984 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8985 ++seg)
8986 {
8987 if (seg->p_type != PT_LOAD)
8988 continue;
8989
8990 if (sec->sh_addr >= seg->p_vaddr
8991 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8992 {
8993 aux->seg_base = seg->p_vaddr;
8994 break;
8995 }
8996 }
8997 }
8998
8999 /* Second, build the unwind table from the contents of the unwind
9000 section. */
9001 size = sec->sh_size;
dda8d76d 9002 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9003 _("unwind table"));
57346661 9004 if (!table)
015dc7e1 9005 return false;
57346661 9006
1c0751b2
DA
9007 unw_ent_size = 16;
9008 nentries = size / unw_ent_size;
9009 size = unw_ent_size * nentries;
57346661 9010
e3fdc001 9011 aux->table_len = nentries;
3f5e193b
NC
9012 tep = aux->table = (struct hppa_unw_table_entry *)
9013 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9014
1c0751b2 9015 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9016 {
9017 unsigned int tmp1, tmp2;
9018
9019 tep->start.section = SHN_UNDEF;
9020 tep->end.section = SHN_UNDEF;
9021
1c0751b2
DA
9022 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9023 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9024 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9025 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9026
9027 tep->start.offset += aux->seg_base;
9028 tep->end.offset += aux->seg_base;
57346661
AM
9029
9030 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9031 tep->Millicode = (tmp1 >> 30) & 0x1;
9032 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9033 tep->Region_description = (tmp1 >> 27) & 0x3;
9034 tep->reserved1 = (tmp1 >> 26) & 0x1;
9035 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9036 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9037 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9038 tep->Args_stored = (tmp1 >> 15) & 0x1;
9039 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9040 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9041 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9042 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9043 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9044 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9045 tep->cxx_info = (tmp1 >> 8) & 0x1;
9046 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9047 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9048 tep->reserved2 = (tmp1 >> 5) & 0x1;
9049 tep->Save_SP = (tmp1 >> 4) & 0x1;
9050 tep->Save_RP = (tmp1 >> 3) & 0x1;
9051 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9052 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9053 tep->Cleanup_defined = tmp1 & 0x1;
9054
9055 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9056 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9057 tep->Large_frame = (tmp2 >> 29) & 0x1;
9058 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9059 tep->reserved4 = (tmp2 >> 27) & 0x1;
9060 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9061 }
9062 free (table);
9063
9064 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9065 for (relsec = filedata->section_headers;
9066 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9067 ++relsec)
9068 {
9069 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9070 || relsec->sh_info >= filedata->file_header.e_shnum
9071 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9072 continue;
9073
dda8d76d 9074 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9075 & rela, & nrelas))
015dc7e1 9076 return false;
57346661
AM
9077
9078 for (rp = rela; rp < rela + nrelas; ++rp)
9079 {
4770fb94 9080 unsigned int sym_ndx;
726bd37d
AM
9081 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9082 relname = elf_hppa_reloc_type (r_type);
57346661 9083
726bd37d
AM
9084 if (relname == NULL)
9085 {
9086 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9087 continue;
9088 }
9089
57346661 9090 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9091 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9092 {
726bd37d 9093 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9094 continue;
9095 }
9096
9097 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9098 if (i >= aux->table_len)
9099 {
9100 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9101 continue;
9102 }
57346661 9103
4770fb94
AM
9104 sym_ndx = get_reloc_symindex (rp->r_info);
9105 if (sym_ndx >= aux->nsyms)
9106 {
9107 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9108 sym_ndx);
9109 continue;
9110 }
9111 sym = aux->symtab + sym_ndx;
9112
43f6cd05 9113 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9114 {
9115 case 0:
9116 aux->table[i].start.section = sym->st_shndx;
1e456d54 9117 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9118 break;
9119 case 1:
9120 aux->table[i].end.section = sym->st_shndx;
1e456d54 9121 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9122 break;
9123 default:
9124 break;
9125 }
9126 }
9127
9128 free (rela);
9129 }
9130
015dc7e1 9131 return true;
57346661
AM
9132}
9133
015dc7e1 9134static bool
dda8d76d 9135hppa_process_unwind (Filedata * filedata)
57346661 9136{
57346661 9137 struct hppa_unw_aux_info aux;
2cf0635d 9138 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9139 Elf_Internal_Shdr * sec;
18bd398b 9140 unsigned long i;
015dc7e1 9141 bool res = true;
57346661 9142
dda8d76d 9143 if (filedata->string_table == NULL)
015dc7e1 9144 return false;
1b31d05e
NC
9145
9146 memset (& aux, 0, sizeof (aux));
57346661 9147
dda8d76d 9148 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9149 {
28d13567 9150 if (sec->sh_type == SHT_SYMTAB)
57346661 9151 {
28d13567 9152 if (aux.symtab)
4082ef84 9153 {
28d13567
AM
9154 error (_("Multiple symbol tables encountered\n"));
9155 free (aux.symtab);
9156 aux.symtab = NULL;
4082ef84 9157 free (aux.strtab);
28d13567 9158 aux.strtab = NULL;
4082ef84 9159 }
28d13567
AM
9160 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9161 &aux.strtab, &aux.strtab_size))
015dc7e1 9162 return false;
57346661 9163 }
84714f86
AM
9164 else if (section_name_valid (filedata, sec)
9165 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9166 unwsec = sec;
9167 }
9168
9169 if (!unwsec)
9170 printf (_("\nThere are no unwind sections in this file.\n"));
9171
dda8d76d 9172 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9173 {
84714f86
AM
9174 if (section_name_valid (filedata, sec)
9175 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9176 {
43f6cd05 9177 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9178
d3a49aa8
AM
9179 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9180 "contains %lu entry:\n",
9181 "\nUnwind section '%s' at offset 0x%lx "
9182 "contains %lu entries:\n",
9183 num_unwind),
dda8d76d 9184 printable_section_name (filedata, sec),
57346661 9185 (unsigned long) sec->sh_offset,
d3a49aa8 9186 num_unwind);
57346661 9187
dda8d76d 9188 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9189 res = false;
66b09c7e
S
9190
9191 if (res && aux.table_len > 0)
32ec8896 9192 {
dda8d76d 9193 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9194 res = false;
32ec8896 9195 }
57346661 9196
9db70fc3 9197 free ((char *) aux.table);
57346661
AM
9198 aux.table = NULL;
9199 }
9200 }
9201
9db70fc3
AM
9202 free (aux.symtab);
9203 free ((char *) aux.strtab);
32ec8896
NC
9204
9205 return res;
57346661
AM
9206}
9207
0b6ae522
DJ
9208struct arm_section
9209{
a734115a
NC
9210 unsigned char * data; /* The unwind data. */
9211 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9212 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9213 unsigned long nrelas; /* The number of relocations. */
9214 unsigned int rel_type; /* REL or RELA ? */
9215 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9216};
9217
9218struct arm_unw_aux_info
9219{
dda8d76d 9220 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9221 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9222 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9223 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9224 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9225 char * strtab; /* The file's string table. */
9226 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9227};
9228
9229static const char *
dda8d76d
NC
9230arm_print_vma_and_name (Filedata * filedata,
9231 struct arm_unw_aux_info * aux,
9232 bfd_vma fn,
9233 struct absaddr addr)
0b6ae522
DJ
9234{
9235 const char *procname;
9236 bfd_vma sym_offset;
9237
9238 if (addr.section == SHN_UNDEF)
9239 addr.offset = fn;
9240
dda8d76d 9241 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9242 aux->strtab_size, addr, &procname,
9243 &sym_offset);
9244
9245 print_vma (fn, PREFIX_HEX);
9246
9247 if (procname)
9248 {
9249 fputs (" <", stdout);
9250 fputs (procname, stdout);
9251
9252 if (sym_offset)
9253 printf ("+0x%lx", (unsigned long) sym_offset);
9254 fputc ('>', stdout);
9255 }
9256
9257 return procname;
9258}
9259
9260static void
9261arm_free_section (struct arm_section *arm_sec)
9262{
9db70fc3
AM
9263 free (arm_sec->data);
9264 free (arm_sec->rela);
0b6ae522
DJ
9265}
9266
a734115a
NC
9267/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9268 cached section and install SEC instead.
9269 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9270 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9271 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9272 relocation's offset in ADDR.
1b31d05e
NC
9273 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9274 into the string table of the symbol associated with the reloc. If no
9275 reloc was applied store -1 there.
9276 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9277
015dc7e1 9278static bool
dda8d76d
NC
9279get_unwind_section_word (Filedata * filedata,
9280 struct arm_unw_aux_info * aux,
1b31d05e
NC
9281 struct arm_section * arm_sec,
9282 Elf_Internal_Shdr * sec,
9283 bfd_vma word_offset,
9284 unsigned int * wordp,
9285 struct absaddr * addr,
9286 bfd_vma * sym_name)
0b6ae522
DJ
9287{
9288 Elf_Internal_Rela *rp;
9289 Elf_Internal_Sym *sym;
9290 const char * relname;
9291 unsigned int word;
015dc7e1 9292 bool wrapped;
0b6ae522 9293
e0a31db1 9294 if (sec == NULL || arm_sec == NULL)
015dc7e1 9295 return false;
e0a31db1 9296
0b6ae522
DJ
9297 addr->section = SHN_UNDEF;
9298 addr->offset = 0;
9299
1b31d05e
NC
9300 if (sym_name != NULL)
9301 *sym_name = (bfd_vma) -1;
9302
a734115a 9303 /* If necessary, update the section cache. */
0b6ae522
DJ
9304 if (sec != arm_sec->sec)
9305 {
9306 Elf_Internal_Shdr *relsec;
9307
9308 arm_free_section (arm_sec);
9309
9310 arm_sec->sec = sec;
dda8d76d 9311 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9312 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9313 arm_sec->rela = NULL;
9314 arm_sec->nrelas = 0;
9315
dda8d76d
NC
9316 for (relsec = filedata->section_headers;
9317 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9318 ++relsec)
9319 {
dda8d76d
NC
9320 if (relsec->sh_info >= filedata->file_header.e_shnum
9321 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9322 /* PR 15745: Check the section type as well. */
9323 || (relsec->sh_type != SHT_REL
9324 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9325 continue;
9326
a734115a 9327 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9328 if (relsec->sh_type == SHT_REL)
9329 {
dda8d76d 9330 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9331 relsec->sh_size,
9332 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9333 return false;
0b6ae522 9334 }
1ae40aa4 9335 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9336 {
dda8d76d 9337 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9338 relsec->sh_size,
9339 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9340 return false;
0b6ae522 9341 }
1ae40aa4 9342 break;
0b6ae522
DJ
9343 }
9344
9345 arm_sec->next_rela = arm_sec->rela;
9346 }
9347
a734115a 9348 /* If there is no unwind data we can do nothing. */
0b6ae522 9349 if (arm_sec->data == NULL)
015dc7e1 9350 return false;
0b6ae522 9351
e0a31db1 9352 /* If the offset is invalid then fail. */
f32ba729
NC
9353 if (/* PR 21343 *//* PR 18879 */
9354 sec->sh_size < 4
9355 || word_offset > (sec->sh_size - 4)
1a915552 9356 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9357 return false;
e0a31db1 9358
a734115a 9359 /* Get the word at the required offset. */
0b6ae522
DJ
9360 word = byte_get (arm_sec->data + word_offset, 4);
9361
0eff7165
NC
9362 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9363 if (arm_sec->rela == NULL)
9364 {
9365 * wordp = word;
015dc7e1 9366 return true;
0eff7165
NC
9367 }
9368
a734115a 9369 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9370 wrapped = false;
0b6ae522
DJ
9371 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9372 {
9373 bfd_vma prelval, offset;
9374
9375 if (rp->r_offset > word_offset && !wrapped)
9376 {
9377 rp = arm_sec->rela;
015dc7e1 9378 wrapped = true;
0b6ae522
DJ
9379 }
9380 if (rp->r_offset > word_offset)
9381 break;
9382
9383 if (rp->r_offset & 3)
9384 {
9385 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9386 (unsigned long) rp->r_offset);
9387 continue;
9388 }
9389
9390 if (rp->r_offset < word_offset)
9391 continue;
9392
74e1a04b
NC
9393 /* PR 17531: file: 027-161405-0.004 */
9394 if (aux->symtab == NULL)
9395 continue;
9396
0b6ae522
DJ
9397 if (arm_sec->rel_type == SHT_REL)
9398 {
9399 offset = word & 0x7fffffff;
9400 if (offset & 0x40000000)
9401 offset |= ~ (bfd_vma) 0x7fffffff;
9402 }
a734115a 9403 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9404 offset = rp->r_addend;
a734115a 9405 else
74e1a04b
NC
9406 {
9407 error (_("Unknown section relocation type %d encountered\n"),
9408 arm_sec->rel_type);
9409 break;
9410 }
0b6ae522 9411
071436c6
NC
9412 /* PR 17531 file: 027-1241568-0.004. */
9413 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9414 {
9415 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9416 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9417 break;
9418 }
9419
9420 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9421 offset += sym->st_value;
9422 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9423
a734115a 9424 /* Check that we are processing the expected reloc type. */
dda8d76d 9425 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9426 {
9427 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9428 if (relname == NULL)
9429 {
9430 warn (_("Skipping unknown ARM relocation type: %d\n"),
9431 (int) ELF32_R_TYPE (rp->r_info));
9432 continue;
9433 }
a734115a
NC
9434
9435 if (streq (relname, "R_ARM_NONE"))
9436 continue;
0b4362b0 9437
a734115a
NC
9438 if (! streq (relname, "R_ARM_PREL31"))
9439 {
071436c6 9440 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9441 continue;
9442 }
9443 }
dda8d76d 9444 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9445 {
9446 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9447 if (relname == NULL)
9448 {
9449 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9450 (int) ELF32_R_TYPE (rp->r_info));
9451 continue;
9452 }
0b4362b0 9453
a734115a
NC
9454 if (streq (relname, "R_C6000_NONE"))
9455 continue;
9456
9457 if (! streq (relname, "R_C6000_PREL31"))
9458 {
071436c6 9459 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9460 continue;
9461 }
9462
9463 prelval >>= 1;
9464 }
9465 else
74e1a04b
NC
9466 {
9467 /* This function currently only supports ARM and TI unwinders. */
9468 warn (_("Only TI and ARM unwinders are currently supported\n"));
9469 break;
9470 }
fa197c1c 9471
0b6ae522
DJ
9472 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9473 addr->section = sym->st_shndx;
9474 addr->offset = offset;
74e1a04b 9475
1b31d05e
NC
9476 if (sym_name)
9477 * sym_name = sym->st_name;
0b6ae522
DJ
9478 break;
9479 }
9480
9481 *wordp = word;
9482 arm_sec->next_rela = rp;
9483
015dc7e1 9484 return true;
0b6ae522
DJ
9485}
9486
a734115a
NC
9487static const char *tic6x_unwind_regnames[16] =
9488{
0b4362b0
RM
9489 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9490 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9491 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9492};
fa197c1c 9493
0b6ae522 9494static void
fa197c1c 9495decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9496{
fa197c1c
PB
9497 int i;
9498
9499 for (i = 12; mask; mask >>= 1, i--)
9500 {
9501 if (mask & 1)
9502 {
9503 fputs (tic6x_unwind_regnames[i], stdout);
9504 if (mask > 1)
9505 fputs (", ", stdout);
9506 }
9507 }
9508}
0b6ae522
DJ
9509
9510#define ADVANCE \
9511 if (remaining == 0 && more_words) \
9512 { \
9513 data_offset += 4; \
dda8d76d 9514 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9515 data_offset, & word, & addr, NULL)) \
015dc7e1 9516 return false; \
0b6ae522
DJ
9517 remaining = 4; \
9518 more_words--; \
9519 } \
9520
9521#define GET_OP(OP) \
9522 ADVANCE; \
9523 if (remaining) \
9524 { \
9525 remaining--; \
9526 (OP) = word >> 24; \
9527 word <<= 8; \
9528 } \
9529 else \
9530 { \
2b692964 9531 printf (_("[Truncated opcode]\n")); \
015dc7e1 9532 return false; \
0b6ae522 9533 } \
cc5914eb 9534 printf ("0x%02x ", OP)
0b6ae522 9535
015dc7e1 9536static bool
dda8d76d
NC
9537decode_arm_unwind_bytecode (Filedata * filedata,
9538 struct arm_unw_aux_info * aux,
948f632f
DA
9539 unsigned int word,
9540 unsigned int remaining,
9541 unsigned int more_words,
9542 bfd_vma data_offset,
9543 Elf_Internal_Shdr * data_sec,
9544 struct arm_section * data_arm_sec)
fa197c1c
PB
9545{
9546 struct absaddr addr;
015dc7e1 9547 bool res = true;
0b6ae522
DJ
9548
9549 /* Decode the unwinding instructions. */
9550 while (1)
9551 {
9552 unsigned int op, op2;
9553
9554 ADVANCE;
9555 if (remaining == 0)
9556 break;
9557 remaining--;
9558 op = word >> 24;
9559 word <<= 8;
9560
cc5914eb 9561 printf (" 0x%02x ", op);
0b6ae522
DJ
9562
9563 if ((op & 0xc0) == 0x00)
9564 {
9565 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9566
cc5914eb 9567 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9568 }
9569 else if ((op & 0xc0) == 0x40)
9570 {
9571 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9572
cc5914eb 9573 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9574 }
9575 else if ((op & 0xf0) == 0x80)
9576 {
9577 GET_OP (op2);
9578 if (op == 0x80 && op2 == 0)
9579 printf (_("Refuse to unwind"));
9580 else
9581 {
9582 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9583 bool first = true;
0b6ae522 9584 int i;
2b692964 9585
0b6ae522
DJ
9586 printf ("pop {");
9587 for (i = 0; i < 12; i++)
9588 if (mask & (1 << i))
9589 {
9590 if (first)
015dc7e1 9591 first = false;
0b6ae522
DJ
9592 else
9593 printf (", ");
9594 printf ("r%d", 4 + i);
9595 }
9596 printf ("}");
9597 }
9598 }
9599 else if ((op & 0xf0) == 0x90)
9600 {
9601 if (op == 0x9d || op == 0x9f)
9602 printf (_(" [Reserved]"));
9603 else
cc5914eb 9604 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9605 }
9606 else if ((op & 0xf0) == 0xa0)
9607 {
9608 int end = 4 + (op & 0x07);
015dc7e1 9609 bool first = true;
0b6ae522 9610 int i;
61865e30 9611
0b6ae522
DJ
9612 printf (" pop {");
9613 for (i = 4; i <= end; i++)
9614 {
9615 if (first)
015dc7e1 9616 first = false;
0b6ae522
DJ
9617 else
9618 printf (", ");
9619 printf ("r%d", i);
9620 }
9621 if (op & 0x08)
9622 {
1b31d05e 9623 if (!first)
0b6ae522
DJ
9624 printf (", ");
9625 printf ("r14");
9626 }
9627 printf ("}");
9628 }
9629 else if (op == 0xb0)
9630 printf (_(" finish"));
9631 else if (op == 0xb1)
9632 {
9633 GET_OP (op2);
9634 if (op2 == 0 || (op2 & 0xf0) != 0)
9635 printf (_("[Spare]"));
9636 else
9637 {
9638 unsigned int mask = op2 & 0x0f;
015dc7e1 9639 bool first = true;
0b6ae522 9640 int i;
61865e30 9641
0b6ae522
DJ
9642 printf ("pop {");
9643 for (i = 0; i < 12; i++)
9644 if (mask & (1 << i))
9645 {
9646 if (first)
015dc7e1 9647 first = false;
0b6ae522
DJ
9648 else
9649 printf (", ");
9650 printf ("r%d", i);
9651 }
9652 printf ("}");
9653 }
9654 }
9655 else if (op == 0xb2)
9656 {
b115cf96 9657 unsigned char buf[9];
0b6ae522
DJ
9658 unsigned int i, len;
9659 unsigned long offset;
61865e30 9660
b115cf96 9661 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9662 {
9663 GET_OP (buf[i]);
9664 if ((buf[i] & 0x80) == 0)
9665 break;
9666 }
4082ef84 9667 if (i == sizeof (buf))
32ec8896 9668 {
27a45f42 9669 error (_("corrupt change to vsp\n"));
015dc7e1 9670 res = false;
32ec8896 9671 }
4082ef84
NC
9672 else
9673 {
015dc7e1 9674 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9675 assert (len == i + 1);
9676 offset = offset * 4 + 0x204;
9677 printf ("vsp = vsp + %ld", offset);
9678 }
0b6ae522 9679 }
61865e30 9680 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9681 {
61865e30
NC
9682 unsigned int first, last;
9683
9684 GET_OP (op2);
9685 first = op2 >> 4;
9686 last = op2 & 0x0f;
9687 if (op == 0xc8)
9688 first = first + 16;
9689 printf ("pop {D%d", first);
9690 if (last)
9691 printf ("-D%d", first + last);
9692 printf ("}");
9693 }
09854a88
TB
9694 else if (op == 0xb4)
9695 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9696 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9697 {
9698 unsigned int count = op & 0x07;
9699
9700 printf ("pop {D8");
9701 if (count)
9702 printf ("-D%d", 8 + count);
9703 printf ("}");
9704 }
9705 else if (op >= 0xc0 && op <= 0xc5)
9706 {
9707 unsigned int count = op & 0x07;
9708
9709 printf (" pop {wR10");
9710 if (count)
9711 printf ("-wR%d", 10 + count);
9712 printf ("}");
9713 }
9714 else if (op == 0xc6)
9715 {
9716 unsigned int first, last;
9717
9718 GET_OP (op2);
9719 first = op2 >> 4;
9720 last = op2 & 0x0f;
9721 printf ("pop {wR%d", first);
9722 if (last)
9723 printf ("-wR%d", first + last);
9724 printf ("}");
9725 }
9726 else if (op == 0xc7)
9727 {
9728 GET_OP (op2);
9729 if (op2 == 0 || (op2 & 0xf0) != 0)
9730 printf (_("[Spare]"));
0b6ae522
DJ
9731 else
9732 {
61865e30 9733 unsigned int mask = op2 & 0x0f;
015dc7e1 9734 bool first = true;
61865e30
NC
9735 int i;
9736
9737 printf ("pop {");
9738 for (i = 0; i < 4; i++)
9739 if (mask & (1 << i))
9740 {
9741 if (first)
015dc7e1 9742 first = false;
61865e30
NC
9743 else
9744 printf (", ");
9745 printf ("wCGR%d", i);
9746 }
9747 printf ("}");
0b6ae522
DJ
9748 }
9749 }
61865e30 9750 else
32ec8896
NC
9751 {
9752 printf (_(" [unsupported opcode]"));
015dc7e1 9753 res = false;
32ec8896
NC
9754 }
9755
0b6ae522
DJ
9756 printf ("\n");
9757 }
32ec8896
NC
9758
9759 return res;
fa197c1c
PB
9760}
9761
015dc7e1 9762static bool
dda8d76d
NC
9763decode_tic6x_unwind_bytecode (Filedata * filedata,
9764 struct arm_unw_aux_info * aux,
948f632f
DA
9765 unsigned int word,
9766 unsigned int remaining,
9767 unsigned int more_words,
9768 bfd_vma data_offset,
9769 Elf_Internal_Shdr * data_sec,
9770 struct arm_section * data_arm_sec)
fa197c1c
PB
9771{
9772 struct absaddr addr;
9773
9774 /* Decode the unwinding instructions. */
9775 while (1)
9776 {
9777 unsigned int op, op2;
9778
9779 ADVANCE;
9780 if (remaining == 0)
9781 break;
9782 remaining--;
9783 op = word >> 24;
9784 word <<= 8;
9785
9cf03b7e 9786 printf (" 0x%02x ", op);
fa197c1c
PB
9787
9788 if ((op & 0xc0) == 0x00)
9789 {
9790 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9791 printf (" sp = sp + %d", offset);
fa197c1c
PB
9792 }
9793 else if ((op & 0xc0) == 0x80)
9794 {
9795 GET_OP (op2);
9796 if (op == 0x80 && op2 == 0)
9797 printf (_("Refuse to unwind"));
9798 else
9799 {
9800 unsigned int mask = ((op & 0x1f) << 8) | op2;
9801 if (op & 0x20)
9802 printf ("pop compact {");
9803 else
9804 printf ("pop {");
9805
9806 decode_tic6x_unwind_regmask (mask);
9807 printf("}");
9808 }
9809 }
9810 else if ((op & 0xf0) == 0xc0)
9811 {
9812 unsigned int reg;
9813 unsigned int nregs;
9814 unsigned int i;
9815 const char *name;
a734115a
NC
9816 struct
9817 {
32ec8896
NC
9818 unsigned int offset;
9819 unsigned int reg;
fa197c1c
PB
9820 } regpos[16];
9821
9822 /* Scan entire instruction first so that GET_OP output is not
9823 interleaved with disassembly. */
9824 nregs = 0;
9825 for (i = 0; nregs < (op & 0xf); i++)
9826 {
9827 GET_OP (op2);
9828 reg = op2 >> 4;
9829 if (reg != 0xf)
9830 {
9831 regpos[nregs].offset = i * 2;
9832 regpos[nregs].reg = reg;
9833 nregs++;
9834 }
9835
9836 reg = op2 & 0xf;
9837 if (reg != 0xf)
9838 {
9839 regpos[nregs].offset = i * 2 + 1;
9840 regpos[nregs].reg = reg;
9841 nregs++;
9842 }
9843 }
9844
9845 printf (_("pop frame {"));
18344509 9846 if (nregs == 0)
fa197c1c 9847 {
18344509
NC
9848 printf (_("*corrupt* - no registers specified"));
9849 }
9850 else
9851 {
9852 reg = nregs - 1;
9853 for (i = i * 2; i > 0; i--)
fa197c1c 9854 {
18344509
NC
9855 if (regpos[reg].offset == i - 1)
9856 {
9857 name = tic6x_unwind_regnames[regpos[reg].reg];
9858 if (reg > 0)
9859 reg--;
9860 }
9861 else
9862 name = _("[pad]");
fa197c1c 9863
18344509
NC
9864 fputs (name, stdout);
9865 if (i > 1)
9866 printf (", ");
9867 }
fa197c1c
PB
9868 }
9869
9870 printf ("}");
9871 }
9872 else if (op == 0xd0)
9873 printf (" MOV FP, SP");
9874 else if (op == 0xd1)
9875 printf (" __c6xabi_pop_rts");
9876 else if (op == 0xd2)
9877 {
9878 unsigned char buf[9];
9879 unsigned int i, len;
9880 unsigned long offset;
a734115a 9881
fa197c1c
PB
9882 for (i = 0; i < sizeof (buf); i++)
9883 {
9884 GET_OP (buf[i]);
9885 if ((buf[i] & 0x80) == 0)
9886 break;
9887 }
0eff7165
NC
9888 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9889 if (i == sizeof (buf))
9890 {
0eff7165 9891 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9892 return false;
0eff7165 9893 }
948f632f 9894
015dc7e1 9895 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9896 assert (len == i + 1);
9897 offset = offset * 8 + 0x408;
9898 printf (_("sp = sp + %ld"), offset);
9899 }
9900 else if ((op & 0xf0) == 0xe0)
9901 {
9902 if ((op & 0x0f) == 7)
9903 printf (" RETURN");
9904 else
9905 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9906 }
9907 else
9908 {
9909 printf (_(" [unsupported opcode]"));
9910 }
9911 putchar ('\n');
9912 }
32ec8896 9913
015dc7e1 9914 return true;
fa197c1c
PB
9915}
9916
9917static bfd_vma
dda8d76d 9918arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9919{
9920 bfd_vma offset;
9921
9922 offset = word & 0x7fffffff;
9923 if (offset & 0x40000000)
9924 offset |= ~ (bfd_vma) 0x7fffffff;
9925
dda8d76d 9926 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9927 offset <<= 1;
9928
9929 return offset + where;
9930}
9931
015dc7e1 9932static bool
dda8d76d
NC
9933decode_arm_unwind (Filedata * filedata,
9934 struct arm_unw_aux_info * aux,
1b31d05e
NC
9935 unsigned int word,
9936 unsigned int remaining,
9937 bfd_vma data_offset,
9938 Elf_Internal_Shdr * data_sec,
9939 struct arm_section * data_arm_sec)
fa197c1c
PB
9940{
9941 int per_index;
9942 unsigned int more_words = 0;
37e14bc3 9943 struct absaddr addr;
1b31d05e 9944 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9945 bool res = true;
fa197c1c
PB
9946
9947 if (remaining == 0)
9948 {
1b31d05e
NC
9949 /* Fetch the first word.
9950 Note - when decoding an object file the address extracted
9951 here will always be 0. So we also pass in the sym_name
9952 parameter so that we can find the symbol associated with
9953 the personality routine. */
dda8d76d 9954 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9955 & word, & addr, & sym_name))
015dc7e1 9956 return false;
1b31d05e 9957
fa197c1c
PB
9958 remaining = 4;
9959 }
c93dbb25
CZ
9960 else
9961 {
9962 addr.section = SHN_UNDEF;
9963 addr.offset = 0;
9964 }
fa197c1c
PB
9965
9966 if ((word & 0x80000000) == 0)
9967 {
9968 /* Expand prel31 for personality routine. */
9969 bfd_vma fn;
9970 const char *procname;
9971
dda8d76d 9972 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9973 printf (_(" Personality routine: "));
1b31d05e
NC
9974 if (fn == 0
9975 && addr.section == SHN_UNDEF && addr.offset == 0
9976 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9977 {
9978 procname = aux->strtab + sym_name;
9979 print_vma (fn, PREFIX_HEX);
9980 if (procname)
9981 {
9982 fputs (" <", stdout);
9983 fputs (procname, stdout);
9984 fputc ('>', stdout);
9985 }
9986 }
9987 else
dda8d76d 9988 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9989 fputc ('\n', stdout);
9990
9991 /* The GCC personality routines use the standard compact
9992 encoding, starting with one byte giving the number of
9993 words. */
9994 if (procname != NULL
24d127aa
ML
9995 && (startswith (procname, "__gcc_personality_v0")
9996 || startswith (procname, "__gxx_personality_v0")
9997 || startswith (procname, "__gcj_personality_v0")
9998 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
9999 {
10000 remaining = 0;
10001 more_words = 1;
10002 ADVANCE;
10003 if (!remaining)
10004 {
10005 printf (_(" [Truncated data]\n"));
015dc7e1 10006 return false;
fa197c1c
PB
10007 }
10008 more_words = word >> 24;
10009 word <<= 8;
10010 remaining--;
10011 per_index = -1;
10012 }
10013 else
015dc7e1 10014 return true;
fa197c1c
PB
10015 }
10016 else
10017 {
1b31d05e 10018 /* ARM EHABI Section 6.3:
0b4362b0 10019
1b31d05e 10020 An exception-handling table entry for the compact model looks like:
0b4362b0 10021
1b31d05e
NC
10022 31 30-28 27-24 23-0
10023 -- ----- ----- ----
10024 1 0 index Data for personalityRoutine[index] */
10025
dda8d76d 10026 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10027 && (word & 0x70000000))
32ec8896
NC
10028 {
10029 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10030 res = false;
32ec8896 10031 }
1b31d05e 10032
fa197c1c 10033 per_index = (word >> 24) & 0x7f;
1b31d05e 10034 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10035 if (per_index == 0)
10036 {
10037 more_words = 0;
10038 word <<= 8;
10039 remaining--;
10040 }
10041 else if (per_index < 3)
10042 {
10043 more_words = (word >> 16) & 0xff;
10044 word <<= 16;
10045 remaining -= 2;
10046 }
10047 }
10048
dda8d76d 10049 switch (filedata->file_header.e_machine)
fa197c1c
PB
10050 {
10051 case EM_ARM:
10052 if (per_index < 3)
10053 {
dda8d76d 10054 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10055 data_offset, data_sec, data_arm_sec))
015dc7e1 10056 res = false;
fa197c1c
PB
10057 }
10058 else
1b31d05e
NC
10059 {
10060 warn (_("Unknown ARM compact model index encountered\n"));
10061 printf (_(" [reserved]\n"));
015dc7e1 10062 res = false;
1b31d05e 10063 }
fa197c1c
PB
10064 break;
10065
10066 case EM_TI_C6000:
10067 if (per_index < 3)
10068 {
dda8d76d 10069 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10070 data_offset, data_sec, data_arm_sec))
015dc7e1 10071 res = false;
fa197c1c
PB
10072 }
10073 else if (per_index < 5)
10074 {
10075 if (((word >> 17) & 0x7f) == 0x7f)
10076 printf (_(" Restore stack from frame pointer\n"));
10077 else
10078 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10079 printf (_(" Registers restored: "));
10080 if (per_index == 4)
10081 printf (" (compact) ");
10082 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10083 putchar ('\n');
10084 printf (_(" Return register: %s\n"),
10085 tic6x_unwind_regnames[word & 0xf]);
10086 }
10087 else
1b31d05e 10088 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10089 break;
10090
10091 default:
74e1a04b 10092 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10093 filedata->file_header.e_machine);
015dc7e1 10094 res = false;
fa197c1c 10095 }
0b6ae522
DJ
10096
10097 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10098
10099 return res;
0b6ae522
DJ
10100}
10101
015dc7e1 10102static bool
dda8d76d
NC
10103dump_arm_unwind (Filedata * filedata,
10104 struct arm_unw_aux_info * aux,
10105 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10106{
10107 struct arm_section exidx_arm_sec, extab_arm_sec;
10108 unsigned int i, exidx_len;
948f632f 10109 unsigned long j, nfuns;
015dc7e1 10110 bool res = true;
0b6ae522
DJ
10111
10112 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10113 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10114 exidx_len = exidx_sec->sh_size / 8;
10115
948f632f
DA
10116 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10117 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10118 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10119 aux->funtab[nfuns++] = aux->symtab[j];
10120 aux->nfuns = nfuns;
10121 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10122
0b6ae522
DJ
10123 for (i = 0; i < exidx_len; i++)
10124 {
10125 unsigned int exidx_fn, exidx_entry;
10126 struct absaddr fn_addr, entry_addr;
10127 bfd_vma fn;
10128
10129 fputc ('\n', stdout);
10130
dda8d76d 10131 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10132 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10133 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10134 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10135 {
948f632f 10136 free (aux->funtab);
1b31d05e
NC
10137 arm_free_section (& exidx_arm_sec);
10138 arm_free_section (& extab_arm_sec);
015dc7e1 10139 return false;
0b6ae522
DJ
10140 }
10141
83c257ca
NC
10142 /* ARM EHABI, Section 5:
10143 An index table entry consists of 2 words.
10144 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10145 if (exidx_fn & 0x80000000)
32ec8896
NC
10146 {
10147 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10148 res = false;
32ec8896 10149 }
83c257ca 10150
dda8d76d 10151 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10152
dda8d76d 10153 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10154 fputs (": ", stdout);
10155
10156 if (exidx_entry == 1)
10157 {
10158 print_vma (exidx_entry, PREFIX_HEX);
10159 fputs (" [cantunwind]\n", stdout);
10160 }
10161 else if (exidx_entry & 0x80000000)
10162 {
10163 print_vma (exidx_entry, PREFIX_HEX);
10164 fputc ('\n', stdout);
dda8d76d 10165 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10166 }
10167 else
10168 {
8f73510c 10169 bfd_vma table, table_offset = 0;
0b6ae522
DJ
10170 Elf_Internal_Shdr *table_sec;
10171
10172 fputs ("@", stdout);
dda8d76d 10173 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10174 print_vma (table, PREFIX_HEX);
10175 printf ("\n");
10176
10177 /* Locate the matching .ARM.extab. */
10178 if (entry_addr.section != SHN_UNDEF
dda8d76d 10179 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10180 {
dda8d76d 10181 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10182 table_offset = entry_addr.offset;
1a915552
NC
10183 /* PR 18879 */
10184 if (table_offset > table_sec->sh_size
10185 || ((bfd_signed_vma) table_offset) < 0)
10186 {
10187 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10188 (unsigned long) table_offset,
dda8d76d 10189 printable_section_name (filedata, table_sec));
015dc7e1 10190 res = false;
1a915552
NC
10191 continue;
10192 }
0b6ae522
DJ
10193 }
10194 else
10195 {
dda8d76d 10196 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10197 if (table_sec != NULL)
10198 table_offset = table - table_sec->sh_addr;
10199 }
32ec8896 10200
0b6ae522
DJ
10201 if (table_sec == NULL)
10202 {
10203 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10204 (unsigned long) table);
015dc7e1 10205 res = false;
0b6ae522
DJ
10206 continue;
10207 }
32ec8896 10208
dda8d76d 10209 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10210 &extab_arm_sec))
015dc7e1 10211 res = false;
0b6ae522
DJ
10212 }
10213 }
10214
10215 printf ("\n");
10216
948f632f 10217 free (aux->funtab);
0b6ae522
DJ
10218 arm_free_section (&exidx_arm_sec);
10219 arm_free_section (&extab_arm_sec);
32ec8896
NC
10220
10221 return res;
0b6ae522
DJ
10222}
10223
fa197c1c 10224/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10225
015dc7e1 10226static bool
dda8d76d 10227arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10228{
10229 struct arm_unw_aux_info aux;
10230 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10231 Elf_Internal_Shdr *sec;
10232 unsigned long i;
fa197c1c 10233 unsigned int sec_type;
015dc7e1 10234 bool res = true;
0b6ae522 10235
dda8d76d 10236 switch (filedata->file_header.e_machine)
fa197c1c
PB
10237 {
10238 case EM_ARM:
10239 sec_type = SHT_ARM_EXIDX;
10240 break;
10241
10242 case EM_TI_C6000:
10243 sec_type = SHT_C6000_UNWIND;
10244 break;
10245
0b4362b0 10246 default:
74e1a04b 10247 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10248 filedata->file_header.e_machine);
015dc7e1 10249 return false;
fa197c1c
PB
10250 }
10251
dda8d76d 10252 if (filedata->string_table == NULL)
015dc7e1 10253 return false;
1b31d05e
NC
10254
10255 memset (& aux, 0, sizeof (aux));
dda8d76d 10256 aux.filedata = filedata;
0b6ae522 10257
dda8d76d 10258 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10259 {
28d13567 10260 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10261 {
28d13567 10262 if (aux.symtab)
74e1a04b 10263 {
28d13567
AM
10264 error (_("Multiple symbol tables encountered\n"));
10265 free (aux.symtab);
10266 aux.symtab = NULL;
74e1a04b 10267 free (aux.strtab);
28d13567 10268 aux.strtab = NULL;
74e1a04b 10269 }
28d13567
AM
10270 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10271 &aux.strtab, &aux.strtab_size))
015dc7e1 10272 return false;
0b6ae522 10273 }
fa197c1c 10274 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10275 unwsec = sec;
10276 }
10277
1b31d05e 10278 if (unwsec == NULL)
0b6ae522 10279 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10280 else
dda8d76d 10281 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10282 {
10283 if (sec->sh_type == sec_type)
10284 {
d3a49aa8
AM
10285 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10286 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10287 "contains %lu entry:\n",
10288 "\nUnwind section '%s' at offset 0x%lx "
10289 "contains %lu entries:\n",
10290 num_unwind),
dda8d76d 10291 printable_section_name (filedata, sec),
1b31d05e 10292 (unsigned long) sec->sh_offset,
d3a49aa8 10293 num_unwind);
0b6ae522 10294
dda8d76d 10295 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10296 res = false;
1b31d05e
NC
10297 }
10298 }
0b6ae522 10299
9db70fc3
AM
10300 free (aux.symtab);
10301 free ((char *) aux.strtab);
32ec8896
NC
10302
10303 return res;
0b6ae522
DJ
10304}
10305
3ecc00ec
NC
10306static bool
10307no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10308{
10309 printf (_("No processor specific unwind information to decode\n"));
10310 return true;
10311}
10312
015dc7e1 10313static bool
dda8d76d 10314process_unwind (Filedata * filedata)
57346661 10315{
2cf0635d
NC
10316 struct unwind_handler
10317 {
32ec8896 10318 unsigned int machtype;
015dc7e1 10319 bool (* handler)(Filedata *);
2cf0635d
NC
10320 } handlers[] =
10321 {
0b6ae522 10322 { EM_ARM, arm_process_unwind },
57346661
AM
10323 { EM_IA_64, ia64_process_unwind },
10324 { EM_PARISC, hppa_process_unwind },
fa197c1c 10325 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10326 { EM_386, no_processor_specific_unwind },
10327 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10328 { 0, NULL }
57346661
AM
10329 };
10330 int i;
10331
10332 if (!do_unwind)
015dc7e1 10333 return true;
57346661
AM
10334
10335 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10336 if (filedata->file_header.e_machine == handlers[i].machtype)
10337 return handlers[i].handler (filedata);
57346661 10338
1b31d05e 10339 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10340 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10341 return true;
57346661
AM
10342}
10343
37c18eed
SD
10344static void
10345dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10346{
10347 switch (entry->d_tag)
10348 {
10349 case DT_AARCH64_BTI_PLT:
1dbade74 10350 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10351 break;
10352 default:
10353 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10354 break;
10355 }
10356 putchar ('\n');
10357}
10358
252b5132 10359static void
978c4450 10360dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10361{
10362 switch (entry->d_tag)
10363 {
10364 case DT_MIPS_FLAGS:
10365 if (entry->d_un.d_val == 0)
4b68bca3 10366 printf (_("NONE"));
252b5132
RH
10367 else
10368 {
10369 static const char * opts[] =
10370 {
10371 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10372 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10373 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10374 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10375 "RLD_ORDER_SAFE"
10376 };
10377 unsigned int cnt;
015dc7e1 10378 bool first = true;
2b692964 10379
60bca95a 10380 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10381 if (entry->d_un.d_val & (1 << cnt))
10382 {
10383 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10384 first = false;
252b5132 10385 }
252b5132
RH
10386 }
10387 break;
103f02d3 10388
252b5132 10389 case DT_MIPS_IVERSION:
84714f86 10390 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10391 printf (_("Interface Version: %s"),
84714f86 10392 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10393 else
76ca31c0
NC
10394 {
10395 char buf[40];
10396 sprintf_vma (buf, entry->d_un.d_ptr);
10397 /* Note: coded this way so that there is a single string for translation. */
10398 printf (_("<corrupt: %s>"), buf);
10399 }
252b5132 10400 break;
103f02d3 10401
252b5132
RH
10402 case DT_MIPS_TIME_STAMP:
10403 {
d5b07ef4 10404 char timebuf[128];
2cf0635d 10405 struct tm * tmp;
91d6fa6a 10406 time_t atime = entry->d_un.d_val;
82b1b41b 10407
91d6fa6a 10408 tmp = gmtime (&atime);
82b1b41b
NC
10409 /* PR 17531: file: 6accc532. */
10410 if (tmp == NULL)
10411 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10412 else
10413 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10414 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10415 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10416 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10417 }
10418 break;
103f02d3 10419
252b5132
RH
10420 case DT_MIPS_RLD_VERSION:
10421 case DT_MIPS_LOCAL_GOTNO:
10422 case DT_MIPS_CONFLICTNO:
10423 case DT_MIPS_LIBLISTNO:
10424 case DT_MIPS_SYMTABNO:
10425 case DT_MIPS_UNREFEXTNO:
10426 case DT_MIPS_HIPAGENO:
10427 case DT_MIPS_DELTA_CLASS_NO:
10428 case DT_MIPS_DELTA_INSTANCE_NO:
10429 case DT_MIPS_DELTA_RELOC_NO:
10430 case DT_MIPS_DELTA_SYM_NO:
10431 case DT_MIPS_DELTA_CLASSSYM_NO:
10432 case DT_MIPS_COMPACT_SIZE:
c69075ac 10433 print_vma (entry->d_un.d_val, DEC);
252b5132 10434 break;
103f02d3 10435
f16a9783 10436 case DT_MIPS_XHASH:
978c4450
AM
10437 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10438 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10439 /* Falls through. */
10440
103f02d3 10441 default:
4b68bca3 10442 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10443 }
4b68bca3 10444 putchar ('\n');
103f02d3
UD
10445}
10446
103f02d3 10447static void
2cf0635d 10448dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10449{
10450 switch (entry->d_tag)
10451 {
10452 case DT_HP_DLD_FLAGS:
10453 {
10454 static struct
10455 {
10456 long int bit;
2cf0635d 10457 const char * str;
5e220199
NC
10458 }
10459 flags[] =
10460 {
10461 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10462 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10463 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10464 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10465 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10466 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10467 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10468 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10469 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10470 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10471 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10472 { DT_HP_GST, "HP_GST" },
10473 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10474 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10475 { DT_HP_NODELETE, "HP_NODELETE" },
10476 { DT_HP_GROUP, "HP_GROUP" },
10477 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10478 };
015dc7e1 10479 bool first = true;
5e220199 10480 size_t cnt;
f7a99963 10481 bfd_vma val = entry->d_un.d_val;
103f02d3 10482
60bca95a 10483 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10484 if (val & flags[cnt].bit)
30800947
NC
10485 {
10486 if (! first)
10487 putchar (' ');
10488 fputs (flags[cnt].str, stdout);
015dc7e1 10489 first = false;
30800947
NC
10490 val ^= flags[cnt].bit;
10491 }
76da6bbe 10492
103f02d3 10493 if (val != 0 || first)
f7a99963
NC
10494 {
10495 if (! first)
10496 putchar (' ');
10497 print_vma (val, HEX);
10498 }
103f02d3
UD
10499 }
10500 break;
76da6bbe 10501
252b5132 10502 default:
f7a99963
NC
10503 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10504 break;
252b5132 10505 }
35b1837e 10506 putchar ('\n');
252b5132
RH
10507}
10508
28f997cf
TG
10509#ifdef BFD64
10510
10511/* VMS vs Unix time offset and factor. */
10512
10513#define VMS_EPOCH_OFFSET 35067168000000000LL
10514#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10515#ifndef INT64_MIN
10516#define INT64_MIN (-9223372036854775807LL - 1)
10517#endif
28f997cf
TG
10518
10519/* Display a VMS time in a human readable format. */
10520
10521static void
10522print_vms_time (bfd_int64_t vmstime)
10523{
dccc31de 10524 struct tm *tm = NULL;
28f997cf
TG
10525 time_t unxtime;
10526
dccc31de
AM
10527 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10528 {
10529 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10530 unxtime = vmstime;
10531 if (unxtime == vmstime)
10532 tm = gmtime (&unxtime);
10533 }
10534 if (tm != NULL)
10535 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10536 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10537 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10538}
10539#endif /* BFD64 */
10540
ecc51f48 10541static void
2cf0635d 10542dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10543{
10544 switch (entry->d_tag)
10545 {
0de14b54 10546 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10547 /* First 3 slots reserved. */
ecc51f48
NC
10548 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10549 printf (" -- ");
10550 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10551 break;
10552
28f997cf
TG
10553 case DT_IA_64_VMS_LINKTIME:
10554#ifdef BFD64
10555 print_vms_time (entry->d_un.d_val);
10556#endif
10557 break;
10558
10559 case DT_IA_64_VMS_LNKFLAGS:
10560 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10561 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10562 printf (" CALL_DEBUG");
10563 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10564 printf (" NOP0BUFS");
10565 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10566 printf (" P0IMAGE");
10567 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10568 printf (" MKTHREADS");
10569 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10570 printf (" UPCALLS");
10571 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10572 printf (" IMGSTA");
10573 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10574 printf (" INITIALIZE");
10575 if (entry->d_un.d_val & VMS_LF_MAIN)
10576 printf (" MAIN");
10577 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10578 printf (" EXE_INIT");
10579 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10580 printf (" TBK_IN_IMG");
10581 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10582 printf (" DBG_IN_IMG");
10583 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10584 printf (" TBK_IN_DSF");
10585 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10586 printf (" DBG_IN_DSF");
10587 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10588 printf (" SIGNATURES");
10589 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10590 printf (" REL_SEG_OFF");
10591 break;
10592
bdf4d63a
JJ
10593 default:
10594 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10595 break;
ecc51f48 10596 }
bdf4d63a 10597 putchar ('\n');
ecc51f48
NC
10598}
10599
015dc7e1 10600static bool
dda8d76d 10601get_32bit_dynamic_section (Filedata * filedata)
252b5132 10602{
2cf0635d
NC
10603 Elf32_External_Dyn * edyn;
10604 Elf32_External_Dyn * ext;
10605 Elf_Internal_Dyn * entry;
103f02d3 10606
978c4450
AM
10607 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10608 filedata->dynamic_addr, 1,
10609 filedata->dynamic_size,
10610 _("dynamic section"));
a6e9f9df 10611 if (!edyn)
015dc7e1 10612 return false;
103f02d3 10613
071436c6
NC
10614 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10615 might not have the luxury of section headers. Look for the DT_NULL
10616 terminator to determine the number of entries. */
978c4450
AM
10617 for (ext = edyn, filedata->dynamic_nent = 0;
10618 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10619 ext++)
10620 {
978c4450 10621 filedata->dynamic_nent++;
ba2685cc
AM
10622 if (BYTE_GET (ext->d_tag) == DT_NULL)
10623 break;
10624 }
252b5132 10625
978c4450
AM
10626 filedata->dynamic_section
10627 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10628 if (filedata->dynamic_section == NULL)
252b5132 10629 {
8b73c356 10630 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10631 (unsigned long) filedata->dynamic_nent);
9ea033b2 10632 free (edyn);
015dc7e1 10633 return false;
9ea033b2 10634 }
252b5132 10635
978c4450
AM
10636 for (ext = edyn, entry = filedata->dynamic_section;
10637 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10638 ext++, entry++)
9ea033b2 10639 {
fb514b26
AM
10640 entry->d_tag = BYTE_GET (ext->d_tag);
10641 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10642 }
10643
9ea033b2
NC
10644 free (edyn);
10645
015dc7e1 10646 return true;
9ea033b2
NC
10647}
10648
015dc7e1 10649static bool
dda8d76d 10650get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10651{
2cf0635d
NC
10652 Elf64_External_Dyn * edyn;
10653 Elf64_External_Dyn * ext;
10654 Elf_Internal_Dyn * entry;
103f02d3 10655
071436c6 10656 /* Read in the data. */
978c4450
AM
10657 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10658 filedata->dynamic_addr, 1,
10659 filedata->dynamic_size,
10660 _("dynamic section"));
a6e9f9df 10661 if (!edyn)
015dc7e1 10662 return false;
103f02d3 10663
071436c6
NC
10664 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10665 might not have the luxury of section headers. Look for the DT_NULL
10666 terminator to determine the number of entries. */
978c4450 10667 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10668 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10669 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10670 ext++)
10671 {
978c4450 10672 filedata->dynamic_nent++;
66543521 10673 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10674 break;
10675 }
252b5132 10676
978c4450
AM
10677 filedata->dynamic_section
10678 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10679 if (filedata->dynamic_section == NULL)
252b5132 10680 {
8b73c356 10681 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10682 (unsigned long) filedata->dynamic_nent);
252b5132 10683 free (edyn);
015dc7e1 10684 return false;
252b5132
RH
10685 }
10686
071436c6 10687 /* Convert from external to internal formats. */
978c4450
AM
10688 for (ext = edyn, entry = filedata->dynamic_section;
10689 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10690 ext++, entry++)
252b5132 10691 {
66543521
AM
10692 entry->d_tag = BYTE_GET (ext->d_tag);
10693 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10694 }
10695
10696 free (edyn);
10697
015dc7e1 10698 return true;
9ea033b2
NC
10699}
10700
4de91c10
AM
10701static bool
10702get_dynamic_section (Filedata *filedata)
10703{
10704 if (filedata->dynamic_section)
10705 return true;
10706
10707 if (is_32bit_elf)
10708 return get_32bit_dynamic_section (filedata);
10709 else
10710 return get_64bit_dynamic_section (filedata);
10711}
10712
e9e44622
JJ
10713static void
10714print_dynamic_flags (bfd_vma flags)
d1133906 10715{
015dc7e1 10716 bool first = true;
13ae64f3 10717
d1133906
NC
10718 while (flags)
10719 {
10720 bfd_vma flag;
10721
10722 flag = flags & - flags;
10723 flags &= ~ flag;
10724
e9e44622 10725 if (first)
015dc7e1 10726 first = false;
e9e44622
JJ
10727 else
10728 putc (' ', stdout);
13ae64f3 10729
d1133906
NC
10730 switch (flag)
10731 {
e9e44622
JJ
10732 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10733 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10734 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10735 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10736 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10737 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10738 }
10739 }
e9e44622 10740 puts ("");
d1133906
NC
10741}
10742
10ca4b04
L
10743static bfd_vma *
10744get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10745{
10746 unsigned char * e_data;
10747 bfd_vma * i_data;
10748
10749 /* If the size_t type is smaller than the bfd_size_type, eg because
10750 you are building a 32-bit tool on a 64-bit host, then make sure
10751 that when (number) is cast to (size_t) no information is lost. */
10752 if (sizeof (size_t) < sizeof (bfd_size_type)
10753 && (bfd_size_type) ((size_t) number) != number)
10754 {
10755 error (_("Size truncation prevents reading %s elements of size %u\n"),
10756 bfd_vmatoa ("u", number), ent_size);
10757 return NULL;
10758 }
10759
10760 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10761 attempting to allocate memory when the read is bound to fail. */
10762 if (ent_size * number > filedata->file_size)
10763 {
10764 error (_("Invalid number of dynamic entries: %s\n"),
10765 bfd_vmatoa ("u", number));
10766 return NULL;
10767 }
10768
10769 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10770 if (e_data == NULL)
10771 {
10772 error (_("Out of memory reading %s dynamic entries\n"),
10773 bfd_vmatoa ("u", number));
10774 return NULL;
10775 }
10776
10777 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10778 {
10779 error (_("Unable to read in %s bytes of dynamic data\n"),
10780 bfd_vmatoa ("u", number * ent_size));
10781 free (e_data);
10782 return NULL;
10783 }
10784
10785 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10786 if (i_data == NULL)
10787 {
10788 error (_("Out of memory allocating space for %s dynamic entries\n"),
10789 bfd_vmatoa ("u", number));
10790 free (e_data);
10791 return NULL;
10792 }
10793
10794 while (number--)
10795 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10796
10797 free (e_data);
10798
10799 return i_data;
10800}
10801
10802static unsigned long
10803get_num_dynamic_syms (Filedata * filedata)
10804{
10805 unsigned long num_of_syms = 0;
10806
10807 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10808 return num_of_syms;
10809
978c4450 10810 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10811 {
10812 unsigned char nb[8];
10813 unsigned char nc[8];
10814 unsigned int hash_ent_size = 4;
10815
10816 if ((filedata->file_header.e_machine == EM_ALPHA
10817 || filedata->file_header.e_machine == EM_S390
10818 || filedata->file_header.e_machine == EM_S390_OLD)
10819 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10820 hash_ent_size = 8;
10821
10822 if (fseek (filedata->handle,
978c4450
AM
10823 (filedata->archive_file_offset
10824 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10825 sizeof nb + sizeof nc)),
10826 SEEK_SET))
10827 {
10828 error (_("Unable to seek to start of dynamic information\n"));
10829 goto no_hash;
10830 }
10831
10832 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10833 {
10834 error (_("Failed to read in number of buckets\n"));
10835 goto no_hash;
10836 }
10837
10838 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10839 {
10840 error (_("Failed to read in number of chains\n"));
10841 goto no_hash;
10842 }
10843
978c4450
AM
10844 filedata->nbuckets = byte_get (nb, hash_ent_size);
10845 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10846
2482f306
AM
10847 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10848 {
10849 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10850 hash_ent_size);
10851 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10852 hash_ent_size);
001890e1 10853
2482f306
AM
10854 if (filedata->buckets != NULL && filedata->chains != NULL)
10855 num_of_syms = filedata->nchains;
10856 }
ceb9bf11 10857 no_hash:
10ca4b04
L
10858 if (num_of_syms == 0)
10859 {
9db70fc3
AM
10860 free (filedata->buckets);
10861 filedata->buckets = NULL;
10862 free (filedata->chains);
10863 filedata->chains = NULL;
978c4450 10864 filedata->nbuckets = 0;
10ca4b04
L
10865 }
10866 }
10867
978c4450 10868 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10869 {
10870 unsigned char nb[16];
10871 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10872 bfd_vma buckets_vma;
10873 unsigned long hn;
10ca4b04
L
10874
10875 if (fseek (filedata->handle,
978c4450
AM
10876 (filedata->archive_file_offset
10877 + offset_from_vma (filedata,
10878 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10879 sizeof nb)),
10880 SEEK_SET))
10881 {
10882 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10883 goto no_gnu_hash;
10884 }
10885
10886 if (fread (nb, 16, 1, filedata->handle) != 1)
10887 {
10888 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10889 goto no_gnu_hash;
10890 }
10891
978c4450
AM
10892 filedata->ngnubuckets = byte_get (nb, 4);
10893 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10894 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10895 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10896 if (is_32bit_elf)
10897 buckets_vma += bitmaskwords * 4;
10898 else
10899 buckets_vma += bitmaskwords * 8;
10900
10901 if (fseek (filedata->handle,
978c4450 10902 (filedata->archive_file_offset
10ca4b04
L
10903 + offset_from_vma (filedata, buckets_vma, 4)),
10904 SEEK_SET))
10905 {
10906 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10907 goto no_gnu_hash;
10908 }
10909
978c4450
AM
10910 filedata->gnubuckets
10911 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10912
978c4450 10913 if (filedata->gnubuckets == NULL)
90837ea7 10914 goto no_gnu_hash;
10ca4b04 10915
978c4450
AM
10916 for (i = 0; i < filedata->ngnubuckets; i++)
10917 if (filedata->gnubuckets[i] != 0)
10ca4b04 10918 {
978c4450 10919 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10920 goto no_gnu_hash;
10ca4b04 10921
978c4450
AM
10922 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10923 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10924 }
10925
10926 if (maxchain == 0xffffffff)
90837ea7 10927 goto no_gnu_hash;
10ca4b04 10928
978c4450 10929 maxchain -= filedata->gnusymidx;
10ca4b04
L
10930
10931 if (fseek (filedata->handle,
978c4450
AM
10932 (filedata->archive_file_offset
10933 + offset_from_vma (filedata,
10934 buckets_vma + 4 * (filedata->ngnubuckets
10935 + maxchain),
10936 4)),
10ca4b04
L
10937 SEEK_SET))
10938 {
10939 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10940 goto no_gnu_hash;
10941 }
10942
10943 do
10944 {
10945 if (fread (nb, 4, 1, filedata->handle) != 1)
10946 {
10947 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10948 goto no_gnu_hash;
10949 }
10950
10951 if (maxchain + 1 == 0)
90837ea7 10952 goto no_gnu_hash;
10ca4b04
L
10953
10954 ++maxchain;
10955 }
10956 while ((byte_get (nb, 4) & 1) == 0);
10957
10958 if (fseek (filedata->handle,
978c4450
AM
10959 (filedata->archive_file_offset
10960 + offset_from_vma (filedata, (buckets_vma
10961 + 4 * filedata->ngnubuckets),
10962 4)),
10ca4b04
L
10963 SEEK_SET))
10964 {
10965 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10966 goto no_gnu_hash;
10967 }
10968
978c4450
AM
10969 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10970 filedata->ngnuchains = maxchain;
10ca4b04 10971
978c4450 10972 if (filedata->gnuchains == NULL)
90837ea7 10973 goto no_gnu_hash;
10ca4b04 10974
978c4450 10975 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10976 {
10977 if (fseek (filedata->handle,
978c4450 10978 (filedata->archive_file_offset
10ca4b04 10979 + offset_from_vma (filedata, (buckets_vma
978c4450 10980 + 4 * (filedata->ngnubuckets
10ca4b04
L
10981 + maxchain)), 4)),
10982 SEEK_SET))
10983 {
10984 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10985 goto no_gnu_hash;
10986 }
10987
978c4450 10988 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10989 if (filedata->mipsxlat == NULL)
10990 goto no_gnu_hash;
10ca4b04
L
10991 }
10992
978c4450
AM
10993 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10994 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10995 {
978c4450
AM
10996 bfd_vma si = filedata->gnubuckets[hn];
10997 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10998
10999 do
11000 {
978c4450 11001 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11002 {
c31ab5a0
AM
11003 if (off < filedata->ngnuchains
11004 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11005 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11006 }
11007 else
11008 {
11009 if (si >= num_of_syms)
11010 num_of_syms = si + 1;
11011 }
11012 si++;
11013 }
978c4450
AM
11014 while (off < filedata->ngnuchains
11015 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11016 }
11017
90837ea7 11018 if (num_of_syms == 0)
10ca4b04 11019 {
90837ea7 11020 no_gnu_hash:
9db70fc3
AM
11021 free (filedata->mipsxlat);
11022 filedata->mipsxlat = NULL;
11023 free (filedata->gnuchains);
11024 filedata->gnuchains = NULL;
11025 free (filedata->gnubuckets);
11026 filedata->gnubuckets = NULL;
978c4450
AM
11027 filedata->ngnubuckets = 0;
11028 filedata->ngnuchains = 0;
10ca4b04
L
11029 }
11030 }
11031
11032 return num_of_syms;
11033}
11034
b2d38a17
NC
11035/* Parse and display the contents of the dynamic section. */
11036
015dc7e1 11037static bool
dda8d76d 11038process_dynamic_section (Filedata * filedata)
9ea033b2 11039{
2cf0635d 11040 Elf_Internal_Dyn * entry;
9ea033b2 11041
93df3340 11042 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11043 {
11044 if (do_dynamic)
ca0e11aa
NC
11045 {
11046 if (filedata->is_separate)
11047 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11048 filedata->file_name);
11049 else
11050 printf (_("\nThere is no dynamic section in this file.\n"));
11051 }
9ea033b2 11052
015dc7e1 11053 return true;
9ea033b2
NC
11054 }
11055
4de91c10
AM
11056 if (!get_dynamic_section (filedata))
11057 return false;
9ea033b2 11058
252b5132 11059 /* Find the appropriate symbol table. */
978c4450 11060 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11061 {
2482f306
AM
11062 unsigned long num_of_syms;
11063
978c4450
AM
11064 for (entry = filedata->dynamic_section;
11065 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11066 ++entry)
10ca4b04 11067 if (entry->d_tag == DT_SYMTAB)
978c4450 11068 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11069 else if (entry->d_tag == DT_SYMENT)
978c4450 11070 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11071 else if (entry->d_tag == DT_HASH)
978c4450 11072 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11073 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11074 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11075 else if ((filedata->file_header.e_machine == EM_MIPS
11076 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11077 && entry->d_tag == DT_MIPS_XHASH)
11078 {
978c4450
AM
11079 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11080 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11081 }
252b5132 11082
2482f306
AM
11083 num_of_syms = get_num_dynamic_syms (filedata);
11084
11085 if (num_of_syms != 0
11086 && filedata->dynamic_symbols == NULL
11087 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11088 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11089 {
11090 Elf_Internal_Phdr *seg;
2482f306 11091 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11092
2482f306
AM
11093 if (! get_program_headers (filedata))
11094 {
11095 error (_("Cannot interpret virtual addresses "
11096 "without program headers.\n"));
015dc7e1 11097 return false;
2482f306 11098 }
252b5132 11099
2482f306
AM
11100 for (seg = filedata->program_headers;
11101 seg < filedata->program_headers + filedata->file_header.e_phnum;
11102 ++seg)
11103 {
11104 if (seg->p_type != PT_LOAD)
11105 continue;
252b5132 11106
2482f306
AM
11107 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11108 {
11109 /* See PR 21379 for a reproducer. */
11110 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11111 return false;
2482f306 11112 }
252b5132 11113
2482f306
AM
11114 if (vma >= (seg->p_vaddr & -seg->p_align)
11115 && vma < seg->p_vaddr + seg->p_filesz)
11116 {
11117 /* Since we do not know how big the symbol table is,
11118 we default to reading in up to the end of PT_LOAD
11119 segment and processing that. This is overkill, I
11120 know, but it should work. */
11121 Elf_Internal_Shdr section;
11122 section.sh_offset = (vma - seg->p_vaddr
11123 + seg->p_offset);
11124 section.sh_size = (num_of_syms
11125 * filedata->dynamic_info[DT_SYMENT]);
11126 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11127
11128 if (do_checks
11129 && filedata->dynamic_symtab_section != NULL
11130 && ((filedata->dynamic_symtab_section->sh_offset
11131 != section.sh_offset)
11132 || (filedata->dynamic_symtab_section->sh_size
11133 != section.sh_size)
11134 || (filedata->dynamic_symtab_section->sh_entsize
11135 != section.sh_entsize)))
11136 warn (_("\
11137the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11138
2482f306
AM
11139 section.sh_name = filedata->string_table_length;
11140 filedata->dynamic_symbols
4de91c10 11141 = get_elf_symbols (filedata, &section,
2482f306
AM
11142 &filedata->num_dynamic_syms);
11143 if (filedata->dynamic_symbols == NULL
11144 || filedata->num_dynamic_syms != num_of_syms)
11145 {
11146 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11147 return false;
2482f306
AM
11148 }
11149 break;
11150 }
11151 }
11152 }
11153 }
252b5132
RH
11154
11155 /* Similarly find a string table. */
978c4450
AM
11156 if (filedata->dynamic_strings == NULL)
11157 for (entry = filedata->dynamic_section;
11158 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11159 ++entry)
11160 {
11161 if (entry->d_tag == DT_STRTAB)
978c4450 11162 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11163
10ca4b04 11164 if (entry->d_tag == DT_STRSZ)
978c4450 11165 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11166
978c4450
AM
11167 if (filedata->dynamic_info[DT_STRTAB]
11168 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11169 {
11170 unsigned long offset;
978c4450 11171 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11172
11173 offset = offset_from_vma (filedata,
978c4450 11174 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11175 str_tab_len);
8ac10c5b
L
11176 if (do_checks
11177 && filedata->dynamic_strtab_section
11178 && ((filedata->dynamic_strtab_section->sh_offset
11179 != (file_ptr) offset)
11180 || (filedata->dynamic_strtab_section->sh_size
11181 != str_tab_len)))
11182 warn (_("\
11183the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11184
978c4450
AM
11185 filedata->dynamic_strings
11186 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11187 _("dynamic string table"));
11188 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11189 {
11190 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11191 break;
11192 }
e3d39609 11193
978c4450 11194 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11195 break;
11196 }
11197 }
252b5132
RH
11198
11199 /* And find the syminfo section if available. */
978c4450 11200 if (filedata->dynamic_syminfo == NULL)
252b5132 11201 {
3e8bba36 11202 unsigned long syminsz = 0;
252b5132 11203
978c4450
AM
11204 for (entry = filedata->dynamic_section;
11205 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11206 ++entry)
252b5132
RH
11207 {
11208 if (entry->d_tag == DT_SYMINENT)
11209 {
11210 /* Note: these braces are necessary to avoid a syntax
11211 error from the SunOS4 C compiler. */
049b0c3a
NC
11212 /* PR binutils/17531: A corrupt file can trigger this test.
11213 So do not use an assert, instead generate an error message. */
11214 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11215 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11216 (int) entry->d_un.d_val);
252b5132
RH
11217 }
11218 else if (entry->d_tag == DT_SYMINSZ)
11219 syminsz = entry->d_un.d_val;
11220 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11221 filedata->dynamic_syminfo_offset
11222 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11223 }
11224
978c4450 11225 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11226 {
2cf0635d
NC
11227 Elf_External_Syminfo * extsyminfo;
11228 Elf_External_Syminfo * extsym;
11229 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11230
11231 /* There is a syminfo section. Read the data. */
3f5e193b 11232 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11233 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11234 1, syminsz, _("symbol information"));
a6e9f9df 11235 if (!extsyminfo)
015dc7e1 11236 return false;
252b5132 11237
978c4450 11238 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11239 {
11240 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11241 free (filedata->dynamic_syminfo);
e3d39609 11242 }
978c4450
AM
11243 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11244 if (filedata->dynamic_syminfo == NULL)
252b5132 11245 {
2482f306
AM
11246 error (_("Out of memory allocating %lu bytes "
11247 "for dynamic symbol info\n"),
8b73c356 11248 (unsigned long) syminsz);
015dc7e1 11249 return false;
252b5132
RH
11250 }
11251
2482f306
AM
11252 filedata->dynamic_syminfo_nent
11253 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11254 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11255 syminfo < (filedata->dynamic_syminfo
11256 + filedata->dynamic_syminfo_nent);
86dba8ee 11257 ++syminfo, ++extsym)
252b5132 11258 {
86dba8ee
AM
11259 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11260 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11261 }
11262
11263 free (extsyminfo);
11264 }
11265 }
11266
978c4450 11267 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11268 {
f253158f
NC
11269 if (filedata->is_separate)
11270 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11271 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11272 (unsigned long) filedata->dynamic_nent),
11273 filedata->file_name,
11274 filedata->dynamic_addr,
11275 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11276 else
f253158f
NC
11277 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11278 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11279 (unsigned long) filedata->dynamic_nent),
ca0e11aa
NC
11280 filedata->dynamic_addr,
11281 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11282 }
252b5132
RH
11283 if (do_dynamic)
11284 printf (_(" Tag Type Name/Value\n"));
11285
978c4450
AM
11286 for (entry = filedata->dynamic_section;
11287 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11288 entry++)
252b5132
RH
11289 {
11290 if (do_dynamic)
f7a99963 11291 {
2cf0635d 11292 const char * dtype;
e699b9ff 11293
f7a99963
NC
11294 putchar (' ');
11295 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11296 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11297 printf (" (%s)%*s", dtype,
32ec8896 11298 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11299 }
252b5132
RH
11300
11301 switch (entry->d_tag)
11302 {
d1133906
NC
11303 case DT_FLAGS:
11304 if (do_dynamic)
e9e44622 11305 print_dynamic_flags (entry->d_un.d_val);
d1133906 11306 break;
76da6bbe 11307
252b5132
RH
11308 case DT_AUXILIARY:
11309 case DT_FILTER:
019148e4
L
11310 case DT_CONFIG:
11311 case DT_DEPAUDIT:
11312 case DT_AUDIT:
252b5132
RH
11313 if (do_dynamic)
11314 {
019148e4 11315 switch (entry->d_tag)
b34976b6 11316 {
019148e4
L
11317 case DT_AUXILIARY:
11318 printf (_("Auxiliary library"));
11319 break;
11320
11321 case DT_FILTER:
11322 printf (_("Filter library"));
11323 break;
11324
b34976b6 11325 case DT_CONFIG:
019148e4
L
11326 printf (_("Configuration file"));
11327 break;
11328
11329 case DT_DEPAUDIT:
11330 printf (_("Dependency audit library"));
11331 break;
11332
11333 case DT_AUDIT:
11334 printf (_("Audit library"));
11335 break;
11336 }
252b5132 11337
84714f86 11338 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11339 printf (": [%s]\n",
84714f86 11340 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11341 else
f7a99963
NC
11342 {
11343 printf (": ");
11344 print_vma (entry->d_un.d_val, PREFIX_HEX);
11345 putchar ('\n');
11346 }
252b5132
RH
11347 }
11348 break;
11349
dcefbbbd 11350 case DT_FEATURE:
252b5132
RH
11351 if (do_dynamic)
11352 {
11353 printf (_("Flags:"));
86f55779 11354
252b5132
RH
11355 if (entry->d_un.d_val == 0)
11356 printf (_(" None\n"));
11357 else
11358 {
11359 unsigned long int val = entry->d_un.d_val;
86f55779 11360
252b5132
RH
11361 if (val & DTF_1_PARINIT)
11362 {
11363 printf (" PARINIT");
11364 val ^= DTF_1_PARINIT;
11365 }
dcefbbbd
L
11366 if (val & DTF_1_CONFEXP)
11367 {
11368 printf (" CONFEXP");
11369 val ^= DTF_1_CONFEXP;
11370 }
252b5132
RH
11371 if (val != 0)
11372 printf (" %lx", val);
11373 puts ("");
11374 }
11375 }
11376 break;
11377
11378 case DT_POSFLAG_1:
11379 if (do_dynamic)
11380 {
11381 printf (_("Flags:"));
86f55779 11382
252b5132
RH
11383 if (entry->d_un.d_val == 0)
11384 printf (_(" None\n"));
11385 else
11386 {
11387 unsigned long int val = entry->d_un.d_val;
86f55779 11388
252b5132
RH
11389 if (val & DF_P1_LAZYLOAD)
11390 {
11391 printf (" LAZYLOAD");
11392 val ^= DF_P1_LAZYLOAD;
11393 }
11394 if (val & DF_P1_GROUPPERM)
11395 {
11396 printf (" GROUPPERM");
11397 val ^= DF_P1_GROUPPERM;
11398 }
11399 if (val != 0)
11400 printf (" %lx", val);
11401 puts ("");
11402 }
11403 }
11404 break;
11405
11406 case DT_FLAGS_1:
11407 if (do_dynamic)
11408 {
11409 printf (_("Flags:"));
11410 if (entry->d_un.d_val == 0)
11411 printf (_(" None\n"));
11412 else
11413 {
11414 unsigned long int val = entry->d_un.d_val;
86f55779 11415
252b5132
RH
11416 if (val & DF_1_NOW)
11417 {
11418 printf (" NOW");
11419 val ^= DF_1_NOW;
11420 }
11421 if (val & DF_1_GLOBAL)
11422 {
11423 printf (" GLOBAL");
11424 val ^= DF_1_GLOBAL;
11425 }
11426 if (val & DF_1_GROUP)
11427 {
11428 printf (" GROUP");
11429 val ^= DF_1_GROUP;
11430 }
11431 if (val & DF_1_NODELETE)
11432 {
11433 printf (" NODELETE");
11434 val ^= DF_1_NODELETE;
11435 }
11436 if (val & DF_1_LOADFLTR)
11437 {
11438 printf (" LOADFLTR");
11439 val ^= DF_1_LOADFLTR;
11440 }
11441 if (val & DF_1_INITFIRST)
11442 {
11443 printf (" INITFIRST");
11444 val ^= DF_1_INITFIRST;
11445 }
11446 if (val & DF_1_NOOPEN)
11447 {
11448 printf (" NOOPEN");
11449 val ^= DF_1_NOOPEN;
11450 }
11451 if (val & DF_1_ORIGIN)
11452 {
11453 printf (" ORIGIN");
11454 val ^= DF_1_ORIGIN;
11455 }
11456 if (val & DF_1_DIRECT)
11457 {
11458 printf (" DIRECT");
11459 val ^= DF_1_DIRECT;
11460 }
11461 if (val & DF_1_TRANS)
11462 {
11463 printf (" TRANS");
11464 val ^= DF_1_TRANS;
11465 }
11466 if (val & DF_1_INTERPOSE)
11467 {
11468 printf (" INTERPOSE");
11469 val ^= DF_1_INTERPOSE;
11470 }
f7db6139 11471 if (val & DF_1_NODEFLIB)
dcefbbbd 11472 {
f7db6139
L
11473 printf (" NODEFLIB");
11474 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11475 }
11476 if (val & DF_1_NODUMP)
11477 {
11478 printf (" NODUMP");
11479 val ^= DF_1_NODUMP;
11480 }
34b60028 11481 if (val & DF_1_CONFALT)
dcefbbbd 11482 {
34b60028
L
11483 printf (" CONFALT");
11484 val ^= DF_1_CONFALT;
11485 }
11486 if (val & DF_1_ENDFILTEE)
11487 {
11488 printf (" ENDFILTEE");
11489 val ^= DF_1_ENDFILTEE;
11490 }
11491 if (val & DF_1_DISPRELDNE)
11492 {
11493 printf (" DISPRELDNE");
11494 val ^= DF_1_DISPRELDNE;
11495 }
11496 if (val & DF_1_DISPRELPND)
11497 {
11498 printf (" DISPRELPND");
11499 val ^= DF_1_DISPRELPND;
11500 }
11501 if (val & DF_1_NODIRECT)
11502 {
11503 printf (" NODIRECT");
11504 val ^= DF_1_NODIRECT;
11505 }
11506 if (val & DF_1_IGNMULDEF)
11507 {
11508 printf (" IGNMULDEF");
11509 val ^= DF_1_IGNMULDEF;
11510 }
11511 if (val & DF_1_NOKSYMS)
11512 {
11513 printf (" NOKSYMS");
11514 val ^= DF_1_NOKSYMS;
11515 }
11516 if (val & DF_1_NOHDR)
11517 {
11518 printf (" NOHDR");
11519 val ^= DF_1_NOHDR;
11520 }
11521 if (val & DF_1_EDITED)
11522 {
11523 printf (" EDITED");
11524 val ^= DF_1_EDITED;
11525 }
11526 if (val & DF_1_NORELOC)
11527 {
11528 printf (" NORELOC");
11529 val ^= DF_1_NORELOC;
11530 }
11531 if (val & DF_1_SYMINTPOSE)
11532 {
11533 printf (" SYMINTPOSE");
11534 val ^= DF_1_SYMINTPOSE;
11535 }
11536 if (val & DF_1_GLOBAUDIT)
11537 {
11538 printf (" GLOBAUDIT");
11539 val ^= DF_1_GLOBAUDIT;
11540 }
11541 if (val & DF_1_SINGLETON)
11542 {
11543 printf (" SINGLETON");
11544 val ^= DF_1_SINGLETON;
dcefbbbd 11545 }
5c383f02
RO
11546 if (val & DF_1_STUB)
11547 {
11548 printf (" STUB");
11549 val ^= DF_1_STUB;
11550 }
11551 if (val & DF_1_PIE)
11552 {
11553 printf (" PIE");
11554 val ^= DF_1_PIE;
11555 }
b1202ffa
L
11556 if (val & DF_1_KMOD)
11557 {
11558 printf (" KMOD");
11559 val ^= DF_1_KMOD;
11560 }
11561 if (val & DF_1_WEAKFILTER)
11562 {
11563 printf (" WEAKFILTER");
11564 val ^= DF_1_WEAKFILTER;
11565 }
11566 if (val & DF_1_NOCOMMON)
11567 {
11568 printf (" NOCOMMON");
11569 val ^= DF_1_NOCOMMON;
11570 }
252b5132
RH
11571 if (val != 0)
11572 printf (" %lx", val);
11573 puts ("");
11574 }
11575 }
11576 break;
11577
11578 case DT_PLTREL:
978c4450 11579 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11580 if (do_dynamic)
dda8d76d 11581 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11582 break;
11583
11584 case DT_NULL :
11585 case DT_NEEDED :
11586 case DT_PLTGOT :
11587 case DT_HASH :
11588 case DT_STRTAB :
11589 case DT_SYMTAB :
11590 case DT_RELA :
11591 case DT_INIT :
11592 case DT_FINI :
11593 case DT_SONAME :
11594 case DT_RPATH :
11595 case DT_SYMBOLIC:
11596 case DT_REL :
a7fd1186 11597 case DT_RELR :
252b5132
RH
11598 case DT_DEBUG :
11599 case DT_TEXTREL :
11600 case DT_JMPREL :
019148e4 11601 case DT_RUNPATH :
978c4450 11602 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11603
11604 if (do_dynamic)
11605 {
84714f86 11606 const char *name;
252b5132 11607
84714f86
AM
11608 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11609 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11610 else
d79b3d50 11611 name = NULL;
252b5132
RH
11612
11613 if (name)
11614 {
11615 switch (entry->d_tag)
11616 {
11617 case DT_NEEDED:
11618 printf (_("Shared library: [%s]"), name);
11619
13acb58d
AM
11620 if (filedata->program_interpreter
11621 && streq (name, filedata->program_interpreter))
f7a99963 11622 printf (_(" program interpreter"));
252b5132
RH
11623 break;
11624
11625 case DT_SONAME:
f7a99963 11626 printf (_("Library soname: [%s]"), name);
252b5132
RH
11627 break;
11628
11629 case DT_RPATH:
f7a99963 11630 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11631 break;
11632
019148e4
L
11633 case DT_RUNPATH:
11634 printf (_("Library runpath: [%s]"), name);
11635 break;
11636
252b5132 11637 default:
f7a99963
NC
11638 print_vma (entry->d_un.d_val, PREFIX_HEX);
11639 break;
252b5132
RH
11640 }
11641 }
11642 else
f7a99963
NC
11643 print_vma (entry->d_un.d_val, PREFIX_HEX);
11644
11645 putchar ('\n');
252b5132
RH
11646 }
11647 break;
11648
11649 case DT_PLTRELSZ:
11650 case DT_RELASZ :
11651 case DT_STRSZ :
11652 case DT_RELSZ :
11653 case DT_RELAENT :
a7fd1186
FS
11654 case DT_RELRENT :
11655 case DT_RELRSZ :
252b5132
RH
11656 case DT_SYMENT :
11657 case DT_RELENT :
978c4450 11658 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11659 /* Fall through. */
252b5132
RH
11660 case DT_PLTPADSZ:
11661 case DT_MOVEENT :
11662 case DT_MOVESZ :
04d8355a 11663 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11664 case DT_INIT_ARRAYSZ:
11665 case DT_FINI_ARRAYSZ:
047b2264
JJ
11666 case DT_GNU_CONFLICTSZ:
11667 case DT_GNU_LIBLISTSZ:
252b5132 11668 if (do_dynamic)
f7a99963
NC
11669 {
11670 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11671 printf (_(" (bytes)\n"));
f7a99963 11672 }
252b5132
RH
11673 break;
11674
11675 case DT_VERDEFNUM:
11676 case DT_VERNEEDNUM:
11677 case DT_RELACOUNT:
11678 case DT_RELCOUNT:
11679 if (do_dynamic)
f7a99963
NC
11680 {
11681 print_vma (entry->d_un.d_val, UNSIGNED);
11682 putchar ('\n');
11683 }
252b5132
RH
11684 break;
11685
11686 case DT_SYMINSZ:
11687 case DT_SYMINENT:
11688 case DT_SYMINFO:
11689 case DT_USED:
11690 case DT_INIT_ARRAY:
11691 case DT_FINI_ARRAY:
11692 if (do_dynamic)
11693 {
d79b3d50 11694 if (entry->d_tag == DT_USED
84714f86 11695 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11696 {
84714f86
AM
11697 const char *name
11698 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11699
b34976b6 11700 if (*name)
252b5132
RH
11701 {
11702 printf (_("Not needed object: [%s]\n"), name);
11703 break;
11704 }
11705 }
103f02d3 11706
f7a99963
NC
11707 print_vma (entry->d_un.d_val, PREFIX_HEX);
11708 putchar ('\n');
252b5132
RH
11709 }
11710 break;
11711
11712 case DT_BIND_NOW:
11713 /* The value of this entry is ignored. */
35b1837e
AM
11714 if (do_dynamic)
11715 putchar ('\n');
252b5132 11716 break;
103f02d3 11717
047b2264
JJ
11718 case DT_GNU_PRELINKED:
11719 if (do_dynamic)
11720 {
2cf0635d 11721 struct tm * tmp;
91d6fa6a 11722 time_t atime = entry->d_un.d_val;
047b2264 11723
91d6fa6a 11724 tmp = gmtime (&atime);
071436c6
NC
11725 /* PR 17533 file: 041-1244816-0.004. */
11726 if (tmp == NULL)
5a2cbcf4
L
11727 printf (_("<corrupt time val: %lx"),
11728 (unsigned long) atime);
071436c6
NC
11729 else
11730 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11731 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11732 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11733
11734 }
11735 break;
11736
fdc90cb4 11737 case DT_GNU_HASH:
978c4450 11738 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11739 if (do_dynamic)
11740 {
11741 print_vma (entry->d_un.d_val, PREFIX_HEX);
11742 putchar ('\n');
11743 }
11744 break;
11745
a5da3dee
VDM
11746 case DT_GNU_FLAGS_1:
11747 if (do_dynamic)
11748 {
11749 printf (_("Flags:"));
11750 if (entry->d_un.d_val == 0)
11751 printf (_(" None\n"));
11752 else
11753 {
11754 unsigned long int val = entry->d_un.d_val;
11755
11756 if (val & DF_GNU_1_UNIQUE)
11757 {
11758 printf (" UNIQUE");
11759 val ^= DF_GNU_1_UNIQUE;
11760 }
11761 if (val != 0)
11762 printf (" %lx", val);
11763 puts ("");
11764 }
11765 }
11766 break;
11767
252b5132
RH
11768 default:
11769 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11770 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11771 = entry->d_un.d_val;
252b5132
RH
11772
11773 if (do_dynamic)
11774 {
dda8d76d 11775 switch (filedata->file_header.e_machine)
252b5132 11776 {
37c18eed
SD
11777 case EM_AARCH64:
11778 dynamic_section_aarch64_val (entry);
11779 break;
252b5132 11780 case EM_MIPS:
4fe85591 11781 case EM_MIPS_RS3_LE:
978c4450 11782 dynamic_section_mips_val (filedata, entry);
252b5132 11783 break;
103f02d3 11784 case EM_PARISC:
b2d38a17 11785 dynamic_section_parisc_val (entry);
103f02d3 11786 break;
ecc51f48 11787 case EM_IA_64:
b2d38a17 11788 dynamic_section_ia64_val (entry);
ecc51f48 11789 break;
252b5132 11790 default:
f7a99963
NC
11791 print_vma (entry->d_un.d_val, PREFIX_HEX);
11792 putchar ('\n');
252b5132
RH
11793 }
11794 }
11795 break;
11796 }
11797 }
11798
015dc7e1 11799 return true;
252b5132
RH
11800}
11801
11802static char *
d3ba0551 11803get_ver_flags (unsigned int flags)
252b5132 11804{
6d4f21f6 11805 static char buff[128];
252b5132
RH
11806
11807 buff[0] = 0;
11808
11809 if (flags == 0)
11810 return _("none");
11811
11812 if (flags & VER_FLG_BASE)
7bb1ad17 11813 strcat (buff, "BASE");
252b5132
RH
11814
11815 if (flags & VER_FLG_WEAK)
11816 {
11817 if (flags & VER_FLG_BASE)
7bb1ad17 11818 strcat (buff, " | ");
252b5132 11819
7bb1ad17 11820 strcat (buff, "WEAK");
252b5132
RH
11821 }
11822
44ec90b9
RO
11823 if (flags & VER_FLG_INFO)
11824 {
11825 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11826 strcat (buff, " | ");
44ec90b9 11827
7bb1ad17 11828 strcat (buff, "INFO");
44ec90b9
RO
11829 }
11830
11831 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11832 {
11833 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11834 strcat (buff, " | ");
11835
11836 strcat (buff, _("<unknown>"));
11837 }
252b5132
RH
11838
11839 return buff;
11840}
11841
11842/* Display the contents of the version sections. */
98fb390a 11843
015dc7e1 11844static bool
dda8d76d 11845process_version_sections (Filedata * filedata)
252b5132 11846{
2cf0635d 11847 Elf_Internal_Shdr * section;
b34976b6 11848 unsigned i;
015dc7e1 11849 bool found = false;
252b5132
RH
11850
11851 if (! do_version)
015dc7e1 11852 return true;
252b5132 11853
dda8d76d
NC
11854 for (i = 0, section = filedata->section_headers;
11855 i < filedata->file_header.e_shnum;
b34976b6 11856 i++, section++)
252b5132
RH
11857 {
11858 switch (section->sh_type)
11859 {
11860 case SHT_GNU_verdef:
11861 {
2cf0635d 11862 Elf_External_Verdef * edefs;
452bf675
AM
11863 unsigned long idx;
11864 unsigned long cnt;
2cf0635d 11865 char * endbuf;
252b5132 11866
015dc7e1 11867 found = true;
252b5132 11868
ca0e11aa
NC
11869 if (filedata->is_separate)
11870 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11871 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11872 section->sh_info),
11873 filedata->file_name,
11874 printable_section_name (filedata, section),
11875 section->sh_info);
11876 else
11877 printf (ngettext ("\nVersion definition section '%s' "
11878 "contains %u entry:\n",
11879 "\nVersion definition section '%s' "
11880 "contains %u entries:\n",
11881 section->sh_info),
11882 printable_section_name (filedata, section),
11883 section->sh_info);
047c3dbf 11884
ae9ac79e 11885 printf (_(" Addr: 0x"));
252b5132 11886 printf_vma (section->sh_addr);
233f82cf 11887 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11888 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11889 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11890
3f5e193b 11891 edefs = (Elf_External_Verdef *)
dda8d76d 11892 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11893 _("version definition section"));
a6e9f9df
AM
11894 if (!edefs)
11895 break;
59245841 11896 endbuf = (char *) edefs + section->sh_size;
252b5132 11897
1445030f 11898 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11899 {
2cf0635d
NC
11900 char * vstart;
11901 Elf_External_Verdef * edef;
b34976b6 11902 Elf_Internal_Verdef ent;
2cf0635d 11903 Elf_External_Verdaux * eaux;
b34976b6 11904 Elf_Internal_Verdaux aux;
452bf675 11905 unsigned long isum;
b34976b6 11906 int j;
103f02d3 11907
252b5132 11908 vstart = ((char *) edefs) + idx;
54806181
AM
11909 if (vstart + sizeof (*edef) > endbuf)
11910 break;
252b5132
RH
11911
11912 edef = (Elf_External_Verdef *) vstart;
11913
11914 ent.vd_version = BYTE_GET (edef->vd_version);
11915 ent.vd_flags = BYTE_GET (edef->vd_flags);
11916 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11917 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11918 ent.vd_hash = BYTE_GET (edef->vd_hash);
11919 ent.vd_aux = BYTE_GET (edef->vd_aux);
11920 ent.vd_next = BYTE_GET (edef->vd_next);
11921
452bf675 11922 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11923 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11924
11925 printf (_(" Index: %d Cnt: %d "),
11926 ent.vd_ndx, ent.vd_cnt);
11927
452bf675 11928 /* Check for overflow. */
1445030f 11929 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11930 break;
11931
252b5132
RH
11932 vstart += ent.vd_aux;
11933
1445030f
AM
11934 if (vstart + sizeof (*eaux) > endbuf)
11935 break;
252b5132
RH
11936 eaux = (Elf_External_Verdaux *) vstart;
11937
11938 aux.vda_name = BYTE_GET (eaux->vda_name);
11939 aux.vda_next = BYTE_GET (eaux->vda_next);
11940
84714f86 11941 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 11942 printf (_("Name: %s\n"),
84714f86 11943 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
11944 else
11945 printf (_("Name index: %ld\n"), aux.vda_name);
11946
11947 isum = idx + ent.vd_aux;
11948
b34976b6 11949 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11950 {
1445030f
AM
11951 if (aux.vda_next < sizeof (*eaux)
11952 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11953 {
11954 warn (_("Invalid vda_next field of %lx\n"),
11955 aux.vda_next);
11956 j = ent.vd_cnt;
11957 break;
11958 }
dd24e3da 11959 /* Check for overflow. */
7e26601c 11960 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11961 break;
11962
252b5132
RH
11963 isum += aux.vda_next;
11964 vstart += aux.vda_next;
11965
54806181
AM
11966 if (vstart + sizeof (*eaux) > endbuf)
11967 break;
1445030f 11968 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11969
11970 aux.vda_name = BYTE_GET (eaux->vda_name);
11971 aux.vda_next = BYTE_GET (eaux->vda_next);
11972
84714f86 11973 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 11974 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 11975 isum, j,
84714f86 11976 get_dynamic_name (filedata, aux.vda_name));
252b5132 11977 else
452bf675 11978 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11979 isum, j, aux.vda_name);
11980 }
dd24e3da 11981
54806181
AM
11982 if (j < ent.vd_cnt)
11983 printf (_(" Version def aux past end of section\n"));
252b5132 11984
c9f02c3e
MR
11985 /* PR 17531:
11986 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11987 if (ent.vd_next < sizeof (*edef)
11988 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11989 {
11990 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11991 cnt = section->sh_info;
11992 break;
11993 }
452bf675 11994 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11995 break;
11996
252b5132
RH
11997 idx += ent.vd_next;
11998 }
dd24e3da 11999
54806181
AM
12000 if (cnt < section->sh_info)
12001 printf (_(" Version definition past end of section\n"));
252b5132
RH
12002
12003 free (edefs);
12004 }
12005 break;
103f02d3 12006
252b5132
RH
12007 case SHT_GNU_verneed:
12008 {
2cf0635d 12009 Elf_External_Verneed * eneed;
452bf675
AM
12010 unsigned long idx;
12011 unsigned long cnt;
2cf0635d 12012 char * endbuf;
252b5132 12013
015dc7e1 12014 found = true;
252b5132 12015
ca0e11aa
NC
12016 if (filedata->is_separate)
12017 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12018 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12019 section->sh_info),
12020 filedata->file_name,
12021 printable_section_name (filedata, section),
12022 section->sh_info);
12023 else
12024 printf (ngettext ("\nVersion needs section '%s' "
12025 "contains %u entry:\n",
12026 "\nVersion needs section '%s' "
12027 "contains %u entries:\n",
12028 section->sh_info),
12029 printable_section_name (filedata, section),
12030 section->sh_info);
047c3dbf 12031
252b5132
RH
12032 printf (_(" Addr: 0x"));
12033 printf_vma (section->sh_addr);
72de5009 12034 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12035 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12036 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12037
dda8d76d 12038 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12039 section->sh_offset, 1,
12040 section->sh_size,
9cf03b7e 12041 _("Version Needs section"));
a6e9f9df
AM
12042 if (!eneed)
12043 break;
59245841 12044 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12045
12046 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12047 {
2cf0635d 12048 Elf_External_Verneed * entry;
b34976b6 12049 Elf_Internal_Verneed ent;
452bf675 12050 unsigned long isum;
b34976b6 12051 int j;
2cf0635d 12052 char * vstart;
252b5132
RH
12053
12054 vstart = ((char *) eneed) + idx;
54806181
AM
12055 if (vstart + sizeof (*entry) > endbuf)
12056 break;
252b5132
RH
12057
12058 entry = (Elf_External_Verneed *) vstart;
12059
12060 ent.vn_version = BYTE_GET (entry->vn_version);
12061 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12062 ent.vn_file = BYTE_GET (entry->vn_file);
12063 ent.vn_aux = BYTE_GET (entry->vn_aux);
12064 ent.vn_next = BYTE_GET (entry->vn_next);
12065
452bf675 12066 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12067
84714f86 12068 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12069 printf (_(" File: %s"),
84714f86 12070 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12071 else
12072 printf (_(" File: %lx"), ent.vn_file);
12073
12074 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12075
dd24e3da 12076 /* Check for overflow. */
7e26601c 12077 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12078 break;
252b5132
RH
12079 vstart += ent.vn_aux;
12080
12081 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12082 {
2cf0635d 12083 Elf_External_Vernaux * eaux;
b34976b6 12084 Elf_Internal_Vernaux aux;
252b5132 12085
54806181
AM
12086 if (vstart + sizeof (*eaux) > endbuf)
12087 break;
252b5132
RH
12088 eaux = (Elf_External_Vernaux *) vstart;
12089
12090 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12091 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12092 aux.vna_other = BYTE_GET (eaux->vna_other);
12093 aux.vna_name = BYTE_GET (eaux->vna_name);
12094 aux.vna_next = BYTE_GET (eaux->vna_next);
12095
84714f86 12096 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12097 printf (_(" %#06lx: Name: %s"),
84714f86 12098 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12099 else
452bf675 12100 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12101 isum, aux.vna_name);
12102
12103 printf (_(" Flags: %s Version: %d\n"),
12104 get_ver_flags (aux.vna_flags), aux.vna_other);
12105
1445030f
AM
12106 if (aux.vna_next < sizeof (*eaux)
12107 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12108 {
12109 warn (_("Invalid vna_next field of %lx\n"),
12110 aux.vna_next);
12111 j = ent.vn_cnt;
12112 break;
12113 }
1445030f
AM
12114 /* Check for overflow. */
12115 if (aux.vna_next > (size_t) (endbuf - vstart))
12116 break;
252b5132
RH
12117 isum += aux.vna_next;
12118 vstart += aux.vna_next;
12119 }
9cf03b7e 12120
54806181 12121 if (j < ent.vn_cnt)
f9a6a8f0 12122 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12123
1445030f
AM
12124 if (ent.vn_next < sizeof (*entry)
12125 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12126 {
452bf675 12127 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12128 cnt = section->sh_info;
12129 break;
12130 }
1445030f
AM
12131 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12132 break;
252b5132
RH
12133 idx += ent.vn_next;
12134 }
9cf03b7e 12135
54806181 12136 if (cnt < section->sh_info)
9cf03b7e 12137 warn (_("Missing Version Needs information\n"));
103f02d3 12138
252b5132
RH
12139 free (eneed);
12140 }
12141 break;
12142
12143 case SHT_GNU_versym:
12144 {
2cf0635d 12145 Elf_Internal_Shdr * link_section;
8b73c356
NC
12146 size_t total;
12147 unsigned int cnt;
2cf0635d
NC
12148 unsigned char * edata;
12149 unsigned short * data;
12150 char * strtab;
12151 Elf_Internal_Sym * symbols;
12152 Elf_Internal_Shdr * string_sec;
ba5cdace 12153 unsigned long num_syms;
d3ba0551 12154 long off;
252b5132 12155
dda8d76d 12156 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12157 break;
12158
dda8d76d 12159 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12160 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12161
dda8d76d 12162 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12163 break;
12164
015dc7e1 12165 found = true;
252b5132 12166
4de91c10 12167 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12168 if (symbols == NULL)
12169 break;
252b5132 12170
dda8d76d 12171 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12172
dda8d76d 12173 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12174 string_sec->sh_size,
12175 _("version string table"));
a6e9f9df 12176 if (!strtab)
0429c154
MS
12177 {
12178 free (symbols);
12179 break;
12180 }
252b5132 12181
ca0e11aa
NC
12182 if (filedata->is_separate)
12183 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12184 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12185 total),
12186 filedata->file_name,
12187 printable_section_name (filedata, section),
12188 (unsigned long) total);
12189 else
12190 printf (ngettext ("\nVersion symbols section '%s' "
12191 "contains %lu entry:\n",
12192 "\nVersion symbols section '%s' "
12193 "contains %lu entries:\n",
12194 total),
12195 printable_section_name (filedata, section),
12196 (unsigned long) total);
252b5132 12197
ae9ac79e 12198 printf (_(" Addr: 0x"));
252b5132 12199 printf_vma (section->sh_addr);
72de5009 12200 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12201 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12202 printable_section_name (filedata, link_section));
252b5132 12203
dda8d76d 12204 off = offset_from_vma (filedata,
978c4450 12205 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12206 total * sizeof (short));
95099889
AM
12207 edata = (unsigned char *) get_data (NULL, filedata, off,
12208 sizeof (short), total,
12209 _("version symbol data"));
a6e9f9df
AM
12210 if (!edata)
12211 {
12212 free (strtab);
0429c154 12213 free (symbols);
a6e9f9df
AM
12214 break;
12215 }
252b5132 12216
3f5e193b 12217 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12218
12219 for (cnt = total; cnt --;)
b34976b6
AM
12220 data[cnt] = byte_get (edata + cnt * sizeof (short),
12221 sizeof (short));
252b5132
RH
12222
12223 free (edata);
12224
12225 for (cnt = 0; cnt < total; cnt += 4)
12226 {
12227 int j, nn;
ab273396
AM
12228 char *name;
12229 char *invalid = _("*invalid*");
252b5132
RH
12230
12231 printf (" %03x:", cnt);
12232
12233 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12234 switch (data[cnt + j])
252b5132
RH
12235 {
12236 case 0:
12237 fputs (_(" 0 (*local*) "), stdout);
12238 break;
12239
12240 case 1:
12241 fputs (_(" 1 (*global*) "), stdout);
12242 break;
12243
12244 default:
c244d050
NC
12245 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12246 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12247
dd24e3da 12248 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12249 array, break to avoid an out-of-bounds read. */
12250 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12251 {
12252 warn (_("invalid index into symbol array\n"));
12253 break;
12254 }
12255
ab273396 12256 name = NULL;
978c4450 12257 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12258 {
b34976b6
AM
12259 Elf_Internal_Verneed ivn;
12260 unsigned long offset;
252b5132 12261
d93f0186 12262 offset = offset_from_vma
978c4450
AM
12263 (filedata,
12264 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12265 sizeof (Elf_External_Verneed));
252b5132 12266
b34976b6 12267 do
252b5132 12268 {
b34976b6
AM
12269 Elf_Internal_Vernaux ivna;
12270 Elf_External_Verneed evn;
12271 Elf_External_Vernaux evna;
12272 unsigned long a_off;
252b5132 12273
dda8d76d 12274 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12275 _("version need")) == NULL)
12276 break;
0b4362b0 12277
252b5132
RH
12278 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12279 ivn.vn_next = BYTE_GET (evn.vn_next);
12280
12281 a_off = offset + ivn.vn_aux;
12282
12283 do
12284 {
dda8d76d 12285 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12286 1, _("version need aux (2)")) == NULL)
12287 {
12288 ivna.vna_next = 0;
12289 ivna.vna_other = 0;
12290 }
12291 else
12292 {
12293 ivna.vna_next = BYTE_GET (evna.vna_next);
12294 ivna.vna_other = BYTE_GET (evna.vna_other);
12295 }
252b5132
RH
12296
12297 a_off += ivna.vna_next;
12298 }
b34976b6 12299 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12300 && ivna.vna_next != 0);
12301
b34976b6 12302 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12303 {
12304 ivna.vna_name = BYTE_GET (evna.vna_name);
12305
54806181 12306 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12307 name = invalid;
54806181
AM
12308 else
12309 name = strtab + ivna.vna_name;
252b5132
RH
12310 break;
12311 }
12312
12313 offset += ivn.vn_next;
12314 }
12315 while (ivn.vn_next);
12316 }
00d93f34 12317
ab273396 12318 if (data[cnt + j] != 0x8001
978c4450 12319 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12320 {
b34976b6
AM
12321 Elf_Internal_Verdef ivd;
12322 Elf_External_Verdef evd;
12323 unsigned long offset;
252b5132 12324
d93f0186 12325 offset = offset_from_vma
978c4450
AM
12326 (filedata,
12327 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12328 sizeof evd);
252b5132
RH
12329
12330 do
12331 {
dda8d76d 12332 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12333 _("version def")) == NULL)
12334 {
12335 ivd.vd_next = 0;
948f632f 12336 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12337 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12338 break;
59245841
NC
12339 }
12340 else
12341 {
12342 ivd.vd_next = BYTE_GET (evd.vd_next);
12343 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12344 }
252b5132
RH
12345
12346 offset += ivd.vd_next;
12347 }
c244d050 12348 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12349 && ivd.vd_next != 0);
12350
c244d050 12351 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12352 {
b34976b6
AM
12353 Elf_External_Verdaux evda;
12354 Elf_Internal_Verdaux ivda;
252b5132
RH
12355
12356 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12357
dda8d76d 12358 if (get_data (&evda, filedata,
59245841
NC
12359 offset - ivd.vd_next + ivd.vd_aux,
12360 sizeof (evda), 1,
12361 _("version def aux")) == NULL)
12362 break;
252b5132
RH
12363
12364 ivda.vda_name = BYTE_GET (evda.vda_name);
12365
54806181 12366 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12367 name = invalid;
12368 else if (name != NULL && name != invalid)
12369 name = _("*both*");
54806181
AM
12370 else
12371 name = strtab + ivda.vda_name;
252b5132
RH
12372 }
12373 }
ab273396
AM
12374 if (name != NULL)
12375 nn += printf ("(%s%-*s",
12376 name,
12377 12 - (int) strlen (name),
12378 ")");
252b5132
RH
12379
12380 if (nn < 18)
12381 printf ("%*c", 18 - nn, ' ');
12382 }
12383
12384 putchar ('\n');
12385 }
12386
12387 free (data);
12388 free (strtab);
12389 free (symbols);
12390 }
12391 break;
103f02d3 12392
252b5132
RH
12393 default:
12394 break;
12395 }
12396 }
12397
12398 if (! found)
ca0e11aa
NC
12399 {
12400 if (filedata->is_separate)
12401 printf (_("\nNo version information found in linked file '%s'.\n"),
12402 filedata->file_name);
12403 else
12404 printf (_("\nNo version information found in this file.\n"));
12405 }
252b5132 12406
015dc7e1 12407 return true;
252b5132
RH
12408}
12409
d1133906 12410static const char *
dda8d76d 12411get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12412{
89246a0e 12413 static char buff[64];
252b5132
RH
12414
12415 switch (binding)
12416 {
b34976b6
AM
12417 case STB_LOCAL: return "LOCAL";
12418 case STB_GLOBAL: return "GLOBAL";
12419 case STB_WEAK: return "WEAK";
252b5132
RH
12420 default:
12421 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12422 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12423 binding);
252b5132 12424 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12425 {
12426 if (binding == STB_GNU_UNIQUE
df3a023b 12427 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12428 return "UNIQUE";
12429 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12430 }
252b5132 12431 else
e9e44622 12432 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12433 return buff;
12434 }
12435}
12436
d1133906 12437static const char *
dda8d76d 12438get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12439{
89246a0e 12440 static char buff[64];
252b5132
RH
12441
12442 switch (type)
12443 {
b34976b6
AM
12444 case STT_NOTYPE: return "NOTYPE";
12445 case STT_OBJECT: return "OBJECT";
12446 case STT_FUNC: return "FUNC";
12447 case STT_SECTION: return "SECTION";
12448 case STT_FILE: return "FILE";
12449 case STT_COMMON: return "COMMON";
12450 case STT_TLS: return "TLS";
15ab5209
DB
12451 case STT_RELC: return "RELC";
12452 case STT_SRELC: return "SRELC";
252b5132
RH
12453 default:
12454 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12455 {
dda8d76d 12456 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12457 return "THUMB_FUNC";
103f02d3 12458
dda8d76d 12459 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12460 return "REGISTER";
12461
dda8d76d 12462 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12463 return "PARISC_MILLI";
12464
e9e44622 12465 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12466 }
252b5132 12467 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12468 {
dda8d76d 12469 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12470 {
12471 if (type == STT_HP_OPAQUE)
12472 return "HP_OPAQUE";
12473 if (type == STT_HP_STUB)
12474 return "HP_STUB";
12475 }
12476
d8045f23 12477 if (type == STT_GNU_IFUNC
dda8d76d 12478 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12479 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12480 return "IFUNC";
12481
e9e44622 12482 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12483 }
252b5132 12484 else
e9e44622 12485 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12486 return buff;
12487 }
12488}
12489
d1133906 12490static const char *
d3ba0551 12491get_symbol_visibility (unsigned int visibility)
d1133906
NC
12492{
12493 switch (visibility)
12494 {
b34976b6
AM
12495 case STV_DEFAULT: return "DEFAULT";
12496 case STV_INTERNAL: return "INTERNAL";
12497 case STV_HIDDEN: return "HIDDEN";
d1133906 12498 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12499 default:
27a45f42 12500 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12501 return _("<unknown>");
d1133906
NC
12502 }
12503}
12504
2057d69d
CZ
12505static const char *
12506get_alpha_symbol_other (unsigned int other)
9abca702 12507{
2057d69d
CZ
12508 switch (other)
12509 {
12510 case STO_ALPHA_NOPV: return "NOPV";
12511 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12512 default:
27a45f42 12513 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12514 return _("<unknown>");
9abca702 12515 }
2057d69d
CZ
12516}
12517
fd85a6a1
NC
12518static const char *
12519get_solaris_symbol_visibility (unsigned int visibility)
12520{
12521 switch (visibility)
12522 {
12523 case 4: return "EXPORTED";
12524 case 5: return "SINGLETON";
12525 case 6: return "ELIMINATE";
12526 default: return get_symbol_visibility (visibility);
12527 }
12528}
12529
2301ed1c
SN
12530static const char *
12531get_aarch64_symbol_other (unsigned int other)
12532{
12533 static char buf[32];
12534
12535 if (other & STO_AARCH64_VARIANT_PCS)
12536 {
12537 other &= ~STO_AARCH64_VARIANT_PCS;
12538 if (other == 0)
12539 return "VARIANT_PCS";
12540 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12541 return buf;
12542 }
12543 return NULL;
12544}
12545
5e2b0d47
NC
12546static const char *
12547get_mips_symbol_other (unsigned int other)
12548{
12549 switch (other)
12550 {
32ec8896
NC
12551 case STO_OPTIONAL: return "OPTIONAL";
12552 case STO_MIPS_PLT: return "MIPS PLT";
12553 case STO_MIPS_PIC: return "MIPS PIC";
12554 case STO_MICROMIPS: return "MICROMIPS";
12555 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12556 case STO_MIPS16: return "MIPS16";
12557 default: return NULL;
5e2b0d47
NC
12558 }
12559}
12560
28f997cf 12561static const char *
dda8d76d 12562get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12563{
dda8d76d 12564 if (is_ia64_vms (filedata))
28f997cf
TG
12565 {
12566 static char res[32];
12567
12568 res[0] = 0;
12569
12570 /* Function types is for images and .STB files only. */
dda8d76d 12571 switch (filedata->file_header.e_type)
28f997cf
TG
12572 {
12573 case ET_DYN:
12574 case ET_EXEC:
12575 switch (VMS_ST_FUNC_TYPE (other))
12576 {
12577 case VMS_SFT_CODE_ADDR:
12578 strcat (res, " CA");
12579 break;
12580 case VMS_SFT_SYMV_IDX:
12581 strcat (res, " VEC");
12582 break;
12583 case VMS_SFT_FD:
12584 strcat (res, " FD");
12585 break;
12586 case VMS_SFT_RESERVE:
12587 strcat (res, " RSV");
12588 break;
12589 default:
bee0ee85
NC
12590 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12591 VMS_ST_FUNC_TYPE (other));
12592 strcat (res, " <unknown>");
12593 break;
28f997cf
TG
12594 }
12595 break;
12596 default:
12597 break;
12598 }
12599 switch (VMS_ST_LINKAGE (other))
12600 {
12601 case VMS_STL_IGNORE:
12602 strcat (res, " IGN");
12603 break;
12604 case VMS_STL_RESERVE:
12605 strcat (res, " RSV");
12606 break;
12607 case VMS_STL_STD:
12608 strcat (res, " STD");
12609 break;
12610 case VMS_STL_LNK:
12611 strcat (res, " LNK");
12612 break;
12613 default:
bee0ee85
NC
12614 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12615 VMS_ST_LINKAGE (other));
12616 strcat (res, " <unknown>");
12617 break;
28f997cf
TG
12618 }
12619
12620 if (res[0] != 0)
12621 return res + 1;
12622 else
12623 return res;
12624 }
12625 return NULL;
12626}
12627
6911b7dc
AM
12628static const char *
12629get_ppc64_symbol_other (unsigned int other)
12630{
14732552
AM
12631 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12632 return NULL;
12633
12634 other >>= STO_PPC64_LOCAL_BIT;
12635 if (other <= 6)
6911b7dc 12636 {
89246a0e 12637 static char buf[64];
14732552
AM
12638 if (other >= 2)
12639 other = ppc64_decode_local_entry (other);
12640 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12641 return buf;
12642 }
12643 return NULL;
12644}
12645
5e2b0d47 12646static const char *
dda8d76d 12647get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12648{
12649 const char * result = NULL;
89246a0e 12650 static char buff [64];
5e2b0d47
NC
12651
12652 if (other == 0)
12653 return "";
12654
dda8d76d 12655 switch (filedata->file_header.e_machine)
5e2b0d47 12656 {
2057d69d
CZ
12657 case EM_ALPHA:
12658 result = get_alpha_symbol_other (other);
12659 break;
2301ed1c
SN
12660 case EM_AARCH64:
12661 result = get_aarch64_symbol_other (other);
12662 break;
5e2b0d47
NC
12663 case EM_MIPS:
12664 result = get_mips_symbol_other (other);
28f997cf
TG
12665 break;
12666 case EM_IA_64:
dda8d76d 12667 result = get_ia64_symbol_other (filedata, other);
28f997cf 12668 break;
6911b7dc
AM
12669 case EM_PPC64:
12670 result = get_ppc64_symbol_other (other);
12671 break;
5e2b0d47 12672 default:
fd85a6a1 12673 result = NULL;
5e2b0d47
NC
12674 break;
12675 }
12676
12677 if (result)
12678 return result;
12679
12680 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12681 return buff;
12682}
12683
d1133906 12684static const char *
dda8d76d 12685get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12686{
b34976b6 12687 static char buff[32];
5cf1065c 12688
252b5132
RH
12689 switch (type)
12690 {
b34976b6
AM
12691 case SHN_UNDEF: return "UND";
12692 case SHN_ABS: return "ABS";
12693 case SHN_COMMON: return "COM";
252b5132 12694 default:
9ce701e2 12695 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12696 && filedata->file_header.e_machine == EM_IA_64
12697 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12698 return "ANSI_COM";
12699 else if ((filedata->file_header.e_machine == EM_X86_64
12700 || filedata->file_header.e_machine == EM_L1OM
12701 || filedata->file_header.e_machine == EM_K1OM)
12702 && type == SHN_X86_64_LCOMMON)
12703 return "LARGE_COM";
12704 else if ((type == SHN_MIPS_SCOMMON
12705 && filedata->file_header.e_machine == EM_MIPS)
12706 || (type == SHN_TIC6X_SCOMMON
12707 && filedata->file_header.e_machine == EM_TI_C6000))
12708 return "SCOM";
12709 else if (type == SHN_MIPS_SUNDEFINED
12710 && filedata->file_header.e_machine == EM_MIPS)
12711 return "SUND";
12712 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12713 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12714 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12715 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12716 else if (type >= SHN_LORESERVE)
12717 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12718 else if (filedata->file_header.e_shnum != 0
12719 && type >= filedata->file_header.e_shnum)
12720 sprintf (buff, _("bad section index[%3d]"), type);
12721 else
12722 sprintf (buff, "%3d", type);
12723 break;
fd85a6a1
NC
12724 }
12725
10ca4b04 12726 return buff;
6bd1a22c
L
12727}
12728
bb4d2ac2 12729static const char *
dda8d76d 12730get_symbol_version_string (Filedata * filedata,
015dc7e1 12731 bool is_dynsym,
1449284b
NC
12732 const char * strtab,
12733 unsigned long int strtab_size,
12734 unsigned int si,
12735 Elf_Internal_Sym * psym,
12736 enum versioned_symbol_info * sym_info,
12737 unsigned short * vna_other)
bb4d2ac2 12738{
ab273396
AM
12739 unsigned char data[2];
12740 unsigned short vers_data;
12741 unsigned long offset;
7a815dd5 12742 unsigned short max_vd_ndx;
bb4d2ac2 12743
ab273396 12744 if (!is_dynsym
978c4450 12745 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12746 return NULL;
bb4d2ac2 12747
978c4450
AM
12748 offset = offset_from_vma (filedata,
12749 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12750 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12751
dda8d76d 12752 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12753 sizeof (data), 1, _("version data")) == NULL)
12754 return NULL;
12755
12756 vers_data = byte_get (data, 2);
bb4d2ac2 12757
1f6f5dba 12758 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12759 return NULL;
bb4d2ac2 12760
0b8b7609 12761 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12762 max_vd_ndx = 0;
12763
ab273396
AM
12764 /* Usually we'd only see verdef for defined symbols, and verneed for
12765 undefined symbols. However, symbols defined by the linker in
12766 .dynbss for variables copied from a shared library in order to
12767 avoid text relocations are defined yet have verneed. We could
12768 use a heuristic to detect the special case, for example, check
12769 for verneed first on symbols defined in SHT_NOBITS sections, but
12770 it is simpler and more reliable to just look for both verdef and
12771 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12772
ab273396
AM
12773 if (psym->st_shndx != SHN_UNDEF
12774 && vers_data != 0x8001
978c4450 12775 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12776 {
12777 Elf_Internal_Verdef ivd;
12778 Elf_Internal_Verdaux ivda;
12779 Elf_External_Verdaux evda;
12780 unsigned long off;
bb4d2ac2 12781
dda8d76d 12782 off = offset_from_vma (filedata,
978c4450 12783 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12784 sizeof (Elf_External_Verdef));
12785
12786 do
bb4d2ac2 12787 {
ab273396
AM
12788 Elf_External_Verdef evd;
12789
dda8d76d 12790 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12791 _("version def")) == NULL)
12792 {
12793 ivd.vd_ndx = 0;
12794 ivd.vd_aux = 0;
12795 ivd.vd_next = 0;
1f6f5dba 12796 ivd.vd_flags = 0;
ab273396
AM
12797 }
12798 else
bb4d2ac2 12799 {
ab273396
AM
12800 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12801 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12802 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12803 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12804 }
bb4d2ac2 12805
7a815dd5
L
12806 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12807 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12808
ab273396
AM
12809 off += ivd.vd_next;
12810 }
12811 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12812
ab273396
AM
12813 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12814 {
9abca702 12815 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12816 return NULL;
12817
ab273396
AM
12818 off -= ivd.vd_next;
12819 off += ivd.vd_aux;
bb4d2ac2 12820
dda8d76d 12821 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12822 _("version def aux")) != NULL)
12823 {
12824 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12825
ab273396 12826 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12827 return (ivda.vda_name < strtab_size
12828 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12829 }
12830 }
12831 }
bb4d2ac2 12832
978c4450 12833 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12834 {
12835 Elf_External_Verneed evn;
12836 Elf_Internal_Verneed ivn;
12837 Elf_Internal_Vernaux ivna;
bb4d2ac2 12838
dda8d76d 12839 offset = offset_from_vma (filedata,
978c4450 12840 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12841 sizeof evn);
12842 do
12843 {
12844 unsigned long vna_off;
bb4d2ac2 12845
dda8d76d 12846 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12847 _("version need")) == NULL)
12848 {
12849 ivna.vna_next = 0;
12850 ivna.vna_other = 0;
12851 ivna.vna_name = 0;
12852 break;
12853 }
bb4d2ac2 12854
ab273396
AM
12855 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12856 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12857
ab273396 12858 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12859
ab273396
AM
12860 do
12861 {
12862 Elf_External_Vernaux evna;
bb4d2ac2 12863
dda8d76d 12864 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12865 _("version need aux (3)")) == NULL)
bb4d2ac2 12866 {
ab273396
AM
12867 ivna.vna_next = 0;
12868 ivna.vna_other = 0;
12869 ivna.vna_name = 0;
bb4d2ac2 12870 }
bb4d2ac2 12871 else
bb4d2ac2 12872 {
ab273396
AM
12873 ivna.vna_other = BYTE_GET (evna.vna_other);
12874 ivna.vna_next = BYTE_GET (evna.vna_next);
12875 ivna.vna_name = BYTE_GET (evna.vna_name);
12876 }
bb4d2ac2 12877
ab273396
AM
12878 vna_off += ivna.vna_next;
12879 }
12880 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12881
ab273396
AM
12882 if (ivna.vna_other == vers_data)
12883 break;
bb4d2ac2 12884
ab273396
AM
12885 offset += ivn.vn_next;
12886 }
12887 while (ivn.vn_next != 0);
bb4d2ac2 12888
ab273396
AM
12889 if (ivna.vna_other == vers_data)
12890 {
12891 *sym_info = symbol_undefined;
12892 *vna_other = ivna.vna_other;
12893 return (ivna.vna_name < strtab_size
12894 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12895 }
7a815dd5
L
12896 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12897 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12898 return _("<corrupt>");
bb4d2ac2 12899 }
ab273396 12900 return NULL;
bb4d2ac2
L
12901}
12902
047c3dbf
NL
12903/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12904
12905static unsigned int
12906print_dynamic_symbol_size (bfd_vma vma, int base)
12907{
12908 switch (base)
12909 {
12910 case 8:
12911 return print_vma (vma, OCTAL_5);
12912
12913 case 10:
12914 return print_vma (vma, UNSIGNED_5);
12915
12916 case 16:
12917 return print_vma (vma, PREFIX_HEX_5);
12918
12919 case 0:
12920 default:
12921 return print_vma (vma, DEC_5);
12922 }
12923}
12924
10ca4b04
L
12925static void
12926print_dynamic_symbol (Filedata *filedata, unsigned long si,
12927 Elf_Internal_Sym *symtab,
12928 Elf_Internal_Shdr *section,
12929 char *strtab, size_t strtab_size)
252b5132 12930{
10ca4b04
L
12931 const char *version_string;
12932 enum versioned_symbol_info sym_info;
12933 unsigned short vna_other;
23356397
NC
12934 bool is_valid;
12935 const char * sstr;
10ca4b04 12936 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12937
10ca4b04
L
12938 printf ("%6ld: ", si);
12939 print_vma (psym->st_value, LONG_HEX);
12940 putchar (' ');
047c3dbf 12941 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12942 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12943 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12944 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12945 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12946 else
252b5132 12947 {
10ca4b04 12948 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12949
10ca4b04
L
12950 printf (" %-7s", get_symbol_visibility (vis));
12951 /* Check to see if any other bits in the st_other field are set.
12952 Note - displaying this information disrupts the layout of the
12953 table being generated, but for the moment this case is very rare. */
12954 if (psym->st_other ^ vis)
12955 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12956 }
10ca4b04 12957 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12958
23356397
NC
12959 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12960 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 12961 && filedata->section_headers != NULL
23356397
NC
12962 && psym->st_name == 0)
12963 {
84714f86
AM
12964 is_valid
12965 = section_name_valid (filedata,
12966 filedata->section_headers + psym->st_shndx);
23356397 12967 sstr = is_valid ?
84714f86
AM
12968 section_name_print (filedata,
12969 filedata->section_headers + psym->st_shndx)
23356397
NC
12970 : _("<corrupt>");
12971 }
12972 else
12973 {
84714f86 12974 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
12975 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
12976 }
10ca4b04
L
12977
12978 version_string
12979 = get_symbol_version_string (filedata,
12980 (section == NULL
12981 || section->sh_type == SHT_DYNSYM),
12982 strtab, strtab_size, si,
12983 psym, &sym_info, &vna_other);
b9e920ec 12984
0942c7ab
NC
12985 int len_avail = 21;
12986 if (! do_wide && version_string != NULL)
12987 {
ddb43bab 12988 char buffer[16];
0942c7ab 12989
ddb43bab 12990 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12991
12992 if (sym_info == symbol_undefined)
12993 len_avail -= sprintf (buffer," (%d)", vna_other);
12994 else if (sym_info != symbol_hidden)
12995 len_avail -= 1;
12996 }
12997
12998 print_symbol (len_avail, sstr);
b9e920ec 12999
10ca4b04
L
13000 if (version_string)
13001 {
13002 if (sym_info == symbol_undefined)
13003 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13004 else
10ca4b04
L
13005 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13006 version_string);
13007 }
6bd1a22c 13008
10ca4b04 13009 putchar ('\n');
6bd1a22c 13010
10ca4b04
L
13011 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13012 && section != NULL
13013 && si >= section->sh_info
13014 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13015 && filedata->file_header.e_machine != EM_MIPS
13016 /* Solaris binaries have been found to violate this requirement as
13017 well. Not sure if this is a bug or an ABI requirement. */
13018 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13019 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13020 si, printable_section_name (filedata, section), section->sh_info);
13021}
f16a9783 13022
0f03783c
NC
13023static const char *
13024get_lto_kind (unsigned int kind)
13025{
13026 switch (kind)
13027 {
13028 case 0: return "DEF";
13029 case 1: return "WEAKDEF";
13030 case 2: return "UNDEF";
13031 case 3: return "WEAKUNDEF";
13032 case 4: return "COMMON";
13033 default:
13034 break;
13035 }
13036
13037 static char buffer[30];
13038 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13039 sprintf (buffer, "<unknown: %u>", kind);
13040 return buffer;
13041}
13042
13043static const char *
13044get_lto_visibility (unsigned int visibility)
13045{
13046 switch (visibility)
13047 {
13048 case 0: return "DEFAULT";
13049 case 1: return "PROTECTED";
13050 case 2: return "INTERNAL";
13051 case 3: return "HIDDEN";
13052 default:
13053 break;
13054 }
13055
13056 static char buffer[30];
13057 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13058 sprintf (buffer, "<unknown: %u>", visibility);
13059 return buffer;
13060}
13061
13062static const char *
13063get_lto_sym_type (unsigned int sym_type)
13064{
13065 switch (sym_type)
13066 {
13067 case 0: return "UNKNOWN";
13068 case 1: return "FUNCTION";
13069 case 2: return "VARIABLE";
13070 default:
13071 break;
13072 }
13073
13074 static char buffer[30];
13075 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13076 sprintf (buffer, "<unknown: %u>", sym_type);
13077 return buffer;
13078}
13079
13080/* Display an LTO format symbol table.
13081 FIXME: The format of LTO symbol tables is not formalized.
13082 So this code could need changing in the future. */
13083
015dc7e1 13084static bool
0f03783c
NC
13085display_lto_symtab (Filedata * filedata,
13086 Elf_Internal_Shdr * section)
13087{
13088 if (section->sh_size == 0)
13089 {
ca0e11aa
NC
13090 if (filedata->is_separate)
13091 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13092 printable_section_name (filedata, section),
13093 filedata->file_name);
13094 else
13095 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13096 printable_section_name (filedata, section));
047c3dbf 13097
015dc7e1 13098 return true;
0f03783c
NC
13099 }
13100
13101 if (section->sh_size > filedata->file_size)
13102 {
13103 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13104 printable_section_name (filedata, section),
13105 (unsigned long) section->sh_size);
015dc7e1 13106 return false;
0f03783c
NC
13107 }
13108
13109 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13110 section->sh_size, 1, _("LTO symbols"));
13111 if (alloced_data == NULL)
015dc7e1 13112 return false;
0f03783c
NC
13113
13114 /* Look for extended data for the symbol table. */
13115 Elf_Internal_Shdr * ext;
13116 void * ext_data_orig = NULL;
13117 char * ext_data = NULL;
13118 char * ext_data_end = NULL;
13119 char * ext_name = NULL;
13120
13121 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13122 (section_name (filedata, section)
13123 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13124 && ext_name != NULL /* Paranoia. */
13125 && (ext = find_section (filedata, ext_name)) != NULL)
13126 {
13127 if (ext->sh_size < 3)
13128 error (_("LTO Symbol extension table '%s' is empty!\n"),
13129 printable_section_name (filedata, ext));
13130 else
13131 {
13132 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13133 ext->sh_size, 1,
13134 _("LTO ext symbol data"));
13135 if (ext_data != NULL)
13136 {
13137 ext_data_end = ext_data + ext->sh_size;
13138 if (* ext_data++ != 1)
13139 error (_("Unexpected version number in symbol extension table\n"));
13140 }
13141 }
13142 }
b9e920ec 13143
0f03783c
NC
13144 const unsigned char * data = (const unsigned char *) alloced_data;
13145 const unsigned char * end = data + section->sh_size;
13146
ca0e11aa
NC
13147 if (filedata->is_separate)
13148 printf (_("\nIn linked file '%s': "), filedata->file_name);
13149 else
13150 printf ("\n");
13151
0f03783c
NC
13152 if (ext_data_orig != NULL)
13153 {
13154 if (do_wide)
ca0e11aa 13155 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13156 printable_section_name (filedata, section),
13157 printable_section_name (filedata, ext));
13158 else
13159 {
ca0e11aa 13160 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13161 printable_section_name (filedata, section));
13162 printf (_(" and extension table '%s' contain:\n"),
13163 printable_section_name (filedata, ext));
13164 }
13165 }
13166 else
ca0e11aa 13167 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13168 printable_section_name (filedata, section));
b9e920ec 13169
0f03783c 13170 /* FIXME: Add a wide version. */
b9e920ec 13171 if (ext_data_orig != NULL)
0f03783c
NC
13172 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13173 else
13174 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13175
13176 /* FIXME: We do not handle style prefixes. */
13177
13178 while (data < end)
13179 {
13180 const unsigned char * sym_name = data;
13181 data += strnlen ((const char *) sym_name, end - data) + 1;
13182 if (data >= end)
13183 goto fail;
13184
13185 const unsigned char * comdat_key = data;
13186 data += strnlen ((const char *) comdat_key, end - data) + 1;
13187 if (data >= end)
13188 goto fail;
13189
13190 if (data + 2 + 8 + 4 > end)
13191 goto fail;
13192
13193 unsigned int kind = *data++;
13194 unsigned int visibility = *data++;
13195
13196 elf_vma size = byte_get (data, 8);
13197 data += 8;
13198
13199 elf_vma slot = byte_get (data, 4);
13200 data += 4;
13201
13202 if (ext_data != NULL)
13203 {
13204 if (ext_data < (ext_data_end - 1))
13205 {
13206 unsigned int sym_type = * ext_data ++;
13207 unsigned int sec_kind = * ext_data ++;
13208
13209 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
13210 * comdat_key == 0 ? "-" : (char *) comdat_key,
13211 get_lto_kind (kind),
13212 get_lto_visibility (visibility),
13213 (long) size,
13214 (long) slot,
13215 get_lto_sym_type (sym_type),
13216 (long) sec_kind);
13217 print_symbol (6, (const char *) sym_name);
13218 }
13219 else
13220 {
13221 error (_("Ran out of LTO symbol extension data\n"));
13222 ext_data = NULL;
13223 /* FIXME: return FAIL result ? */
13224 }
13225 }
13226 else
13227 {
13228 printf (" %10s %10s %11s %08lx %08lx _",
13229 * comdat_key == 0 ? "-" : (char *) comdat_key,
13230 get_lto_kind (kind),
13231 get_lto_visibility (visibility),
13232 (long) size,
13233 (long) slot);
13234 print_symbol (21, (const char *) sym_name);
13235 }
13236 putchar ('\n');
13237 }
13238
13239 if (ext_data != NULL && ext_data < ext_data_end)
13240 {
13241 error (_("Data remains in the LTO symbol extension table\n"));
13242 goto fail;
13243 }
13244
13245 free (alloced_data);
13246 free (ext_data_orig);
13247 free (ext_name);
015dc7e1 13248 return true;
b9e920ec 13249
0f03783c
NC
13250 fail:
13251 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13252 free (alloced_data);
13253 free (ext_data_orig);
13254 free (ext_name);
015dc7e1 13255 return false;
0f03783c
NC
13256}
13257
13258/* Display LTO symbol tables. */
13259
015dc7e1 13260static bool
0f03783c
NC
13261process_lto_symbol_tables (Filedata * filedata)
13262{
13263 Elf_Internal_Shdr * section;
13264 unsigned int i;
015dc7e1 13265 bool res = true;
0f03783c
NC
13266
13267 if (!do_lto_syms)
015dc7e1 13268 return true;
0f03783c
NC
13269
13270 if (filedata->section_headers == NULL)
015dc7e1 13271 return true;
0f03783c
NC
13272
13273 for (i = 0, section = filedata->section_headers;
13274 i < filedata->file_header.e_shnum;
13275 i++, section++)
84714f86
AM
13276 if (section_name_valid (filedata, section)
13277 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13278 res &= display_lto_symtab (filedata, section);
13279
b9e920ec 13280 return res;
0f03783c
NC
13281}
13282
10ca4b04 13283/* Dump the symbol table. */
0f03783c 13284
015dc7e1 13285static bool
10ca4b04
L
13286process_symbol_table (Filedata * filedata)
13287{
13288 Elf_Internal_Shdr * section;
f16a9783 13289
10ca4b04 13290 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13291 return true;
6bd1a22c 13292
978c4450 13293 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13294 && do_syms
13295 && do_using_dynamic
978c4450
AM
13296 && filedata->dynamic_strings != NULL
13297 && filedata->dynamic_symbols != NULL)
6bd1a22c 13298 {
10ca4b04 13299 unsigned long si;
6bd1a22c 13300
ca0e11aa
NC
13301 if (filedata->is_separate)
13302 {
13303 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13304 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13305 filedata->num_dynamic_syms),
13306 filedata->file_name,
13307 filedata->num_dynamic_syms);
13308 }
13309 else
13310 {
13311 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13312 "\nSymbol table for image contains %lu entries:\n",
13313 filedata->num_dynamic_syms),
13314 filedata->num_dynamic_syms);
13315 }
10ca4b04
L
13316 if (is_32bit_elf)
13317 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13318 else
13319 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13320
978c4450
AM
13321 for (si = 0; si < filedata->num_dynamic_syms; si++)
13322 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13323 filedata->dynamic_strings,
13324 filedata->dynamic_strings_length);
252b5132 13325 }
8b73c356 13326 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13327 && filedata->section_headers != NULL)
252b5132 13328 {
b34976b6 13329 unsigned int i;
252b5132 13330
dda8d76d
NC
13331 for (i = 0, section = filedata->section_headers;
13332 i < filedata->file_header.e_shnum;
252b5132
RH
13333 i++, section++)
13334 {
2cf0635d 13335 char * strtab = NULL;
c256ffe7 13336 unsigned long int strtab_size = 0;
2cf0635d 13337 Elf_Internal_Sym * symtab;
ef3df110 13338 unsigned long si, num_syms;
252b5132 13339
2c610e4b
L
13340 if ((section->sh_type != SHT_SYMTAB
13341 && section->sh_type != SHT_DYNSYM)
13342 || (!do_syms
13343 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13344 continue;
13345
dd24e3da
NC
13346 if (section->sh_entsize == 0)
13347 {
13348 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13349 printable_section_name (filedata, section));
dd24e3da
NC
13350 continue;
13351 }
13352
d3a49aa8 13353 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13354
13355 if (filedata->is_separate)
13356 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13357 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13358 num_syms),
13359 filedata->file_name,
13360 printable_section_name (filedata, section),
13361 num_syms);
13362 else
13363 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13364 "\nSymbol table '%s' contains %lu entries:\n",
13365 num_syms),
13366 printable_section_name (filedata, section),
13367 num_syms);
dd24e3da 13368
f7a99963 13369 if (is_32bit_elf)
ca47b30c 13370 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13371 else
ca47b30c 13372 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13373
4de91c10 13374 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13375 if (symtab == NULL)
13376 continue;
13377
dda8d76d 13378 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13379 {
dda8d76d
NC
13380 strtab = filedata->string_table;
13381 strtab_size = filedata->string_table_length;
c256ffe7 13382 }
dda8d76d 13383 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13384 {
2cf0635d 13385 Elf_Internal_Shdr * string_sec;
252b5132 13386
dda8d76d 13387 string_sec = filedata->section_headers + section->sh_link;
252b5132 13388
dda8d76d 13389 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13390 1, string_sec->sh_size,
13391 _("string table"));
c256ffe7 13392 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13393 }
13394
10ca4b04
L
13395 for (si = 0; si < num_syms; si++)
13396 print_dynamic_symbol (filedata, si, symtab, section,
13397 strtab, strtab_size);
252b5132
RH
13398
13399 free (symtab);
dda8d76d 13400 if (strtab != filedata->string_table)
252b5132
RH
13401 free (strtab);
13402 }
13403 }
13404 else if (do_syms)
13405 printf
13406 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13407
978c4450 13408 if (do_histogram && filedata->buckets != NULL)
252b5132 13409 {
2cf0635d
NC
13410 unsigned long * lengths;
13411 unsigned long * counts;
66543521
AM
13412 unsigned long hn;
13413 bfd_vma si;
13414 unsigned long maxlength = 0;
13415 unsigned long nzero_counts = 0;
13416 unsigned long nsyms = 0;
6bd6a03d 13417 char *visited;
252b5132 13418
d3a49aa8
AM
13419 printf (ngettext ("\nHistogram for bucket list length "
13420 "(total of %lu bucket):\n",
13421 "\nHistogram for bucket list length "
13422 "(total of %lu buckets):\n",
978c4450
AM
13423 (unsigned long) filedata->nbuckets),
13424 (unsigned long) filedata->nbuckets);
252b5132 13425
978c4450
AM
13426 lengths = (unsigned long *) calloc (filedata->nbuckets,
13427 sizeof (*lengths));
252b5132
RH
13428 if (lengths == NULL)
13429 {
8b73c356 13430 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13431 goto err_out;
252b5132 13432 }
978c4450
AM
13433 visited = xcmalloc (filedata->nchains, 1);
13434 memset (visited, 0, filedata->nchains);
8b73c356
NC
13435
13436 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13437 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13438 {
978c4450 13439 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13440 {
b34976b6 13441 ++nsyms;
252b5132 13442 if (maxlength < ++lengths[hn])
b34976b6 13443 ++maxlength;
978c4450 13444 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13445 {
13446 error (_("histogram chain is corrupt\n"));
13447 break;
13448 }
13449 visited[si] = 1;
252b5132
RH
13450 }
13451 }
6bd6a03d 13452 free (visited);
252b5132 13453
3f5e193b 13454 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13455 if (counts == NULL)
13456 {
b2e951ec 13457 free (lengths);
8b73c356 13458 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13459 goto err_out;
252b5132
RH
13460 }
13461
978c4450 13462 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13463 ++counts[lengths[hn]];
252b5132 13464
978c4450 13465 if (filedata->nbuckets > 0)
252b5132 13466 {
66543521
AM
13467 unsigned long i;
13468 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13469 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13470 for (i = 1; i <= maxlength; ++i)
103f02d3 13471 {
66543521
AM
13472 nzero_counts += counts[i] * i;
13473 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13474 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13475 (nzero_counts * 100.0) / nsyms);
13476 }
252b5132
RH
13477 }
13478
13479 free (counts);
13480 free (lengths);
13481 }
13482
978c4450
AM
13483 free (filedata->buckets);
13484 filedata->buckets = NULL;
13485 filedata->nbuckets = 0;
13486 free (filedata->chains);
13487 filedata->chains = NULL;
252b5132 13488
978c4450 13489 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13490 {
2cf0635d
NC
13491 unsigned long * lengths;
13492 unsigned long * counts;
fdc90cb4
JJ
13493 unsigned long hn;
13494 unsigned long maxlength = 0;
13495 unsigned long nzero_counts = 0;
13496 unsigned long nsyms = 0;
fdc90cb4 13497
f16a9783 13498 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13499 "(total of %lu bucket):\n",
f16a9783 13500 "\nHistogram for `%s' bucket list length "
d3a49aa8 13501 "(total of %lu buckets):\n",
978c4450
AM
13502 (unsigned long) filedata->ngnubuckets),
13503 GNU_HASH_SECTION_NAME (filedata),
13504 (unsigned long) filedata->ngnubuckets);
8b73c356 13505
978c4450
AM
13506 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13507 sizeof (*lengths));
fdc90cb4
JJ
13508 if (lengths == NULL)
13509 {
8b73c356 13510 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13511 goto err_out;
fdc90cb4
JJ
13512 }
13513
fdc90cb4
JJ
13514 printf (_(" Length Number %% of total Coverage\n"));
13515
978c4450
AM
13516 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13517 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13518 {
13519 bfd_vma off, length = 1;
13520
978c4450 13521 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13522 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13523 off < filedata->ngnuchains
13524 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13525 ++off)
fdc90cb4
JJ
13526 ++length;
13527 lengths[hn] = length;
13528 if (length > maxlength)
13529 maxlength = length;
13530 nsyms += length;
13531 }
13532
3f5e193b 13533 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13534 if (counts == NULL)
13535 {
b2e951ec 13536 free (lengths);
8b73c356 13537 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13538 goto err_out;
fdc90cb4
JJ
13539 }
13540
978c4450 13541 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13542 ++counts[lengths[hn]];
13543
978c4450 13544 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13545 {
13546 unsigned long j;
13547 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13548 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13549 for (j = 1; j <= maxlength; ++j)
13550 {
13551 nzero_counts += counts[j] * j;
13552 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13553 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13554 (nzero_counts * 100.0) / nsyms);
13555 }
13556 }
13557
13558 free (counts);
13559 free (lengths);
fdc90cb4 13560 }
978c4450
AM
13561 free (filedata->gnubuckets);
13562 filedata->gnubuckets = NULL;
13563 filedata->ngnubuckets = 0;
13564 free (filedata->gnuchains);
13565 filedata->gnuchains = NULL;
13566 filedata->ngnuchains = 0;
13567 free (filedata->mipsxlat);
13568 filedata->mipsxlat = NULL;
015dc7e1 13569 return true;
fd486f32
AM
13570
13571 err_out:
978c4450
AM
13572 free (filedata->gnubuckets);
13573 filedata->gnubuckets = NULL;
13574 filedata->ngnubuckets = 0;
13575 free (filedata->gnuchains);
13576 filedata->gnuchains = NULL;
13577 filedata->ngnuchains = 0;
13578 free (filedata->mipsxlat);
13579 filedata->mipsxlat = NULL;
13580 free (filedata->buckets);
13581 filedata->buckets = NULL;
13582 filedata->nbuckets = 0;
13583 free (filedata->chains);
13584 filedata->chains = NULL;
015dc7e1 13585 return false;
252b5132
RH
13586}
13587
015dc7e1 13588static bool
ca0e11aa 13589process_syminfo (Filedata * filedata)
252b5132 13590{
b4c96d0d 13591 unsigned int i;
252b5132 13592
978c4450 13593 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13594 || !do_dynamic)
13595 /* No syminfo, this is ok. */
015dc7e1 13596 return true;
252b5132
RH
13597
13598 /* There better should be a dynamic symbol section. */
978c4450 13599 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13600 return false;
252b5132 13601
ca0e11aa
NC
13602 if (filedata->is_separate)
13603 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13604 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13605 filedata->dynamic_syminfo_nent),
13606 filedata->file_name,
13607 filedata->dynamic_syminfo_offset,
13608 filedata->dynamic_syminfo_nent);
13609 else
d3a49aa8
AM
13610 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13611 "contains %d entry:\n",
13612 "\nDynamic info segment at offset 0x%lx "
13613 "contains %d entries:\n",
978c4450 13614 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13615 filedata->dynamic_syminfo_offset,
13616 filedata->dynamic_syminfo_nent);
252b5132
RH
13617
13618 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13619 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13620 {
978c4450 13621 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13622
31104126 13623 printf ("%4d: ", i);
978c4450 13624 if (i >= filedata->num_dynamic_syms)
4082ef84 13625 printf (_("<corrupt index>"));
84714f86
AM
13626 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13627 print_symbol (30, get_dynamic_name (filedata,
978c4450 13628 filedata->dynamic_symbols[i].st_name));
d79b3d50 13629 else
978c4450 13630 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13631 putchar (' ');
252b5132 13632
978c4450 13633 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13634 {
13635 case SYMINFO_BT_SELF:
13636 fputs ("SELF ", stdout);
13637 break;
13638 case SYMINFO_BT_PARENT:
13639 fputs ("PARENT ", stdout);
13640 break;
13641 default:
978c4450
AM
13642 if (filedata->dynamic_syminfo[i].si_boundto > 0
13643 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13644 && valid_dynamic_name (filedata,
978c4450 13645 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13646 {
84714f86 13647 print_symbol (10, get_dynamic_name (filedata,
978c4450 13648 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13649 putchar (' ' );
13650 }
252b5132 13651 else
978c4450 13652 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13653 break;
13654 }
13655
13656 if (flags & SYMINFO_FLG_DIRECT)
13657 printf (" DIRECT");
13658 if (flags & SYMINFO_FLG_PASSTHRU)
13659 printf (" PASSTHRU");
13660 if (flags & SYMINFO_FLG_COPY)
13661 printf (" COPY");
13662 if (flags & SYMINFO_FLG_LAZYLOAD)
13663 printf (" LAZYLOAD");
13664
13665 puts ("");
13666 }
13667
015dc7e1 13668 return true;
252b5132
RH
13669}
13670
75802ccb
CE
13671/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13672 is contained by the region START .. END. The types of ADDR, START
13673 and END should all be the same. Note both ADDR + NELEM and END
13674 point to just beyond the end of the regions that are being tested. */
13675#define IN_RANGE(START,END,ADDR,NELEM) \
13676 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13677
cf13d699
NC
13678/* Check to see if the given reloc needs to be handled in a target specific
13679 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13680 FALSE.
13681
13682 If called with reloc == NULL, then this is a signal that reloc processing
13683 for the current section has finished, and any saved state should be
13684 discarded. */
09c11c86 13685
015dc7e1 13686static bool
dda8d76d
NC
13687target_specific_reloc_handling (Filedata * filedata,
13688 Elf_Internal_Rela * reloc,
13689 unsigned char * start,
13690 unsigned char * end,
13691 Elf_Internal_Sym * symtab,
13692 unsigned long num_syms)
252b5132 13693{
f84ce13b
NC
13694 unsigned int reloc_type = 0;
13695 unsigned long sym_index = 0;
13696
13697 if (reloc)
13698 {
dda8d76d 13699 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13700 sym_index = get_reloc_symindex (reloc->r_info);
13701 }
252b5132 13702
dda8d76d 13703 switch (filedata->file_header.e_machine)
252b5132 13704 {
13761a11
NC
13705 case EM_MSP430:
13706 case EM_MSP430_OLD:
13707 {
13708 static Elf_Internal_Sym * saved_sym = NULL;
13709
f84ce13b
NC
13710 if (reloc == NULL)
13711 {
13712 saved_sym = NULL;
015dc7e1 13713 return true;
f84ce13b
NC
13714 }
13715
13761a11
NC
13716 switch (reloc_type)
13717 {
13718 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13719 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13720 if (uses_msp430x_relocs (filedata))
13761a11 13721 break;
1a0670f3 13722 /* Fall through. */
13761a11 13723 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13724 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13725 /* PR 21139. */
13726 if (sym_index >= num_syms)
13727 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13728 sym_index);
13729 else
13730 saved_sym = symtab + sym_index;
015dc7e1 13731 return true;
13761a11
NC
13732
13733 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13734 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13735 goto handle_sym_diff;
0b4362b0 13736
13761a11
NC
13737 case 5: /* R_MSP430_16_BYTE */
13738 case 9: /* R_MSP430_8 */
7d81bc93 13739 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13740 if (uses_msp430x_relocs (filedata))
13761a11
NC
13741 break;
13742 goto handle_sym_diff;
13743
13744 case 2: /* R_MSP430_ABS16 */
13745 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13746 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13747 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13748 break;
13749 goto handle_sym_diff;
0b4362b0 13750
13761a11
NC
13751 handle_sym_diff:
13752 if (saved_sym != NULL)
13753 {
13754 bfd_vma value;
5a805384 13755 unsigned int reloc_size = 0;
7d81bc93
JL
13756 int leb_ret = 0;
13757 switch (reloc_type)
13758 {
13759 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13760 reloc_size = 4;
13761 break;
13762 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13763 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13764 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13765 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13766 &reloc_size, &leb_ret);
7d81bc93
JL
13767 break;
13768 default:
13769 reloc_size = 2;
13770 break;
13771 }
13761a11 13772
5a805384 13773 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13774 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13775 "ULEB128 value\n"),
13776 (long) reloc->r_offset);
13777 else if (sym_index >= num_syms)
f84ce13b
NC
13778 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13779 sym_index);
03f7786e 13780 else
f84ce13b
NC
13781 {
13782 value = reloc->r_addend + (symtab[sym_index].st_value
13783 - saved_sym->st_value);
13784
b32e566b 13785 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13786 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13787 else
13788 /* PR 21137 */
13789 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13790 (long) reloc->r_offset);
f84ce13b 13791 }
13761a11
NC
13792
13793 saved_sym = NULL;
015dc7e1 13794 return true;
13761a11
NC
13795 }
13796 break;
13797
13798 default:
13799 if (saved_sym != NULL)
071436c6 13800 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13801 break;
13802 }
13803 break;
13804 }
13805
cf13d699
NC
13806 case EM_MN10300:
13807 case EM_CYGNUS_MN10300:
13808 {
13809 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13810
f84ce13b
NC
13811 if (reloc == NULL)
13812 {
13813 saved_sym = NULL;
015dc7e1 13814 return true;
f84ce13b
NC
13815 }
13816
cf13d699
NC
13817 switch (reloc_type)
13818 {
13819 case 34: /* R_MN10300_ALIGN */
015dc7e1 13820 return true;
cf13d699 13821 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13822 if (sym_index >= num_syms)
13823 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13824 sym_index);
13825 else
13826 saved_sym = symtab + sym_index;
015dc7e1 13827 return true;
f84ce13b 13828
cf13d699
NC
13829 case 1: /* R_MN10300_32 */
13830 case 2: /* R_MN10300_16 */
13831 if (saved_sym != NULL)
13832 {
03f7786e 13833 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13834 bfd_vma value;
252b5132 13835
f84ce13b
NC
13836 if (sym_index >= num_syms)
13837 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13838 sym_index);
03f7786e 13839 else
f84ce13b
NC
13840 {
13841 value = reloc->r_addend + (symtab[sym_index].st_value
13842 - saved_sym->st_value);
13843
b32e566b 13844 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13845 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13846 else
13847 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13848 (long) reloc->r_offset);
f84ce13b 13849 }
252b5132 13850
cf13d699 13851 saved_sym = NULL;
015dc7e1 13852 return true;
cf13d699
NC
13853 }
13854 break;
13855 default:
13856 if (saved_sym != NULL)
071436c6 13857 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13858 break;
13859 }
13860 break;
13861 }
6ff71e76
NC
13862
13863 case EM_RL78:
13864 {
13865 static bfd_vma saved_sym1 = 0;
13866 static bfd_vma saved_sym2 = 0;
13867 static bfd_vma value;
13868
f84ce13b
NC
13869 if (reloc == NULL)
13870 {
13871 saved_sym1 = saved_sym2 = 0;
015dc7e1 13872 return true;
f84ce13b
NC
13873 }
13874
6ff71e76
NC
13875 switch (reloc_type)
13876 {
13877 case 0x80: /* R_RL78_SYM. */
13878 saved_sym1 = saved_sym2;
f84ce13b
NC
13879 if (sym_index >= num_syms)
13880 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13881 sym_index);
13882 else
13883 {
13884 saved_sym2 = symtab[sym_index].st_value;
13885 saved_sym2 += reloc->r_addend;
13886 }
015dc7e1 13887 return true;
6ff71e76
NC
13888
13889 case 0x83: /* R_RL78_OPsub. */
13890 value = saved_sym1 - saved_sym2;
13891 saved_sym2 = saved_sym1 = 0;
015dc7e1 13892 return true;
6ff71e76
NC
13893 break;
13894
13895 case 0x41: /* R_RL78_ABS32. */
b32e566b 13896 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13897 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13898 else
13899 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13900 (long) reloc->r_offset);
6ff71e76 13901 value = 0;
015dc7e1 13902 return true;
6ff71e76
NC
13903
13904 case 0x43: /* R_RL78_ABS16. */
b32e566b 13905 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13906 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13907 else
13908 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13909 (long) reloc->r_offset);
6ff71e76 13910 value = 0;
015dc7e1 13911 return true;
6ff71e76
NC
13912
13913 default:
13914 break;
13915 }
13916 break;
13917 }
252b5132
RH
13918 }
13919
015dc7e1 13920 return false;
252b5132
RH
13921}
13922
aca88567
NC
13923/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13924 DWARF debug sections. This is a target specific test. Note - we do not
13925 go through the whole including-target-headers-multiple-times route, (as
13926 we have already done with <elf/h8.h>) because this would become very
13927 messy and even then this function would have to contain target specific
13928 information (the names of the relocs instead of their numeric values).
13929 FIXME: This is not the correct way to solve this problem. The proper way
13930 is to have target specific reloc sizing and typing functions created by
13931 the reloc-macros.h header, in the same way that it already creates the
13932 reloc naming functions. */
13933
015dc7e1 13934static bool
dda8d76d 13935is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13936{
d347c9df 13937 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13938 switch (filedata->file_header.e_machine)
aca88567 13939 {
41e92641 13940 case EM_386:
22abe556 13941 case EM_IAMCU:
41e92641 13942 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13943 case EM_68K:
13944 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13945 case EM_860:
13946 return reloc_type == 1; /* R_860_32. */
13947 case EM_960:
13948 return reloc_type == 2; /* R_960_32. */
a06ea964 13949 case EM_AARCH64:
9282b95a
JW
13950 return (reloc_type == 258
13951 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13952 case EM_BPF:
13953 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13954 case EM_ADAPTEVA_EPIPHANY:
13955 return reloc_type == 3;
aca88567 13956 case EM_ALPHA:
137b6b5f 13957 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13958 case EM_ARC:
13959 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13960 case EM_ARC_COMPACT:
13961 case EM_ARC_COMPACT2:
13962 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13963 case EM_ARM:
13964 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13965 case EM_AVR_OLD:
aca88567
NC
13966 case EM_AVR:
13967 return reloc_type == 1;
13968 case EM_BLACKFIN:
13969 return reloc_type == 0x12; /* R_byte4_data. */
13970 case EM_CRIS:
13971 return reloc_type == 3; /* R_CRIS_32. */
13972 case EM_CR16:
13973 return reloc_type == 3; /* R_CR16_NUM32. */
13974 case EM_CRX:
13975 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13976 case EM_CSKY:
13977 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13978 case EM_CYGNUS_FRV:
13979 return reloc_type == 1;
41e92641
NC
13980 case EM_CYGNUS_D10V:
13981 case EM_D10V:
13982 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13983 case EM_CYGNUS_D30V:
13984 case EM_D30V:
13985 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13986 case EM_DLX:
13987 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13988 case EM_CYGNUS_FR30:
13989 case EM_FR30:
13990 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13991 case EM_FT32:
13992 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13993 case EM_H8S:
13994 case EM_H8_300:
13995 case EM_H8_300H:
13996 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13997 case EM_IA_64:
262cdac7
AM
13998 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13999 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14000 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14001 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14002 case EM_IP2K_OLD:
14003 case EM_IP2K:
14004 return reloc_type == 2; /* R_IP2K_32. */
14005 case EM_IQ2000:
14006 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14007 case EM_LATTICEMICO32:
14008 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14009 case EM_LOONGARCH:
14010 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14011 case EM_M32C_OLD:
aca88567
NC
14012 case EM_M32C:
14013 return reloc_type == 3; /* R_M32C_32. */
14014 case EM_M32R:
14015 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14016 case EM_68HC11:
14017 case EM_68HC12:
14018 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14019 case EM_S12Z:
2849d19f
JD
14020 return reloc_type == 7 || /* R_S12Z_EXT32 */
14021 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14022 case EM_MCORE:
14023 return reloc_type == 1; /* R_MCORE_ADDR32. */
14024 case EM_CYGNUS_MEP:
14025 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14026 case EM_METAG:
14027 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14028 case EM_MICROBLAZE:
14029 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14030 case EM_MIPS:
14031 return reloc_type == 2; /* R_MIPS_32. */
14032 case EM_MMIX:
14033 return reloc_type == 4; /* R_MMIX_32. */
14034 case EM_CYGNUS_MN10200:
14035 case EM_MN10200:
14036 return reloc_type == 1; /* R_MN10200_32. */
14037 case EM_CYGNUS_MN10300:
14038 case EM_MN10300:
14039 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14040 case EM_MOXIE:
14041 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14042 case EM_MSP430_OLD:
14043 case EM_MSP430:
13761a11 14044 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14045 case EM_MT:
14046 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
14047 case EM_NDS32:
14048 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 14049 case EM_ALTERA_NIOS2:
36591ba1 14050 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14051 case EM_NIOS32:
14052 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14053 case EM_OR1K:
14054 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14055 case EM_PARISC:
9abca702 14056 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14057 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14058 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14059 case EM_PJ:
14060 case EM_PJ_OLD:
14061 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14062 case EM_PPC64:
14063 return reloc_type == 1; /* R_PPC64_ADDR32. */
14064 case EM_PPC:
14065 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14066 case EM_TI_PRU:
14067 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14068 case EM_RISCV:
14069 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14070 case EM_RL78:
14071 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14072 case EM_RX:
14073 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14074 case EM_S370:
14075 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14076 case EM_S390_OLD:
14077 case EM_S390:
14078 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14079 case EM_SCORE:
14080 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14081 case EM_SH:
14082 return reloc_type == 1; /* R_SH_DIR32. */
14083 case EM_SPARC32PLUS:
14084 case EM_SPARCV9:
14085 case EM_SPARC:
14086 return reloc_type == 3 /* R_SPARC_32. */
14087 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14088 case EM_SPU:
14089 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14090 case EM_TI_C6000:
14091 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14092 case EM_TILEGX:
14093 return reloc_type == 2; /* R_TILEGX_32. */
14094 case EM_TILEPRO:
14095 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14096 case EM_CYGNUS_V850:
14097 case EM_V850:
14098 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14099 case EM_V800:
14100 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14101 case EM_VAX:
14102 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14103 case EM_VISIUM:
14104 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14105 case EM_WEBASSEMBLY:
14106 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14107 case EM_X86_64:
8a9036a4 14108 case EM_L1OM:
7a9068fe 14109 case EM_K1OM:
aca88567 14110 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
14111 case EM_XC16X:
14112 case EM_C166:
14113 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
14114 case EM_XGATE:
14115 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14116 case EM_XSTORMY16:
14117 return reloc_type == 1; /* R_XSTROMY16_32. */
14118 case EM_XTENSA_OLD:
14119 case EM_XTENSA:
14120 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14121 case EM_Z80:
14122 return reloc_type == 6; /* R_Z80_32. */
aca88567 14123 default:
bee0ee85
NC
14124 {
14125 static unsigned int prev_warn = 0;
14126
14127 /* Avoid repeating the same warning multiple times. */
dda8d76d 14128 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14129 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14130 filedata->file_header.e_machine);
14131 prev_warn = filedata->file_header.e_machine;
015dc7e1 14132 return false;
bee0ee85 14133 }
aca88567
NC
14134 }
14135}
14136
14137/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14138 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14139
015dc7e1 14140static bool
dda8d76d 14141is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14142{
dda8d76d 14143 switch (filedata->file_header.e_machine)
d347c9df 14144 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14145 {
41e92641 14146 case EM_386:
22abe556 14147 case EM_IAMCU:
3e0873ac 14148 return reloc_type == 2; /* R_386_PC32. */
aca88567 14149 case EM_68K:
3e0873ac 14150 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14151 case EM_AARCH64:
14152 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14153 case EM_ADAPTEVA_EPIPHANY:
14154 return reloc_type == 6;
aca88567
NC
14155 case EM_ALPHA:
14156 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14157 case EM_ARC_COMPACT:
14158 case EM_ARC_COMPACT2:
14159 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14160 case EM_ARM:
3e0873ac 14161 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14162 case EM_AVR_OLD:
14163 case EM_AVR:
14164 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
14165 case EM_MICROBLAZE:
14166 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14167 case EM_OR1K:
14168 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14169 case EM_PARISC:
85acf597 14170 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14171 case EM_PPC:
14172 return reloc_type == 26; /* R_PPC_REL32. */
14173 case EM_PPC64:
3e0873ac 14174 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14175 case EM_RISCV:
14176 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14177 case EM_S390_OLD:
14178 case EM_S390:
3e0873ac 14179 return reloc_type == 5; /* R_390_PC32. */
aca88567 14180 case EM_SH:
3e0873ac 14181 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14182 case EM_SPARC32PLUS:
14183 case EM_SPARCV9:
14184 case EM_SPARC:
3e0873ac 14185 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14186 case EM_SPU:
14187 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14188 case EM_TILEGX:
14189 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14190 case EM_TILEPRO:
14191 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14192 case EM_VISIUM:
14193 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14194 case EM_X86_64:
8a9036a4 14195 case EM_L1OM:
7a9068fe 14196 case EM_K1OM:
3e0873ac 14197 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14198 case EM_VAX:
14199 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14200 case EM_XTENSA_OLD:
14201 case EM_XTENSA:
14202 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14203 default:
14204 /* Do not abort or issue an error message here. Not all targets use
14205 pc-relative 32-bit relocs in their DWARF debug information and we
14206 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14207 more helpful warning message will be generated by apply_relocations
14208 anyway, so just return. */
015dc7e1 14209 return false;
aca88567
NC
14210 }
14211}
14212
14213/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14214 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14215
015dc7e1 14216static bool
dda8d76d 14217is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14218{
dda8d76d 14219 switch (filedata->file_header.e_machine)
aca88567 14220 {
a06ea964
NC
14221 case EM_AARCH64:
14222 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14223 case EM_ALPHA:
14224 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14225 case EM_IA_64:
262cdac7
AM
14226 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14227 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14228 case EM_LOONGARCH:
14229 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14230 case EM_PARISC:
14231 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14232 case EM_PPC64:
14233 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14234 case EM_RISCV:
14235 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14236 case EM_SPARC32PLUS:
14237 case EM_SPARCV9:
14238 case EM_SPARC:
714da62f
NC
14239 return reloc_type == 32 /* R_SPARC_64. */
14240 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14241 case EM_X86_64:
8a9036a4 14242 case EM_L1OM:
7a9068fe 14243 case EM_K1OM:
aca88567 14244 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14245 case EM_S390_OLD:
14246 case EM_S390:
aa137e4d
NC
14247 return reloc_type == 22; /* R_S390_64. */
14248 case EM_TILEGX:
14249 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14250 case EM_MIPS:
aa137e4d 14251 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14252 default:
015dc7e1 14253 return false;
aca88567
NC
14254 }
14255}
14256
85acf597
RH
14257/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14258 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14259
015dc7e1 14260static bool
dda8d76d 14261is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14262{
dda8d76d 14263 switch (filedata->file_header.e_machine)
85acf597 14264 {
a06ea964
NC
14265 case EM_AARCH64:
14266 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14267 case EM_ALPHA:
aa137e4d 14268 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14269 case EM_IA_64:
262cdac7
AM
14270 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14271 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14272 case EM_PARISC:
aa137e4d 14273 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14274 case EM_PPC64:
aa137e4d 14275 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14276 case EM_SPARC32PLUS:
14277 case EM_SPARCV9:
14278 case EM_SPARC:
aa137e4d 14279 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14280 case EM_X86_64:
8a9036a4 14281 case EM_L1OM:
7a9068fe 14282 case EM_K1OM:
aa137e4d 14283 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14284 case EM_S390_OLD:
14285 case EM_S390:
aa137e4d
NC
14286 return reloc_type == 23; /* R_S390_PC64. */
14287 case EM_TILEGX:
14288 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14289 default:
015dc7e1 14290 return false;
85acf597
RH
14291 }
14292}
14293
4dc3c23d
AM
14294/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14295 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14296
015dc7e1 14297static bool
dda8d76d 14298is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14299{
dda8d76d 14300 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14301 {
14302 case EM_CYGNUS_MN10200:
14303 case EM_MN10200:
14304 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14305 case EM_FT32:
14306 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14307 case EM_Z80:
14308 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14309 default:
015dc7e1 14310 return false;
4dc3c23d
AM
14311 }
14312}
14313
aca88567
NC
14314/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14315 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14316
015dc7e1 14317static bool
dda8d76d 14318is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14319{
d347c9df 14320 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14321 switch (filedata->file_header.e_machine)
4b78141a 14322 {
886a2506
NC
14323 case EM_ARC:
14324 case EM_ARC_COMPACT:
14325 case EM_ARC_COMPACT2:
14326 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14327 case EM_ADAPTEVA_EPIPHANY:
14328 return reloc_type == 5;
aca88567
NC
14329 case EM_AVR_OLD:
14330 case EM_AVR:
14331 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14332 case EM_CYGNUS_D10V:
14333 case EM_D10V:
14334 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14335 case EM_FT32:
14336 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14337 case EM_H8S:
14338 case EM_H8_300:
14339 case EM_H8_300H:
aca88567
NC
14340 return reloc_type == R_H8_DIR16;
14341 case EM_IP2K_OLD:
14342 case EM_IP2K:
14343 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14344 case EM_M32C_OLD:
f4236fe4
DD
14345 case EM_M32C:
14346 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14347 case EM_CYGNUS_MN10200:
14348 case EM_MN10200:
14349 return reloc_type == 2; /* R_MN10200_16. */
14350 case EM_CYGNUS_MN10300:
14351 case EM_MN10300:
14352 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14353 case EM_MSP430:
dda8d76d 14354 if (uses_msp430x_relocs (filedata))
13761a11 14355 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14356 /* Fall through. */
78c8d46c 14357 case EM_MSP430_OLD:
aca88567 14358 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
14359 case EM_NDS32:
14360 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 14361 case EM_ALTERA_NIOS2:
36591ba1 14362 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14363 case EM_NIOS32:
14364 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14365 case EM_OR1K:
14366 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14367 case EM_RISCV:
14368 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14369 case EM_TI_PRU:
14370 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14371 case EM_TI_C6000:
14372 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14373 case EM_VISIUM:
14374 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
14375 case EM_XC16X:
14376 case EM_C166:
14377 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
14378 case EM_XGATE:
14379 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14380 case EM_Z80:
14381 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14382 default:
015dc7e1 14383 return false;
4b78141a
NC
14384 }
14385}
14386
39e07931
AS
14387/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14388 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14389
015dc7e1 14390static bool
39e07931
AS
14391is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14392{
14393 switch (filedata->file_header.e_machine)
14394 {
14395 case EM_RISCV:
14396 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14397 case EM_Z80:
14398 return reloc_type == 1; /* R_Z80_8. */
39e07931 14399 default:
015dc7e1 14400 return false;
39e07931
AS
14401 }
14402}
14403
14404/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14405 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14406
015dc7e1 14407static bool
39e07931
AS
14408is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14409{
14410 switch (filedata->file_header.e_machine)
14411 {
14412 case EM_RISCV:
14413 return reloc_type == 53; /* R_RISCV_SET6. */
14414 default:
015dc7e1 14415 return false;
39e07931
AS
14416 }
14417}
14418
03336641
JW
14419/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14420 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14421
015dc7e1 14422static bool
03336641
JW
14423is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14424{
14425 /* Please keep this table alpha-sorted for ease of visual lookup. */
14426 switch (filedata->file_header.e_machine)
14427 {
14428 case EM_RISCV:
14429 return reloc_type == 35; /* R_RISCV_ADD32. */
14430 default:
015dc7e1 14431 return false;
03336641
JW
14432 }
14433}
14434
14435/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14436 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14437
015dc7e1 14438static bool
03336641
JW
14439is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14440{
14441 /* Please keep this table alpha-sorted for ease of visual lookup. */
14442 switch (filedata->file_header.e_machine)
14443 {
14444 case EM_RISCV:
14445 return reloc_type == 39; /* R_RISCV_SUB32. */
14446 default:
015dc7e1 14447 return false;
03336641
JW
14448 }
14449}
14450
14451/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14452 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14453
015dc7e1 14454static bool
03336641
JW
14455is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14456{
14457 /* Please keep this table alpha-sorted for ease of visual lookup. */
14458 switch (filedata->file_header.e_machine)
14459 {
14460 case EM_RISCV:
14461 return reloc_type == 36; /* R_RISCV_ADD64. */
14462 default:
015dc7e1 14463 return false;
03336641
JW
14464 }
14465}
14466
14467/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14468 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14469
015dc7e1 14470static bool
03336641
JW
14471is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14472{
14473 /* Please keep this table alpha-sorted for ease of visual lookup. */
14474 switch (filedata->file_header.e_machine)
14475 {
14476 case EM_RISCV:
14477 return reloc_type == 40; /* R_RISCV_SUB64. */
14478 default:
015dc7e1 14479 return false;
03336641
JW
14480 }
14481}
14482
14483/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14484 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14485
015dc7e1 14486static bool
03336641
JW
14487is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14488{
14489 /* Please keep this table alpha-sorted for ease of visual lookup. */
14490 switch (filedata->file_header.e_machine)
14491 {
14492 case EM_RISCV:
14493 return reloc_type == 34; /* R_RISCV_ADD16. */
14494 default:
015dc7e1 14495 return false;
03336641
JW
14496 }
14497}
14498
14499/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14500 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14501
015dc7e1 14502static bool
03336641
JW
14503is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14504{
14505 /* Please keep this table alpha-sorted for ease of visual lookup. */
14506 switch (filedata->file_header.e_machine)
14507 {
14508 case EM_RISCV:
14509 return reloc_type == 38; /* R_RISCV_SUB16. */
14510 default:
015dc7e1 14511 return false;
03336641
JW
14512 }
14513}
14514
14515/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14516 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14517
015dc7e1 14518static bool
03336641
JW
14519is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14520{
14521 /* Please keep this table alpha-sorted for ease of visual lookup. */
14522 switch (filedata->file_header.e_machine)
14523 {
14524 case EM_RISCV:
14525 return reloc_type == 33; /* R_RISCV_ADD8. */
14526 default:
015dc7e1 14527 return false;
03336641
JW
14528 }
14529}
14530
14531/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14532 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14533
015dc7e1 14534static bool
03336641
JW
14535is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14536{
14537 /* Please keep this table alpha-sorted for ease of visual lookup. */
14538 switch (filedata->file_header.e_machine)
14539 {
14540 case EM_RISCV:
14541 return reloc_type == 37; /* R_RISCV_SUB8. */
14542 default:
015dc7e1 14543 return false;
03336641
JW
14544 }
14545}
14546
39e07931
AS
14547/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14548 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14549
015dc7e1 14550static bool
39e07931
AS
14551is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14552{
14553 switch (filedata->file_header.e_machine)
14554 {
14555 case EM_RISCV:
14556 return reloc_type == 52; /* R_RISCV_SUB6. */
14557 default:
015dc7e1 14558 return false;
39e07931
AS
14559 }
14560}
14561
2a7b2e88
JK
14562/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14563 relocation entries (possibly formerly used for SHT_GROUP sections). */
14564
015dc7e1 14565static bool
dda8d76d 14566is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14567{
dda8d76d 14568 switch (filedata->file_header.e_machine)
2a7b2e88 14569 {
cb8f3167 14570 case EM_386: /* R_386_NONE. */
d347c9df 14571 case EM_68K: /* R_68K_NONE. */
cfb8c092 14572 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14573 case EM_ALPHA: /* R_ALPHA_NONE. */
14574 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14575 case EM_ARC: /* R_ARC_NONE. */
886a2506 14576 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14577 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14578 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14579 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14580 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14581 case EM_FT32: /* R_FT32_NONE. */
14582 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14583 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14584 case EM_L1OM: /* R_X86_64_NONE. */
14585 case EM_M32R: /* R_M32R_NONE. */
14586 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14587 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14588 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14589 case EM_NIOS32: /* R_NIOS_NONE. */
14590 case EM_OR1K: /* R_OR1K_NONE. */
14591 case EM_PARISC: /* R_PARISC_NONE. */
14592 case EM_PPC64: /* R_PPC64_NONE. */
14593 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14594 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14595 case EM_S390: /* R_390_NONE. */
14596 case EM_S390_OLD:
14597 case EM_SH: /* R_SH_NONE. */
14598 case EM_SPARC32PLUS:
14599 case EM_SPARC: /* R_SPARC_NONE. */
14600 case EM_SPARCV9:
aa137e4d
NC
14601 case EM_TILEGX: /* R_TILEGX_NONE. */
14602 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14603 case EM_TI_C6000:/* R_C6000_NONE. */
14604 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14605 case EM_XC16X:
6655dba2 14606 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14607 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14608 return reloc_type == 0;
d347c9df 14609
a06ea964
NC
14610 case EM_AARCH64:
14611 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14612 case EM_AVR_OLD:
14613 case EM_AVR:
14614 return (reloc_type == 0 /* R_AVR_NONE. */
14615 || reloc_type == 30 /* R_AVR_DIFF8. */
14616 || reloc_type == 31 /* R_AVR_DIFF16. */
14617 || reloc_type == 32 /* R_AVR_DIFF32. */);
14618 case EM_METAG:
14619 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14620 case EM_NDS32:
14621 return (reloc_type == 0 /* R_XTENSA_NONE. */
14622 || reloc_type == 204 /* R_NDS32_DIFF8. */
14623 || reloc_type == 205 /* R_NDS32_DIFF16. */
14624 || reloc_type == 206 /* R_NDS32_DIFF32. */
14625 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14626 case EM_TI_PRU:
14627 return (reloc_type == 0 /* R_PRU_NONE. */
14628 || reloc_type == 65 /* R_PRU_DIFF8. */
14629 || reloc_type == 66 /* R_PRU_DIFF16. */
14630 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14631 case EM_XTENSA_OLD:
14632 case EM_XTENSA:
4dc3c23d
AM
14633 return (reloc_type == 0 /* R_XTENSA_NONE. */
14634 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14635 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14636 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14637 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14638 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14639 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14640 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14641 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14642 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14643 }
015dc7e1 14644 return false;
2a7b2e88
JK
14645}
14646
d1c4b12b
NC
14647/* Returns TRUE if there is a relocation against
14648 section NAME at OFFSET bytes. */
14649
015dc7e1 14650bool
d1c4b12b
NC
14651reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14652{
14653 Elf_Internal_Rela * relocs;
14654 Elf_Internal_Rela * rp;
14655
14656 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14657 return false;
d1c4b12b
NC
14658
14659 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14660
14661 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14662 if (rp->r_offset == offset)
015dc7e1 14663 return true;
d1c4b12b 14664
015dc7e1 14665 return false;
d1c4b12b
NC
14666}
14667
cf13d699 14668/* Apply relocations to a section.
32ec8896
NC
14669 Returns TRUE upon success, FALSE otherwise.
14670 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14671 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14672 will be set to the number of relocs loaded.
14673
cf13d699 14674 Note: So far support has been added only for those relocations
32ec8896
NC
14675 which can be found in debug sections. FIXME: Add support for
14676 more relocations ? */
1b315056 14677
015dc7e1 14678static bool
dda8d76d 14679apply_relocations (Filedata * filedata,
d1c4b12b
NC
14680 const Elf_Internal_Shdr * section,
14681 unsigned char * start,
14682 bfd_size_type size,
1449284b 14683 void ** relocs_return,
d1c4b12b 14684 unsigned long * num_relocs_return)
1b315056 14685{
cf13d699 14686 Elf_Internal_Shdr * relsec;
0d2a7a93 14687 unsigned char * end = start + size;
cb8f3167 14688
d1c4b12b
NC
14689 if (relocs_return != NULL)
14690 {
14691 * (Elf_Internal_Rela **) relocs_return = NULL;
14692 * num_relocs_return = 0;
14693 }
14694
dda8d76d 14695 if (filedata->file_header.e_type != ET_REL)
32ec8896 14696 /* No relocs to apply. */
015dc7e1 14697 return true;
1b315056 14698
cf13d699 14699 /* Find the reloc section associated with the section. */
dda8d76d
NC
14700 for (relsec = filedata->section_headers;
14701 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14702 ++relsec)
252b5132 14703 {
015dc7e1 14704 bool is_rela;
41e92641 14705 unsigned long num_relocs;
2cf0635d
NC
14706 Elf_Internal_Rela * relocs;
14707 Elf_Internal_Rela * rp;
14708 Elf_Internal_Shdr * symsec;
14709 Elf_Internal_Sym * symtab;
ba5cdace 14710 unsigned long num_syms;
2cf0635d 14711 Elf_Internal_Sym * sym;
252b5132 14712
41e92641 14713 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14714 || relsec->sh_info >= filedata->file_header.e_shnum
14715 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14716 || relsec->sh_size == 0
dda8d76d 14717 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14718 continue;
428409d5 14719
a788aedd
AM
14720 symsec = filedata->section_headers + relsec->sh_link;
14721 if (symsec->sh_type != SHT_SYMTAB
14722 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14723 return false;
a788aedd 14724
41e92641
NC
14725 is_rela = relsec->sh_type == SHT_RELA;
14726
14727 if (is_rela)
14728 {
dda8d76d 14729 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14730 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14731 return false;
41e92641
NC
14732 }
14733 else
14734 {
dda8d76d 14735 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14736 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14737 return false;
41e92641
NC
14738 }
14739
14740 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14741 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14742 is_rela = false;
428409d5 14743
4de91c10 14744 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14745
41e92641 14746 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14747 {
015dc7e1
AM
14748 bfd_vma addend;
14749 unsigned int reloc_type;
14750 unsigned int reloc_size;
14751 bool reloc_inplace = false;
14752 bool reloc_subtract = false;
14753 unsigned char *rloc;
14754 unsigned long sym_index;
4b78141a 14755
dda8d76d 14756 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14757
dda8d76d 14758 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14759 continue;
dda8d76d 14760 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14761 continue;
dda8d76d
NC
14762 else if (is_32bit_abs_reloc (filedata, reloc_type)
14763 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14764 reloc_size = 4;
dda8d76d
NC
14765 else if (is_64bit_abs_reloc (filedata, reloc_type)
14766 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14767 reloc_size = 8;
dda8d76d 14768 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14769 reloc_size = 3;
dda8d76d 14770 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14771 reloc_size = 2;
39e07931
AS
14772 else if (is_8bit_abs_reloc (filedata, reloc_type)
14773 || is_6bit_abs_reloc (filedata, reloc_type))
14774 reloc_size = 1;
03336641
JW
14775 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14776 reloc_type))
14777 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14778 {
14779 reloc_size = 4;
015dc7e1 14780 reloc_inplace = true;
03336641
JW
14781 }
14782 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14783 reloc_type))
14784 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14785 {
14786 reloc_size = 8;
015dc7e1 14787 reloc_inplace = true;
03336641
JW
14788 }
14789 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14790 reloc_type))
14791 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14792 {
14793 reloc_size = 2;
015dc7e1 14794 reloc_inplace = true;
03336641
JW
14795 }
14796 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14797 reloc_type))
14798 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14799 {
14800 reloc_size = 1;
015dc7e1 14801 reloc_inplace = true;
03336641 14802 }
39e07931
AS
14803 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14804 reloc_type)))
14805 {
14806 reloc_size = 1;
015dc7e1 14807 reloc_inplace = true;
39e07931 14808 }
aca88567 14809 else
4b78141a 14810 {
bee0ee85 14811 static unsigned int prev_reloc = 0;
dda8d76d 14812
bee0ee85
NC
14813 if (reloc_type != prev_reloc)
14814 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14815 reloc_type, printable_section_name (filedata, section));
bee0ee85 14816 prev_reloc = reloc_type;
4b78141a
NC
14817 continue;
14818 }
103f02d3 14819
91d6fa6a 14820 rloc = start + rp->r_offset;
75802ccb 14821 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14822 {
14823 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14824 (unsigned long) rp->r_offset,
dda8d76d 14825 printable_section_name (filedata, section));
700dd8b7
L
14826 continue;
14827 }
103f02d3 14828
ba5cdace
NC
14829 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14830 if (sym_index >= num_syms)
14831 {
14832 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14833 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14834 continue;
14835 }
14836 sym = symtab + sym_index;
41e92641
NC
14837
14838 /* If the reloc has a symbol associated with it,
55f25fc3
L
14839 make sure that it is of an appropriate type.
14840
14841 Relocations against symbols without type can happen.
14842 Gcc -feliminate-dwarf2-dups may generate symbols
14843 without type for debug info.
14844
14845 Icc generates relocations against function symbols
14846 instead of local labels.
14847
14848 Relocations against object symbols can happen, eg when
14849 referencing a global array. For an example of this see
14850 the _clz.o binary in libgcc.a. */
aca88567 14851 if (sym != symtab
b8871f35 14852 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14853 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14854 {
d3a49aa8 14855 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14856 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14857 printable_section_name (filedata, relsec),
d3a49aa8 14858 (long int)(rp - relocs));
aca88567 14859 continue;
5b18a4bc 14860 }
252b5132 14861
4dc3c23d
AM
14862 addend = 0;
14863 if (is_rela)
14864 addend += rp->r_addend;
c47320c3
AM
14865 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14866 partial_inplace. */
4dc3c23d 14867 if (!is_rela
dda8d76d 14868 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14869 && reloc_type == 1)
dda8d76d
NC
14870 || ((filedata->file_header.e_machine == EM_PJ
14871 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14872 && reloc_type == 1)
dda8d76d
NC
14873 || ((filedata->file_header.e_machine == EM_D30V
14874 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14875 && reloc_type == 12)
14876 || reloc_inplace)
39e07931
AS
14877 {
14878 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14879 addend += byte_get (rloc, reloc_size) & 0x3f;
14880 else
14881 addend += byte_get (rloc, reloc_size);
14882 }
cb8f3167 14883
dda8d76d
NC
14884 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14885 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14886 {
14887 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14888 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14889 addend -= 8;
91d6fa6a 14890 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14891 reloc_size);
14892 }
39e07931
AS
14893 else if (is_6bit_abs_reloc (filedata, reloc_type)
14894 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14895 {
14896 if (reloc_subtract)
14897 addend -= sym->st_value;
14898 else
14899 addend += sym->st_value;
14900 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14901 byte_put (rloc, addend, reloc_size);
14902 }
03336641
JW
14903 else if (reloc_subtract)
14904 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14905 else
91d6fa6a 14906 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14907 }
252b5132 14908
5b18a4bc 14909 free (symtab);
f84ce13b
NC
14910 /* Let the target specific reloc processing code know that
14911 we have finished with these relocs. */
dda8d76d 14912 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14913
14914 if (relocs_return)
14915 {
14916 * (Elf_Internal_Rela **) relocs_return = relocs;
14917 * num_relocs_return = num_relocs;
14918 }
14919 else
14920 free (relocs);
14921
5b18a4bc
NC
14922 break;
14923 }
32ec8896 14924
015dc7e1 14925 return true;
5b18a4bc 14926}
103f02d3 14927
cf13d699 14928#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14929static bool
dda8d76d 14930disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14931{
dda8d76d 14932 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14933
74e1a04b 14934 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14935
015dc7e1 14936 return true;
cf13d699
NC
14937}
14938#endif
14939
14940/* Reads in the contents of SECTION from FILE, returning a pointer
14941 to a malloc'ed buffer or NULL if something went wrong. */
14942
14943static char *
dda8d76d 14944get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14945{
dda8d76d 14946 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14947
14948 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14949 {
c6b78c96 14950 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14951 printable_section_name (filedata, section));
cf13d699
NC
14952 return NULL;
14953 }
14954
dda8d76d 14955 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14956 _("section contents"));
cf13d699
NC
14957}
14958
0e602686
NC
14959/* Uncompresses a section that was compressed using zlib, in place. */
14960
015dc7e1 14961static bool
dda8d76d
NC
14962uncompress_section_contents (unsigned char ** buffer,
14963 dwarf_size_type uncompressed_size,
14964 dwarf_size_type * size)
0e602686
NC
14965{
14966 dwarf_size_type compressed_size = *size;
14967 unsigned char * compressed_buffer = *buffer;
14968 unsigned char * uncompressed_buffer;
14969 z_stream strm;
14970 int rc;
14971
14972 /* It is possible the section consists of several compressed
14973 buffers concatenated together, so we uncompress in a loop. */
14974 /* PR 18313: The state field in the z_stream structure is supposed
14975 to be invisible to the user (ie us), but some compilers will
14976 still complain about it being used without initialisation. So
14977 we first zero the entire z_stream structure and then set the fields
14978 that we need. */
14979 memset (& strm, 0, sizeof strm);
14980 strm.avail_in = compressed_size;
14981 strm.next_in = (Bytef *) compressed_buffer;
14982 strm.avail_out = uncompressed_size;
14983 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14984
14985 rc = inflateInit (& strm);
14986 while (strm.avail_in > 0)
14987 {
14988 if (rc != Z_OK)
3624a6c1 14989 break;
0e602686
NC
14990 strm.next_out = ((Bytef *) uncompressed_buffer
14991 + (uncompressed_size - strm.avail_out));
14992 rc = inflate (&strm, Z_FINISH);
14993 if (rc != Z_STREAM_END)
3624a6c1 14994 break;
0e602686
NC
14995 rc = inflateReset (& strm);
14996 }
ad92f33d
AM
14997 if (inflateEnd (& strm) != Z_OK
14998 || rc != Z_OK
0e602686
NC
14999 || strm.avail_out != 0)
15000 goto fail;
15001
15002 *buffer = uncompressed_buffer;
15003 *size = uncompressed_size;
015dc7e1 15004 return true;
0e602686
NC
15005
15006 fail:
15007 free (uncompressed_buffer);
15008 /* Indicate decompression failure. */
15009 *buffer = NULL;
015dc7e1 15010 return false;
0e602686 15011}
dd24e3da 15012
015dc7e1 15013static bool
dda8d76d 15014dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15015{
015dc7e1
AM
15016 Elf_Internal_Shdr *relsec;
15017 bfd_size_type num_bytes;
15018 unsigned char *data;
15019 unsigned char *end;
15020 unsigned char *real_start;
15021 unsigned char *start;
15022 bool some_strings_shown;
cf13d699 15023
dda8d76d 15024 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15025 if (start == NULL)
c6b78c96 15026 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15027 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15028
0e602686 15029 num_bytes = section->sh_size;
cf13d699 15030
835f2fae
NC
15031 if (filedata->is_separate)
15032 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15033 printable_section_name (filedata, section),
15034 filedata->file_name);
15035 else
15036 printf (_("\nString dump of section '%s':\n"),
15037 printable_section_name (filedata, section));
cf13d699 15038
0e602686
NC
15039 if (decompress_dumps)
15040 {
15041 dwarf_size_type new_size = num_bytes;
15042 dwarf_size_type uncompressed_size = 0;
15043
15044 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15045 {
15046 Elf_Internal_Chdr chdr;
15047 unsigned int compression_header_size
ebdf1ebf
NC
15048 = get_compression_header (& chdr, (unsigned char *) start,
15049 num_bytes);
5844b465
NC
15050 if (compression_header_size == 0)
15051 /* An error message will have already been generated
15052 by get_compression_header. */
15053 goto error_out;
0e602686 15054
813dabb9 15055 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15056 {
813dabb9 15057 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15058 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15059 goto error_out;
813dabb9 15060 }
813dabb9
L
15061 uncompressed_size = chdr.ch_size;
15062 start += compression_header_size;
15063 new_size -= compression_header_size;
0e602686
NC
15064 }
15065 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15066 {
15067 /* Read the zlib header. In this case, it should be "ZLIB"
15068 followed by the uncompressed section size, 8 bytes in
15069 big-endian order. */
15070 uncompressed_size = start[4]; uncompressed_size <<= 8;
15071 uncompressed_size += start[5]; uncompressed_size <<= 8;
15072 uncompressed_size += start[6]; uncompressed_size <<= 8;
15073 uncompressed_size += start[7]; uncompressed_size <<= 8;
15074 uncompressed_size += start[8]; uncompressed_size <<= 8;
15075 uncompressed_size += start[9]; uncompressed_size <<= 8;
15076 uncompressed_size += start[10]; uncompressed_size <<= 8;
15077 uncompressed_size += start[11];
15078 start += 12;
15079 new_size -= 12;
15080 }
15081
1835f746
NC
15082 if (uncompressed_size)
15083 {
15084 if (uncompress_section_contents (& start,
15085 uncompressed_size, & new_size))
15086 num_bytes = new_size;
15087 else
15088 {
15089 error (_("Unable to decompress section %s\n"),
dda8d76d 15090 printable_section_name (filedata, section));
f761cb13 15091 goto error_out;
1835f746
NC
15092 }
15093 }
bc303e5d
NC
15094 else
15095 start = real_start;
0e602686 15096 }
fd8008d8 15097
cf13d699
NC
15098 /* If the section being dumped has relocations against it the user might
15099 be expecting these relocations to have been applied. Check for this
15100 case and issue a warning message in order to avoid confusion.
15101 FIXME: Maybe we ought to have an option that dumps a section with
15102 relocs applied ? */
dda8d76d
NC
15103 for (relsec = filedata->section_headers;
15104 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15105 ++relsec)
15106 {
15107 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15108 || relsec->sh_info >= filedata->file_header.e_shnum
15109 || filedata->section_headers + relsec->sh_info != section
cf13d699 15110 || relsec->sh_size == 0
dda8d76d 15111 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15112 continue;
15113
15114 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15115 break;
15116 }
15117
cf13d699
NC
15118 data = start;
15119 end = start + num_bytes;
015dc7e1 15120 some_strings_shown = false;
cf13d699 15121
ba3265d0
NC
15122#ifdef HAVE_MBSTATE_T
15123 mbstate_t state;
15124 /* Initialise the multibyte conversion state. */
15125 memset (& state, 0, sizeof (state));
15126#endif
15127
015dc7e1 15128 bool continuing = false;
ba3265d0 15129
cf13d699
NC
15130 while (data < end)
15131 {
15132 while (!ISPRINT (* data))
15133 if (++ data >= end)
15134 break;
15135
15136 if (data < end)
15137 {
071436c6
NC
15138 size_t maxlen = end - data;
15139
ba3265d0
NC
15140 if (continuing)
15141 {
15142 printf (" ");
015dc7e1 15143 continuing = false;
ba3265d0
NC
15144 }
15145 else
15146 {
d1ce973e 15147 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15148 }
15149
4082ef84
NC
15150 if (maxlen > 0)
15151 {
f3da8a96 15152 char c = 0;
ba3265d0
NC
15153
15154 while (maxlen)
15155 {
15156 c = *data++;
15157
15158 if (c == 0)
15159 break;
15160
15161 /* PR 25543: Treat new-lines as string-ending characters. */
15162 if (c == '\n')
15163 {
15164 printf ("\\n\n");
15165 if (*data != 0)
015dc7e1 15166 continuing = true;
ba3265d0
NC
15167 break;
15168 }
15169
15170 /* Do not print control characters directly as they can affect terminal
15171 settings. Such characters usually appear in the names generated
15172 by the assembler for local labels. */
15173 if (ISCNTRL (c))
15174 {
15175 printf ("^%c", c + 0x40);
15176 }
15177 else if (ISPRINT (c))
15178 {
15179 putchar (c);
15180 }
15181 else
15182 {
15183 size_t n;
15184#ifdef HAVE_MBSTATE_T
15185 wchar_t w;
15186#endif
15187 /* Let printf do the hard work of displaying multibyte characters. */
15188 printf ("%.1s", data - 1);
15189#ifdef HAVE_MBSTATE_T
15190 /* Try to find out how many bytes made up the character that was
15191 just printed. Advance the symbol pointer past the bytes that
15192 were displayed. */
15193 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15194#else
15195 n = 1;
15196#endif
15197 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15198 data += (n - 1);
15199 }
15200 }
15201
15202 if (c != '\n')
15203 putchar ('\n');
4082ef84
NC
15204 }
15205 else
15206 {
15207 printf (_("<corrupt>\n"));
15208 data = end;
15209 }
015dc7e1 15210 some_strings_shown = true;
cf13d699
NC
15211 }
15212 }
15213
15214 if (! some_strings_shown)
15215 printf (_(" No strings found in this section."));
15216
0e602686 15217 free (real_start);
cf13d699
NC
15218
15219 putchar ('\n');
015dc7e1 15220 return true;
f761cb13
AM
15221
15222error_out:
15223 free (real_start);
015dc7e1 15224 return false;
cf13d699
NC
15225}
15226
015dc7e1
AM
15227static bool
15228dump_section_as_bytes (Elf_Internal_Shdr *section,
15229 Filedata *filedata,
15230 bool relocate)
cf13d699
NC
15231{
15232 Elf_Internal_Shdr * relsec;
0e602686
NC
15233 bfd_size_type bytes;
15234 bfd_size_type section_size;
15235 bfd_vma addr;
15236 unsigned char * data;
15237 unsigned char * real_start;
15238 unsigned char * start;
15239
dda8d76d 15240 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15241 if (start == NULL)
c6b78c96 15242 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15243 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15244
0e602686 15245 section_size = section->sh_size;
cf13d699 15246
835f2fae
NC
15247 if (filedata->is_separate)
15248 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15249 printable_section_name (filedata, section),
15250 filedata->file_name);
15251 else
15252 printf (_("\nHex dump of section '%s':\n"),
15253 printable_section_name (filedata, section));
cf13d699 15254
0e602686
NC
15255 if (decompress_dumps)
15256 {
15257 dwarf_size_type new_size = section_size;
15258 dwarf_size_type uncompressed_size = 0;
15259
15260 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15261 {
15262 Elf_Internal_Chdr chdr;
15263 unsigned int compression_header_size
ebdf1ebf 15264 = get_compression_header (& chdr, start, section_size);
0e602686 15265
5844b465
NC
15266 if (compression_header_size == 0)
15267 /* An error message will have already been generated
15268 by get_compression_header. */
15269 goto error_out;
15270
813dabb9 15271 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15272 {
813dabb9 15273 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15274 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15275 goto error_out;
0e602686 15276 }
813dabb9
L
15277 uncompressed_size = chdr.ch_size;
15278 start += compression_header_size;
15279 new_size -= compression_header_size;
0e602686
NC
15280 }
15281 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15282 {
15283 /* Read the zlib header. In this case, it should be "ZLIB"
15284 followed by the uncompressed section size, 8 bytes in
15285 big-endian order. */
15286 uncompressed_size = start[4]; uncompressed_size <<= 8;
15287 uncompressed_size += start[5]; uncompressed_size <<= 8;
15288 uncompressed_size += start[6]; uncompressed_size <<= 8;
15289 uncompressed_size += start[7]; uncompressed_size <<= 8;
15290 uncompressed_size += start[8]; uncompressed_size <<= 8;
15291 uncompressed_size += start[9]; uncompressed_size <<= 8;
15292 uncompressed_size += start[10]; uncompressed_size <<= 8;
15293 uncompressed_size += start[11];
15294 start += 12;
15295 new_size -= 12;
15296 }
15297
f055032e
NC
15298 if (uncompressed_size)
15299 {
15300 if (uncompress_section_contents (& start, uncompressed_size,
15301 & new_size))
bc303e5d
NC
15302 {
15303 section_size = new_size;
15304 }
f055032e
NC
15305 else
15306 {
15307 error (_("Unable to decompress section %s\n"),
dda8d76d 15308 printable_section_name (filedata, section));
bc303e5d 15309 /* FIXME: Print the section anyway ? */
f761cb13 15310 goto error_out;
f055032e
NC
15311 }
15312 }
bc303e5d
NC
15313 else
15314 start = real_start;
0e602686 15315 }
14ae95f2 15316
cf13d699
NC
15317 if (relocate)
15318 {
dda8d76d 15319 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15320 goto error_out;
cf13d699
NC
15321 }
15322 else
15323 {
15324 /* If the section being dumped has relocations against it the user might
15325 be expecting these relocations to have been applied. Check for this
15326 case and issue a warning message in order to avoid confusion.
15327 FIXME: Maybe we ought to have an option that dumps a section with
15328 relocs applied ? */
dda8d76d
NC
15329 for (relsec = filedata->section_headers;
15330 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15331 ++relsec)
15332 {
15333 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15334 || relsec->sh_info >= filedata->file_header.e_shnum
15335 || filedata->section_headers + relsec->sh_info != section
cf13d699 15336 || relsec->sh_size == 0
dda8d76d 15337 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15338 continue;
15339
15340 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15341 break;
15342 }
15343 }
15344
15345 addr = section->sh_addr;
0e602686 15346 bytes = section_size;
cf13d699
NC
15347 data = start;
15348
15349 while (bytes)
15350 {
15351 int j;
15352 int k;
15353 int lbytes;
15354
15355 lbytes = (bytes > 16 ? 16 : bytes);
15356
15357 printf (" 0x%8.8lx ", (unsigned long) addr);
15358
15359 for (j = 0; j < 16; j++)
15360 {
15361 if (j < lbytes)
15362 printf ("%2.2x", data[j]);
15363 else
15364 printf (" ");
15365
15366 if ((j & 3) == 3)
15367 printf (" ");
15368 }
15369
15370 for (j = 0; j < lbytes; j++)
15371 {
15372 k = data[j];
15373 if (k >= ' ' && k < 0x7f)
15374 printf ("%c", k);
15375 else
15376 printf (".");
15377 }
15378
15379 putchar ('\n');
15380
15381 data += lbytes;
15382 addr += lbytes;
15383 bytes -= lbytes;
15384 }
15385
0e602686 15386 free (real_start);
cf13d699
NC
15387
15388 putchar ('\n');
015dc7e1 15389 return true;
f761cb13
AM
15390
15391 error_out:
15392 free (real_start);
015dc7e1 15393 return false;
cf13d699
NC
15394}
15395
094e34f2 15396#ifdef ENABLE_LIBCTF
7d9813f1
NA
15397static ctf_sect_t *
15398shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15399{
84714f86 15400 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15401 buf->cts_size = shdr->sh_size;
15402 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15403
15404 return buf;
15405}
15406
15407/* Formatting callback function passed to ctf_dump. Returns either the pointer
15408 it is passed, or a pointer to newly-allocated storage, in which case
15409 dump_ctf() will free it when it no longer needs it. */
15410
2f6ecaed
NA
15411static char *
15412dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15413 char *s, void *arg)
7d9813f1 15414{
3e50a591 15415 const char *blanks = arg;
7d9813f1
NA
15416 char *new_s;
15417
3e50a591 15418 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15419 return s;
15420 return new_s;
15421}
15422
926c9e76
NA
15423/* Dump CTF errors/warnings. */
15424static void
139633c3 15425dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15426{
15427 ctf_next_t *it = NULL;
15428 char *errtext;
15429 int is_warning;
15430 int err;
15431
15432 /* Dump accumulated errors and warnings. */
15433 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15434 {
5e9b84f7 15435 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15436 errtext);
15437 free (errtext);
15438 }
15439 if (err != ECTF_NEXT_END)
15440 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15441}
15442
2f6ecaed
NA
15443/* Dump one CTF archive member. */
15444
80b56fad
NA
15445static void
15446dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15447 size_t member)
2f6ecaed 15448{
2f6ecaed
NA
15449 const char *things[] = {"Header", "Labels", "Data objects",
15450 "Function objects", "Variables", "Types", "Strings",
15451 ""};
15452 const char **thing;
15453 size_t i;
15454
80b56fad
NA
15455 /* Don't print out the name of the default-named archive member if it appears
15456 first in the list. The name .ctf appears everywhere, even for things that
15457 aren't really archives, so printing it out is liable to be confusing; also,
15458 the common case by far is for only one archive member to exist, and hiding
15459 it in that case seems worthwhile. */
2f6ecaed 15460
80b56fad
NA
15461 if (strcmp (name, ".ctf") != 0 || member != 0)
15462 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15463
80b56fad
NA
15464 if (ctf_parent_name (ctf) != NULL)
15465 ctf_import (ctf, parent);
2f6ecaed
NA
15466
15467 for (i = 0, thing = things; *thing[0]; thing++, i++)
15468 {
15469 ctf_dump_state_t *s = NULL;
15470 char *item;
15471
15472 printf ("\n %s:\n", *thing);
15473 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15474 (void *) " ")) != NULL)
15475 {
15476 printf ("%s\n", item);
15477 free (item);
15478 }
15479
15480 if (ctf_errno (ctf))
15481 {
15482 error (_("Iteration failed: %s, %s\n"), *thing,
15483 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15484 break;
2f6ecaed
NA
15485 }
15486 }
8b37e7b6 15487
926c9e76 15488 dump_ctf_errs (ctf);
2f6ecaed
NA
15489}
15490
015dc7e1 15491static bool
7d9813f1
NA
15492dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15493{
7d9813f1
NA
15494 Elf_Internal_Shdr * symtab_sec = NULL;
15495 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15496 void * data = NULL;
15497 void * symdata = NULL;
15498 void * strdata = NULL;
80b56fad 15499 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15500 ctf_sect_t * symsectp = NULL;
15501 ctf_sect_t * strsectp = NULL;
2f6ecaed 15502 ctf_archive_t * ctfa = NULL;
139633c3 15503 ctf_dict_t * parent = NULL;
80b56fad 15504 ctf_dict_t * fp;
7d9813f1 15505
80b56fad
NA
15506 ctf_next_t *i = NULL;
15507 const char *name;
15508 size_t member = 0;
7d9813f1 15509 int err;
015dc7e1 15510 bool ret = false;
7d9813f1
NA
15511
15512 shdr_to_ctf_sect (&ctfsect, section, filedata);
15513 data = get_section_contents (section, filedata);
15514 ctfsect.cts_data = data;
15515
616febde 15516 if (!dump_ctf_symtab_name)
3d16b64e 15517 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15518
15519 if (!dump_ctf_strtab_name)
3d16b64e 15520 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15521
15522 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15523 {
15524 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15525 {
15526 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15527 goto fail;
15528 }
15529 if ((symdata = (void *) get_data (NULL, filedata,
15530 symtab_sec->sh_offset, 1,
15531 symtab_sec->sh_size,
15532 _("symbols"))) == NULL)
15533 goto fail;
15534 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15535 symsect.cts_data = symdata;
15536 }
835f2fae 15537
df16e041 15538 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15539 {
15540 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15541 {
15542 error (_("No string table section named %s\n"),
15543 dump_ctf_strtab_name);
15544 goto fail;
15545 }
15546 if ((strdata = (void *) get_data (NULL, filedata,
15547 strtab_sec->sh_offset, 1,
15548 strtab_sec->sh_size,
15549 _("strings"))) == NULL)
15550 goto fail;
15551 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15552 strsect.cts_data = strdata;
15553 }
835f2fae 15554
2f6ecaed
NA
15555 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15556 libctf papers over the difference, so we can pretend it is always an
80b56fad 15557 archive. */
7d9813f1 15558
2f6ecaed 15559 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15560 {
926c9e76 15561 dump_ctf_errs (NULL);
7d9813f1
NA
15562 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15563 goto fail;
15564 }
15565
96c61be5
NA
15566 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15567 != ELFDATA2MSB);
15568
80b56fad
NA
15569 /* Preload the parent dict, since it will need to be imported into every
15570 child in turn. */
15571 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15572 {
926c9e76 15573 dump_ctf_errs (NULL);
2f6ecaed
NA
15574 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15575 goto fail;
7d9813f1
NA
15576 }
15577
015dc7e1 15578 ret = true;
7d9813f1 15579
835f2fae
NC
15580 if (filedata->is_separate)
15581 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15582 printable_section_name (filedata, section),
15583 filedata->file_name);
15584 else
15585 printf (_("\nDump of CTF section '%s':\n"),
15586 printable_section_name (filedata, section));
7d9813f1 15587
80b56fad
NA
15588 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15589 dump_ctf_archive_member (fp, name, parent, member++);
15590 if (err != ECTF_NEXT_END)
15591 {
15592 dump_ctf_errs (NULL);
15593 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15594 ret = false;
15595 }
7d9813f1
NA
15596
15597 fail:
139633c3 15598 ctf_dict_close (parent);
2f6ecaed 15599 ctf_close (ctfa);
7d9813f1
NA
15600 free (data);
15601 free (symdata);
15602 free (strdata);
15603 return ret;
15604}
094e34f2 15605#endif
7d9813f1 15606
015dc7e1 15607static bool
dda8d76d
NC
15608load_specific_debug_section (enum dwarf_section_display_enum debug,
15609 const Elf_Internal_Shdr * sec,
15610 void * data)
1007acb3 15611{
2cf0635d 15612 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15613 char buf [64];
dda8d76d 15614 Filedata * filedata = (Filedata *) data;
9abca702 15615
19e6b90e 15616 if (section->start != NULL)
dda8d76d
NC
15617 {
15618 /* If it is already loaded, do nothing. */
15619 if (streq (section->filename, filedata->file_name))
015dc7e1 15620 return true;
dda8d76d
NC
15621 free (section->start);
15622 }
1007acb3 15623
19e6b90e
L
15624 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15625 section->address = sec->sh_addr;
dda8d76d
NC
15626 section->filename = filedata->file_name;
15627 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15628 sec->sh_offset, 1,
15629 sec->sh_size, buf);
59245841
NC
15630 if (section->start == NULL)
15631 section->size = 0;
15632 else
15633 {
77115a4a
L
15634 unsigned char *start = section->start;
15635 dwarf_size_type size = sec->sh_size;
dab394de 15636 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15637
15638 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15639 {
15640 Elf_Internal_Chdr chdr;
d8024a91
NC
15641 unsigned int compression_header_size;
15642
f53be977
L
15643 if (size < (is_32bit_elf
15644 ? sizeof (Elf32_External_Chdr)
15645 : sizeof (Elf64_External_Chdr)))
d8024a91 15646 {
55be8fd0 15647 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15648 section->name);
015dc7e1 15649 return false;
d8024a91
NC
15650 }
15651
ebdf1ebf 15652 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15653 if (compression_header_size == 0)
15654 /* An error message will have already been generated
15655 by get_compression_header. */
015dc7e1 15656 return false;
d8024a91 15657
813dabb9
L
15658 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15659 {
15660 warn (_("section '%s' has unsupported compress type: %d\n"),
15661 section->name, chdr.ch_type);
015dc7e1 15662 return false;
813dabb9 15663 }
dab394de 15664 uncompressed_size = chdr.ch_size;
77115a4a
L
15665 start += compression_header_size;
15666 size -= compression_header_size;
15667 }
dab394de
L
15668 else if (size > 12 && streq ((char *) start, "ZLIB"))
15669 {
15670 /* Read the zlib header. In this case, it should be "ZLIB"
15671 followed by the uncompressed section size, 8 bytes in
15672 big-endian order. */
15673 uncompressed_size = start[4]; uncompressed_size <<= 8;
15674 uncompressed_size += start[5]; uncompressed_size <<= 8;
15675 uncompressed_size += start[6]; uncompressed_size <<= 8;
15676 uncompressed_size += start[7]; uncompressed_size <<= 8;
15677 uncompressed_size += start[8]; uncompressed_size <<= 8;
15678 uncompressed_size += start[9]; uncompressed_size <<= 8;
15679 uncompressed_size += start[10]; uncompressed_size <<= 8;
15680 uncompressed_size += start[11];
15681 start += 12;
15682 size -= 12;
15683 }
15684
1835f746 15685 if (uncompressed_size)
77115a4a 15686 {
1835f746
NC
15687 if (uncompress_section_contents (&start, uncompressed_size,
15688 &size))
15689 {
15690 /* Free the compressed buffer, update the section buffer
15691 and the section size if uncompress is successful. */
15692 free (section->start);
15693 section->start = start;
15694 }
15695 else
15696 {
15697 error (_("Unable to decompress section %s\n"),
dda8d76d 15698 printable_section_name (filedata, sec));
015dc7e1 15699 return false;
1835f746 15700 }
77115a4a 15701 }
bc303e5d 15702
77115a4a 15703 section->size = size;
59245841 15704 }
4a114e3e 15705
1b315056 15706 if (section->start == NULL)
015dc7e1 15707 return false;
1b315056 15708
19e6b90e 15709 if (debug_displays [debug].relocate)
32ec8896 15710 {
dda8d76d 15711 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15712 & section->reloc_info, & section->num_relocs))
015dc7e1 15713 return false;
32ec8896 15714 }
d1c4b12b
NC
15715 else
15716 {
15717 section->reloc_info = NULL;
15718 section->num_relocs = 0;
15719 }
1007acb3 15720
015dc7e1 15721 return true;
1007acb3
L
15722}
15723
301a9420
AM
15724#if HAVE_LIBDEBUGINFOD
15725/* Return a hex string representation of the build-id. */
15726unsigned char *
15727get_build_id (void * data)
15728{
ca0e11aa 15729 Filedata * filedata = (Filedata *) data;
301a9420
AM
15730 Elf_Internal_Shdr * shdr;
15731 unsigned long i;
15732
55be8fd0
NC
15733 /* Iterate through notes to find note.gnu.build-id.
15734 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15735 for (i = 0, shdr = filedata->section_headers;
15736 i < filedata->file_header.e_shnum && shdr != NULL;
15737 i++, shdr++)
15738 {
15739 if (shdr->sh_type != SHT_NOTE)
15740 continue;
15741
15742 char * next;
15743 char * end;
15744 size_t data_remaining;
15745 size_t min_notesz;
15746 Elf_External_Note * enote;
15747 Elf_Internal_Note inote;
15748
15749 bfd_vma offset = shdr->sh_offset;
15750 bfd_vma align = shdr->sh_addralign;
15751 bfd_vma length = shdr->sh_size;
15752
15753 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15754 if (enote == NULL)
15755 continue;
15756
15757 if (align < 4)
15758 align = 4;
15759 else if (align != 4 && align != 8)
f761cb13
AM
15760 {
15761 free (enote);
15762 continue;
15763 }
301a9420
AM
15764
15765 end = (char *) enote + length;
15766 data_remaining = end - (char *) enote;
15767
15768 if (!is_ia64_vms (filedata))
15769 {
15770 min_notesz = offsetof (Elf_External_Note, name);
15771 if (data_remaining < min_notesz)
15772 {
55be8fd0
NC
15773 warn (_("\
15774malformed note encountered in section %s whilst scanning for build-id note\n"),
15775 printable_section_name (filedata, shdr));
f761cb13 15776 free (enote);
55be8fd0 15777 continue;
301a9420
AM
15778 }
15779 data_remaining -= min_notesz;
15780
15781 inote.type = BYTE_GET (enote->type);
15782 inote.namesz = BYTE_GET (enote->namesz);
15783 inote.namedata = enote->name;
15784 inote.descsz = BYTE_GET (enote->descsz);
15785 inote.descdata = ((char *) enote
15786 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15787 inote.descpos = offset + (inote.descdata - (char *) enote);
15788 next = ((char *) enote
15789 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15790 }
15791 else
15792 {
15793 Elf64_External_VMS_Note *vms_enote;
15794
15795 /* PR binutils/15191
15796 Make sure that there is enough data to read. */
15797 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15798 if (data_remaining < min_notesz)
15799 {
55be8fd0
NC
15800 warn (_("\
15801malformed note encountered in section %s whilst scanning for build-id note\n"),
15802 printable_section_name (filedata, shdr));
f761cb13 15803 free (enote);
55be8fd0 15804 continue;
301a9420
AM
15805 }
15806 data_remaining -= min_notesz;
15807
15808 vms_enote = (Elf64_External_VMS_Note *) enote;
15809 inote.type = BYTE_GET (vms_enote->type);
15810 inote.namesz = BYTE_GET (vms_enote->namesz);
15811 inote.namedata = vms_enote->name;
15812 inote.descsz = BYTE_GET (vms_enote->descsz);
15813 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15814 inote.descpos = offset + (inote.descdata - (char *) enote);
15815 next = inote.descdata + align_power (inote.descsz, 3);
15816 }
15817
15818 /* Skip malformed notes. */
15819 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15820 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15821 || (size_t) (next - inote.descdata) < inote.descsz
15822 || ((size_t) (next - inote.descdata)
15823 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15824 {
55be8fd0
NC
15825 warn (_("\
15826malformed note encountered in section %s whilst scanning for build-id note\n"),
15827 printable_section_name (filedata, shdr));
f761cb13 15828 free (enote);
301a9420
AM
15829 continue;
15830 }
15831
15832 /* Check if this is the build-id note. If so then convert the build-id
15833 bytes to a hex string. */
15834 if (inote.namesz > 0
24d127aa 15835 && startswith (inote.namedata, "GNU")
301a9420
AM
15836 && inote.type == NT_GNU_BUILD_ID)
15837 {
15838 unsigned long j;
15839 char * build_id;
15840
15841 build_id = malloc (inote.descsz * 2 + 1);
15842 if (build_id == NULL)
f761cb13
AM
15843 {
15844 free (enote);
15845 return NULL;
15846 }
301a9420
AM
15847
15848 for (j = 0; j < inote.descsz; ++j)
15849 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15850 build_id[inote.descsz * 2] = '\0';
f761cb13 15851 free (enote);
301a9420 15852
55be8fd0 15853 return (unsigned char *) build_id;
301a9420 15854 }
f761cb13 15855 free (enote);
301a9420
AM
15856 }
15857
15858 return NULL;
15859}
15860#endif /* HAVE_LIBDEBUGINFOD */
15861
657d0d47
CC
15862/* If this is not NULL, load_debug_section will only look for sections
15863 within the list of sections given here. */
32ec8896 15864static unsigned int * section_subset = NULL;
657d0d47 15865
015dc7e1 15866bool
dda8d76d 15867load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15868{
2cf0635d
NC
15869 struct dwarf_section * section = &debug_displays [debug].section;
15870 Elf_Internal_Shdr * sec;
dda8d76d
NC
15871 Filedata * filedata = (Filedata *) data;
15872
f425ec66
NC
15873 /* Without section headers we cannot find any sections. */
15874 if (filedata->section_headers == NULL)
015dc7e1 15875 return false;
f425ec66 15876
9c1ce108
AM
15877 if (filedata->string_table == NULL
15878 && filedata->file_header.e_shstrndx != SHN_UNDEF
15879 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15880 {
15881 Elf_Internal_Shdr * strs;
15882
15883 /* Read in the string table, so that we have section names to scan. */
15884 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15885
4dff97b2 15886 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15887 {
9c1ce108
AM
15888 filedata->string_table
15889 = (char *) get_data (NULL, filedata, strs->sh_offset,
15890 1, strs->sh_size, _("string table"));
dda8d76d 15891
9c1ce108
AM
15892 filedata->string_table_length
15893 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15894 }
15895 }
d966045b
DJ
15896
15897 /* Locate the debug section. */
dda8d76d 15898 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15899 if (sec != NULL)
15900 section->name = section->uncompressed_name;
15901 else
15902 {
dda8d76d 15903 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15904 if (sec != NULL)
15905 section->name = section->compressed_name;
15906 }
15907 if (sec == NULL)
015dc7e1 15908 return false;
d966045b 15909
657d0d47
CC
15910 /* If we're loading from a subset of sections, and we've loaded
15911 a section matching this name before, it's likely that it's a
15912 different one. */
15913 if (section_subset != NULL)
15914 free_debug_section (debug);
15915
dda8d76d 15916 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15917}
15918
19e6b90e
L
15919void
15920free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15921{
2cf0635d 15922 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15923
19e6b90e
L
15924 if (section->start == NULL)
15925 return;
1007acb3 15926
19e6b90e
L
15927 free ((char *) section->start);
15928 section->start = NULL;
15929 section->address = 0;
15930 section->size = 0;
a788aedd 15931
9db70fc3
AM
15932 free (section->reloc_info);
15933 section->reloc_info = NULL;
15934 section->num_relocs = 0;
1007acb3
L
15935}
15936
015dc7e1 15937static bool
dda8d76d 15938display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15939{
84714f86
AM
15940 const char *name = (section_name_valid (filedata, section)
15941 ? section_name (filedata, section) : "");
15942 const char *print_name = printable_section_name (filedata, section);
19e6b90e 15943 bfd_size_type length;
015dc7e1 15944 bool result = true;
3f5e193b 15945 int i;
1007acb3 15946
19e6b90e
L
15947 length = section->sh_size;
15948 if (length == 0)
1007acb3 15949 {
74e1a04b 15950 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15951 return true;
1007acb3 15952 }
5dff79d8
NC
15953 if (section->sh_type == SHT_NOBITS)
15954 {
15955 /* There is no point in dumping the contents of a debugging section
15956 which has the NOBITS type - the bits in the file will be random.
15957 This can happen when a file containing a .eh_frame section is
15958 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15959 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15960 print_name);
015dc7e1 15961 return false;
5dff79d8 15962 }
1007acb3 15963
24d127aa 15964 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 15965 name = ".debug_info";
1007acb3 15966
19e6b90e
L
15967 /* See if we know how to display the contents of this section. */
15968 for (i = 0; i < max; i++)
d85bf2ba
NC
15969 {
15970 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15971 struct dwarf_section_display * display = debug_displays + i;
15972 struct dwarf_section * sec = & display->section;
d966045b 15973
d85bf2ba 15974 if (streq (sec->uncompressed_name, name)
24d127aa 15975 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15976 || streq (sec->compressed_name, name))
15977 {
015dc7e1 15978 bool secondary = (section != find_section (filedata, name));
1007acb3 15979
d85bf2ba
NC
15980 if (secondary)
15981 free_debug_section (id);
dda8d76d 15982
24d127aa 15983 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15984 sec->name = name;
15985 else if (streq (sec->uncompressed_name, name))
15986 sec->name = sec->uncompressed_name;
15987 else
15988 sec->name = sec->compressed_name;
657d0d47 15989
d85bf2ba
NC
15990 if (load_specific_debug_section (id, section, filedata))
15991 {
15992 /* If this debug section is part of a CU/TU set in a .dwp file,
15993 restrict load_debug_section to the sections in that set. */
15994 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15995
d85bf2ba 15996 result &= display->display (sec, filedata);
657d0d47 15997
d85bf2ba 15998 section_subset = NULL;
1007acb3 15999
44266f36 16000 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16001 free_debug_section (id);
16002 }
16003 break;
16004 }
16005 }
1007acb3 16006
19e6b90e 16007 if (i == max)
1007acb3 16008 {
74e1a04b 16009 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16010 result = false;
1007acb3
L
16011 }
16012
19e6b90e 16013 return result;
5b18a4bc 16014}
103f02d3 16015
aef1f6d0
DJ
16016/* Set DUMP_SECTS for all sections where dumps were requested
16017 based on section name. */
16018
16019static void
dda8d76d 16020initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16021{
2cf0635d 16022 struct dump_list_entry * cur;
aef1f6d0
DJ
16023
16024 for (cur = dump_sects_byname; cur; cur = cur->next)
16025 {
16026 unsigned int i;
015dc7e1 16027 bool any = false;
aef1f6d0 16028
dda8d76d 16029 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16030 if (section_name_valid (filedata, filedata->section_headers + i)
16031 && streq (section_name (filedata, filedata->section_headers + i),
16032 cur->name))
aef1f6d0 16033 {
6431e409 16034 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16035 any = true;
aef1f6d0
DJ
16036 }
16037
835f2fae
NC
16038 if (!any && !filedata->is_separate)
16039 warn (_("Section '%s' was not dumped because it does not exist\n"),
16040 cur->name);
aef1f6d0
DJ
16041 }
16042}
16043
015dc7e1 16044static bool
dda8d76d 16045process_section_contents (Filedata * filedata)
5b18a4bc 16046{
2cf0635d 16047 Elf_Internal_Shdr * section;
19e6b90e 16048 unsigned int i;
015dc7e1 16049 bool res = true;
103f02d3 16050
19e6b90e 16051 if (! do_dump)
015dc7e1 16052 return true;
103f02d3 16053
dda8d76d 16054 initialise_dumps_byname (filedata);
aef1f6d0 16055
dda8d76d 16056 for (i = 0, section = filedata->section_headers;
6431e409 16057 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16058 i++, section++)
16059 {
6431e409 16060 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16061
d6bfbc39
NC
16062 if (filedata->is_separate && ! process_links)
16063 dump &= DEBUG_DUMP;
047c3dbf 16064
19e6b90e 16065#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16066 if (dump & DISASS_DUMP)
16067 {
16068 if (! disassemble_section (section, filedata))
015dc7e1 16069 res = false;
dda8d76d 16070 }
19e6b90e 16071#endif
dda8d76d 16072 if (dump & HEX_DUMP)
32ec8896 16073 {
015dc7e1
AM
16074 if (! dump_section_as_bytes (section, filedata, false))
16075 res = false;
32ec8896 16076 }
103f02d3 16077
dda8d76d 16078 if (dump & RELOC_DUMP)
32ec8896 16079 {
015dc7e1
AM
16080 if (! dump_section_as_bytes (section, filedata, true))
16081 res = false;
32ec8896 16082 }
09c11c86 16083
dda8d76d 16084 if (dump & STRING_DUMP)
32ec8896 16085 {
dda8d76d 16086 if (! dump_section_as_strings (section, filedata))
015dc7e1 16087 res = false;
32ec8896 16088 }
cf13d699 16089
dda8d76d 16090 if (dump & DEBUG_DUMP)
32ec8896 16091 {
dda8d76d 16092 if (! display_debug_section (i, section, filedata))
015dc7e1 16093 res = false;
32ec8896 16094 }
7d9813f1 16095
094e34f2 16096#ifdef ENABLE_LIBCTF
7d9813f1
NA
16097 if (dump & CTF_DUMP)
16098 {
16099 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16100 res = false;
7d9813f1 16101 }
094e34f2 16102#endif
5b18a4bc 16103 }
103f02d3 16104
835f2fae 16105 if (! filedata->is_separate)
0ee3043f 16106 {
835f2fae
NC
16107 /* Check to see if the user requested a
16108 dump of a section that does not exist. */
16109 for (; i < filedata->dump.num_dump_sects; i++)
16110 if (filedata->dump.dump_sects[i])
16111 {
ca0e11aa 16112 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16113 res = false;
835f2fae 16114 }
0ee3043f 16115 }
32ec8896
NC
16116
16117 return res;
5b18a4bc 16118}
103f02d3 16119
5b18a4bc 16120static void
19e6b90e 16121process_mips_fpe_exception (int mask)
5b18a4bc 16122{
19e6b90e
L
16123 if (mask)
16124 {
015dc7e1 16125 bool first = true;
32ec8896 16126
19e6b90e 16127 if (mask & OEX_FPU_INEX)
015dc7e1 16128 fputs ("INEX", stdout), first = false;
19e6b90e 16129 if (mask & OEX_FPU_UFLO)
015dc7e1 16130 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16131 if (mask & OEX_FPU_OFLO)
015dc7e1 16132 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16133 if (mask & OEX_FPU_DIV0)
015dc7e1 16134 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16135 if (mask & OEX_FPU_INVAL)
16136 printf ("%sINVAL", first ? "" : "|");
16137 }
5b18a4bc 16138 else
19e6b90e 16139 fputs ("0", stdout);
5b18a4bc 16140}
103f02d3 16141
f6f0e17b
NC
16142/* Display's the value of TAG at location P. If TAG is
16143 greater than 0 it is assumed to be an unknown tag, and
16144 a message is printed to this effect. Otherwise it is
16145 assumed that a message has already been printed.
16146
16147 If the bottom bit of TAG is set it assumed to have a
16148 string value, otherwise it is assumed to have an integer
16149 value.
16150
16151 Returns an updated P pointing to the first unread byte
16152 beyond the end of TAG's value.
16153
16154 Reads at or beyond END will not be made. */
16155
16156static unsigned char *
60abdbed 16157display_tag_value (signed int tag,
f6f0e17b
NC
16158 unsigned char * p,
16159 const unsigned char * const end)
16160{
16161 unsigned long val;
16162
16163 if (tag > 0)
16164 printf (" Tag_unknown_%d: ", tag);
16165
16166 if (p >= end)
16167 {
4082ef84 16168 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16169 }
16170 else if (tag & 1)
16171 {
071436c6
NC
16172 /* PR 17531 file: 027-19978-0.004. */
16173 size_t maxlen = (end - p) - 1;
16174
16175 putchar ('"');
4082ef84
NC
16176 if (maxlen > 0)
16177 {
16178 print_symbol ((int) maxlen, (const char *) p);
16179 p += strnlen ((char *) p, maxlen) + 1;
16180 }
16181 else
16182 {
16183 printf (_("<corrupt string tag>"));
16184 p = (unsigned char *) end;
16185 }
071436c6 16186 printf ("\"\n");
f6f0e17b
NC
16187 }
16188 else
16189 {
cd30bcef 16190 READ_ULEB (val, p, end);
f6f0e17b
NC
16191 printf ("%ld (0x%lx)\n", val, val);
16192 }
16193
4082ef84 16194 assert (p <= end);
f6f0e17b
NC
16195 return p;
16196}
16197
53a346d8
CZ
16198/* ARC ABI attributes section. */
16199
16200static unsigned char *
16201display_arc_attribute (unsigned char * p,
16202 const unsigned char * const end)
16203{
16204 unsigned int tag;
53a346d8
CZ
16205 unsigned int val;
16206
cd30bcef 16207 READ_ULEB (tag, p, end);
53a346d8
CZ
16208
16209 switch (tag)
16210 {
16211 case Tag_ARC_PCS_config:
cd30bcef 16212 READ_ULEB (val, p, end);
53a346d8
CZ
16213 printf (" Tag_ARC_PCS_config: ");
16214 switch (val)
16215 {
16216 case 0:
16217 printf (_("Absent/Non standard\n"));
16218 break;
16219 case 1:
16220 printf (_("Bare metal/mwdt\n"));
16221 break;
16222 case 2:
16223 printf (_("Bare metal/newlib\n"));
16224 break;
16225 case 3:
16226 printf (_("Linux/uclibc\n"));
16227 break;
16228 case 4:
16229 printf (_("Linux/glibc\n"));
16230 break;
16231 default:
16232 printf (_("Unknown\n"));
16233 break;
16234 }
16235 break;
16236
16237 case Tag_ARC_CPU_base:
cd30bcef 16238 READ_ULEB (val, p, end);
53a346d8
CZ
16239 printf (" Tag_ARC_CPU_base: ");
16240 switch (val)
16241 {
16242 default:
16243 case TAG_CPU_NONE:
16244 printf (_("Absent\n"));
16245 break;
16246 case TAG_CPU_ARC6xx:
16247 printf ("ARC6xx\n");
16248 break;
16249 case TAG_CPU_ARC7xx:
16250 printf ("ARC7xx\n");
16251 break;
16252 case TAG_CPU_ARCEM:
16253 printf ("ARCEM\n");
16254 break;
16255 case TAG_CPU_ARCHS:
16256 printf ("ARCHS\n");
16257 break;
16258 }
16259 break;
16260
16261 case Tag_ARC_CPU_variation:
cd30bcef 16262 READ_ULEB (val, p, end);
53a346d8
CZ
16263 printf (" Tag_ARC_CPU_variation: ");
16264 switch (val)
16265 {
16266 default:
16267 if (val > 0 && val < 16)
53a346d8 16268 printf ("Core%d\n", val);
d8cbc93b
JL
16269 else
16270 printf ("Unknown\n");
16271 break;
16272
53a346d8
CZ
16273 case 0:
16274 printf (_("Absent\n"));
16275 break;
16276 }
16277 break;
16278
16279 case Tag_ARC_CPU_name:
16280 printf (" Tag_ARC_CPU_name: ");
16281 p = display_tag_value (-1, p, end);
16282 break;
16283
16284 case Tag_ARC_ABI_rf16:
cd30bcef 16285 READ_ULEB (val, p, end);
53a346d8
CZ
16286 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16287 break;
16288
16289 case Tag_ARC_ABI_osver:
cd30bcef 16290 READ_ULEB (val, p, end);
53a346d8
CZ
16291 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16292 break;
16293
16294 case Tag_ARC_ABI_pic:
16295 case Tag_ARC_ABI_sda:
cd30bcef 16296 READ_ULEB (val, p, end);
53a346d8
CZ
16297 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16298 : " Tag_ARC_ABI_pic: ");
16299 switch (val)
16300 {
16301 case 0:
16302 printf (_("Absent\n"));
16303 break;
16304 case 1:
16305 printf ("MWDT\n");
16306 break;
16307 case 2:
16308 printf ("GNU\n");
16309 break;
16310 default:
16311 printf (_("Unknown\n"));
16312 break;
16313 }
16314 break;
16315
16316 case Tag_ARC_ABI_tls:
cd30bcef 16317 READ_ULEB (val, p, end);
53a346d8
CZ
16318 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16319 break;
16320
16321 case Tag_ARC_ABI_enumsize:
cd30bcef 16322 READ_ULEB (val, p, end);
53a346d8
CZ
16323 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16324 _("smallest"));
16325 break;
16326
16327 case Tag_ARC_ABI_exceptions:
cd30bcef 16328 READ_ULEB (val, p, end);
53a346d8
CZ
16329 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16330 : _("default"));
16331 break;
16332
16333 case Tag_ARC_ABI_double_size:
cd30bcef 16334 READ_ULEB (val, p, end);
53a346d8
CZ
16335 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16336 break;
16337
16338 case Tag_ARC_ISA_config:
16339 printf (" Tag_ARC_ISA_config: ");
16340 p = display_tag_value (-1, p, end);
16341 break;
16342
16343 case Tag_ARC_ISA_apex:
16344 printf (" Tag_ARC_ISA_apex: ");
16345 p = display_tag_value (-1, p, end);
16346 break;
16347
16348 case Tag_ARC_ISA_mpy_option:
cd30bcef 16349 READ_ULEB (val, p, end);
53a346d8
CZ
16350 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16351 break;
16352
db1e1b45 16353 case Tag_ARC_ATR_version:
cd30bcef 16354 READ_ULEB (val, p, end);
db1e1b45 16355 printf (" Tag_ARC_ATR_version: %d\n", val);
16356 break;
16357
53a346d8
CZ
16358 default:
16359 return display_tag_value (tag & 1, p, end);
16360 }
16361
16362 return p;
16363}
16364
11c1ff18
PB
16365/* ARM EABI attributes section. */
16366typedef struct
16367{
70e99720 16368 unsigned int tag;
2cf0635d 16369 const char * name;
11c1ff18 16370 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16371 unsigned int type;
288f0ba2 16372 const char *const *table;
11c1ff18
PB
16373} arm_attr_public_tag;
16374
288f0ba2 16375static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16376 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16377 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16378 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16379 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16380static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16381static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16382 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16383static const char *const arm_attr_tag_FP_arch[] =
bca38921 16384 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16385 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16386static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16387static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16388 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16389 "NEON for ARMv8.1"};
288f0ba2 16390static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16391 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16392 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16393static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16394 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16395static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16396 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16397static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16398 {"Absolute", "PC-relative", "None"};
288f0ba2 16399static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16400 {"None", "direct", "GOT-indirect"};
288f0ba2 16401static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16402 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16403static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16404static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16405 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16406static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16407static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16408static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16409 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16410static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16411 {"Unused", "small", "int", "forced to int"};
288f0ba2 16412static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16413 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16414static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16415 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16416static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16417 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16418static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16419 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16420 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16421static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16422 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16423 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16424static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16425static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16426 {"Not Allowed", "Allowed"};
288f0ba2 16427static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16428 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16429static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16430 {"Follow architecture", "Allowed"};
288f0ba2 16431static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16432 {"Not Allowed", "Allowed"};
288f0ba2 16433static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16434 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16435 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16436static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16437static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16438 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16439 "TrustZone and Virtualization Extensions"};
288f0ba2 16440static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16441 {"Not Allowed", "Allowed"};
11c1ff18 16442
288f0ba2 16443static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16444 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16445
99db83d0
AC
16446static const char * arm_attr_tag_PAC_extension[] =
16447 {"No PAC/AUT instructions",
16448 "PAC/AUT instructions permitted in the NOP space",
16449 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16450
4b535030
AC
16451static const char * arm_attr_tag_BTI_extension[] =
16452 {"BTI instructions not permitted",
16453 "BTI instructions permitted in the NOP space",
16454 "BTI instructions permitted in the NOP and in the non-NOP space"};
16455
b81ee92f
AC
16456static const char * arm_attr_tag_BTI_use[] =
16457 {"Compiled without branch target enforcement",
16458 "Compiled with branch target enforcement"};
16459
c9fed665
AC
16460static const char * arm_attr_tag_PACRET_use[] =
16461 {"Compiled without return address signing and authentication",
16462 "Compiled with return address signing and authentication"};
16463
11c1ff18
PB
16464#define LOOKUP(id, name) \
16465 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16466static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16467{
16468 {4, "CPU_raw_name", 1, NULL},
16469 {5, "CPU_name", 1, NULL},
16470 LOOKUP(6, CPU_arch),
16471 {7, "CPU_arch_profile", 0, NULL},
16472 LOOKUP(8, ARM_ISA_use),
16473 LOOKUP(9, THUMB_ISA_use),
75375b3e 16474 LOOKUP(10, FP_arch),
11c1ff18 16475 LOOKUP(11, WMMX_arch),
f5f53991
AS
16476 LOOKUP(12, Advanced_SIMD_arch),
16477 LOOKUP(13, PCS_config),
11c1ff18
PB
16478 LOOKUP(14, ABI_PCS_R9_use),
16479 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16480 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16481 LOOKUP(17, ABI_PCS_GOT_use),
16482 LOOKUP(18, ABI_PCS_wchar_t),
16483 LOOKUP(19, ABI_FP_rounding),
16484 LOOKUP(20, ABI_FP_denormal),
16485 LOOKUP(21, ABI_FP_exceptions),
16486 LOOKUP(22, ABI_FP_user_exceptions),
16487 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16488 {24, "ABI_align_needed", 0, NULL},
16489 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16490 LOOKUP(26, ABI_enum_size),
16491 LOOKUP(27, ABI_HardFP_use),
16492 LOOKUP(28, ABI_VFP_args),
16493 LOOKUP(29, ABI_WMMX_args),
16494 LOOKUP(30, ABI_optimization_goals),
16495 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16496 {32, "compatibility", 0, NULL},
f5f53991 16497 LOOKUP(34, CPU_unaligned_access),
75375b3e 16498 LOOKUP(36, FP_HP_extension),
8e79c3df 16499 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16500 LOOKUP(42, MPextension_use),
16501 LOOKUP(44, DIV_use),
15afaa63 16502 LOOKUP(46, DSP_extension),
a7ad558c 16503 LOOKUP(48, MVE_arch),
99db83d0 16504 LOOKUP(50, PAC_extension),
4b535030 16505 LOOKUP(52, BTI_extension),
b81ee92f 16506 LOOKUP(74, BTI_use),
c9fed665 16507 LOOKUP(76, PACRET_use),
f5f53991
AS
16508 {64, "nodefaults", 0, NULL},
16509 {65, "also_compatible_with", 0, NULL},
16510 LOOKUP(66, T2EE_use),
16511 {67, "conformance", 1, NULL},
16512 LOOKUP(68, Virtualization_use),
cd21e546 16513 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16514};
16515#undef LOOKUP
16516
11c1ff18 16517static unsigned char *
f6f0e17b
NC
16518display_arm_attribute (unsigned char * p,
16519 const unsigned char * const end)
11c1ff18 16520{
70e99720 16521 unsigned int tag;
70e99720 16522 unsigned int val;
2cf0635d 16523 arm_attr_public_tag * attr;
11c1ff18 16524 unsigned i;
70e99720 16525 unsigned int type;
11c1ff18 16526
cd30bcef 16527 READ_ULEB (tag, p, end);
11c1ff18 16528 attr = NULL;
2cf0635d 16529 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16530 {
16531 if (arm_attr_public_tags[i].tag == tag)
16532 {
16533 attr = &arm_attr_public_tags[i];
16534 break;
16535 }
16536 }
16537
16538 if (attr)
16539 {
16540 printf (" Tag_%s: ", attr->name);
16541 switch (attr->type)
16542 {
16543 case 0:
16544 switch (tag)
16545 {
16546 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16547 READ_ULEB (val, p, end);
11c1ff18
PB
16548 switch (val)
16549 {
2b692964
NC
16550 case 0: printf (_("None\n")); break;
16551 case 'A': printf (_("Application\n")); break;
16552 case 'R': printf (_("Realtime\n")); break;
16553 case 'M': printf (_("Microcontroller\n")); break;
16554 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16555 default: printf ("??? (%d)\n", val); break;
16556 }
16557 break;
16558
75375b3e 16559 case 24: /* Tag_align_needed. */
cd30bcef 16560 READ_ULEB (val, p, end);
75375b3e
MGD
16561 switch (val)
16562 {
2b692964
NC
16563 case 0: printf (_("None\n")); break;
16564 case 1: printf (_("8-byte\n")); break;
16565 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16566 case 3: printf ("??? 3\n"); break;
16567 default:
16568 if (val <= 12)
dd24e3da 16569 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16570 1 << val);
16571 else
16572 printf ("??? (%d)\n", val);
16573 break;
16574 }
16575 break;
16576
16577 case 25: /* Tag_align_preserved. */
cd30bcef 16578 READ_ULEB (val, p, end);
75375b3e
MGD
16579 switch (val)
16580 {
2b692964
NC
16581 case 0: printf (_("None\n")); break;
16582 case 1: printf (_("8-byte, except leaf SP\n")); break;
16583 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16584 case 3: printf ("??? 3\n"); break;
16585 default:
16586 if (val <= 12)
dd24e3da 16587 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16588 1 << val);
16589 else
16590 printf ("??? (%d)\n", val);
16591 break;
16592 }
16593 break;
16594
11c1ff18 16595 case 32: /* Tag_compatibility. */
071436c6 16596 {
cd30bcef 16597 READ_ULEB (val, p, end);
071436c6 16598 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16599 if (p < end - 1)
16600 {
16601 size_t maxlen = (end - p) - 1;
16602
16603 print_symbol ((int) maxlen, (const char *) p);
16604 p += strnlen ((char *) p, maxlen) + 1;
16605 }
16606 else
16607 {
16608 printf (_("<corrupt>"));
16609 p = (unsigned char *) end;
16610 }
071436c6 16611 putchar ('\n');
071436c6 16612 }
11c1ff18
PB
16613 break;
16614
f5f53991 16615 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16616 /* PR 17531: file: 001-505008-0.01. */
16617 if (p < end)
16618 p++;
2b692964 16619 printf (_("True\n"));
f5f53991
AS
16620 break;
16621
16622 case 65: /* Tag_also_compatible_with. */
cd30bcef 16623 READ_ULEB (val, p, end);
f5f53991
AS
16624 if (val == 6 /* Tag_CPU_arch. */)
16625 {
cd30bcef 16626 READ_ULEB (val, p, end);
071436c6 16627 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16628 printf ("??? (%d)\n", val);
16629 else
16630 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16631 }
16632 else
16633 printf ("???\n");
071436c6
NC
16634 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16635 ;
f5f53991
AS
16636 break;
16637
11c1ff18 16638 default:
bee0ee85
NC
16639 printf (_("<unknown: %d>\n"), tag);
16640 break;
11c1ff18
PB
16641 }
16642 return p;
16643
16644 case 1:
f6f0e17b 16645 return display_tag_value (-1, p, end);
11c1ff18 16646 case 2:
f6f0e17b 16647 return display_tag_value (0, p, end);
11c1ff18
PB
16648
16649 default:
16650 assert (attr->type & 0x80);
cd30bcef 16651 READ_ULEB (val, p, end);
11c1ff18
PB
16652 type = attr->type & 0x7f;
16653 if (val >= type)
16654 printf ("??? (%d)\n", val);
16655 else
16656 printf ("%s\n", attr->table[val]);
16657 return p;
16658 }
16659 }
11c1ff18 16660
f6f0e17b 16661 return display_tag_value (tag, p, end);
11c1ff18
PB
16662}
16663
104d59d1 16664static unsigned char *
60bca95a 16665display_gnu_attribute (unsigned char * p,
60abdbed 16666 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16667 const unsigned char * const end)
104d59d1 16668{
cd30bcef 16669 unsigned int tag;
60abdbed 16670 unsigned int val;
104d59d1 16671
cd30bcef 16672 READ_ULEB (tag, p, end);
104d59d1
JM
16673
16674 /* Tag_compatibility is the only generic GNU attribute defined at
16675 present. */
16676 if (tag == 32)
16677 {
cd30bcef 16678 READ_ULEB (val, p, end);
071436c6
NC
16679
16680 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16681 if (p == end)
16682 {
071436c6 16683 printf (_("<corrupt>\n"));
f6f0e17b
NC
16684 warn (_("corrupt vendor attribute\n"));
16685 }
16686 else
16687 {
4082ef84
NC
16688 if (p < end - 1)
16689 {
16690 size_t maxlen = (end - p) - 1;
071436c6 16691
4082ef84
NC
16692 print_symbol ((int) maxlen, (const char *) p);
16693 p += strnlen ((char *) p, maxlen) + 1;
16694 }
16695 else
16696 {
16697 printf (_("<corrupt>"));
16698 p = (unsigned char *) end;
16699 }
071436c6 16700 putchar ('\n');
f6f0e17b 16701 }
104d59d1
JM
16702 return p;
16703 }
16704
16705 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16706 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16707
f6f0e17b 16708 return display_tag_value (tag, p, end);
104d59d1
JM
16709}
16710
85f7484a
PB
16711static unsigned char *
16712display_m68k_gnu_attribute (unsigned char * p,
16713 unsigned int tag,
16714 const unsigned char * const end)
16715{
16716 unsigned int val;
16717
16718 if (tag == Tag_GNU_M68K_ABI_FP)
16719 {
16720 printf (" Tag_GNU_M68K_ABI_FP: ");
16721 if (p == end)
16722 {
16723 printf (_("<corrupt>\n"));
16724 return p;
16725 }
16726 READ_ULEB (val, p, end);
16727
16728 if (val > 3)
16729 printf ("(%#x), ", val);
16730
16731 switch (val & 3)
16732 {
16733 case 0:
16734 printf (_("unspecified hard/soft float\n"));
16735 break;
16736 case 1:
16737 printf (_("hard float\n"));
16738 break;
16739 case 2:
16740 printf (_("soft float\n"));
16741 break;
16742 }
16743 return p;
16744 }
16745
16746 return display_tag_value (tag & 1, p, end);
16747}
16748
34c8bcba 16749static unsigned char *
f6f0e17b 16750display_power_gnu_attribute (unsigned char * p,
60abdbed 16751 unsigned int tag,
f6f0e17b 16752 const unsigned char * const end)
34c8bcba 16753{
005d79fd 16754 unsigned int val;
34c8bcba
JM
16755
16756 if (tag == Tag_GNU_Power_ABI_FP)
16757 {
34c8bcba 16758 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16759 if (p == end)
005d79fd
AM
16760 {
16761 printf (_("<corrupt>\n"));
16762 return p;
16763 }
cd30bcef 16764 READ_ULEB (val, p, end);
60bca95a 16765
005d79fd
AM
16766 if (val > 15)
16767 printf ("(%#x), ", val);
16768
16769 switch (val & 3)
34c8bcba
JM
16770 {
16771 case 0:
005d79fd 16772 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16773 break;
16774 case 1:
005d79fd 16775 printf (_("hard float, "));
34c8bcba
JM
16776 break;
16777 case 2:
005d79fd 16778 printf (_("soft float, "));
34c8bcba 16779 break;
3c7b9897 16780 case 3:
005d79fd 16781 printf (_("single-precision hard float, "));
3c7b9897 16782 break;
005d79fd
AM
16783 }
16784
16785 switch (val & 0xC)
16786 {
16787 case 0:
16788 printf (_("unspecified long double\n"));
16789 break;
16790 case 4:
16791 printf (_("128-bit IBM long double\n"));
16792 break;
16793 case 8:
16794 printf (_("64-bit long double\n"));
16795 break;
16796 case 12:
16797 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16798 break;
16799 }
16800 return p;
005d79fd 16801 }
34c8bcba 16802
c6e65352
DJ
16803 if (tag == Tag_GNU_Power_ABI_Vector)
16804 {
c6e65352 16805 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16806 if (p == end)
005d79fd
AM
16807 {
16808 printf (_("<corrupt>\n"));
16809 return p;
16810 }
cd30bcef 16811 READ_ULEB (val, p, end);
005d79fd
AM
16812
16813 if (val > 3)
16814 printf ("(%#x), ", val);
16815
16816 switch (val & 3)
c6e65352
DJ
16817 {
16818 case 0:
005d79fd 16819 printf (_("unspecified\n"));
c6e65352
DJ
16820 break;
16821 case 1:
005d79fd 16822 printf (_("generic\n"));
c6e65352
DJ
16823 break;
16824 case 2:
16825 printf ("AltiVec\n");
16826 break;
16827 case 3:
16828 printf ("SPE\n");
16829 break;
c6e65352
DJ
16830 }
16831 return p;
005d79fd 16832 }
c6e65352 16833
f82e0623
NF
16834 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16835 {
005d79fd 16836 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16837 if (p == end)
f6f0e17b 16838 {
005d79fd 16839 printf (_("<corrupt>\n"));
f6f0e17b
NC
16840 return p;
16841 }
cd30bcef 16842 READ_ULEB (val, p, end);
0b4362b0 16843
005d79fd
AM
16844 if (val > 2)
16845 printf ("(%#x), ", val);
16846
16847 switch (val & 3)
16848 {
16849 case 0:
16850 printf (_("unspecified\n"));
16851 break;
16852 case 1:
16853 printf ("r3/r4\n");
16854 break;
16855 case 2:
16856 printf (_("memory\n"));
16857 break;
16858 case 3:
16859 printf ("???\n");
16860 break;
16861 }
f82e0623
NF
16862 return p;
16863 }
16864
f6f0e17b 16865 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16866}
16867
643f7afb
AK
16868static unsigned char *
16869display_s390_gnu_attribute (unsigned char * p,
60abdbed 16870 unsigned int tag,
643f7afb
AK
16871 const unsigned char * const end)
16872{
cd30bcef 16873 unsigned int val;
643f7afb
AK
16874
16875 if (tag == Tag_GNU_S390_ABI_Vector)
16876 {
643f7afb 16877 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16878 READ_ULEB (val, p, end);
643f7afb
AK
16879
16880 switch (val)
16881 {
16882 case 0:
16883 printf (_("any\n"));
16884 break;
16885 case 1:
16886 printf (_("software\n"));
16887 break;
16888 case 2:
16889 printf (_("hardware\n"));
16890 break;
16891 default:
16892 printf ("??? (%d)\n", val);
16893 break;
16894 }
16895 return p;
16896 }
16897
16898 return display_tag_value (tag & 1, p, end);
16899}
16900
9e8c70f9 16901static void
60abdbed 16902display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16903{
16904 if (mask)
16905 {
015dc7e1 16906 bool first = true;
071436c6 16907
9e8c70f9 16908 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16909 fputs ("mul32", stdout), first = false;
9e8c70f9 16910 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16911 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16912 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16913 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16914 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16915 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16916 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16917 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16918 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16919 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16920 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16921 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16922 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16923 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16924 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16925 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16926 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16927 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16928 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16929 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16930 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16931 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16932 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16933 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16934 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16935 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16936 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16937 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16938 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16939 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16940 }
16941 else
071436c6
NC
16942 fputc ('0', stdout);
16943 fputc ('\n', stdout);
9e8c70f9
DM
16944}
16945
3d68f91c 16946static void
60abdbed 16947display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16948{
16949 if (mask)
16950 {
015dc7e1 16951 bool first = true;
071436c6 16952
3d68f91c 16953 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16954 fputs ("fjathplus", stdout), first = false;
3d68f91c 16955 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16956 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16957 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16958 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16959 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16960 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 16961 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 16962 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 16963 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 16964 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 16965 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 16966 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 16967 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 16968 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 16969 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 16970 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 16971 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 16972 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 16973 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 16974 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
16975 }
16976 else
071436c6
NC
16977 fputc ('0', stdout);
16978 fputc ('\n', stdout);
3d68f91c
JM
16979}
16980
9e8c70f9 16981static unsigned char *
f6f0e17b 16982display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16983 unsigned int tag,
f6f0e17b 16984 const unsigned char * const end)
9e8c70f9 16985{
cd30bcef 16986 unsigned int val;
3d68f91c 16987
9e8c70f9
DM
16988 if (tag == Tag_GNU_Sparc_HWCAPS)
16989 {
cd30bcef 16990 READ_ULEB (val, p, end);
9e8c70f9 16991 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16992 display_sparc_hwcaps (val);
16993 return p;
3d68f91c
JM
16994 }
16995 if (tag == Tag_GNU_Sparc_HWCAPS2)
16996 {
cd30bcef 16997 READ_ULEB (val, p, end);
3d68f91c
JM
16998 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16999 display_sparc_hwcaps2 (val);
17000 return p;
17001 }
9e8c70f9 17002
f6f0e17b 17003 return display_tag_value (tag, p, end);
9e8c70f9
DM
17004}
17005
351cdf24 17006static void
32ec8896 17007print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17008{
17009 switch (val)
17010 {
17011 case Val_GNU_MIPS_ABI_FP_ANY:
17012 printf (_("Hard or soft float\n"));
17013 break;
17014 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17015 printf (_("Hard float (double precision)\n"));
17016 break;
17017 case Val_GNU_MIPS_ABI_FP_SINGLE:
17018 printf (_("Hard float (single precision)\n"));
17019 break;
17020 case Val_GNU_MIPS_ABI_FP_SOFT:
17021 printf (_("Soft float\n"));
17022 break;
17023 case Val_GNU_MIPS_ABI_FP_OLD_64:
17024 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17025 break;
17026 case Val_GNU_MIPS_ABI_FP_XX:
17027 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17028 break;
17029 case Val_GNU_MIPS_ABI_FP_64:
17030 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17031 break;
17032 case Val_GNU_MIPS_ABI_FP_64A:
17033 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17034 break;
3350cc01
CM
17035 case Val_GNU_MIPS_ABI_FP_NAN2008:
17036 printf (_("NaN 2008 compatibility\n"));
17037 break;
351cdf24
MF
17038 default:
17039 printf ("??? (%d)\n", val);
17040 break;
17041 }
17042}
17043
2cf19d5c 17044static unsigned char *
f6f0e17b 17045display_mips_gnu_attribute (unsigned char * p,
60abdbed 17046 unsigned int tag,
f6f0e17b 17047 const unsigned char * const end)
2cf19d5c 17048{
2cf19d5c
JM
17049 if (tag == Tag_GNU_MIPS_ABI_FP)
17050 {
32ec8896 17051 unsigned int val;
f6f0e17b 17052
2cf19d5c 17053 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17054 READ_ULEB (val, p, end);
351cdf24 17055 print_mips_fp_abi_value (val);
2cf19d5c
JM
17056 return p;
17057 }
17058
a9f58168
CF
17059 if (tag == Tag_GNU_MIPS_ABI_MSA)
17060 {
32ec8896 17061 unsigned int val;
a9f58168 17062
a9f58168 17063 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17064 READ_ULEB (val, p, end);
a9f58168
CF
17065
17066 switch (val)
17067 {
17068 case Val_GNU_MIPS_ABI_MSA_ANY:
17069 printf (_("Any MSA or not\n"));
17070 break;
17071 case Val_GNU_MIPS_ABI_MSA_128:
17072 printf (_("128-bit MSA\n"));
17073 break;
17074 default:
17075 printf ("??? (%d)\n", val);
17076 break;
17077 }
17078 return p;
17079 }
17080
f6f0e17b 17081 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17082}
17083
59e6276b 17084static unsigned char *
f6f0e17b
NC
17085display_tic6x_attribute (unsigned char * p,
17086 const unsigned char * const end)
59e6276b 17087{
60abdbed 17088 unsigned int tag;
cd30bcef 17089 unsigned int val;
59e6276b 17090
cd30bcef 17091 READ_ULEB (tag, p, end);
59e6276b
JM
17092
17093 switch (tag)
17094 {
75fa6dc1 17095 case Tag_ISA:
75fa6dc1 17096 printf (" Tag_ISA: ");
cd30bcef 17097 READ_ULEB (val, p, end);
59e6276b
JM
17098
17099 switch (val)
17100 {
75fa6dc1 17101 case C6XABI_Tag_ISA_none:
59e6276b
JM
17102 printf (_("None\n"));
17103 break;
75fa6dc1 17104 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17105 printf ("C62x\n");
17106 break;
75fa6dc1 17107 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17108 printf ("C67x\n");
17109 break;
75fa6dc1 17110 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17111 printf ("C67x+\n");
17112 break;
75fa6dc1 17113 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17114 printf ("C64x\n");
17115 break;
75fa6dc1 17116 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17117 printf ("C64x+\n");
17118 break;
75fa6dc1 17119 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17120 printf ("C674x\n");
17121 break;
17122 default:
17123 printf ("??? (%d)\n", val);
17124 break;
17125 }
17126 return p;
17127
87779176 17128 case Tag_ABI_wchar_t:
87779176 17129 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17130 READ_ULEB (val, p, end);
87779176
JM
17131 switch (val)
17132 {
17133 case 0:
17134 printf (_("Not used\n"));
17135 break;
17136 case 1:
17137 printf (_("2 bytes\n"));
17138 break;
17139 case 2:
17140 printf (_("4 bytes\n"));
17141 break;
17142 default:
17143 printf ("??? (%d)\n", val);
17144 break;
17145 }
17146 return p;
17147
17148 case Tag_ABI_stack_align_needed:
87779176 17149 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17150 READ_ULEB (val, p, end);
87779176
JM
17151 switch (val)
17152 {
17153 case 0:
17154 printf (_("8-byte\n"));
17155 break;
17156 case 1:
17157 printf (_("16-byte\n"));
17158 break;
17159 default:
17160 printf ("??? (%d)\n", val);
17161 break;
17162 }
17163 return p;
17164
17165 case Tag_ABI_stack_align_preserved:
cd30bcef 17166 READ_ULEB (val, p, end);
87779176
JM
17167 printf (" Tag_ABI_stack_align_preserved: ");
17168 switch (val)
17169 {
17170 case 0:
17171 printf (_("8-byte\n"));
17172 break;
17173 case 1:
17174 printf (_("16-byte\n"));
17175 break;
17176 default:
17177 printf ("??? (%d)\n", val);
17178 break;
17179 }
17180 return p;
17181
b5593623 17182 case Tag_ABI_DSBT:
cd30bcef 17183 READ_ULEB (val, p, end);
b5593623
JM
17184 printf (" Tag_ABI_DSBT: ");
17185 switch (val)
17186 {
17187 case 0:
17188 printf (_("DSBT addressing not used\n"));
17189 break;
17190 case 1:
17191 printf (_("DSBT addressing used\n"));
17192 break;
17193 default:
17194 printf ("??? (%d)\n", val);
17195 break;
17196 }
17197 return p;
17198
87779176 17199 case Tag_ABI_PID:
cd30bcef 17200 READ_ULEB (val, p, end);
87779176
JM
17201 printf (" Tag_ABI_PID: ");
17202 switch (val)
17203 {
17204 case 0:
17205 printf (_("Data addressing position-dependent\n"));
17206 break;
17207 case 1:
17208 printf (_("Data addressing position-independent, GOT near DP\n"));
17209 break;
17210 case 2:
17211 printf (_("Data addressing position-independent, GOT far from DP\n"));
17212 break;
17213 default:
17214 printf ("??? (%d)\n", val);
17215 break;
17216 }
17217 return p;
17218
17219 case Tag_ABI_PIC:
cd30bcef 17220 READ_ULEB (val, p, end);
87779176
JM
17221 printf (" Tag_ABI_PIC: ");
17222 switch (val)
17223 {
17224 case 0:
17225 printf (_("Code addressing position-dependent\n"));
17226 break;
17227 case 1:
17228 printf (_("Code addressing position-independent\n"));
17229 break;
17230 default:
17231 printf ("??? (%d)\n", val);
17232 break;
17233 }
17234 return p;
17235
17236 case Tag_ABI_array_object_alignment:
cd30bcef 17237 READ_ULEB (val, p, end);
87779176
JM
17238 printf (" Tag_ABI_array_object_alignment: ");
17239 switch (val)
17240 {
17241 case 0:
17242 printf (_("8-byte\n"));
17243 break;
17244 case 1:
17245 printf (_("4-byte\n"));
17246 break;
17247 case 2:
17248 printf (_("16-byte\n"));
17249 break;
17250 default:
17251 printf ("??? (%d)\n", val);
17252 break;
17253 }
17254 return p;
17255
17256 case Tag_ABI_array_object_align_expected:
cd30bcef 17257 READ_ULEB (val, p, end);
87779176
JM
17258 printf (" Tag_ABI_array_object_align_expected: ");
17259 switch (val)
17260 {
17261 case 0:
17262 printf (_("8-byte\n"));
17263 break;
17264 case 1:
17265 printf (_("4-byte\n"));
17266 break;
17267 case 2:
17268 printf (_("16-byte\n"));
17269 break;
17270 default:
17271 printf ("??? (%d)\n", val);
17272 break;
17273 }
17274 return p;
17275
3cbd1c06 17276 case Tag_ABI_compatibility:
071436c6 17277 {
cd30bcef 17278 READ_ULEB (val, p, end);
071436c6 17279 printf (" Tag_ABI_compatibility: ");
071436c6 17280 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17281 if (p < end - 1)
17282 {
17283 size_t maxlen = (end - p) - 1;
17284
17285 print_symbol ((int) maxlen, (const char *) p);
17286 p += strnlen ((char *) p, maxlen) + 1;
17287 }
17288 else
17289 {
17290 printf (_("<corrupt>"));
17291 p = (unsigned char *) end;
17292 }
071436c6 17293 putchar ('\n');
071436c6
NC
17294 return p;
17295 }
87779176
JM
17296
17297 case Tag_ABI_conformance:
071436c6 17298 {
4082ef84
NC
17299 printf (" Tag_ABI_conformance: \"");
17300 if (p < end - 1)
17301 {
17302 size_t maxlen = (end - p) - 1;
071436c6 17303
4082ef84
NC
17304 print_symbol ((int) maxlen, (const char *) p);
17305 p += strnlen ((char *) p, maxlen) + 1;
17306 }
17307 else
17308 {
17309 printf (_("<corrupt>"));
17310 p = (unsigned char *) end;
17311 }
071436c6 17312 printf ("\"\n");
071436c6
NC
17313 return p;
17314 }
59e6276b
JM
17315 }
17316
f6f0e17b
NC
17317 return display_tag_value (tag, p, end);
17318}
59e6276b 17319
f6f0e17b 17320static void
60abdbed 17321display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17322{
17323 unsigned long addr = 0;
17324 size_t bytes = end - p;
17325
feceaa59 17326 assert (end >= p);
f6f0e17b 17327 while (bytes)
87779176 17328 {
f6f0e17b
NC
17329 int j;
17330 int k;
17331 int lbytes = (bytes > 16 ? 16 : bytes);
17332
17333 printf (" 0x%8.8lx ", addr);
17334
17335 for (j = 0; j < 16; j++)
17336 {
17337 if (j < lbytes)
17338 printf ("%2.2x", p[j]);
17339 else
17340 printf (" ");
17341
17342 if ((j & 3) == 3)
17343 printf (" ");
17344 }
17345
17346 for (j = 0; j < lbytes; j++)
17347 {
17348 k = p[j];
17349 if (k >= ' ' && k < 0x7f)
17350 printf ("%c", k);
17351 else
17352 printf (".");
17353 }
17354
17355 putchar ('\n');
17356
17357 p += lbytes;
17358 bytes -= lbytes;
17359 addr += lbytes;
87779176 17360 }
59e6276b 17361
f6f0e17b 17362 putchar ('\n');
59e6276b
JM
17363}
17364
13761a11 17365static unsigned char *
b0191216 17366display_msp430_attribute (unsigned char * p,
13761a11
NC
17367 const unsigned char * const end)
17368{
60abdbed
NC
17369 unsigned int val;
17370 unsigned int tag;
13761a11 17371
cd30bcef 17372 READ_ULEB (tag, p, end);
0b4362b0 17373
13761a11
NC
17374 switch (tag)
17375 {
17376 case OFBA_MSPABI_Tag_ISA:
13761a11 17377 printf (" Tag_ISA: ");
cd30bcef 17378 READ_ULEB (val, p, end);
13761a11
NC
17379 switch (val)
17380 {
17381 case 0: printf (_("None\n")); break;
17382 case 1: printf (_("MSP430\n")); break;
17383 case 2: printf (_("MSP430X\n")); break;
17384 default: printf ("??? (%d)\n", val); break;
17385 }
17386 break;
17387
17388 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17389 printf (" Tag_Code_Model: ");
cd30bcef 17390 READ_ULEB (val, p, end);
13761a11
NC
17391 switch (val)
17392 {
17393 case 0: printf (_("None\n")); break;
17394 case 1: printf (_("Small\n")); break;
17395 case 2: printf (_("Large\n")); break;
17396 default: printf ("??? (%d)\n", val); break;
17397 }
17398 break;
17399
17400 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17401 printf (" Tag_Data_Model: ");
cd30bcef 17402 READ_ULEB (val, p, end);
13761a11
NC
17403 switch (val)
17404 {
17405 case 0: printf (_("None\n")); break;
17406 case 1: printf (_("Small\n")); break;
17407 case 2: printf (_("Large\n")); break;
17408 case 3: printf (_("Restricted Large\n")); break;
17409 default: printf ("??? (%d)\n", val); break;
17410 }
17411 break;
17412
17413 default:
17414 printf (_(" <unknown tag %d>: "), tag);
17415
17416 if (tag & 1)
17417 {
071436c6 17418 putchar ('"');
4082ef84
NC
17419 if (p < end - 1)
17420 {
17421 size_t maxlen = (end - p) - 1;
17422
17423 print_symbol ((int) maxlen, (const char *) p);
17424 p += strnlen ((char *) p, maxlen) + 1;
17425 }
17426 else
17427 {
17428 printf (_("<corrupt>"));
17429 p = (unsigned char *) end;
17430 }
071436c6 17431 printf ("\"\n");
13761a11
NC
17432 }
17433 else
17434 {
cd30bcef 17435 READ_ULEB (val, p, end);
13761a11
NC
17436 printf ("%d (0x%x)\n", val, val);
17437 }
17438 break;
17439 }
17440
4082ef84 17441 assert (p <= end);
13761a11
NC
17442 return p;
17443}
17444
c0ea7c52
JL
17445static unsigned char *
17446display_msp430_gnu_attribute (unsigned char * p,
17447 unsigned int tag,
17448 const unsigned char * const end)
17449{
17450 if (tag == Tag_GNU_MSP430_Data_Region)
17451 {
cd30bcef 17452 unsigned int val;
c0ea7c52 17453
c0ea7c52 17454 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17455 READ_ULEB (val, p, end);
c0ea7c52
JL
17456
17457 switch (val)
17458 {
17459 case Val_GNU_MSP430_Data_Region_Any:
17460 printf (_("Any Region\n"));
17461 break;
17462 case Val_GNU_MSP430_Data_Region_Lower:
17463 printf (_("Lower Region Only\n"));
17464 break;
17465 default:
cd30bcef 17466 printf ("??? (%u)\n", val);
c0ea7c52
JL
17467 }
17468 return p;
17469 }
17470 return display_tag_value (tag & 1, p, end);
17471}
17472
2dc8dd17
JW
17473struct riscv_attr_tag_t {
17474 const char *name;
cd30bcef 17475 unsigned int tag;
2dc8dd17
JW
17476};
17477
17478static struct riscv_attr_tag_t riscv_attr_tag[] =
17479{
17480#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17481 T(arch),
17482 T(priv_spec),
17483 T(priv_spec_minor),
17484 T(priv_spec_revision),
17485 T(unaligned_access),
17486 T(stack_align),
17487#undef T
17488};
17489
17490static unsigned char *
17491display_riscv_attribute (unsigned char *p,
17492 const unsigned char * const end)
17493{
cd30bcef
AM
17494 unsigned int val;
17495 unsigned int tag;
2dc8dd17
JW
17496 struct riscv_attr_tag_t *attr = NULL;
17497 unsigned i;
17498
cd30bcef 17499 READ_ULEB (tag, p, end);
2dc8dd17
JW
17500
17501 /* Find the name of attribute. */
17502 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17503 {
17504 if (riscv_attr_tag[i].tag == tag)
17505 {
17506 attr = &riscv_attr_tag[i];
17507 break;
17508 }
17509 }
17510
17511 if (attr)
17512 printf (" %s: ", attr->name);
17513 else
17514 return display_tag_value (tag, p, end);
17515
17516 switch (tag)
17517 {
17518 case Tag_RISCV_priv_spec:
17519 case Tag_RISCV_priv_spec_minor:
17520 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17521 READ_ULEB (val, p, end);
17522 printf (_("%u\n"), val);
2dc8dd17
JW
17523 break;
17524 case Tag_RISCV_unaligned_access:
cd30bcef 17525 READ_ULEB (val, p, end);
2dc8dd17
JW
17526 switch (val)
17527 {
17528 case 0:
17529 printf (_("No unaligned access\n"));
17530 break;
17531 case 1:
17532 printf (_("Unaligned access\n"));
17533 break;
17534 }
17535 break;
17536 case Tag_RISCV_stack_align:
cd30bcef
AM
17537 READ_ULEB (val, p, end);
17538 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17539 break;
17540 case Tag_RISCV_arch:
17541 p = display_tag_value (-1, p, end);
17542 break;
17543 default:
17544 return display_tag_value (tag, p, end);
17545 }
17546
17547 return p;
17548}
17549
0861f561
CQ
17550static unsigned char *
17551display_csky_attribute (unsigned char * p,
17552 const unsigned char * const end)
17553{
17554 unsigned int tag;
17555 unsigned int val;
17556 READ_ULEB (tag, p, end);
17557
17558 if (tag >= Tag_CSKY_MAX)
17559 {
17560 return display_tag_value (-1, p, end);
17561 }
17562
17563 switch (tag)
17564 {
17565 case Tag_CSKY_ARCH_NAME:
17566 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17567 return display_tag_value (-1, p, end);
17568 case Tag_CSKY_CPU_NAME:
17569 printf (" Tag_CSKY_CPU_NAME:\t\t");
17570 return display_tag_value (-1, p, end);
17571
17572 case Tag_CSKY_ISA_FLAGS:
17573 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17574 return display_tag_value (0, p, end);
17575 case Tag_CSKY_ISA_EXT_FLAGS:
17576 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17577 return display_tag_value (0, p, end);
17578
17579 case Tag_CSKY_DSP_VERSION:
17580 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17581 READ_ULEB (val, p, end);
17582 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17583 printf ("DSP Extension\n");
17584 else if (val == VAL_CSKY_DSP_VERSION_2)
17585 printf ("DSP 2.0\n");
17586 break;
17587
17588 case Tag_CSKY_VDSP_VERSION:
17589 printf (" Tag_CSKY_VDSP_VERSION:\t");
17590 READ_ULEB (val, p, end);
17591 printf ("VDSP Version %d\n", val);
17592 break;
17593
17594 case Tag_CSKY_FPU_VERSION:
17595 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17596 READ_ULEB (val, p, end);
17597 if (val == VAL_CSKY_FPU_VERSION_1)
17598 printf ("ABIV1 FPU Version 1\n");
17599 else if (val == VAL_CSKY_FPU_VERSION_2)
17600 printf ("FPU Version 2\n");
17601 break;
17602
17603 case Tag_CSKY_FPU_ABI:
17604 printf (" Tag_CSKY_FPU_ABI:\t\t");
17605 READ_ULEB (val, p, end);
17606 if (val == VAL_CSKY_FPU_ABI_HARD)
17607 printf ("Hard\n");
17608 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17609 printf ("SoftFP\n");
17610 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17611 printf ("Soft\n");
17612 break;
17613 case Tag_CSKY_FPU_ROUNDING:
17614 READ_ULEB (val, p, end);
f253158f
NC
17615 if (val == 1)
17616 {
17617 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17618 printf ("Needed\n");
17619 }
0861f561
CQ
17620 break;
17621 case Tag_CSKY_FPU_DENORMAL:
17622 READ_ULEB (val, p, end);
f253158f
NC
17623 if (val == 1)
17624 {
17625 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17626 printf ("Needed\n");
17627 }
0861f561
CQ
17628 break;
17629 case Tag_CSKY_FPU_Exception:
17630 READ_ULEB (val, p, end);
f253158f
NC
17631 if (val == 1)
17632 {
17633 printf (" Tag_CSKY_FPU_Exception:\t");
17634 printf ("Needed\n");
17635 }
0861f561
CQ
17636 break;
17637 case Tag_CSKY_FPU_NUMBER_MODULE:
17638 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17639 return display_tag_value (-1, p, end);
17640 case Tag_CSKY_FPU_HARDFP:
17641 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17642 READ_ULEB (val, p, end);
17643 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17644 printf (" Half");
17645 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17646 printf (" Single");
17647 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17648 printf (" Double");
17649 printf ("\n");
17650 break;
17651 default:
17652 return display_tag_value (tag, p, end);
17653 }
17654 return p;
17655}
17656
015dc7e1 17657static bool
dda8d76d 17658process_attributes (Filedata * filedata,
60bca95a 17659 const char * public_name,
104d59d1 17660 unsigned int proc_type,
f6f0e17b 17661 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17662 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17663{
2cf0635d 17664 Elf_Internal_Shdr * sect;
11c1ff18 17665 unsigned i;
015dc7e1 17666 bool res = true;
11c1ff18
PB
17667
17668 /* Find the section header so that we get the size. */
dda8d76d
NC
17669 for (i = 0, sect = filedata->section_headers;
17670 i < filedata->file_header.e_shnum;
11c1ff18
PB
17671 i++, sect++)
17672 {
071436c6
NC
17673 unsigned char * contents;
17674 unsigned char * p;
17675
104d59d1 17676 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17677 continue;
17678
dda8d76d 17679 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17680 sect->sh_size, _("attributes"));
60bca95a 17681 if (contents == NULL)
32ec8896 17682 {
015dc7e1 17683 res = false;
32ec8896
NC
17684 continue;
17685 }
60bca95a 17686
11c1ff18 17687 p = contents;
60abdbed
NC
17688 /* The first character is the version of the attributes.
17689 Currently only version 1, (aka 'A') is recognised here. */
17690 if (*p != 'A')
32ec8896
NC
17691 {
17692 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17693 res = false;
32ec8896 17694 }
60abdbed 17695 else
11c1ff18 17696 {
071436c6
NC
17697 bfd_vma section_len;
17698
17699 section_len = sect->sh_size - 1;
11c1ff18 17700 p++;
60bca95a 17701
071436c6 17702 while (section_len > 0)
11c1ff18 17703 {
071436c6 17704 bfd_vma attr_len;
e9847026 17705 unsigned int namelen;
015dc7e1
AM
17706 bool public_section;
17707 bool gnu_section;
11c1ff18 17708
071436c6 17709 if (section_len <= 4)
e0a31db1
NC
17710 {
17711 error (_("Tag section ends prematurely\n"));
015dc7e1 17712 res = false;
e0a31db1
NC
17713 break;
17714 }
071436c6 17715 attr_len = byte_get (p, 4);
11c1ff18 17716 p += 4;
60bca95a 17717
071436c6 17718 if (attr_len > section_len)
11c1ff18 17719 {
071436c6
NC
17720 error (_("Bad attribute length (%u > %u)\n"),
17721 (unsigned) attr_len, (unsigned) section_len);
17722 attr_len = section_len;
015dc7e1 17723 res = false;
11c1ff18 17724 }
74e1a04b 17725 /* PR 17531: file: 001-101425-0.004 */
071436c6 17726 else if (attr_len < 5)
74e1a04b 17727 {
071436c6 17728 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17729 res = false;
74e1a04b
NC
17730 break;
17731 }
e9847026 17732
071436c6
NC
17733 section_len -= attr_len;
17734 attr_len -= 4;
17735
17736 namelen = strnlen ((char *) p, attr_len) + 1;
17737 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17738 {
17739 error (_("Corrupt attribute section name\n"));
015dc7e1 17740 res = false;
e9847026
NC
17741 break;
17742 }
17743
071436c6
NC
17744 printf (_("Attribute Section: "));
17745 print_symbol (INT_MAX, (const char *) p);
17746 putchar ('\n');
60bca95a
NC
17747
17748 if (public_name && streq ((char *) p, public_name))
015dc7e1 17749 public_section = true;
11c1ff18 17750 else
015dc7e1 17751 public_section = false;
60bca95a
NC
17752
17753 if (streq ((char *) p, "gnu"))
015dc7e1 17754 gnu_section = true;
104d59d1 17755 else
015dc7e1 17756 gnu_section = false;
60bca95a 17757
11c1ff18 17758 p += namelen;
071436c6 17759 attr_len -= namelen;
e0a31db1 17760
071436c6 17761 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17762 {
e0a31db1 17763 int tag;
cd30bcef 17764 unsigned int val;
11c1ff18 17765 bfd_vma size;
071436c6 17766 unsigned char * end;
60bca95a 17767
e0a31db1 17768 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17769 if (attr_len < 6)
e0a31db1
NC
17770 {
17771 error (_("Unused bytes at end of section\n"));
015dc7e1 17772 res = false;
e0a31db1
NC
17773 section_len = 0;
17774 break;
17775 }
17776
17777 tag = *(p++);
11c1ff18 17778 size = byte_get (p, 4);
071436c6 17779 if (size > attr_len)
11c1ff18 17780 {
e9847026 17781 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17782 (unsigned) size, (unsigned) attr_len);
015dc7e1 17783 res = false;
071436c6 17784 size = attr_len;
11c1ff18 17785 }
e0a31db1
NC
17786 /* PR binutils/17531: Safe handling of corrupt files. */
17787 if (size < 6)
17788 {
17789 error (_("Bad subsection length (%u < 6)\n"),
17790 (unsigned) size);
015dc7e1 17791 res = false;
e0a31db1
NC
17792 section_len = 0;
17793 break;
17794 }
60bca95a 17795
071436c6 17796 attr_len -= size;
11c1ff18 17797 end = p + size - 1;
071436c6 17798 assert (end <= contents + sect->sh_size);
11c1ff18 17799 p += 4;
60bca95a 17800
11c1ff18
PB
17801 switch (tag)
17802 {
17803 case 1:
2b692964 17804 printf (_("File Attributes\n"));
11c1ff18
PB
17805 break;
17806 case 2:
2b692964 17807 printf (_("Section Attributes:"));
11c1ff18
PB
17808 goto do_numlist;
17809 case 3:
2b692964 17810 printf (_("Symbol Attributes:"));
1a0670f3 17811 /* Fall through. */
11c1ff18
PB
17812 do_numlist:
17813 for (;;)
17814 {
cd30bcef 17815 READ_ULEB (val, p, end);
11c1ff18
PB
17816 if (val == 0)
17817 break;
17818 printf (" %d", val);
17819 }
17820 printf ("\n");
17821 break;
17822 default:
2b692964 17823 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17824 public_section = false;
11c1ff18
PB
17825 break;
17826 }
60bca95a 17827
071436c6 17828 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17829 {
17830 while (p < end)
f6f0e17b 17831 p = display_pub_attribute (p, end);
60abdbed 17832 assert (p == end);
104d59d1 17833 }
071436c6 17834 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17835 {
17836 while (p < end)
17837 p = display_gnu_attribute (p,
f6f0e17b
NC
17838 display_proc_gnu_attribute,
17839 end);
60abdbed 17840 assert (p == end);
11c1ff18 17841 }
071436c6 17842 else if (p < end)
11c1ff18 17843 {
071436c6 17844 printf (_(" Unknown attribute:\n"));
f6f0e17b 17845 display_raw_attribute (p, end);
11c1ff18
PB
17846 p = end;
17847 }
071436c6
NC
17848 else
17849 attr_len = 0;
11c1ff18
PB
17850 }
17851 }
17852 }
d70c5fc7 17853
60bca95a 17854 free (contents);
11c1ff18 17855 }
32ec8896
NC
17856
17857 return res;
11c1ff18
PB
17858}
17859
ccb4c951
RS
17860/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17861 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17862 and return the VMA of the next entry, or -1 if there was a problem.
17863 Does not read from DATA_END or beyond. */
ccb4c951
RS
17864
17865static bfd_vma
82b1b41b
NC
17866print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17867 unsigned char * data_end)
ccb4c951
RS
17868{
17869 printf (" ");
17870 print_vma (addr, LONG_HEX);
17871 printf (" ");
17872 if (addr < pltgot + 0xfff0)
17873 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17874 else
17875 printf ("%10s", "");
17876 printf (" ");
17877 if (data == NULL)
2b692964 17878 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17879 else
17880 {
17881 bfd_vma entry;
82b1b41b 17882 unsigned char * from = data + addr - pltgot;
ccb4c951 17883
82b1b41b
NC
17884 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17885 {
17886 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17887 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17888 return (bfd_vma) -1;
17889 }
17890 else
17891 {
17892 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17893 print_vma (entry, LONG_HEX);
17894 }
ccb4c951
RS
17895 }
17896 return addr + (is_32bit_elf ? 4 : 8);
17897}
17898
861fb55a
DJ
17899/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17900 PLTGOT. Print the Address and Initial fields of an entry at VMA
17901 ADDR and return the VMA of the next entry. */
17902
17903static bfd_vma
2cf0635d 17904print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17905{
17906 printf (" ");
17907 print_vma (addr, LONG_HEX);
17908 printf (" ");
17909 if (data == NULL)
2b692964 17910 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17911 else
17912 {
17913 bfd_vma entry;
17914
17915 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17916 print_vma (entry, LONG_HEX);
17917 }
17918 return addr + (is_32bit_elf ? 4 : 8);
17919}
17920
351cdf24
MF
17921static void
17922print_mips_ases (unsigned int mask)
17923{
17924 if (mask & AFL_ASE_DSP)
17925 fputs ("\n\tDSP ASE", stdout);
17926 if (mask & AFL_ASE_DSPR2)
17927 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17928 if (mask & AFL_ASE_DSPR3)
17929 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17930 if (mask & AFL_ASE_EVA)
17931 fputs ("\n\tEnhanced VA Scheme", stdout);
17932 if (mask & AFL_ASE_MCU)
17933 fputs ("\n\tMCU (MicroController) ASE", stdout);
17934 if (mask & AFL_ASE_MDMX)
17935 fputs ("\n\tMDMX ASE", stdout);
17936 if (mask & AFL_ASE_MIPS3D)
17937 fputs ("\n\tMIPS-3D ASE", stdout);
17938 if (mask & AFL_ASE_MT)
17939 fputs ("\n\tMT ASE", stdout);
17940 if (mask & AFL_ASE_SMARTMIPS)
17941 fputs ("\n\tSmartMIPS ASE", stdout);
17942 if (mask & AFL_ASE_VIRT)
17943 fputs ("\n\tVZ ASE", stdout);
17944 if (mask & AFL_ASE_MSA)
17945 fputs ("\n\tMSA ASE", stdout);
17946 if (mask & AFL_ASE_MIPS16)
17947 fputs ("\n\tMIPS16 ASE", stdout);
17948 if (mask & AFL_ASE_MICROMIPS)
17949 fputs ("\n\tMICROMIPS ASE", stdout);
17950 if (mask & AFL_ASE_XPA)
17951 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17952 if (mask & AFL_ASE_MIPS16E2)
17953 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17954 if (mask & AFL_ASE_CRC)
17955 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17956 if (mask & AFL_ASE_GINV)
17957 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17958 if (mask & AFL_ASE_LOONGSON_MMI)
17959 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17960 if (mask & AFL_ASE_LOONGSON_CAM)
17961 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17962 if (mask & AFL_ASE_LOONGSON_EXT)
17963 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17964 if (mask & AFL_ASE_LOONGSON_EXT2)
17965 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17966 if (mask == 0)
17967 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17968 else if ((mask & ~AFL_ASE_MASK) != 0)
17969 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17970}
17971
17972static void
17973print_mips_isa_ext (unsigned int isa_ext)
17974{
17975 switch (isa_ext)
17976 {
17977 case 0:
17978 fputs (_("None"), stdout);
17979 break;
17980 case AFL_EXT_XLR:
17981 fputs ("RMI XLR", stdout);
17982 break;
2c629856
N
17983 case AFL_EXT_OCTEON3:
17984 fputs ("Cavium Networks Octeon3", stdout);
17985 break;
351cdf24
MF
17986 case AFL_EXT_OCTEON2:
17987 fputs ("Cavium Networks Octeon2", stdout);
17988 break;
17989 case AFL_EXT_OCTEONP:
17990 fputs ("Cavium Networks OcteonP", stdout);
17991 break;
351cdf24
MF
17992 case AFL_EXT_OCTEON:
17993 fputs ("Cavium Networks Octeon", stdout);
17994 break;
17995 case AFL_EXT_5900:
17996 fputs ("Toshiba R5900", stdout);
17997 break;
17998 case AFL_EXT_4650:
17999 fputs ("MIPS R4650", stdout);
18000 break;
18001 case AFL_EXT_4010:
18002 fputs ("LSI R4010", stdout);
18003 break;
18004 case AFL_EXT_4100:
18005 fputs ("NEC VR4100", stdout);
18006 break;
18007 case AFL_EXT_3900:
18008 fputs ("Toshiba R3900", stdout);
18009 break;
18010 case AFL_EXT_10000:
18011 fputs ("MIPS R10000", stdout);
18012 break;
18013 case AFL_EXT_SB1:
18014 fputs ("Broadcom SB-1", stdout);
18015 break;
18016 case AFL_EXT_4111:
18017 fputs ("NEC VR4111/VR4181", stdout);
18018 break;
18019 case AFL_EXT_4120:
18020 fputs ("NEC VR4120", stdout);
18021 break;
18022 case AFL_EXT_5400:
18023 fputs ("NEC VR5400", stdout);
18024 break;
18025 case AFL_EXT_5500:
18026 fputs ("NEC VR5500", stdout);
18027 break;
18028 case AFL_EXT_LOONGSON_2E:
18029 fputs ("ST Microelectronics Loongson 2E", stdout);
18030 break;
18031 case AFL_EXT_LOONGSON_2F:
18032 fputs ("ST Microelectronics Loongson 2F", stdout);
18033 break;
38bf472a
MR
18034 case AFL_EXT_INTERAPTIV_MR2:
18035 fputs ("Imagination interAptiv MR2", stdout);
18036 break;
351cdf24 18037 default:
00ac7aa0 18038 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18039 }
18040}
18041
32ec8896 18042static signed int
351cdf24
MF
18043get_mips_reg_size (int reg_size)
18044{
18045 return (reg_size == AFL_REG_NONE) ? 0
18046 : (reg_size == AFL_REG_32) ? 32
18047 : (reg_size == AFL_REG_64) ? 64
18048 : (reg_size == AFL_REG_128) ? 128
18049 : -1;
18050}
18051
015dc7e1 18052static bool
dda8d76d 18053process_mips_specific (Filedata * filedata)
5b18a4bc 18054{
2cf0635d 18055 Elf_Internal_Dyn * entry;
351cdf24 18056 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18057 size_t liblist_offset = 0;
18058 size_t liblistno = 0;
18059 size_t conflictsno = 0;
18060 size_t options_offset = 0;
18061 size_t conflicts_offset = 0;
861fb55a
DJ
18062 size_t pltrelsz = 0;
18063 size_t pltrel = 0;
ccb4c951 18064 bfd_vma pltgot = 0;
861fb55a
DJ
18065 bfd_vma mips_pltgot = 0;
18066 bfd_vma jmprel = 0;
ccb4c951
RS
18067 bfd_vma local_gotno = 0;
18068 bfd_vma gotsym = 0;
18069 bfd_vma symtabno = 0;
015dc7e1 18070 bool res = true;
103f02d3 18071
dda8d76d 18072 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18073 display_mips_gnu_attribute))
015dc7e1 18074 res = false;
2cf19d5c 18075
dda8d76d 18076 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18077
18078 if (sect != NULL)
18079 {
18080 Elf_External_ABIFlags_v0 *abiflags_ext;
18081 Elf_Internal_ABIFlags_v0 abiflags_in;
18082
18083 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18084 {
18085 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18086 res = false;
32ec8896 18087 }
351cdf24
MF
18088 else
18089 {
dda8d76d 18090 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18091 sect->sh_size, _("MIPS ABI Flags section"));
18092 if (abiflags_ext)
18093 {
18094 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18095 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18096 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18097 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18098 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18099 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18100 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18101 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18102 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18103 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18104 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18105
18106 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18107 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18108 if (abiflags_in.isa_rev > 1)
18109 printf ("r%d", abiflags_in.isa_rev);
18110 printf ("\nGPR size: %d",
18111 get_mips_reg_size (abiflags_in.gpr_size));
18112 printf ("\nCPR1 size: %d",
18113 get_mips_reg_size (abiflags_in.cpr1_size));
18114 printf ("\nCPR2 size: %d",
18115 get_mips_reg_size (abiflags_in.cpr2_size));
18116 fputs ("\nFP ABI: ", stdout);
18117 print_mips_fp_abi_value (abiflags_in.fp_abi);
18118 fputs ("ISA Extension: ", stdout);
18119 print_mips_isa_ext (abiflags_in.isa_ext);
18120 fputs ("\nASEs:", stdout);
18121 print_mips_ases (abiflags_in.ases);
18122 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18123 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18124 fputc ('\n', stdout);
18125 free (abiflags_ext);
18126 }
18127 }
18128 }
18129
19e6b90e 18130 /* We have a lot of special sections. Thanks SGI! */
978c4450 18131 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18132 {
18133 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18134 sect = find_section (filedata, ".got");
bbdd9a68
MR
18135 if (sect != NULL)
18136 {
18137 unsigned char *data_end;
18138 unsigned char *data;
18139 bfd_vma ent, end;
18140 int addr_size;
18141
18142 pltgot = sect->sh_addr;
18143
18144 ent = pltgot;
18145 addr_size = (is_32bit_elf ? 4 : 8);
18146 end = pltgot + sect->sh_size;
18147
dda8d76d 18148 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18149 end - pltgot, 1,
18150 _("Global Offset Table data"));
18151 /* PR 12855: Null data is handled gracefully throughout. */
18152 data_end = data + (end - pltgot);
18153
18154 printf (_("\nStatic GOT:\n"));
18155 printf (_(" Canonical gp value: "));
18156 print_vma (ent + 0x7ff0, LONG_HEX);
18157 printf ("\n\n");
18158
18159 /* In a dynamic binary GOT[0] is reserved for the dynamic
18160 loader to store the lazy resolver pointer, however in
18161 a static binary it may well have been omitted and GOT
18162 reduced to a table of addresses.
18163 PR 21344: Check for the entry being fully available
18164 before fetching it. */
18165 if (data
18166 && data + ent - pltgot + addr_size <= data_end
18167 && byte_get (data + ent - pltgot, addr_size) == 0)
18168 {
18169 printf (_(" Reserved entries:\n"));
18170 printf (_(" %*s %10s %*s\n"),
18171 addr_size * 2, _("Address"), _("Access"),
18172 addr_size * 2, _("Value"));
18173 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18174 printf ("\n");
18175 if (ent == (bfd_vma) -1)
18176 goto sgot_print_fail;
18177
18178 /* Check for the MSB of GOT[1] being set, identifying a
18179 GNU object. This entry will be used by some runtime
18180 loaders, to store the module pointer. Otherwise this
18181 is an ordinary local entry.
18182 PR 21344: Check for the entry being fully available
18183 before fetching it. */
18184 if (data
18185 && data + ent - pltgot + addr_size <= data_end
18186 && (byte_get (data + ent - pltgot, addr_size)
18187 >> (addr_size * 8 - 1)) != 0)
18188 {
18189 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18190 printf ("\n");
18191 if (ent == (bfd_vma) -1)
18192 goto sgot_print_fail;
18193 }
18194 printf ("\n");
18195 }
18196
f17e9d8a 18197 if (data != NULL && ent < end)
bbdd9a68
MR
18198 {
18199 printf (_(" Local entries:\n"));
18200 printf (" %*s %10s %*s\n",
18201 addr_size * 2, _("Address"), _("Access"),
18202 addr_size * 2, _("Value"));
18203 while (ent < end)
18204 {
18205 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18206 printf ("\n");
18207 if (ent == (bfd_vma) -1)
18208 goto sgot_print_fail;
18209 }
18210 printf ("\n");
18211 }
18212
18213 sgot_print_fail:
9db70fc3 18214 free (data);
bbdd9a68
MR
18215 }
18216 return res;
18217 }
252b5132 18218
978c4450 18219 for (entry = filedata->dynamic_section;
071436c6 18220 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18221 (entry < filedata->dynamic_section + filedata->dynamic_nent
18222 && entry->d_tag != DT_NULL);
071436c6 18223 ++entry)
252b5132
RH
18224 switch (entry->d_tag)
18225 {
18226 case DT_MIPS_LIBLIST:
d93f0186 18227 liblist_offset
dda8d76d 18228 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18229 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18230 break;
18231 case DT_MIPS_LIBLISTNO:
18232 liblistno = entry->d_un.d_val;
18233 break;
18234 case DT_MIPS_OPTIONS:
dda8d76d 18235 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18236 break;
18237 case DT_MIPS_CONFLICT:
d93f0186 18238 conflicts_offset
dda8d76d 18239 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18240 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18241 break;
18242 case DT_MIPS_CONFLICTNO:
18243 conflictsno = entry->d_un.d_val;
18244 break;
ccb4c951 18245 case DT_PLTGOT:
861fb55a
DJ
18246 pltgot = entry->d_un.d_ptr;
18247 break;
ccb4c951
RS
18248 case DT_MIPS_LOCAL_GOTNO:
18249 local_gotno = entry->d_un.d_val;
18250 break;
18251 case DT_MIPS_GOTSYM:
18252 gotsym = entry->d_un.d_val;
18253 break;
18254 case DT_MIPS_SYMTABNO:
18255 symtabno = entry->d_un.d_val;
18256 break;
861fb55a
DJ
18257 case DT_MIPS_PLTGOT:
18258 mips_pltgot = entry->d_un.d_ptr;
18259 break;
18260 case DT_PLTREL:
18261 pltrel = entry->d_un.d_val;
18262 break;
18263 case DT_PLTRELSZ:
18264 pltrelsz = entry->d_un.d_val;
18265 break;
18266 case DT_JMPREL:
18267 jmprel = entry->d_un.d_ptr;
18268 break;
252b5132
RH
18269 default:
18270 break;
18271 }
18272
18273 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18274 {
2cf0635d 18275 Elf32_External_Lib * elib;
252b5132
RH
18276 size_t cnt;
18277
dda8d76d 18278 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18279 sizeof (Elf32_External_Lib),
18280 liblistno,
18281 _("liblist section data"));
a6e9f9df 18282 if (elib)
252b5132 18283 {
d3a49aa8
AM
18284 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18285 "\nSection '.liblist' contains %lu entries:\n",
18286 (unsigned long) liblistno),
a6e9f9df 18287 (unsigned long) liblistno);
2b692964 18288 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18289 stdout);
18290
18291 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18292 {
a6e9f9df 18293 Elf32_Lib liblist;
91d6fa6a 18294 time_t atime;
d5b07ef4 18295 char timebuf[128];
2cf0635d 18296 struct tm * tmp;
a6e9f9df
AM
18297
18298 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18299 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18300 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18301 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18302 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18303
91d6fa6a 18304 tmp = gmtime (&atime);
e9e44622
JJ
18305 snprintf (timebuf, sizeof (timebuf),
18306 "%04u-%02u-%02uT%02u:%02u:%02u",
18307 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18308 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18309
31104126 18310 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18311 if (valid_dynamic_name (filedata, liblist.l_name))
18312 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18313 else
2b692964 18314 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18315 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18316 liblist.l_version);
a6e9f9df
AM
18317
18318 if (liblist.l_flags == 0)
2b692964 18319 puts (_(" NONE"));
a6e9f9df
AM
18320 else
18321 {
18322 static const struct
252b5132 18323 {
2cf0635d 18324 const char * name;
a6e9f9df 18325 int bit;
252b5132 18326 }
a6e9f9df
AM
18327 l_flags_vals[] =
18328 {
18329 { " EXACT_MATCH", LL_EXACT_MATCH },
18330 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18331 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18332 { " EXPORTS", LL_EXPORTS },
18333 { " DELAY_LOAD", LL_DELAY_LOAD },
18334 { " DELTA", LL_DELTA }
18335 };
18336 int flags = liblist.l_flags;
18337 size_t fcnt;
18338
60bca95a 18339 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18340 if ((flags & l_flags_vals[fcnt].bit) != 0)
18341 {
18342 fputs (l_flags_vals[fcnt].name, stdout);
18343 flags ^= l_flags_vals[fcnt].bit;
18344 }
18345 if (flags != 0)
18346 printf (" %#x", (unsigned int) flags);
252b5132 18347
a6e9f9df
AM
18348 puts ("");
18349 }
252b5132 18350 }
252b5132 18351
a6e9f9df
AM
18352 free (elib);
18353 }
32ec8896 18354 else
015dc7e1 18355 res = false;
252b5132
RH
18356 }
18357
18358 if (options_offset != 0)
18359 {
2cf0635d 18360 Elf_External_Options * eopt;
252b5132
RH
18361 size_t offset;
18362 int cnt;
18363
18364 /* Find the section header so that we get the size. */
dda8d76d 18365 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18366 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18367 if (sect == NULL)
18368 {
18369 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18370 return false;
071436c6 18371 }
7fc0c668
NC
18372 /* PR 24243 */
18373 if (sect->sh_size < sizeof (* eopt))
18374 {
18375 error (_("The MIPS options section is too small.\n"));
015dc7e1 18376 return false;
7fc0c668 18377 }
252b5132 18378
dda8d76d 18379 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18380 sect->sh_size, _("options"));
a6e9f9df 18381 if (eopt)
252b5132 18382 {
fd17d1e6 18383 Elf_Internal_Options option;
76da6bbe 18384
a6e9f9df 18385 offset = cnt = 0;
82b1b41b 18386 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18387 {
2cf0635d 18388 Elf_External_Options * eoption;
fd17d1e6 18389 unsigned int optsize;
252b5132 18390
a6e9f9df 18391 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18392
fd17d1e6 18393 optsize = BYTE_GET (eoption->size);
76da6bbe 18394
82b1b41b 18395 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18396 if (optsize < sizeof (* eopt)
18397 || optsize > sect->sh_size - offset)
82b1b41b 18398 {
645f43a8 18399 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18400 optsize);
645f43a8 18401 free (eopt);
015dc7e1 18402 return false;
82b1b41b 18403 }
fd17d1e6 18404 offset += optsize;
a6e9f9df
AM
18405 ++cnt;
18406 }
252b5132 18407
d3a49aa8
AM
18408 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18409 "\nSection '%s' contains %d entries:\n",
18410 cnt),
dda8d76d 18411 printable_section_name (filedata, sect), cnt);
76da6bbe 18412
82b1b41b 18413 offset = 0;
a6e9f9df 18414 while (cnt-- > 0)
252b5132 18415 {
a6e9f9df 18416 size_t len;
fd17d1e6
AM
18417 Elf_External_Options * eoption;
18418
18419 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18420
18421 option.kind = BYTE_GET (eoption->kind);
18422 option.size = BYTE_GET (eoption->size);
18423 option.section = BYTE_GET (eoption->section);
18424 option.info = BYTE_GET (eoption->info);
a6e9f9df 18425
fd17d1e6 18426 switch (option.kind)
252b5132 18427 {
a6e9f9df
AM
18428 case ODK_NULL:
18429 /* This shouldn't happen. */
d0c4e780 18430 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18431 option.section, option.info);
a6e9f9df 18432 break;
2e6be59c 18433
a6e9f9df
AM
18434 case ODK_REGINFO:
18435 printf (" REGINFO ");
dda8d76d 18436 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18437 {
2cf0635d 18438 Elf32_External_RegInfo * ereg;
b34976b6 18439 Elf32_RegInfo reginfo;
a6e9f9df 18440
2e6be59c 18441 /* 32bit form. */
fd17d1e6
AM
18442 if (option.size < (sizeof (Elf_External_Options)
18443 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18444 {
18445 printf (_("<corrupt>\n"));
18446 error (_("Truncated MIPS REGINFO option\n"));
18447 cnt = 0;
18448 break;
18449 }
18450
fd17d1e6 18451 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18452
a6e9f9df
AM
18453 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18454 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18455 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18456 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18457 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18458 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18459
d0c4e780
AM
18460 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18461 reginfo.ri_gprmask, reginfo.ri_gp_value);
18462 printf (" "
18463 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18464 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18465 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18466 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18467 }
18468 else
18469 {
18470 /* 64 bit form. */
2cf0635d 18471 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18472 Elf64_Internal_RegInfo reginfo;
18473
fd17d1e6
AM
18474 if (option.size < (sizeof (Elf_External_Options)
18475 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18476 {
18477 printf (_("<corrupt>\n"));
18478 error (_("Truncated MIPS REGINFO option\n"));
18479 cnt = 0;
18480 break;
18481 }
18482
fd17d1e6 18483 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18484 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18485 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18486 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18487 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18488 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18489 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18490
d0c4e780
AM
18491 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18492 reginfo.ri_gprmask, reginfo.ri_gp_value);
18493 printf (" "
18494 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18495 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18496 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18497 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18498 }
fd17d1e6 18499 offset += option.size;
a6e9f9df 18500 continue;
2e6be59c 18501
a6e9f9df
AM
18502 case ODK_EXCEPTIONS:
18503 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18504 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18505 fputs (") fpe_max(", stdout);
fd17d1e6 18506 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18507 fputs (")", stdout);
18508
fd17d1e6 18509 if (option.info & OEX_PAGE0)
a6e9f9df 18510 fputs (" PAGE0", stdout);
fd17d1e6 18511 if (option.info & OEX_SMM)
a6e9f9df 18512 fputs (" SMM", stdout);
fd17d1e6 18513 if (option.info & OEX_FPDBUG)
a6e9f9df 18514 fputs (" FPDBUG", stdout);
fd17d1e6 18515 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18516 fputs (" DISMISS", stdout);
18517 break;
2e6be59c 18518
a6e9f9df
AM
18519 case ODK_PAD:
18520 fputs (" PAD ", stdout);
fd17d1e6 18521 if (option.info & OPAD_PREFIX)
a6e9f9df 18522 fputs (" PREFIX", stdout);
fd17d1e6 18523 if (option.info & OPAD_POSTFIX)
a6e9f9df 18524 fputs (" POSTFIX", stdout);
fd17d1e6 18525 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18526 fputs (" SYMBOL", stdout);
18527 break;
2e6be59c 18528
a6e9f9df
AM
18529 case ODK_HWPATCH:
18530 fputs (" HWPATCH ", stdout);
fd17d1e6 18531 if (option.info & OHW_R4KEOP)
a6e9f9df 18532 fputs (" R4KEOP", stdout);
fd17d1e6 18533 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18534 fputs (" R8KPFETCH", stdout);
fd17d1e6 18535 if (option.info & OHW_R5KEOP)
a6e9f9df 18536 fputs (" R5KEOP", stdout);
fd17d1e6 18537 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18538 fputs (" R5KCVTL", stdout);
18539 break;
2e6be59c 18540
a6e9f9df
AM
18541 case ODK_FILL:
18542 fputs (" FILL ", stdout);
18543 /* XXX Print content of info word? */
18544 break;
2e6be59c 18545
a6e9f9df
AM
18546 case ODK_TAGS:
18547 fputs (" TAGS ", stdout);
18548 /* XXX Print content of info word? */
18549 break;
2e6be59c 18550
a6e9f9df
AM
18551 case ODK_HWAND:
18552 fputs (" HWAND ", stdout);
fd17d1e6 18553 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18554 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18555 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18556 fputs (" R4KEOP_CLEAN", stdout);
18557 break;
2e6be59c 18558
a6e9f9df
AM
18559 case ODK_HWOR:
18560 fputs (" HWOR ", stdout);
fd17d1e6 18561 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18562 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18563 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18564 fputs (" R4KEOP_CLEAN", stdout);
18565 break;
2e6be59c 18566
a6e9f9df 18567 case ODK_GP_GROUP:
d0c4e780 18568 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18569 option.info & OGP_GROUP,
18570 (option.info & OGP_SELF) >> 16);
a6e9f9df 18571 break;
2e6be59c 18572
a6e9f9df 18573 case ODK_IDENT:
d0c4e780 18574 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18575 option.info & OGP_GROUP,
18576 (option.info & OGP_SELF) >> 16);
a6e9f9df 18577 break;
2e6be59c 18578
a6e9f9df
AM
18579 default:
18580 /* This shouldn't happen. */
d0c4e780 18581 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18582 option.kind, option.section, option.info);
a6e9f9df 18583 break;
252b5132 18584 }
a6e9f9df 18585
2cf0635d 18586 len = sizeof (* eopt);
fd17d1e6 18587 while (len < option.size)
82b1b41b 18588 {
fd17d1e6 18589 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18590
82b1b41b
NC
18591 if (ISPRINT (datum))
18592 printf ("%c", datum);
18593 else
18594 printf ("\\%03o", datum);
18595 len ++;
18596 }
a6e9f9df 18597 fputs ("\n", stdout);
82b1b41b 18598
fd17d1e6 18599 offset += option.size;
252b5132 18600 }
a6e9f9df 18601 free (eopt);
252b5132 18602 }
32ec8896 18603 else
015dc7e1 18604 res = false;
252b5132
RH
18605 }
18606
18607 if (conflicts_offset != 0 && conflictsno != 0)
18608 {
2cf0635d 18609 Elf32_Conflict * iconf;
252b5132
RH
18610 size_t cnt;
18611
978c4450 18612 if (filedata->dynamic_symbols == NULL)
252b5132 18613 {
591a748a 18614 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18615 return false;
252b5132
RH
18616 }
18617
7296a62a
NC
18618 /* PR 21345 - print a slightly more helpful error message
18619 if we are sure that the cmalloc will fail. */
645f43a8 18620 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18621 {
18622 error (_("Overlarge number of conflicts detected: %lx\n"),
18623 (long) conflictsno);
015dc7e1 18624 return false;
7296a62a
NC
18625 }
18626
3f5e193b 18627 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18628 if (iconf == NULL)
18629 {
8b73c356 18630 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18631 return false;
252b5132
RH
18632 }
18633
9ea033b2 18634 if (is_32bit_elf)
252b5132 18635 {
2cf0635d 18636 Elf32_External_Conflict * econf32;
a6e9f9df 18637
3f5e193b 18638 econf32 = (Elf32_External_Conflict *)
95099889
AM
18639 get_data (NULL, filedata, conflicts_offset,
18640 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18641 if (!econf32)
5a814d6d
AM
18642 {
18643 free (iconf);
015dc7e1 18644 return false;
5a814d6d 18645 }
252b5132
RH
18646
18647 for (cnt = 0; cnt < conflictsno; ++cnt)
18648 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18649
18650 free (econf32);
252b5132
RH
18651 }
18652 else
18653 {
2cf0635d 18654 Elf64_External_Conflict * econf64;
a6e9f9df 18655
3f5e193b 18656 econf64 = (Elf64_External_Conflict *)
95099889
AM
18657 get_data (NULL, filedata, conflicts_offset,
18658 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18659 if (!econf64)
5a814d6d
AM
18660 {
18661 free (iconf);
015dc7e1 18662 return false;
5a814d6d 18663 }
252b5132
RH
18664
18665 for (cnt = 0; cnt < conflictsno; ++cnt)
18666 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18667
18668 free (econf64);
252b5132
RH
18669 }
18670
d3a49aa8
AM
18671 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18672 "\nSection '.conflict' contains %lu entries:\n",
18673 (unsigned long) conflictsno),
c7e7ca54 18674 (unsigned long) conflictsno);
252b5132
RH
18675 puts (_(" Num: Index Value Name"));
18676
18677 for (cnt = 0; cnt < conflictsno; ++cnt)
18678 {
b34976b6 18679 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18680
978c4450 18681 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18682 printf (_("<corrupt symbol index>"));
d79b3d50 18683 else
e0a31db1
NC
18684 {
18685 Elf_Internal_Sym * psym;
18686
978c4450 18687 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18688 print_vma (psym->st_value, FULL_HEX);
18689 putchar (' ');
84714f86
AM
18690 if (valid_dynamic_name (filedata, psym->st_name))
18691 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18692 else
18693 printf (_("<corrupt: %14ld>"), psym->st_name);
18694 }
31104126 18695 putchar ('\n');
252b5132
RH
18696 }
18697
252b5132
RH
18698 free (iconf);
18699 }
18700
ccb4c951
RS
18701 if (pltgot != 0 && local_gotno != 0)
18702 {
91d6fa6a 18703 bfd_vma ent, local_end, global_end;
bbeee7ea 18704 size_t i, offset;
2cf0635d 18705 unsigned char * data;
82b1b41b 18706 unsigned char * data_end;
bbeee7ea 18707 int addr_size;
ccb4c951 18708
91d6fa6a 18709 ent = pltgot;
ccb4c951
RS
18710 addr_size = (is_32bit_elf ? 4 : 8);
18711 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18712
74e1a04b
NC
18713 /* PR binutils/17533 file: 012-111227-0.004 */
18714 if (symtabno < gotsym)
18715 {
18716 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18717 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18718 return false;
74e1a04b 18719 }
82b1b41b 18720
74e1a04b 18721 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18722 /* PR 17531: file: 54c91a34. */
18723 if (global_end < local_end)
18724 {
18725 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18726 return false;
82b1b41b 18727 }
948f632f 18728
dda8d76d
NC
18729 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18730 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18731 global_end - pltgot, 1,
18732 _("Global Offset Table data"));
919383ac 18733 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18734 data_end = data + (global_end - pltgot);
59245841 18735
ccb4c951
RS
18736 printf (_("\nPrimary GOT:\n"));
18737 printf (_(" Canonical gp value: "));
18738 print_vma (pltgot + 0x7ff0, LONG_HEX);
18739 printf ("\n\n");
18740
18741 printf (_(" Reserved entries:\n"));
18742 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18743 addr_size * 2, _("Address"), _("Access"),
18744 addr_size * 2, _("Initial"));
82b1b41b 18745 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18746 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18747 if (ent == (bfd_vma) -1)
18748 goto got_print_fail;
75ec1fdb 18749
c4ab9505
MR
18750 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18751 This entry will be used by some runtime loaders, to store the
18752 module pointer. Otherwise this is an ordinary local entry.
18753 PR 21344: Check for the entry being fully available before
18754 fetching it. */
18755 if (data
18756 && data + ent - pltgot + addr_size <= data_end
18757 && (byte_get (data + ent - pltgot, addr_size)
18758 >> (addr_size * 8 - 1)) != 0)
18759 {
18760 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18761 printf (_(" Module pointer (GNU extension)\n"));
18762 if (ent == (bfd_vma) -1)
18763 goto got_print_fail;
ccb4c951
RS
18764 }
18765 printf ("\n");
18766
f17e9d8a 18767 if (data != NULL && ent < local_end)
ccb4c951
RS
18768 {
18769 printf (_(" Local entries:\n"));
cc5914eb 18770 printf (" %*s %10s %*s\n",
2b692964
NC
18771 addr_size * 2, _("Address"), _("Access"),
18772 addr_size * 2, _("Initial"));
91d6fa6a 18773 while (ent < local_end)
ccb4c951 18774 {
82b1b41b 18775 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18776 printf ("\n");
82b1b41b
NC
18777 if (ent == (bfd_vma) -1)
18778 goto got_print_fail;
ccb4c951
RS
18779 }
18780 printf ("\n");
18781 }
18782
f17e9d8a 18783 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18784 {
18785 int sym_width;
18786
18787 printf (_(" Global entries:\n"));
cc5914eb 18788 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18789 addr_size * 2, _("Address"),
18790 _("Access"),
2b692964 18791 addr_size * 2, _("Initial"),
9cf03b7e
NC
18792 addr_size * 2, _("Sym.Val."),
18793 _("Type"),
18794 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18795 _("Ndx"), _("Name"));
0b4362b0 18796
ccb4c951 18797 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18798
ccb4c951
RS
18799 for (i = gotsym; i < symtabno; i++)
18800 {
82b1b41b 18801 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18802 printf (" ");
e0a31db1 18803
978c4450 18804 if (filedata->dynamic_symbols == NULL)
e0a31db1 18805 printf (_("<no dynamic symbols>"));
978c4450 18806 else if (i < filedata->num_dynamic_syms)
e0a31db1 18807 {
978c4450 18808 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18809
18810 print_vma (psym->st_value, LONG_HEX);
18811 printf (" %-7s %3s ",
dda8d76d
NC
18812 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18813 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18814
84714f86 18815 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18816 print_symbol (sym_width,
84714f86 18817 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18818 else
18819 printf (_("<corrupt: %14ld>"), psym->st_name);
18820 }
ccb4c951 18821 else
7fc5ac57
JBG
18822 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18823 (unsigned long) i);
e0a31db1 18824
ccb4c951 18825 printf ("\n");
82b1b41b
NC
18826 if (ent == (bfd_vma) -1)
18827 break;
ccb4c951
RS
18828 }
18829 printf ("\n");
18830 }
18831
82b1b41b 18832 got_print_fail:
9db70fc3 18833 free (data);
ccb4c951
RS
18834 }
18835
861fb55a
DJ
18836 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18837 {
91d6fa6a 18838 bfd_vma ent, end;
861fb55a
DJ
18839 size_t offset, rel_offset;
18840 unsigned long count, i;
2cf0635d 18841 unsigned char * data;
861fb55a 18842 int addr_size, sym_width;
2cf0635d 18843 Elf_Internal_Rela * rels;
861fb55a 18844
dda8d76d 18845 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18846 if (pltrel == DT_RELA)
18847 {
dda8d76d 18848 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18849 return false;
861fb55a
DJ
18850 }
18851 else
18852 {
dda8d76d 18853 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18854 return false;
861fb55a
DJ
18855 }
18856
91d6fa6a 18857 ent = mips_pltgot;
861fb55a
DJ
18858 addr_size = (is_32bit_elf ? 4 : 8);
18859 end = mips_pltgot + (2 + count) * addr_size;
18860
dda8d76d
NC
18861 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18862 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18863 1, _("Procedure Linkage Table data"));
59245841 18864 if (data == NULL)
288f0ba2
AM
18865 {
18866 free (rels);
015dc7e1 18867 return false;
288f0ba2 18868 }
59245841 18869
9cf03b7e 18870 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18871 printf (_(" Reserved entries:\n"));
18872 printf (_(" %*s %*s Purpose\n"),
2b692964 18873 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18874 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18875 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18876 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18877 printf (_(" Module pointer\n"));
861fb55a
DJ
18878 printf ("\n");
18879
18880 printf (_(" Entries:\n"));
cc5914eb 18881 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18882 addr_size * 2, _("Address"),
18883 addr_size * 2, _("Initial"),
18884 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18885 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18886 for (i = 0; i < count; i++)
18887 {
df97ab2a 18888 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18889
91d6fa6a 18890 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18891 printf (" ");
e0a31db1 18892
978c4450 18893 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18894 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18895 else
e0a31db1 18896 {
978c4450 18897 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18898
18899 print_vma (psym->st_value, LONG_HEX);
18900 printf (" %-7s %3s ",
dda8d76d
NC
18901 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18902 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 18903 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18904 print_symbol (sym_width,
84714f86 18905 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18906 else
18907 printf (_("<corrupt: %14ld>"), psym->st_name);
18908 }
861fb55a
DJ
18909 printf ("\n");
18910 }
18911 printf ("\n");
18912
9db70fc3 18913 free (data);
861fb55a
DJ
18914 free (rels);
18915 }
18916
32ec8896 18917 return res;
252b5132
RH
18918}
18919
015dc7e1 18920static bool
dda8d76d 18921process_nds32_specific (Filedata * filedata)
35c08157
KLC
18922{
18923 Elf_Internal_Shdr *sect = NULL;
18924
dda8d76d 18925 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18926 if (sect != NULL && sect->sh_size >= 4)
35c08157 18927 {
9c7b8e9b
AM
18928 unsigned char *buf;
18929 unsigned int flag;
35c08157
KLC
18930
18931 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18932 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18933 _("NDS32 elf flags section"));
35c08157 18934
9c7b8e9b 18935 if (buf == NULL)
015dc7e1 18936 return false;
32ec8896 18937
9c7b8e9b
AM
18938 flag = byte_get (buf, 4);
18939 free (buf);
18940 switch (flag & 0x3)
35c08157
KLC
18941 {
18942 case 0:
18943 printf ("(VEC_SIZE):\tNo entry.\n");
18944 break;
18945 case 1:
18946 printf ("(VEC_SIZE):\t4 bytes\n");
18947 break;
18948 case 2:
18949 printf ("(VEC_SIZE):\t16 bytes\n");
18950 break;
18951 case 3:
18952 printf ("(VEC_SIZE):\treserved\n");
18953 break;
18954 }
18955 }
18956
015dc7e1 18957 return true;
35c08157
KLC
18958}
18959
015dc7e1 18960static bool
dda8d76d 18961process_gnu_liblist (Filedata * filedata)
047b2264 18962{
2cf0635d
NC
18963 Elf_Internal_Shdr * section;
18964 Elf_Internal_Shdr * string_sec;
18965 Elf32_External_Lib * elib;
18966 char * strtab;
c256ffe7 18967 size_t strtab_size;
047b2264 18968 size_t cnt;
d3a49aa8 18969 unsigned long num_liblist;
047b2264 18970 unsigned i;
015dc7e1 18971 bool res = true;
047b2264
JJ
18972
18973 if (! do_arch)
015dc7e1 18974 return true;
047b2264 18975
dda8d76d
NC
18976 for (i = 0, section = filedata->section_headers;
18977 i < filedata->file_header.e_shnum;
b34976b6 18978 i++, section++)
047b2264
JJ
18979 {
18980 switch (section->sh_type)
18981 {
18982 case SHT_GNU_LIBLIST:
dda8d76d 18983 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18984 break;
18985
3f5e193b 18986 elib = (Elf32_External_Lib *)
dda8d76d 18987 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18988 _("liblist section data"));
047b2264
JJ
18989
18990 if (elib == NULL)
32ec8896 18991 {
015dc7e1 18992 res = false;
32ec8896
NC
18993 break;
18994 }
047b2264 18995
dda8d76d
NC
18996 string_sec = filedata->section_headers + section->sh_link;
18997 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18998 string_sec->sh_size,
18999 _("liblist string table"));
047b2264
JJ
19000 if (strtab == NULL
19001 || section->sh_entsize != sizeof (Elf32_External_Lib))
19002 {
19003 free (elib);
2842702f 19004 free (strtab);
015dc7e1 19005 res = false;
047b2264
JJ
19006 break;
19007 }
59245841 19008 strtab_size = string_sec->sh_size;
047b2264 19009
d3a49aa8
AM
19010 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19011 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19012 "\nLibrary list section '%s' contains %lu entries:\n",
19013 num_liblist),
dda8d76d 19014 printable_section_name (filedata, section),
d3a49aa8 19015 num_liblist);
047b2264 19016
2b692964 19017 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19018
19019 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19020 ++cnt)
19021 {
19022 Elf32_Lib liblist;
91d6fa6a 19023 time_t atime;
d5b07ef4 19024 char timebuf[128];
2cf0635d 19025 struct tm * tmp;
047b2264
JJ
19026
19027 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19028 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19029 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19030 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19031 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19032
91d6fa6a 19033 tmp = gmtime (&atime);
e9e44622
JJ
19034 snprintf (timebuf, sizeof (timebuf),
19035 "%04u-%02u-%02uT%02u:%02u:%02u",
19036 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19037 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19038
19039 printf ("%3lu: ", (unsigned long) cnt);
19040 if (do_wide)
c256ffe7 19041 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19042 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19043 else
c256ffe7 19044 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19045 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19046 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19047 liblist.l_version, liblist.l_flags);
19048 }
19049
19050 free (elib);
2842702f 19051 free (strtab);
047b2264
JJ
19052 }
19053 }
19054
32ec8896 19055 return res;
047b2264
JJ
19056}
19057
9437c45b 19058static const char *
dda8d76d 19059get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19060{
19061 static char buff[64];
103f02d3 19062
dda8d76d 19063 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19064 switch (e_type)
19065 {
57346661 19066 case NT_AUXV:
1ec5cd37 19067 return _("NT_AUXV (auxiliary vector)");
57346661 19068 case NT_PRSTATUS:
1ec5cd37 19069 return _("NT_PRSTATUS (prstatus structure)");
57346661 19070 case NT_FPREGSET:
1ec5cd37 19071 return _("NT_FPREGSET (floating point registers)");
57346661 19072 case NT_PRPSINFO:
1ec5cd37 19073 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19074 case NT_TASKSTRUCT:
1ec5cd37 19075 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19076 case NT_GDB_TDESC:
19077 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19078 case NT_PRXFPREG:
1ec5cd37 19079 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19080 case NT_PPC_VMX:
19081 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19082 case NT_PPC_VSX:
19083 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19084 case NT_PPC_TAR:
19085 return _("NT_PPC_TAR (ppc TAR register)");
19086 case NT_PPC_PPR:
19087 return _("NT_PPC_PPR (ppc PPR register)");
19088 case NT_PPC_DSCR:
19089 return _("NT_PPC_DSCR (ppc DSCR register)");
19090 case NT_PPC_EBB:
19091 return _("NT_PPC_EBB (ppc EBB registers)");
19092 case NT_PPC_PMU:
19093 return _("NT_PPC_PMU (ppc PMU registers)");
19094 case NT_PPC_TM_CGPR:
19095 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19096 case NT_PPC_TM_CFPR:
19097 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19098 case NT_PPC_TM_CVMX:
19099 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19100 case NT_PPC_TM_CVSX:
3fd21718 19101 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19102 case NT_PPC_TM_SPR:
19103 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19104 case NT_PPC_TM_CTAR:
19105 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19106 case NT_PPC_TM_CPPR:
19107 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19108 case NT_PPC_TM_CDSCR:
19109 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19110 case NT_386_TLS:
19111 return _("NT_386_TLS (x86 TLS information)");
19112 case NT_386_IOPERM:
19113 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19114 case NT_X86_XSTATE:
19115 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19116 case NT_X86_CET:
19117 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19118 case NT_S390_HIGH_GPRS:
19119 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19120 case NT_S390_TIMER:
19121 return _("NT_S390_TIMER (s390 timer register)");
19122 case NT_S390_TODCMP:
19123 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19124 case NT_S390_TODPREG:
19125 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19126 case NT_S390_CTRS:
19127 return _("NT_S390_CTRS (s390 control registers)");
19128 case NT_S390_PREFIX:
19129 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19130 case NT_S390_LAST_BREAK:
19131 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19132 case NT_S390_SYSTEM_CALL:
19133 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19134 case NT_S390_TDB:
19135 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19136 case NT_S390_VXRS_LOW:
19137 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19138 case NT_S390_VXRS_HIGH:
19139 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19140 case NT_S390_GS_CB:
19141 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19142 case NT_S390_GS_BC:
19143 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19144 case NT_ARM_VFP:
19145 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19146 case NT_ARM_TLS:
19147 return _("NT_ARM_TLS (AArch TLS registers)");
19148 case NT_ARM_HW_BREAK:
19149 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19150 case NT_ARM_HW_WATCH:
19151 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
19152 case NT_ARM_SVE:
19153 return _("NT_ARM_SVE (AArch SVE registers)");
19154 case NT_ARM_PAC_MASK:
19155 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19156 case NT_ARM_PACA_KEYS:
19157 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19158 case NT_ARM_PACG_KEYS:
19159 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19160 case NT_ARM_TAGGED_ADDR_CTRL:
19161 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19162 case NT_ARM_PAC_ENABLED_KEYS:
19163 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19164 case NT_ARC_V2:
19165 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19166 case NT_RISCV_CSR:
19167 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19168 case NT_PSTATUS:
1ec5cd37 19169 return _("NT_PSTATUS (pstatus structure)");
57346661 19170 case NT_FPREGS:
1ec5cd37 19171 return _("NT_FPREGS (floating point registers)");
57346661 19172 case NT_PSINFO:
1ec5cd37 19173 return _("NT_PSINFO (psinfo structure)");
57346661 19174 case NT_LWPSTATUS:
1ec5cd37 19175 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19176 case NT_LWPSINFO:
1ec5cd37 19177 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19178 case NT_WIN32PSTATUS:
1ec5cd37 19179 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19180 case NT_SIGINFO:
19181 return _("NT_SIGINFO (siginfo_t data)");
19182 case NT_FILE:
19183 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19184 default:
19185 break;
19186 }
19187 else
19188 switch (e_type)
19189 {
19190 case NT_VERSION:
19191 return _("NT_VERSION (version)");
19192 case NT_ARCH:
19193 return _("NT_ARCH (architecture)");
9ef920e9 19194 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19195 return _("OPEN");
9ef920e9 19196 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19197 return _("func");
c8795e1f
NC
19198 case NT_GO_BUILDID:
19199 return _("GO BUILDID");
1ec5cd37
NC
19200 default:
19201 break;
19202 }
19203
e9e44622 19204 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19205 return buff;
779fe533
NC
19206}
19207
015dc7e1 19208static bool
9ece1fa9
TT
19209print_core_note (Elf_Internal_Note *pnote)
19210{
19211 unsigned int addr_size = is_32bit_elf ? 4 : 8;
19212 bfd_vma count, page_size;
19213 unsigned char *descdata, *filenames, *descend;
19214
19215 if (pnote->type != NT_FILE)
04ac15ab
AS
19216 {
19217 if (do_wide)
19218 printf ("\n");
015dc7e1 19219 return true;
04ac15ab 19220 }
9ece1fa9
TT
19221
19222#ifndef BFD64
19223 if (!is_32bit_elf)
19224 {
19225 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19226 /* Still "successful". */
015dc7e1 19227 return true;
9ece1fa9
TT
19228 }
19229#endif
19230
19231 if (pnote->descsz < 2 * addr_size)
19232 {
32ec8896 19233 error (_(" Malformed note - too short for header\n"));
015dc7e1 19234 return false;
9ece1fa9
TT
19235 }
19236
19237 descdata = (unsigned char *) pnote->descdata;
19238 descend = descdata + pnote->descsz;
19239
19240 if (descdata[pnote->descsz - 1] != '\0')
19241 {
32ec8896 19242 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19243 return false;
9ece1fa9
TT
19244 }
19245
19246 count = byte_get (descdata, addr_size);
19247 descdata += addr_size;
19248
19249 page_size = byte_get (descdata, addr_size);
19250 descdata += addr_size;
19251
5396a86e
AM
19252 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
19253 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19254 {
32ec8896 19255 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19256 return false;
9ece1fa9
TT
19257 }
19258
19259 printf (_(" Page size: "));
19260 print_vma (page_size, DEC);
19261 printf ("\n");
19262
19263 printf (_(" %*s%*s%*s\n"),
19264 (int) (2 + 2 * addr_size), _("Start"),
19265 (int) (4 + 2 * addr_size), _("End"),
19266 (int) (4 + 2 * addr_size), _("Page Offset"));
19267 filenames = descdata + count * 3 * addr_size;
595712bb 19268 while (count-- > 0)
9ece1fa9
TT
19269 {
19270 bfd_vma start, end, file_ofs;
19271
19272 if (filenames == descend)
19273 {
32ec8896 19274 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19275 return false;
9ece1fa9
TT
19276 }
19277
19278 start = byte_get (descdata, addr_size);
19279 descdata += addr_size;
19280 end = byte_get (descdata, addr_size);
19281 descdata += addr_size;
19282 file_ofs = byte_get (descdata, addr_size);
19283 descdata += addr_size;
19284
19285 printf (" ");
19286 print_vma (start, FULL_HEX);
19287 printf (" ");
19288 print_vma (end, FULL_HEX);
19289 printf (" ");
19290 print_vma (file_ofs, FULL_HEX);
19291 printf ("\n %s\n", filenames);
19292
19293 filenames += 1 + strlen ((char *) filenames);
19294 }
19295
015dc7e1 19296 return true;
9ece1fa9
TT
19297}
19298
1118d252
RM
19299static const char *
19300get_gnu_elf_note_type (unsigned e_type)
19301{
1449284b 19302 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19303 switch (e_type)
19304 {
19305 case NT_GNU_ABI_TAG:
19306 return _("NT_GNU_ABI_TAG (ABI version tag)");
19307 case NT_GNU_HWCAP:
19308 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19309 case NT_GNU_BUILD_ID:
19310 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19311 case NT_GNU_GOLD_VERSION:
19312 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19313 case NT_GNU_PROPERTY_TYPE_0:
19314 return _("NT_GNU_PROPERTY_TYPE_0");
19315 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19316 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19317 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19318 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19319 default:
1449284b
NC
19320 {
19321 static char buff[64];
1118d252 19322
1449284b
NC
19323 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19324 return buff;
19325 }
19326 }
1118d252
RM
19327}
19328
a9eafb08
L
19329static void
19330decode_x86_compat_isa (unsigned int bitmask)
19331{
19332 while (bitmask)
19333 {
19334 unsigned int bit = bitmask & (- bitmask);
19335
19336 bitmask &= ~ bit;
19337 switch (bit)
19338 {
19339 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19340 printf ("i486");
19341 break;
19342 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19343 printf ("586");
19344 break;
19345 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19346 printf ("686");
19347 break;
19348 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19349 printf ("SSE");
19350 break;
19351 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19352 printf ("SSE2");
19353 break;
19354 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19355 printf ("SSE3");
19356 break;
19357 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19358 printf ("SSSE3");
19359 break;
19360 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19361 printf ("SSE4_1");
19362 break;
19363 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19364 printf ("SSE4_2");
19365 break;
19366 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19367 printf ("AVX");
19368 break;
19369 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19370 printf ("AVX2");
19371 break;
19372 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19373 printf ("AVX512F");
19374 break;
19375 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19376 printf ("AVX512CD");
19377 break;
19378 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19379 printf ("AVX512ER");
19380 break;
19381 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19382 printf ("AVX512PF");
19383 break;
19384 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19385 printf ("AVX512VL");
19386 break;
19387 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19388 printf ("AVX512DQ");
19389 break;
19390 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19391 printf ("AVX512BW");
19392 break;
65b3d26e
L
19393 default:
19394 printf (_("<unknown: %x>"), bit);
19395 break;
a9eafb08
L
19396 }
19397 if (bitmask)
19398 printf (", ");
19399 }
19400}
19401
9ef920e9 19402static void
32930e4e 19403decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19404{
0a59decb 19405 if (!bitmask)
90c745dc
L
19406 {
19407 printf (_("<None>"));
19408 return;
19409 }
90c745dc 19410
9ef920e9
NC
19411 while (bitmask)
19412 {
1fc87489 19413 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19414
19415 bitmask &= ~ bit;
19416 switch (bit)
19417 {
32930e4e 19418 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19419 printf ("CMOV");
19420 break;
32930e4e 19421 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19422 printf ("SSE");
19423 break;
32930e4e 19424 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19425 printf ("SSE2");
19426 break;
32930e4e 19427 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19428 printf ("SSE3");
19429 break;
32930e4e 19430 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19431 printf ("SSSE3");
19432 break;
32930e4e 19433 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19434 printf ("SSE4_1");
19435 break;
32930e4e 19436 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19437 printf ("SSE4_2");
19438 break;
32930e4e 19439 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19440 printf ("AVX");
19441 break;
32930e4e 19442 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19443 printf ("AVX2");
19444 break;
32930e4e 19445 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19446 printf ("FMA");
19447 break;
32930e4e 19448 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19449 printf ("AVX512F");
19450 break;
32930e4e 19451 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19452 printf ("AVX512CD");
19453 break;
32930e4e 19454 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19455 printf ("AVX512ER");
19456 break;
32930e4e 19457 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19458 printf ("AVX512PF");
19459 break;
32930e4e 19460 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19461 printf ("AVX512VL");
19462 break;
32930e4e 19463 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19464 printf ("AVX512DQ");
19465 break;
32930e4e 19466 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19467 printf ("AVX512BW");
19468 break;
32930e4e 19469 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19470 printf ("AVX512_4FMAPS");
19471 break;
32930e4e 19472 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19473 printf ("AVX512_4VNNIW");
19474 break;
32930e4e 19475 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19476 printf ("AVX512_BITALG");
19477 break;
32930e4e 19478 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19479 printf ("AVX512_IFMA");
19480 break;
32930e4e 19481 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19482 printf ("AVX512_VBMI");
19483 break;
32930e4e 19484 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19485 printf ("AVX512_VBMI2");
19486 break;
32930e4e 19487 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19488 printf ("AVX512_VNNI");
19489 break;
32930e4e 19490 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19491 printf ("AVX512_BF16");
19492 break;
65b3d26e
L
19493 default:
19494 printf (_("<unknown: %x>"), bit);
19495 break;
9ef920e9
NC
19496 }
19497 if (bitmask)
19498 printf (", ");
19499 }
19500}
19501
32930e4e
L
19502static void
19503decode_x86_isa (unsigned int bitmask)
19504{
32930e4e
L
19505 while (bitmask)
19506 {
19507 unsigned int bit = bitmask & (- bitmask);
19508
19509 bitmask &= ~ bit;
19510 switch (bit)
19511 {
b0ab0693
L
19512 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19513 printf ("x86-64-baseline");
19514 break;
32930e4e
L
19515 case GNU_PROPERTY_X86_ISA_1_V2:
19516 printf ("x86-64-v2");
19517 break;
19518 case GNU_PROPERTY_X86_ISA_1_V3:
19519 printf ("x86-64-v3");
19520 break;
19521 case GNU_PROPERTY_X86_ISA_1_V4:
19522 printf ("x86-64-v4");
19523 break;
19524 default:
19525 printf (_("<unknown: %x>"), bit);
19526 break;
19527 }
19528 if (bitmask)
19529 printf (", ");
19530 }
19531}
19532
ee2fdd6f 19533static void
a9eafb08 19534decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19535{
0a59decb 19536 if (!bitmask)
90c745dc
L
19537 {
19538 printf (_("<None>"));
19539 return;
19540 }
90c745dc 19541
ee2fdd6f
L
19542 while (bitmask)
19543 {
19544 unsigned int bit = bitmask & (- bitmask);
19545
19546 bitmask &= ~ bit;
19547 switch (bit)
19548 {
19549 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19550 printf ("IBT");
ee2fdd6f 19551 break;
48580982 19552 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19553 printf ("SHSTK");
48580982 19554 break;
279d901e
L
19555 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19556 printf ("LAM_U48");
19557 break;
19558 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19559 printf ("LAM_U57");
19560 break;
ee2fdd6f
L
19561 default:
19562 printf (_("<unknown: %x>"), bit);
19563 break;
19564 }
19565 if (bitmask)
19566 printf (", ");
19567 }
19568}
19569
a9eafb08
L
19570static void
19571decode_x86_feature_2 (unsigned int bitmask)
19572{
0a59decb 19573 if (!bitmask)
90c745dc
L
19574 {
19575 printf (_("<None>"));
19576 return;
19577 }
90c745dc 19578
a9eafb08
L
19579 while (bitmask)
19580 {
19581 unsigned int bit = bitmask & (- bitmask);
19582
19583 bitmask &= ~ bit;
19584 switch (bit)
19585 {
19586 case GNU_PROPERTY_X86_FEATURE_2_X86:
19587 printf ("x86");
19588 break;
19589 case GNU_PROPERTY_X86_FEATURE_2_X87:
19590 printf ("x87");
19591 break;
19592 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19593 printf ("MMX");
19594 break;
19595 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19596 printf ("XMM");
19597 break;
19598 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19599 printf ("YMM");
19600 break;
19601 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19602 printf ("ZMM");
19603 break;
a308b89d
L
19604 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19605 printf ("TMM");
19606 break;
32930e4e
L
19607 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19608 printf ("MASK");
19609 break;
a9eafb08
L
19610 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19611 printf ("FXSR");
19612 break;
19613 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19614 printf ("XSAVE");
19615 break;
19616 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19617 printf ("XSAVEOPT");
19618 break;
19619 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19620 printf ("XSAVEC");
19621 break;
65b3d26e
L
19622 default:
19623 printf (_("<unknown: %x>"), bit);
19624 break;
a9eafb08
L
19625 }
19626 if (bitmask)
19627 printf (", ");
19628 }
19629}
19630
cd702818
SD
19631static void
19632decode_aarch64_feature_1_and (unsigned int bitmask)
19633{
19634 while (bitmask)
19635 {
19636 unsigned int bit = bitmask & (- bitmask);
19637
19638 bitmask &= ~ bit;
19639 switch (bit)
19640 {
19641 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19642 printf ("BTI");
19643 break;
19644
19645 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19646 printf ("PAC");
19647 break;
19648
19649 default:
19650 printf (_("<unknown: %x>"), bit);
19651 break;
19652 }
19653 if (bitmask)
19654 printf (", ");
19655 }
19656}
19657
6320fd00
L
19658static void
19659decode_1_needed (unsigned int bitmask)
19660{
19661 while (bitmask)
19662 {
19663 unsigned int bit = bitmask & (- bitmask);
19664
19665 bitmask &= ~ bit;
19666 switch (bit)
19667 {
19668 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19669 printf ("indirect external access");
19670 break;
19671 default:
19672 printf (_("<unknown: %x>"), bit);
19673 break;
19674 }
19675 if (bitmask)
19676 printf (", ");
19677 }
19678}
19679
9ef920e9 19680static void
dda8d76d 19681print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19682{
19683 unsigned char * ptr = (unsigned char *) pnote->descdata;
19684 unsigned char * ptr_end = ptr + pnote->descsz;
19685 unsigned int size = is_32bit_elf ? 4 : 8;
19686
19687 printf (_(" Properties: "));
19688
1fc87489 19689 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19690 {
19691 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19692 return;
19693 }
19694
6ab2c4ed 19695 while (ptr < ptr_end)
9ef920e9 19696 {
1fc87489 19697 unsigned int j;
6ab2c4ed
MC
19698 unsigned int type;
19699 unsigned int datasz;
19700
19701 if ((size_t) (ptr_end - ptr) < 8)
19702 {
19703 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19704 break;
19705 }
19706
19707 type = byte_get (ptr, 4);
19708 datasz = byte_get (ptr + 4, 4);
9ef920e9 19709
1fc87489 19710 ptr += 8;
9ef920e9 19711
6ab2c4ed 19712 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19713 {
1fc87489
L
19714 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19715 type, datasz);
9ef920e9 19716 break;
1fc87489 19717 }
9ef920e9 19718
1fc87489
L
19719 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19720 {
dda8d76d
NC
19721 if (filedata->file_header.e_machine == EM_X86_64
19722 || filedata->file_header.e_machine == EM_IAMCU
19723 || filedata->file_header.e_machine == EM_386)
1fc87489 19724 {
aa7bca9b
L
19725 unsigned int bitmask;
19726
19727 if (datasz == 4)
0a59decb 19728 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19729 else
19730 bitmask = 0;
19731
1fc87489
L
19732 switch (type)
19733 {
19734 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19735 if (datasz != 4)
aa7bca9b
L
19736 printf (_("x86 ISA used: <corrupt length: %#x> "),
19737 datasz);
1fc87489 19738 else
aa7bca9b
L
19739 {
19740 printf ("x86 ISA used: ");
19741 decode_x86_isa (bitmask);
19742 }
1fc87489 19743 goto next;
9ef920e9 19744
1fc87489 19745 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19746 if (datasz != 4)
aa7bca9b
L
19747 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19748 datasz);
1fc87489 19749 else
aa7bca9b
L
19750 {
19751 printf ("x86 ISA needed: ");
19752 decode_x86_isa (bitmask);
19753 }
1fc87489 19754 goto next;
9ef920e9 19755
ee2fdd6f 19756 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19757 if (datasz != 4)
aa7bca9b
L
19758 printf (_("x86 feature: <corrupt length: %#x> "),
19759 datasz);
ee2fdd6f 19760 else
aa7bca9b
L
19761 {
19762 printf ("x86 feature: ");
a9eafb08
L
19763 decode_x86_feature_1 (bitmask);
19764 }
19765 goto next;
19766
19767 case GNU_PROPERTY_X86_FEATURE_2_USED:
19768 if (datasz != 4)
19769 printf (_("x86 feature used: <corrupt length: %#x> "),
19770 datasz);
19771 else
19772 {
19773 printf ("x86 feature used: ");
19774 decode_x86_feature_2 (bitmask);
19775 }
19776 goto next;
19777
19778 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19779 if (datasz != 4)
19780 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19781 else
19782 {
19783 printf ("x86 feature needed: ");
19784 decode_x86_feature_2 (bitmask);
19785 }
19786 goto next;
19787
19788 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19789 if (datasz != 4)
19790 printf (_("x86 ISA used: <corrupt length: %#x> "),
19791 datasz);
19792 else
19793 {
19794 printf ("x86 ISA used: ");
19795 decode_x86_compat_isa (bitmask);
19796 }
19797 goto next;
19798
19799 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19800 if (datasz != 4)
19801 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19802 datasz);
19803 else
19804 {
19805 printf ("x86 ISA needed: ");
19806 decode_x86_compat_isa (bitmask);
aa7bca9b 19807 }
ee2fdd6f
L
19808 goto next;
19809
32930e4e
L
19810 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19811 if (datasz != 4)
19812 printf (_("x86 ISA used: <corrupt length: %#x> "),
19813 datasz);
19814 else
19815 {
19816 printf ("x86 ISA used: ");
19817 decode_x86_compat_2_isa (bitmask);
19818 }
19819 goto next;
19820
19821 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19822 if (datasz != 4)
19823 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19824 datasz);
19825 else
19826 {
19827 printf ("x86 ISA needed: ");
19828 decode_x86_compat_2_isa (bitmask);
19829 }
19830 goto next;
19831
1fc87489
L
19832 default:
19833 break;
19834 }
19835 }
cd702818
SD
19836 else if (filedata->file_header.e_machine == EM_AARCH64)
19837 {
19838 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19839 {
19840 printf ("AArch64 feature: ");
19841 if (datasz != 4)
19842 printf (_("<corrupt length: %#x> "), datasz);
19843 else
19844 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19845 goto next;
19846 }
19847 }
1fc87489
L
19848 }
19849 else
19850 {
19851 switch (type)
9ef920e9 19852 {
1fc87489
L
19853 case GNU_PROPERTY_STACK_SIZE:
19854 printf (_("stack size: "));
19855 if (datasz != size)
19856 printf (_("<corrupt length: %#x> "), datasz);
19857 else
19858 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19859 goto next;
19860
19861 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19862 printf ("no copy on protected ");
19863 if (datasz)
19864 printf (_("<corrupt length: %#x> "), datasz);
19865 goto next;
19866
19867 default:
5a767724
L
19868 if ((type >= GNU_PROPERTY_UINT32_AND_LO
19869 && type <= GNU_PROPERTY_UINT32_AND_HI)
19870 || (type >= GNU_PROPERTY_UINT32_OR_LO
19871 && type <= GNU_PROPERTY_UINT32_OR_HI))
19872 {
6320fd00
L
19873 switch (type)
19874 {
19875 case GNU_PROPERTY_1_NEEDED:
19876 if (datasz != 4)
19877 printf (_("1_needed: <corrupt length: %#x> "),
19878 datasz);
19879 else
19880 {
19881 unsigned int bitmask = byte_get (ptr, 4);
19882 printf ("1_needed: ");
19883 decode_1_needed (bitmask);
19884 }
19885 goto next;
19886
19887 default:
19888 break;
19889 }
5a767724
L
19890 if (type <= GNU_PROPERTY_UINT32_AND_HI)
19891 printf (_("UINT32_AND (%#x): "), type);
19892 else
19893 printf (_("UINT32_OR (%#x): "), type);
19894 if (datasz != 4)
19895 printf (_("<corrupt length: %#x> "), datasz);
19896 else
19897 printf ("%#x", (unsigned int) byte_get (ptr, 4));
19898 goto next;
19899 }
9ef920e9
NC
19900 break;
19901 }
9ef920e9
NC
19902 }
19903
1fc87489
L
19904 if (type < GNU_PROPERTY_LOPROC)
19905 printf (_("<unknown type %#x data: "), type);
19906 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19907 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19908 else
19909 printf (_("<application-specific type %#x data: "), type);
19910 for (j = 0; j < datasz; ++j)
19911 printf ("%02x ", ptr[j] & 0xff);
19912 printf (">");
19913
dc1e8a47 19914 next:
9ef920e9 19915 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19916 if (ptr == ptr_end)
19917 break;
1fc87489 19918
6ab2c4ed
MC
19919 if (do_wide)
19920 printf (", ");
19921 else
19922 printf ("\n\t");
9ef920e9
NC
19923 }
19924
19925 printf ("\n");
19926}
19927
015dc7e1 19928static bool
dda8d76d 19929print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19930{
1449284b 19931 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19932 switch (pnote->type)
19933 {
19934 case NT_GNU_BUILD_ID:
19935 {
19936 unsigned long i;
19937
19938 printf (_(" Build ID: "));
19939 for (i = 0; i < pnote->descsz; ++i)
19940 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19941 printf ("\n");
664f90a3
TT
19942 }
19943 break;
19944
19945 case NT_GNU_ABI_TAG:
19946 {
19947 unsigned long os, major, minor, subminor;
19948 const char *osname;
19949
3102e897
NC
19950 /* PR 17531: file: 030-599401-0.004. */
19951 if (pnote->descsz < 16)
19952 {
19953 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19954 break;
19955 }
19956
664f90a3
TT
19957 os = byte_get ((unsigned char *) pnote->descdata, 4);
19958 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19959 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19960 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19961
19962 switch (os)
19963 {
19964 case GNU_ABI_TAG_LINUX:
19965 osname = "Linux";
19966 break;
19967 case GNU_ABI_TAG_HURD:
19968 osname = "Hurd";
19969 break;
19970 case GNU_ABI_TAG_SOLARIS:
19971 osname = "Solaris";
19972 break;
19973 case GNU_ABI_TAG_FREEBSD:
19974 osname = "FreeBSD";
19975 break;
19976 case GNU_ABI_TAG_NETBSD:
19977 osname = "NetBSD";
19978 break;
14ae95f2
RM
19979 case GNU_ABI_TAG_SYLLABLE:
19980 osname = "Syllable";
19981 break;
19982 case GNU_ABI_TAG_NACL:
19983 osname = "NaCl";
19984 break;
664f90a3
TT
19985 default:
19986 osname = "Unknown";
19987 break;
19988 }
19989
19990 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19991 major, minor, subminor);
19992 }
19993 break;
926c5385
CC
19994
19995 case NT_GNU_GOLD_VERSION:
19996 {
19997 unsigned long i;
19998
19999 printf (_(" Version: "));
20000 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20001 printf ("%c", pnote->descdata[i]);
20002 printf ("\n");
20003 }
20004 break;
1449284b
NC
20005
20006 case NT_GNU_HWCAP:
20007 {
20008 unsigned long num_entries, mask;
20009
20010 /* Hardware capabilities information. Word 0 is the number of entries.
20011 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20012 is a series of entries, where each entry is a single byte followed
20013 by a nul terminated string. The byte gives the bit number to test
20014 if enabled in the bitmask. */
20015 printf (_(" Hardware Capabilities: "));
20016 if (pnote->descsz < 8)
20017 {
32ec8896 20018 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20019 return false;
1449284b
NC
20020 }
20021 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20022 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20023 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20024 /* FIXME: Add code to display the entries... */
20025 }
20026 break;
20027
9ef920e9 20028 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20029 print_gnu_property_note (filedata, pnote);
9ef920e9 20030 break;
9abca702 20031
1449284b
NC
20032 default:
20033 /* Handle unrecognised types. An error message should have already been
20034 created by get_gnu_elf_note_type(), so all that we need to do is to
20035 display the data. */
20036 {
20037 unsigned long i;
20038
20039 printf (_(" Description data: "));
20040 for (i = 0; i < pnote->descsz; ++i)
20041 printf ("%02x ", pnote->descdata[i] & 0xff);
20042 printf ("\n");
20043 }
20044 break;
664f90a3
TT
20045 }
20046
015dc7e1 20047 return true;
664f90a3
TT
20048}
20049
685080f2
NC
20050static const char *
20051get_v850_elf_note_type (enum v850_notes n_type)
20052{
20053 static char buff[64];
20054
20055 switch (n_type)
20056 {
20057 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20058 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20059 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20060 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20061 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20062 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20063 default:
20064 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20065 return buff;
20066 }
20067}
20068
015dc7e1 20069static bool
685080f2
NC
20070print_v850_note (Elf_Internal_Note * pnote)
20071{
20072 unsigned int val;
20073
20074 if (pnote->descsz != 4)
015dc7e1 20075 return false;
32ec8896 20076
685080f2
NC
20077 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20078
20079 if (val == 0)
20080 {
20081 printf (_("not set\n"));
015dc7e1 20082 return true;
685080f2
NC
20083 }
20084
20085 switch (pnote->type)
20086 {
20087 case V850_NOTE_ALIGNMENT:
20088 switch (val)
20089 {
015dc7e1
AM
20090 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20091 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20092 }
20093 break;
14ae95f2 20094
685080f2
NC
20095 case V850_NOTE_DATA_SIZE:
20096 switch (val)
20097 {
015dc7e1
AM
20098 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20099 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20100 }
20101 break;
14ae95f2 20102
685080f2
NC
20103 case V850_NOTE_FPU_INFO:
20104 switch (val)
20105 {
015dc7e1
AM
20106 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20107 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20108 }
20109 break;
14ae95f2 20110
685080f2
NC
20111 case V850_NOTE_MMU_INFO:
20112 case V850_NOTE_CACHE_INFO:
20113 case V850_NOTE_SIMD_INFO:
20114 if (val == EF_RH850_SIMD)
20115 {
20116 printf (_("yes\n"));
015dc7e1 20117 return true;
685080f2
NC
20118 }
20119 break;
20120
20121 default:
20122 /* An 'unknown note type' message will already have been displayed. */
20123 break;
20124 }
20125
20126 printf (_("unknown value: %x\n"), val);
015dc7e1 20127 return false;
685080f2
NC
20128}
20129
015dc7e1 20130static bool
c6056a74
SF
20131process_netbsd_elf_note (Elf_Internal_Note * pnote)
20132{
20133 unsigned int version;
20134
20135 switch (pnote->type)
20136 {
20137 case NT_NETBSD_IDENT:
b966f55f
AM
20138 if (pnote->descsz < 1)
20139 break;
c6056a74
SF
20140 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20141 if ((version / 10000) % 100)
b966f55f 20142 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20143 version, version / 100000000, (version / 1000000) % 100,
20144 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20145 'A' + (version / 10000) % 26);
c6056a74
SF
20146 else
20147 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20148 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20149 (version / 100) % 100);
015dc7e1 20150 return true;
c6056a74
SF
20151
20152 case NT_NETBSD_MARCH:
9abca702 20153 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20154 pnote->descdata);
015dc7e1 20155 return true;
c6056a74 20156
9abca702 20157 case NT_NETBSD_PAX:
b966f55f
AM
20158 if (pnote->descsz < 1)
20159 break;
9abca702
CZ
20160 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20161 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20162 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20163 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20164 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20165 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20166 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20167 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20168 return true;
c6056a74 20169 }
b966f55f
AM
20170
20171 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20172 pnote->descsz, pnote->type);
015dc7e1 20173 return false;
c6056a74
SF
20174}
20175
f4ddf30f 20176static const char *
dda8d76d 20177get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20178{
f4ddf30f
JB
20179 switch (e_type)
20180 {
20181 case NT_FREEBSD_THRMISC:
20182 return _("NT_THRMISC (thrmisc structure)");
20183 case NT_FREEBSD_PROCSTAT_PROC:
20184 return _("NT_PROCSTAT_PROC (proc data)");
20185 case NT_FREEBSD_PROCSTAT_FILES:
20186 return _("NT_PROCSTAT_FILES (files data)");
20187 case NT_FREEBSD_PROCSTAT_VMMAP:
20188 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20189 case NT_FREEBSD_PROCSTAT_GROUPS:
20190 return _("NT_PROCSTAT_GROUPS (groups data)");
20191 case NT_FREEBSD_PROCSTAT_UMASK:
20192 return _("NT_PROCSTAT_UMASK (umask data)");
20193 case NT_FREEBSD_PROCSTAT_RLIMIT:
20194 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20195 case NT_FREEBSD_PROCSTAT_OSREL:
20196 return _("NT_PROCSTAT_OSREL (osreldate data)");
20197 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20198 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20199 case NT_FREEBSD_PROCSTAT_AUXV:
20200 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20201 case NT_FREEBSD_PTLWPINFO:
20202 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 20203 }
dda8d76d 20204 return get_note_type (filedata, e_type);
f4ddf30f
JB
20205}
20206
9437c45b 20207static const char *
dda8d76d 20208get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20209{
20210 static char buff[64];
20211
540e6170
CZ
20212 switch (e_type)
20213 {
20214 case NT_NETBSDCORE_PROCINFO:
20215 /* NetBSD core "procinfo" structure. */
20216 return _("NetBSD procinfo structure");
9437c45b 20217
540e6170
CZ
20218 case NT_NETBSDCORE_AUXV:
20219 return _("NetBSD ELF auxiliary vector data");
9437c45b 20220
06d949ec
KR
20221 case NT_NETBSDCORE_LWPSTATUS:
20222 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20223
540e6170 20224 default:
06d949ec 20225 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20226 defined for NetBSD core files. If the note type is less
20227 than the start of the machine-dependent note types, we don't
20228 understand it. */
20229
20230 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20231 {
20232 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20233 return buff;
20234 }
20235 break;
9437c45b
JT
20236 }
20237
dda8d76d 20238 switch (filedata->file_header.e_machine)
9437c45b
JT
20239 {
20240 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20241 and PT_GETFPREGS == mach+2. */
20242
20243 case EM_OLD_ALPHA:
20244 case EM_ALPHA:
20245 case EM_SPARC:
20246 case EM_SPARC32PLUS:
20247 case EM_SPARCV9:
20248 switch (e_type)
20249 {
2b692964 20250 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20251 return _("PT_GETREGS (reg structure)");
2b692964 20252 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20253 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20254 default:
20255 break;
20256 }
20257 break;
20258
c0d38b0e
CZ
20259 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20260 There's also old PT___GETREGS40 == mach + 1 for old reg
20261 structure which lacks GBR. */
20262 case EM_SH:
20263 switch (e_type)
20264 {
20265 case NT_NETBSDCORE_FIRSTMACH + 1:
20266 return _("PT___GETREGS40 (old reg structure)");
20267 case NT_NETBSDCORE_FIRSTMACH + 3:
20268 return _("PT_GETREGS (reg structure)");
20269 case NT_NETBSDCORE_FIRSTMACH + 5:
20270 return _("PT_GETFPREGS (fpreg structure)");
20271 default:
20272 break;
20273 }
20274 break;
20275
9437c45b
JT
20276 /* On all other arch's, PT_GETREGS == mach+1 and
20277 PT_GETFPREGS == mach+3. */
20278 default:
20279 switch (e_type)
20280 {
2b692964 20281 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20282 return _("PT_GETREGS (reg structure)");
2b692964 20283 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20284 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20285 default:
20286 break;
20287 }
20288 }
20289
9cf03b7e 20290 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20291 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20292 return buff;
20293}
20294
98ca73af
FC
20295static const char *
20296get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20297{
20298 switch (e_type)
20299 {
20300 case NT_OPENBSD_PROCINFO:
20301 return _("OpenBSD procinfo structure");
20302 case NT_OPENBSD_AUXV:
20303 return _("OpenBSD ELF auxiliary vector data");
20304 case NT_OPENBSD_REGS:
20305 return _("OpenBSD regular registers");
20306 case NT_OPENBSD_FPREGS:
20307 return _("OpenBSD floating point registers");
20308 case NT_OPENBSD_WCOOKIE:
20309 return _("OpenBSD window cookie");
20310 }
20311
20312 return get_note_type (filedata, e_type);
20313}
20314
70616151
TT
20315static const char *
20316get_stapsdt_note_type (unsigned e_type)
20317{
20318 static char buff[64];
20319
20320 switch (e_type)
20321 {
20322 case NT_STAPSDT:
20323 return _("NT_STAPSDT (SystemTap probe descriptors)");
20324
20325 default:
20326 break;
20327 }
20328
20329 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20330 return buff;
20331}
20332
015dc7e1 20333static bool
c6a9fc58
TT
20334print_stapsdt_note (Elf_Internal_Note *pnote)
20335{
3ca60c57
NC
20336 size_t len, maxlen;
20337 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20338 char *data = pnote->descdata;
20339 char *data_end = pnote->descdata + pnote->descsz;
20340 bfd_vma pc, base_addr, semaphore;
20341 char *provider, *probe, *arg_fmt;
20342
3ca60c57
NC
20343 if (pnote->descsz < (addr_size * 3))
20344 goto stapdt_note_too_small;
20345
c6a9fc58
TT
20346 pc = byte_get ((unsigned char *) data, addr_size);
20347 data += addr_size;
3ca60c57 20348
c6a9fc58
TT
20349 base_addr = byte_get ((unsigned char *) data, addr_size);
20350 data += addr_size;
3ca60c57 20351
c6a9fc58
TT
20352 semaphore = byte_get ((unsigned char *) data, addr_size);
20353 data += addr_size;
20354
3ca60c57
NC
20355 if (data >= data_end)
20356 goto stapdt_note_too_small;
20357 maxlen = data_end - data;
20358 len = strnlen (data, maxlen);
20359 if (len < maxlen)
20360 {
20361 provider = data;
20362 data += len + 1;
20363 }
20364 else
20365 goto stapdt_note_too_small;
20366
20367 if (data >= data_end)
20368 goto stapdt_note_too_small;
20369 maxlen = data_end - data;
20370 len = strnlen (data, maxlen);
20371 if (len < maxlen)
20372 {
20373 probe = data;
20374 data += len + 1;
20375 }
20376 else
20377 goto stapdt_note_too_small;
9abca702 20378
3ca60c57
NC
20379 if (data >= data_end)
20380 goto stapdt_note_too_small;
20381 maxlen = data_end - data;
20382 len = strnlen (data, maxlen);
20383 if (len < maxlen)
20384 {
20385 arg_fmt = data;
20386 data += len + 1;
20387 }
20388 else
20389 goto stapdt_note_too_small;
c6a9fc58
TT
20390
20391 printf (_(" Provider: %s\n"), provider);
20392 printf (_(" Name: %s\n"), probe);
20393 printf (_(" Location: "));
20394 print_vma (pc, FULL_HEX);
20395 printf (_(", Base: "));
20396 print_vma (base_addr, FULL_HEX);
20397 printf (_(", Semaphore: "));
20398 print_vma (semaphore, FULL_HEX);
9cf03b7e 20399 printf ("\n");
c6a9fc58
TT
20400 printf (_(" Arguments: %s\n"), arg_fmt);
20401
20402 return data == data_end;
3ca60c57
NC
20403
20404 stapdt_note_too_small:
20405 printf (_(" <corrupt - note is too small>\n"));
20406 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20407 return false;
c6a9fc58
TT
20408}
20409
00e98fc7
TG
20410static const char *
20411get_ia64_vms_note_type (unsigned e_type)
20412{
20413 static char buff[64];
20414
20415 switch (e_type)
20416 {
20417 case NT_VMS_MHD:
20418 return _("NT_VMS_MHD (module header)");
20419 case NT_VMS_LNM:
20420 return _("NT_VMS_LNM (language name)");
20421 case NT_VMS_SRC:
20422 return _("NT_VMS_SRC (source files)");
20423 case NT_VMS_TITLE:
9cf03b7e 20424 return "NT_VMS_TITLE";
00e98fc7
TG
20425 case NT_VMS_EIDC:
20426 return _("NT_VMS_EIDC (consistency check)");
20427 case NT_VMS_FPMODE:
20428 return _("NT_VMS_FPMODE (FP mode)");
20429 case NT_VMS_LINKTIME:
9cf03b7e 20430 return "NT_VMS_LINKTIME";
00e98fc7
TG
20431 case NT_VMS_IMGNAM:
20432 return _("NT_VMS_IMGNAM (image name)");
20433 case NT_VMS_IMGID:
20434 return _("NT_VMS_IMGID (image id)");
20435 case NT_VMS_LINKID:
20436 return _("NT_VMS_LINKID (link id)");
20437 case NT_VMS_IMGBID:
20438 return _("NT_VMS_IMGBID (build id)");
20439 case NT_VMS_GSTNAM:
20440 return _("NT_VMS_GSTNAM (sym table name)");
20441 case NT_VMS_ORIG_DYN:
9cf03b7e 20442 return "NT_VMS_ORIG_DYN";
00e98fc7 20443 case NT_VMS_PATCHTIME:
9cf03b7e 20444 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20445 default:
20446 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20447 return buff;
20448 }
20449}
20450
015dc7e1 20451static bool
00e98fc7
TG
20452print_ia64_vms_note (Elf_Internal_Note * pnote)
20453{
8d18bf79
NC
20454 int maxlen = pnote->descsz;
20455
20456 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20457 goto desc_size_fail;
20458
00e98fc7
TG
20459 switch (pnote->type)
20460 {
20461 case NT_VMS_MHD:
8d18bf79
NC
20462 if (maxlen <= 36)
20463 goto desc_size_fail;
20464
20465 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20466
20467 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20468 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20469 if (l + 34 < maxlen)
20470 {
20471 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20472 if (l + 35 < maxlen)
20473 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20474 else
20475 printf (_(" Module version : <missing>\n"));
20476 }
00e98fc7 20477 else
8d18bf79
NC
20478 {
20479 printf (_(" Module name : <missing>\n"));
20480 printf (_(" Module version : <missing>\n"));
20481 }
00e98fc7 20482 break;
8d18bf79 20483
00e98fc7 20484 case NT_VMS_LNM:
8d18bf79 20485 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20486 break;
8d18bf79 20487
00e98fc7
TG
20488#ifdef BFD64
20489 case NT_VMS_FPMODE:
9cf03b7e 20490 printf (_(" Floating Point mode: "));
8d18bf79
NC
20491 if (maxlen < 8)
20492 goto desc_size_fail;
20493 /* FIXME: Generate an error if descsz > 8 ? */
20494
4a5cb34f 20495 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 20496 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 20497 break;
8d18bf79 20498
00e98fc7
TG
20499 case NT_VMS_LINKTIME:
20500 printf (_(" Link time: "));
8d18bf79
NC
20501 if (maxlen < 8)
20502 goto desc_size_fail;
20503 /* FIXME: Generate an error if descsz > 8 ? */
20504
00e98fc7 20505 print_vms_time
8d18bf79 20506 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20507 printf ("\n");
20508 break;
8d18bf79 20509
00e98fc7
TG
20510 case NT_VMS_PATCHTIME:
20511 printf (_(" Patch time: "));
8d18bf79
NC
20512 if (maxlen < 8)
20513 goto desc_size_fail;
20514 /* FIXME: Generate an error if descsz > 8 ? */
20515
00e98fc7 20516 print_vms_time
8d18bf79 20517 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20518 printf ("\n");
20519 break;
8d18bf79 20520
00e98fc7 20521 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20522 if (maxlen < 34)
20523 goto desc_size_fail;
20524
00e98fc7
TG
20525 printf (_(" Major id: %u, minor id: %u\n"),
20526 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20527 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20528 printf (_(" Last modified : "));
00e98fc7
TG
20529 print_vms_time
20530 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20531 printf (_("\n Link flags : "));
4a5cb34f 20532 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20533 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20534 printf (_(" Header flags: 0x%08x\n"),
948f632f 20535 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20536 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20537 break;
20538#endif
8d18bf79 20539
00e98fc7 20540 case NT_VMS_IMGNAM:
8d18bf79 20541 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20542 break;
8d18bf79 20543
00e98fc7 20544 case NT_VMS_GSTNAM:
8d18bf79 20545 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20546 break;
8d18bf79 20547
00e98fc7 20548 case NT_VMS_IMGID:
8d18bf79 20549 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20550 break;
8d18bf79 20551
00e98fc7 20552 case NT_VMS_LINKID:
8d18bf79 20553 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20554 break;
8d18bf79 20555
00e98fc7 20556 default:
015dc7e1 20557 return false;
00e98fc7 20558 }
8d18bf79 20559
015dc7e1 20560 return true;
8d18bf79
NC
20561
20562 desc_size_fail:
20563 printf (_(" <corrupt - data size is too small>\n"));
20564 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20565 return false;
00e98fc7
TG
20566}
20567
fd486f32
AM
20568struct build_attr_cache {
20569 Filedata *filedata;
20570 char *strtab;
20571 unsigned long strtablen;
20572 Elf_Internal_Sym *symtab;
20573 unsigned long nsyms;
20574} ba_cache;
20575
6f156d7a
NC
20576/* Find the symbol associated with a build attribute that is attached
20577 to address OFFSET. If PNAME is non-NULL then store the name of
20578 the symbol (if found) in the provided pointer, Returns NULL if a
20579 symbol could not be found. */
c799a79d 20580
6f156d7a 20581static Elf_Internal_Sym *
015dc7e1
AM
20582get_symbol_for_build_attribute (Filedata *filedata,
20583 unsigned long offset,
20584 bool is_open_attr,
20585 const char **pname)
9ef920e9 20586{
fd486f32
AM
20587 Elf_Internal_Sym *saved_sym = NULL;
20588 Elf_Internal_Sym *sym;
9ef920e9 20589
dda8d76d 20590 if (filedata->section_headers != NULL
fd486f32 20591 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20592 {
c799a79d 20593 Elf_Internal_Shdr * symsec;
9ef920e9 20594
fd486f32
AM
20595 free (ba_cache.strtab);
20596 ba_cache.strtab = NULL;
20597 free (ba_cache.symtab);
20598 ba_cache.symtab = NULL;
20599
c799a79d 20600 /* Load the symbol and string sections. */
dda8d76d
NC
20601 for (symsec = filedata->section_headers;
20602 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20603 symsec ++)
9ef920e9 20604 {
28d13567
AM
20605 if (symsec->sh_type == SHT_SYMTAB
20606 && get_symtab (filedata, symsec,
20607 &ba_cache.symtab, &ba_cache.nsyms,
20608 &ba_cache.strtab, &ba_cache.strtablen))
20609 break;
9ef920e9 20610 }
fd486f32 20611 ba_cache.filedata = filedata;
9ef920e9
NC
20612 }
20613
fd486f32 20614 if (ba_cache.symtab == NULL)
6f156d7a 20615 return NULL;
9ef920e9 20616
c799a79d 20617 /* Find a symbol whose value matches offset. */
fd486f32 20618 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20619 if (sym->st_value == offset)
20620 {
fd486f32 20621 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20622 /* Huh ? This should not happen. */
20623 continue;
9ef920e9 20624
fd486f32 20625 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20626 continue;
9ef920e9 20627
9b9b1092 20628 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20629 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20630 if (ba_cache.strtab[sym->st_name] == '$'
20631 && ba_cache.strtab[sym->st_name + 1] != 0
20632 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20633 continue;
20634
c799a79d
NC
20635 if (is_open_attr)
20636 {
20637 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20638 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20639 FUNC symbols entirely. */
20640 switch (ELF_ST_TYPE (sym->st_info))
20641 {
c799a79d 20642 case STT_OBJECT:
6f156d7a 20643 case STT_FILE:
c799a79d 20644 saved_sym = sym;
6f156d7a
NC
20645 if (sym->st_size)
20646 {
20647 /* If the symbol has a size associated
20648 with it then we can stop searching. */
fd486f32 20649 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20650 }
c799a79d 20651 continue;
9ef920e9 20652
c799a79d
NC
20653 case STT_FUNC:
20654 /* Ignore function symbols. */
20655 continue;
20656
20657 default:
20658 break;
20659 }
20660
20661 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20662 {
c799a79d
NC
20663 case STB_GLOBAL:
20664 if (saved_sym == NULL
20665 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20666 saved_sym = sym;
20667 break;
c871dade 20668
c799a79d
NC
20669 case STB_LOCAL:
20670 if (saved_sym == NULL)
20671 saved_sym = sym;
20672 break;
20673
20674 default:
9ef920e9
NC
20675 break;
20676 }
20677 }
c799a79d
NC
20678 else
20679 {
20680 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20681 continue;
20682
20683 saved_sym = sym;
20684 break;
20685 }
20686 }
20687
6f156d7a 20688 if (saved_sym && pname)
fd486f32 20689 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20690
20691 return saved_sym;
c799a79d
NC
20692}
20693
d20e98ab
NC
20694/* Returns true iff addr1 and addr2 are in the same section. */
20695
015dc7e1 20696static bool
d20e98ab
NC
20697same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20698{
20699 Elf_Internal_Shdr * a1;
20700 Elf_Internal_Shdr * a2;
20701
20702 a1 = find_section_by_address (filedata, addr1);
20703 a2 = find_section_by_address (filedata, addr2);
9abca702 20704
d20e98ab
NC
20705 return a1 == a2 && a1 != NULL;
20706}
20707
015dc7e1 20708static bool
dda8d76d
NC
20709print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20710 Filedata * filedata)
c799a79d 20711{
015dc7e1
AM
20712 static unsigned long global_offset = 0;
20713 static unsigned long global_end = 0;
20714 static unsigned long func_offset = 0;
20715 static unsigned long func_end = 0;
c871dade 20716
015dc7e1
AM
20717 Elf_Internal_Sym *sym;
20718 const char *name;
20719 unsigned long start;
20720 unsigned long end;
20721 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20722
20723 switch (pnote->descsz)
c799a79d 20724 {
6f156d7a
NC
20725 case 0:
20726 /* A zero-length description means that the range of
20727 the previous note of the same type should be used. */
c799a79d 20728 if (is_open_attr)
c871dade 20729 {
6f156d7a
NC
20730 if (global_end > global_offset)
20731 printf (_(" Applies to region from %#lx to %#lx\n"),
20732 global_offset, global_end);
20733 else
20734 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20735 }
20736 else
20737 {
6f156d7a
NC
20738 if (func_end > func_offset)
20739 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20740 else
20741 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20742 }
015dc7e1 20743 return true;
9ef920e9 20744
6f156d7a
NC
20745 case 4:
20746 start = byte_get ((unsigned char *) pnote->descdata, 4);
20747 end = 0;
20748 break;
20749
20750 case 8:
c74147bb
NC
20751 start = byte_get ((unsigned char *) pnote->descdata, 4);
20752 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20753 break;
20754
20755 case 16:
20756 start = byte_get ((unsigned char *) pnote->descdata, 8);
20757 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20758 break;
9abca702 20759
6f156d7a 20760 default:
c799a79d
NC
20761 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20762 printf (_(" <invalid descsz>"));
015dc7e1 20763 return false;
c799a79d
NC
20764 }
20765
6f156d7a
NC
20766 name = NULL;
20767 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20768 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20769 in order to avoid them being confused with the start address of the
20770 first function in the file... */
20771 if (sym == NULL && is_open_attr)
20772 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20773 & name);
6f156d7a
NC
20774
20775 if (end == 0 && sym != NULL && sym->st_size > 0)
20776 end = start + sym->st_size;
c799a79d
NC
20777
20778 if (is_open_attr)
20779 {
d20e98ab
NC
20780 /* FIXME: Need to properly allow for section alignment.
20781 16 is just the alignment used on x86_64. */
20782 if (global_end > 0
20783 && start > BFD_ALIGN (global_end, 16)
20784 /* Build notes are not guaranteed to be organised in order of
20785 increasing address, but we should find the all of the notes
20786 for one section in the same place. */
20787 && same_section (filedata, start, global_end))
6f156d7a
NC
20788 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20789 global_end + 1, start - 1);
20790
20791 printf (_(" Applies to region from %#lx"), start);
20792 global_offset = start;
20793
20794 if (end)
20795 {
20796 printf (_(" to %#lx"), end);
20797 global_end = end;
20798 }
c799a79d
NC
20799 }
20800 else
20801 {
6f156d7a
NC
20802 printf (_(" Applies to region from %#lx"), start);
20803 func_offset = start;
20804
20805 if (end)
20806 {
20807 printf (_(" to %#lx"), end);
20808 func_end = end;
20809 }
c799a79d
NC
20810 }
20811
6f156d7a
NC
20812 if (sym && name)
20813 printf (_(" (%s)"), name);
20814
20815 printf ("\n");
015dc7e1 20816 return true;
9ef920e9
NC
20817}
20818
015dc7e1 20819static bool
9ef920e9
NC
20820print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20821{
1d15e434
NC
20822 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20823 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20824 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20825 char name_type;
20826 char name_attribute;
1d15e434 20827 const char * expected_types;
9ef920e9
NC
20828 const char * name = pnote->namedata;
20829 const char * text;
88305e1b 20830 signed int left;
9ef920e9
NC
20831
20832 if (name == NULL || pnote->namesz < 2)
20833 {
20834 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20835 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20836 return false;
9ef920e9
NC
20837 }
20838
6f156d7a
NC
20839 if (do_wide)
20840 left = 28;
20841 else
20842 left = 20;
88305e1b
NC
20843
20844 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20845 if (name[0] == 'G' && name[1] == 'A')
20846 {
6f156d7a
NC
20847 if (pnote->namesz < 4)
20848 {
20849 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20850 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20851 return false;
6f156d7a
NC
20852 }
20853
88305e1b
NC
20854 printf ("GA");
20855 name += 2;
20856 left -= 2;
20857 }
20858
9ef920e9
NC
20859 switch ((name_type = * name))
20860 {
20861 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20862 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20863 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20864 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20865 printf ("%c", * name);
88305e1b 20866 left --;
9ef920e9
NC
20867 break;
20868 default:
20869 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20870 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20871 return false;
9ef920e9
NC
20872 }
20873
9ef920e9
NC
20874 ++ name;
20875 text = NULL;
20876
20877 switch ((name_attribute = * name))
20878 {
20879 case GNU_BUILD_ATTRIBUTE_VERSION:
20880 text = _("<version>");
1d15e434 20881 expected_types = string_expected;
9ef920e9
NC
20882 ++ name;
20883 break;
20884 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20885 text = _("<stack prot>");
75d7d298 20886 expected_types = "!+*";
9ef920e9
NC
20887 ++ name;
20888 break;
20889 case GNU_BUILD_ATTRIBUTE_RELRO:
20890 text = _("<relro>");
1d15e434 20891 expected_types = bool_expected;
9ef920e9
NC
20892 ++ name;
20893 break;
20894 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20895 text = _("<stack size>");
1d15e434 20896 expected_types = number_expected;
9ef920e9
NC
20897 ++ name;
20898 break;
20899 case GNU_BUILD_ATTRIBUTE_TOOL:
20900 text = _("<tool>");
1d15e434 20901 expected_types = string_expected;
9ef920e9
NC
20902 ++ name;
20903 break;
20904 case GNU_BUILD_ATTRIBUTE_ABI:
20905 text = _("<ABI>");
20906 expected_types = "$*";
20907 ++ name;
20908 break;
20909 case GNU_BUILD_ATTRIBUTE_PIC:
20910 text = _("<PIC>");
1d15e434 20911 expected_types = number_expected;
9ef920e9
NC
20912 ++ name;
20913 break;
a8be5506
NC
20914 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20915 text = _("<short enum>");
1d15e434 20916 expected_types = bool_expected;
a8be5506
NC
20917 ++ name;
20918 break;
9ef920e9
NC
20919 default:
20920 if (ISPRINT (* name))
20921 {
20922 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20923
20924 if (len > left && ! do_wide)
20925 len = left;
75d7d298 20926 printf ("%.*s:", len, name);
9ef920e9 20927 left -= len;
0dd6ae21 20928 name += len;
9ef920e9
NC
20929 }
20930 else
20931 {
3e6b6445 20932 static char tmpbuf [128];
88305e1b 20933
3e6b6445
NC
20934 error (_("unrecognised byte in name field: %d\n"), * name);
20935 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20936 text = tmpbuf;
20937 name ++;
9ef920e9
NC
20938 }
20939 expected_types = "*$!+";
20940 break;
20941 }
20942
20943 if (text)
88305e1b 20944 left -= printf ("%s", text);
9ef920e9
NC
20945
20946 if (strchr (expected_types, name_type) == NULL)
75d7d298 20947 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20948
20949 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20950 {
20951 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20952 (unsigned long) pnote->namesz,
20953 (long) (name - pnote->namedata));
015dc7e1 20954 return false;
9ef920e9
NC
20955 }
20956
20957 if (left < 1 && ! do_wide)
015dc7e1 20958 return true;
9ef920e9
NC
20959
20960 switch (name_type)
20961 {
20962 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20963 {
b06b2c92 20964 unsigned int bytes;
ddef72cd
NC
20965 unsigned long long val = 0;
20966 unsigned int shift = 0;
20967 char * decoded = NULL;
20968
b06b2c92
NC
20969 bytes = pnote->namesz - (name - pnote->namedata);
20970 if (bytes > 0)
20971 /* The -1 is because the name field is always 0 terminated, and we
20972 want to be able to ensure that the shift in the while loop below
20973 will not overflow. */
20974 -- bytes;
20975
ddef72cd
NC
20976 if (bytes > sizeof (val))
20977 {
3e6b6445
NC
20978 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20979 bytes);
20980 bytes = sizeof (val);
ddef72cd 20981 }
3e6b6445
NC
20982 /* We do not bother to warn if bytes == 0 as this can
20983 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20984
20985 while (bytes --)
20986 {
54b8331d 20987 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20988
20989 val |= byte << shift;
9ef920e9
NC
20990 shift += 8;
20991 }
20992
75d7d298 20993 switch (name_attribute)
9ef920e9 20994 {
75d7d298 20995 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20996 switch (val)
20997 {
75d7d298
NC
20998 case 0: decoded = "static"; break;
20999 case 1: decoded = "pic"; break;
21000 case 2: decoded = "PIC"; break;
21001 case 3: decoded = "pie"; break;
21002 case 4: decoded = "PIE"; break;
21003 default: break;
9ef920e9 21004 }
75d7d298
NC
21005 break;
21006 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21007 switch (val)
9ef920e9 21008 {
75d7d298
NC
21009 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21010 case 0: decoded = "off"; break;
21011 case 1: decoded = "on"; break;
21012 case 2: decoded = "all"; break;
21013 case 3: decoded = "strong"; break;
21014 case 4: decoded = "explicit"; break;
21015 default: break;
9ef920e9 21016 }
75d7d298
NC
21017 break;
21018 default:
21019 break;
9ef920e9
NC
21020 }
21021
75d7d298 21022 if (decoded != NULL)
3e6b6445
NC
21023 {
21024 print_symbol (-left, decoded);
21025 left = 0;
21026 }
21027 else if (val == 0)
21028 {
21029 printf ("0x0");
21030 left -= 3;
21031 }
9ef920e9 21032 else
75d7d298
NC
21033 {
21034 if (do_wide)
ddef72cd 21035 left -= printf ("0x%llx", val);
75d7d298 21036 else
ddef72cd 21037 left -= printf ("0x%-.*llx", left, val);
75d7d298 21038 }
9ef920e9
NC
21039 }
21040 break;
21041 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21042 left -= print_symbol (- left, name);
21043 break;
21044 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21045 left -= print_symbol (- left, "true");
21046 break;
21047 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21048 left -= print_symbol (- left, "false");
21049 break;
21050 }
21051
21052 if (do_wide && left > 0)
21053 printf ("%-*s", left, " ");
9abca702 21054
015dc7e1 21055 return true;
9ef920e9
NC
21056}
21057
6d118b09
NC
21058/* Note that by the ELF standard, the name field is already null byte
21059 terminated, and namesz includes the terminating null byte.
21060 I.E. the value of namesz for the name "FSF" is 4.
21061
e3c8793a 21062 If the value of namesz is zero, there is no name present. */
9ef920e9 21063
015dc7e1 21064static bool
9ef920e9 21065process_note (Elf_Internal_Note * pnote,
dda8d76d 21066 Filedata * filedata)
779fe533 21067{
2cf0635d
NC
21068 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21069 const char * nt;
9437c45b
JT
21070
21071 if (pnote->namesz == 0)
1ec5cd37
NC
21072 /* If there is no note name, then use the default set of
21073 note type strings. */
dda8d76d 21074 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21075
24d127aa 21076 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21077 /* GNU-specific object file notes. */
21078 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21079
24d127aa 21080 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21081 /* FreeBSD-specific core file notes. */
dda8d76d 21082 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21083
24d127aa 21084 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21085 /* NetBSD-specific core file notes. */
dda8d76d 21086 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21087
24d127aa 21088 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21089 /* NetBSD-specific core file notes. */
21090 return process_netbsd_elf_note (pnote);
21091
24d127aa 21092 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21093 /* NetBSD-specific core file notes. */
21094 return process_netbsd_elf_note (pnote);
21095
98ca73af
FC
21096 else if (startswith (pnote->namedata, "OpenBSD"))
21097 /* OpenBSD-specific core file notes. */
21098 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21099
e9b095a5 21100 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21101 {
21102 /* SPU-specific core file notes. */
21103 nt = pnote->namedata + 4;
21104 name = "SPU";
21105 }
21106
24d127aa 21107 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21108 /* VMS/ia64-specific file notes. */
21109 nt = get_ia64_vms_note_type (pnote->type);
21110
24d127aa 21111 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21112 nt = get_stapsdt_note_type (pnote->type);
21113
9437c45b 21114 else
1ec5cd37
NC
21115 /* Don't recognize this note name; just use the default set of
21116 note type strings. */
dda8d76d 21117 nt = get_note_type (filedata, pnote->type);
9437c45b 21118
1449284b 21119 printf (" ");
9ef920e9 21120
24d127aa 21121 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21122 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21123 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21124 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21125 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21126 print_gnu_build_attribute_name (pnote);
21127 else
21128 print_symbol (-20, name);
21129
21130 if (do_wide)
21131 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21132 else
21133 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21134
24d127aa 21135 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21136 return print_ia64_vms_note (pnote);
24d127aa 21137 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21138 return print_gnu_note (filedata, pnote);
24d127aa 21139 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21140 return print_stapsdt_note (pnote);
24d127aa 21141 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21142 return print_core_note (pnote);
24d127aa 21143 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21144 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21145 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21146 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21147 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21148 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 21149
9ef920e9 21150 if (pnote->descsz)
1449284b
NC
21151 {
21152 unsigned long i;
21153
21154 printf (_(" description data: "));
21155 for (i = 0; i < pnote->descsz; i++)
178d8719 21156 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
21157 if (!do_wide)
21158 printf ("\n");
1449284b
NC
21159 }
21160
9ef920e9
NC
21161 if (do_wide)
21162 printf ("\n");
21163
015dc7e1 21164 return true;
1449284b 21165}
6d118b09 21166
015dc7e1 21167static bool
dda8d76d
NC
21168process_notes_at (Filedata * filedata,
21169 Elf_Internal_Shdr * section,
21170 bfd_vma offset,
82ed9683
L
21171 bfd_vma length,
21172 bfd_vma align)
779fe533 21173{
015dc7e1
AM
21174 Elf_External_Note *pnotes;
21175 Elf_External_Note *external;
21176 char *end;
21177 bool res = true;
103f02d3 21178
779fe533 21179 if (length <= 0)
015dc7e1 21180 return false;
103f02d3 21181
1449284b
NC
21182 if (section)
21183 {
dda8d76d 21184 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21185 if (pnotes)
32ec8896 21186 {
dda8d76d 21187 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21188 {
21189 free (pnotes);
015dc7e1 21190 return false;
f761cb13 21191 }
32ec8896 21192 }
1449284b
NC
21193 }
21194 else
82ed9683 21195 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21196 _("notes"));
4dff97b2 21197
dd24e3da 21198 if (pnotes == NULL)
015dc7e1 21199 return false;
779fe533 21200
103f02d3 21201 external = pnotes;
103f02d3 21202
ca0e11aa
NC
21203 if (filedata->is_separate)
21204 printf (_("In linked file '%s': "), filedata->file_name);
21205 else
21206 printf ("\n");
1449284b 21207 if (section)
ca0e11aa 21208 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21209 else
ca0e11aa 21210 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21211 (unsigned long) offset, (unsigned long) length);
21212
82ed9683
L
21213 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21214 specifies that notes should be aligned to 4 bytes in 32-bit
21215 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21216 we also support 4 byte alignment in 64-bit objects. If section
21217 alignment is less than 4, we treate alignment as 4 bytes. */
21218 if (align < 4)
21219 align = 4;
21220 else if (align != 4 && align != 8)
21221 {
21222 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21223 (long) align);
a788aedd 21224 free (pnotes);
015dc7e1 21225 return false;
82ed9683
L
21226 }
21227
dbe15e4e 21228 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21229
c8071705
NC
21230 end = (char *) pnotes + length;
21231 while ((char *) external < end)
779fe533 21232 {
b34976b6 21233 Elf_Internal_Note inote;
15b42fb0 21234 size_t min_notesz;
4dff97b2 21235 char * next;
2cf0635d 21236 char * temp = NULL;
c8071705 21237 size_t data_remaining = end - (char *) external;
6d118b09 21238
dda8d76d 21239 if (!is_ia64_vms (filedata))
15b42fb0 21240 {
9dd3a467
NC
21241 /* PR binutils/15191
21242 Make sure that there is enough data to read. */
15b42fb0
AM
21243 min_notesz = offsetof (Elf_External_Note, name);
21244 if (data_remaining < min_notesz)
9dd3a467 21245 {
d3a49aa8
AM
21246 warn (ngettext ("Corrupt note: only %ld byte remains, "
21247 "not enough for a full note\n",
21248 "Corrupt note: only %ld bytes remain, "
21249 "not enough for a full note\n",
21250 data_remaining),
21251 (long) data_remaining);
9dd3a467
NC
21252 break;
21253 }
5396a86e
AM
21254 data_remaining -= min_notesz;
21255
15b42fb0
AM
21256 inote.type = BYTE_GET (external->type);
21257 inote.namesz = BYTE_GET (external->namesz);
21258 inote.namedata = external->name;
21259 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21260 inote.descdata = ((char *) external
4dff97b2 21261 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21262 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21263 next = ((char *) external
4dff97b2 21264 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21265 }
00e98fc7 21266 else
15b42fb0
AM
21267 {
21268 Elf64_External_VMS_Note *vms_external;
00e98fc7 21269
9dd3a467
NC
21270 /* PR binutils/15191
21271 Make sure that there is enough data to read. */
15b42fb0
AM
21272 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21273 if (data_remaining < min_notesz)
9dd3a467 21274 {
d3a49aa8
AM
21275 warn (ngettext ("Corrupt note: only %ld byte remains, "
21276 "not enough for a full note\n",
21277 "Corrupt note: only %ld bytes remain, "
21278 "not enough for a full note\n",
21279 data_remaining),
21280 (long) data_remaining);
9dd3a467
NC
21281 break;
21282 }
5396a86e 21283 data_remaining -= min_notesz;
3e55a963 21284
15b42fb0
AM
21285 vms_external = (Elf64_External_VMS_Note *) external;
21286 inote.type = BYTE_GET (vms_external->type);
21287 inote.namesz = BYTE_GET (vms_external->namesz);
21288 inote.namedata = vms_external->name;
21289 inote.descsz = BYTE_GET (vms_external->descsz);
21290 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21291 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21292 next = inote.descdata + align_power (inote.descsz, 3);
21293 }
21294
5396a86e
AM
21295 /* PR 17531: file: 3443835e. */
21296 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21297 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21298 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21299 || (size_t) (next - inote.descdata) < inote.descsz
21300 || ((size_t) (next - inote.descdata)
21301 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21302 {
15b42fb0 21303 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21304 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21305 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21306 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21307 break;
21308 }
21309
15b42fb0 21310 external = (Elf_External_Note *) next;
dd24e3da 21311
6d118b09
NC
21312 /* Verify that name is null terminated. It appears that at least
21313 one version of Linux (RedHat 6.0) generates corefiles that don't
21314 comply with the ELF spec by failing to include the null byte in
21315 namesz. */
18344509 21316 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21317 {
5396a86e 21318 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21319 {
5396a86e
AM
21320 temp = (char *) malloc (inote.namesz + 1);
21321 if (temp == NULL)
21322 {
21323 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21324 res = false;
5396a86e
AM
21325 break;
21326 }
76da6bbe 21327
5396a86e
AM
21328 memcpy (temp, inote.namedata, inote.namesz);
21329 inote.namedata = temp;
21330 }
21331 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21332 }
21333
dda8d76d 21334 if (! process_note (& inote, filedata))
015dc7e1 21335 res = false;
103f02d3 21336
9db70fc3
AM
21337 free (temp);
21338 temp = NULL;
779fe533
NC
21339 }
21340
21341 free (pnotes);
103f02d3 21342
779fe533
NC
21343 return res;
21344}
21345
015dc7e1 21346static bool
dda8d76d 21347process_corefile_note_segments (Filedata * filedata)
779fe533 21348{
015dc7e1 21349 Elf_Internal_Phdr *segment;
b34976b6 21350 unsigned int i;
015dc7e1 21351 bool res = true;
103f02d3 21352
dda8d76d 21353 if (! get_program_headers (filedata))
015dc7e1 21354 return true;
103f02d3 21355
dda8d76d
NC
21356 for (i = 0, segment = filedata->program_headers;
21357 i < filedata->file_header.e_phnum;
b34976b6 21358 i++, segment++)
779fe533
NC
21359 {
21360 if (segment->p_type == PT_NOTE)
dda8d76d 21361 if (! process_notes_at (filedata, NULL,
32ec8896 21362 (bfd_vma) segment->p_offset,
82ed9683
L
21363 (bfd_vma) segment->p_filesz,
21364 (bfd_vma) segment->p_align))
015dc7e1 21365 res = false;
779fe533 21366 }
103f02d3 21367
779fe533
NC
21368 return res;
21369}
21370
015dc7e1 21371static bool
dda8d76d 21372process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21373{
21374 Elf_External_Note * pnotes;
21375 Elf_External_Note * external;
c8071705 21376 char * end;
015dc7e1 21377 bool res = true;
685080f2
NC
21378
21379 if (length <= 0)
015dc7e1 21380 return false;
685080f2 21381
dda8d76d 21382 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21383 _("v850 notes"));
21384 if (pnotes == NULL)
015dc7e1 21385 return false;
685080f2
NC
21386
21387 external = pnotes;
c8071705 21388 end = (char*) pnotes + length;
685080f2
NC
21389
21390 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21391 (unsigned long) offset, (unsigned long) length);
21392
c8071705 21393 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21394 {
21395 Elf_External_Note * next;
21396 Elf_Internal_Note inote;
21397
21398 inote.type = BYTE_GET (external->type);
21399 inote.namesz = BYTE_GET (external->namesz);
21400 inote.namedata = external->name;
21401 inote.descsz = BYTE_GET (external->descsz);
21402 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21403 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21404
c8071705
NC
21405 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21406 {
21407 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21408 inote.descdata = inote.namedata;
21409 inote.namesz = 0;
21410 }
21411
685080f2
NC
21412 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21413
c8071705 21414 if ( ((char *) next > end)
685080f2
NC
21415 || ((char *) next < (char *) pnotes))
21416 {
21417 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21418 (unsigned long) ((char *) external - (char *) pnotes));
21419 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21420 inote.type, inote.namesz, inote.descsz);
21421 break;
21422 }
21423
21424 external = next;
21425
21426 /* Prevent out-of-bounds indexing. */
c8071705 21427 if ( inote.namedata + inote.namesz > end
685080f2
NC
21428 || inote.namedata + inote.namesz < inote.namedata)
21429 {
21430 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21431 (unsigned long) ((char *) external - (char *) pnotes));
21432 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21433 inote.type, inote.namesz, inote.descsz);
21434 break;
21435 }
21436
21437 printf (" %s: ", get_v850_elf_note_type (inote.type));
21438
21439 if (! print_v850_note (& inote))
21440 {
015dc7e1 21441 res = false;
685080f2
NC
21442 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21443 inote.namesz, inote.descsz);
21444 }
21445 }
21446
21447 free (pnotes);
21448
21449 return res;
21450}
21451
015dc7e1 21452static bool
dda8d76d 21453process_note_sections (Filedata * filedata)
1ec5cd37 21454{
015dc7e1 21455 Elf_Internal_Shdr *section;
1ec5cd37 21456 unsigned long i;
32ec8896 21457 unsigned int n = 0;
015dc7e1 21458 bool res = true;
1ec5cd37 21459
dda8d76d
NC
21460 for (i = 0, section = filedata->section_headers;
21461 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21462 i++, section++)
685080f2
NC
21463 {
21464 if (section->sh_type == SHT_NOTE)
21465 {
dda8d76d 21466 if (! process_notes_at (filedata, section,
32ec8896 21467 (bfd_vma) section->sh_offset,
82ed9683
L
21468 (bfd_vma) section->sh_size,
21469 (bfd_vma) section->sh_addralign))
015dc7e1 21470 res = false;
685080f2
NC
21471 n++;
21472 }
21473
dda8d76d
NC
21474 if (( filedata->file_header.e_machine == EM_V800
21475 || filedata->file_header.e_machine == EM_V850
21476 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21477 && section->sh_type == SHT_RENESAS_INFO)
21478 {
dda8d76d 21479 if (! process_v850_notes (filedata,
32ec8896
NC
21480 (bfd_vma) section->sh_offset,
21481 (bfd_vma) section->sh_size))
015dc7e1 21482 res = false;
685080f2
NC
21483 n++;
21484 }
21485 }
df565f32
NC
21486
21487 if (n == 0)
21488 /* Try processing NOTE segments instead. */
dda8d76d 21489 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21490
21491 return res;
21492}
21493
015dc7e1 21494static bool
dda8d76d 21495process_notes (Filedata * filedata)
779fe533
NC
21496{
21497 /* If we have not been asked to display the notes then do nothing. */
21498 if (! do_notes)
015dc7e1 21499 return true;
103f02d3 21500
dda8d76d
NC
21501 if (filedata->file_header.e_type != ET_CORE)
21502 return process_note_sections (filedata);
103f02d3 21503
779fe533 21504 /* No program headers means no NOTE segment. */
dda8d76d
NC
21505 if (filedata->file_header.e_phnum > 0)
21506 return process_corefile_note_segments (filedata);
779fe533 21507
ca0e11aa
NC
21508 if (filedata->is_separate)
21509 printf (_("No notes found in linked file '%s'.\n"),
21510 filedata->file_name);
21511 else
21512 printf (_("No notes found file.\n"));
21513
015dc7e1 21514 return true;
779fe533
NC
21515}
21516
60abdbed
NC
21517static unsigned char *
21518display_public_gnu_attributes (unsigned char * start,
21519 const unsigned char * const end)
21520{
21521 printf (_(" Unknown GNU attribute: %s\n"), start);
21522
21523 start += strnlen ((char *) start, end - start);
21524 display_raw_attribute (start, end);
21525
21526 return (unsigned char *) end;
21527}
21528
21529static unsigned char *
21530display_generic_attribute (unsigned char * start,
21531 unsigned int tag,
21532 const unsigned char * const end)
21533{
21534 if (tag == 0)
21535 return (unsigned char *) end;
21536
21537 return display_tag_value (tag, start, end);
21538}
21539
015dc7e1 21540static bool
dda8d76d 21541process_arch_specific (Filedata * filedata)
252b5132 21542{
a952a375 21543 if (! do_arch)
015dc7e1 21544 return true;
a952a375 21545
dda8d76d 21546 switch (filedata->file_header.e_machine)
252b5132 21547 {
53a346d8
CZ
21548 case EM_ARC:
21549 case EM_ARC_COMPACT:
21550 case EM_ARC_COMPACT2:
dda8d76d 21551 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21552 display_arc_attribute,
21553 display_generic_attribute);
11c1ff18 21554 case EM_ARM:
dda8d76d 21555 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21556 display_arm_attribute,
21557 display_generic_attribute);
21558
252b5132 21559 case EM_MIPS:
4fe85591 21560 case EM_MIPS_RS3_LE:
dda8d76d 21561 return process_mips_specific (filedata);
60abdbed
NC
21562
21563 case EM_MSP430:
dda8d76d 21564 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21565 display_msp430_attribute,
c0ea7c52 21566 display_msp430_gnu_attribute);
60abdbed 21567
2dc8dd17
JW
21568 case EM_RISCV:
21569 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21570 display_riscv_attribute,
21571 display_generic_attribute);
21572
35c08157 21573 case EM_NDS32:
dda8d76d 21574 return process_nds32_specific (filedata);
60abdbed 21575
85f7484a
PB
21576 case EM_68K:
21577 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21578 display_m68k_gnu_attribute);
21579
34c8bcba 21580 case EM_PPC:
b82317dd 21581 case EM_PPC64:
dda8d76d 21582 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21583 display_power_gnu_attribute);
21584
643f7afb
AK
21585 case EM_S390:
21586 case EM_S390_OLD:
dda8d76d 21587 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21588 display_s390_gnu_attribute);
21589
9e8c70f9
DM
21590 case EM_SPARC:
21591 case EM_SPARC32PLUS:
21592 case EM_SPARCV9:
dda8d76d 21593 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21594 display_sparc_gnu_attribute);
21595
59e6276b 21596 case EM_TI_C6000:
dda8d76d 21597 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21598 display_tic6x_attribute,
21599 display_generic_attribute);
21600
0861f561
CQ
21601 case EM_CSKY:
21602 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21603 display_csky_attribute, NULL);
21604
252b5132 21605 default:
dda8d76d 21606 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21607 display_public_gnu_attributes,
21608 display_generic_attribute);
252b5132 21609 }
252b5132
RH
21610}
21611
015dc7e1 21612static bool
dda8d76d 21613get_file_header (Filedata * filedata)
252b5132 21614{
9ea033b2 21615 /* Read in the identity array. */
dda8d76d 21616 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21617 return false;
252b5132 21618
9ea033b2 21619 /* Determine how to read the rest of the header. */
dda8d76d 21620 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21621 {
1a0670f3
AM
21622 default:
21623 case ELFDATANONE:
adab8cdc
AO
21624 case ELFDATA2LSB:
21625 byte_get = byte_get_little_endian;
21626 byte_put = byte_put_little_endian;
21627 break;
21628 case ELFDATA2MSB:
21629 byte_get = byte_get_big_endian;
21630 byte_put = byte_put_big_endian;
21631 break;
9ea033b2
NC
21632 }
21633
21634 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21635 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21636
21637 /* Read in the rest of the header. */
21638 if (is_32bit_elf)
21639 {
21640 Elf32_External_Ehdr ehdr32;
252b5132 21641
dda8d76d 21642 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21643 return false;
103f02d3 21644
dda8d76d
NC
21645 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21646 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21647 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21648 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21649 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21650 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21651 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21652 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21653 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21654 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21655 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21656 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21657 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21658 }
252b5132 21659 else
9ea033b2
NC
21660 {
21661 Elf64_External_Ehdr ehdr64;
a952a375
NC
21662
21663 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21664 we will not be able to cope with the 64bit data found in
21665 64 ELF files. Detect this now and abort before we start
50c2245b 21666 overwriting things. */
a952a375
NC
21667 if (sizeof (bfd_vma) < 8)
21668 {
e3c8793a
NC
21669 error (_("This instance of readelf has been built without support for a\n\
2167064 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21671 return false;
a952a375 21672 }
103f02d3 21673
dda8d76d 21674 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21675 return false;
103f02d3 21676
dda8d76d
NC
21677 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21678 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21679 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21680 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21681 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21682 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21683 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21684 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21685 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21686 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21687 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21688 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21689 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21690 }
252b5132 21691
015dc7e1 21692 return true;
252b5132
RH
21693}
21694
13acb58d
AM
21695static void
21696free_filedata (Filedata *filedata)
21697{
21698 free (filedata->program_interpreter);
13acb58d 21699 free (filedata->program_headers);
13acb58d 21700 free (filedata->section_headers);
13acb58d 21701 free (filedata->string_table);
13acb58d 21702 free (filedata->dump.dump_sects);
13acb58d 21703 free (filedata->dynamic_strings);
13acb58d 21704 free (filedata->dynamic_symbols);
13acb58d 21705 free (filedata->dynamic_syminfo);
13acb58d 21706 free (filedata->dynamic_section);
13acb58d
AM
21707
21708 while (filedata->symtab_shndx_list != NULL)
21709 {
21710 elf_section_list *next = filedata->symtab_shndx_list->next;
21711 free (filedata->symtab_shndx_list);
21712 filedata->symtab_shndx_list = next;
21713 }
21714
21715 free (filedata->section_headers_groups);
13acb58d
AM
21716
21717 if (filedata->section_groups)
21718 {
21719 size_t i;
21720 struct group_list * g;
21721 struct group_list * next;
21722
21723 for (i = 0; i < filedata->group_count; i++)
21724 {
21725 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21726 {
21727 next = g->next;
21728 free (g);
21729 }
21730 }
21731
21732 free (filedata->section_groups);
13acb58d 21733 }
066f8fbe
AM
21734 memset (&filedata->section_headers, 0,
21735 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
21736}
21737
dda8d76d
NC
21738static void
21739close_file (Filedata * filedata)
21740{
21741 if (filedata)
21742 {
21743 if (filedata->handle)
21744 fclose (filedata->handle);
21745 free (filedata);
21746 }
21747}
21748
21749void
21750close_debug_file (void * data)
21751{
13acb58d 21752 free_filedata ((Filedata *) data);
dda8d76d
NC
21753 close_file ((Filedata *) data);
21754}
21755
21756static Filedata *
015dc7e1 21757open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21758{
21759 struct stat statbuf;
21760 Filedata * filedata = NULL;
21761
21762 if (stat (pathname, & statbuf) < 0
21763 || ! S_ISREG (statbuf.st_mode))
21764 goto fail;
21765
21766 filedata = calloc (1, sizeof * filedata);
21767 if (filedata == NULL)
21768 goto fail;
21769
21770 filedata->handle = fopen (pathname, "rb");
21771 if (filedata->handle == NULL)
21772 goto fail;
21773
21774 filedata->file_size = (bfd_size_type) statbuf.st_size;
21775 filedata->file_name = pathname;
ca0e11aa 21776 filedata->is_separate = is_separate;
dda8d76d
NC
21777
21778 if (! get_file_header (filedata))
21779 goto fail;
21780
4de91c10
AM
21781 if (!get_section_headers (filedata, false))
21782 goto fail;
dda8d76d
NC
21783
21784 return filedata;
21785
21786 fail:
21787 if (filedata)
21788 {
21789 if (filedata->handle)
21790 fclose (filedata->handle);
21791 free (filedata);
21792 }
21793 return NULL;
21794}
21795
21796void *
21797open_debug_file (const char * pathname)
21798{
015dc7e1 21799 return open_file (pathname, true);
dda8d76d
NC
21800}
21801
835f2fae
NC
21802static void
21803initialise_dump_sects (Filedata * filedata)
21804{
21805 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21806 Note we do this even if cmdline_dump_sects is empty because we
21807 must make sure that the dump_sets array is zeroed out before each
21808 object file is processed. */
21809 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21810 memset (filedata->dump.dump_sects, 0,
21811 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21812
21813 if (cmdline.num_dump_sects > 0)
21814 {
21815 if (filedata->dump.num_dump_sects == 0)
21816 /* A sneaky way of allocating the dump_sects array. */
21817 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21818
21819 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21820 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21821 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21822 }
21823}
21824
fb52b2f4
NC
21825/* Process one ELF object file according to the command line options.
21826 This file may actually be stored in an archive. The file is
32ec8896
NC
21827 positioned at the start of the ELF object. Returns TRUE if no
21828 problems were encountered, FALSE otherwise. */
fb52b2f4 21829
015dc7e1 21830static bool
dda8d76d 21831process_object (Filedata * filedata)
252b5132 21832{
015dc7e1 21833 bool have_separate_files;
252b5132 21834 unsigned int i;
015dc7e1 21835 bool res;
252b5132 21836
dda8d76d 21837 if (! get_file_header (filedata))
252b5132 21838 {
dda8d76d 21839 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21840 return false;
252b5132
RH
21841 }
21842
21843 /* Initialise per file variables. */
978c4450
AM
21844 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21845 filedata->version_info[i] = 0;
252b5132 21846
978c4450
AM
21847 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21848 filedata->dynamic_info[i] = 0;
21849 filedata->dynamic_info_DT_GNU_HASH = 0;
21850 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21851
21852 /* Process the file. */
21853 if (show_name)
dda8d76d 21854 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21855
835f2fae 21856 initialise_dump_sects (filedata);
d70c5fc7 21857
4de91c10
AM
21858 /* There may be some extensions in the first section header. Don't
21859 bomb if we can't read it. */
21860 get_section_headers (filedata, true);
21861
dda8d76d 21862 if (! process_file_header (filedata))
4de91c10
AM
21863 {
21864 res = false;
21865 goto out;
21866 }
252b5132 21867
e331b18d
AM
21868 /* Throw away the single section header read above, so that we
21869 re-read the entire set. */
21870 free (filedata->section_headers);
21871 filedata->section_headers = NULL;
21872
dda8d76d 21873 if (! process_section_headers (filedata))
2f62977e 21874 {
32ec8896 21875 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21876 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21877
2f62977e 21878 if (! do_using_dynamic)
015dc7e1 21879 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21880 }
252b5132 21881
dda8d76d 21882 if (! process_section_groups (filedata))
32ec8896 21883 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21884 do_unwind = false;
d1f5c6e3 21885
93df3340
AM
21886 process_program_headers (filedata);
21887
21888 res = process_dynamic_section (filedata);
252b5132 21889
dda8d76d 21890 if (! process_relocs (filedata))
015dc7e1 21891 res = false;
252b5132 21892
dda8d76d 21893 if (! process_unwind (filedata))
015dc7e1 21894 res = false;
4d6ed7c8 21895
dda8d76d 21896 if (! process_symbol_table (filedata))
015dc7e1 21897 res = false;
252b5132 21898
0f03783c 21899 if (! process_lto_symbol_tables (filedata))
015dc7e1 21900 res = false;
b9e920ec 21901
dda8d76d 21902 if (! process_syminfo (filedata))
015dc7e1 21903 res = false;
252b5132 21904
dda8d76d 21905 if (! process_version_sections (filedata))
015dc7e1 21906 res = false;
252b5132 21907
82ed9683 21908 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21909 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21910 else
015dc7e1 21911 have_separate_files = false;
dda8d76d
NC
21912
21913 if (! process_section_contents (filedata))
015dc7e1 21914 res = false;
f5842774 21915
24841daa 21916 if (have_separate_files)
dda8d76d 21917 {
24841daa
NC
21918 separate_info * d;
21919
21920 for (d = first_separate_info; d != NULL; d = d->next)
21921 {
835f2fae
NC
21922 initialise_dump_sects (d->handle);
21923
ca0e11aa 21924 if (process_links && ! process_file_header (d->handle))
015dc7e1 21925 res = false;
ca0e11aa 21926 else if (! process_section_headers (d->handle))
015dc7e1 21927 res = false;
d6bfbc39 21928 else if (! process_section_contents (d->handle))
015dc7e1 21929 res = false;
ca0e11aa
NC
21930 else if (process_links)
21931 {
ca0e11aa 21932 if (! process_section_groups (d->handle))
015dc7e1 21933 res = false;
93df3340 21934 process_program_headers (d->handle);
ca0e11aa 21935 if (! process_dynamic_section (d->handle))
015dc7e1 21936 res = false;
ca0e11aa 21937 if (! process_relocs (d->handle))
015dc7e1 21938 res = false;
ca0e11aa 21939 if (! process_unwind (d->handle))
015dc7e1 21940 res = false;
ca0e11aa 21941 if (! process_symbol_table (d->handle))
015dc7e1 21942 res = false;
ca0e11aa 21943 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21944 res = false;
ca0e11aa 21945 if (! process_syminfo (d->handle))
015dc7e1 21946 res = false;
ca0e11aa 21947 if (! process_version_sections (d->handle))
015dc7e1 21948 res = false;
ca0e11aa 21949 if (! process_notes (d->handle))
015dc7e1 21950 res = false;
ca0e11aa 21951 }
24841daa
NC
21952 }
21953
21954 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21955 }
21956
21957 if (! process_notes (filedata))
015dc7e1 21958 res = false;
103f02d3 21959
dda8d76d 21960 if (! process_gnu_liblist (filedata))
015dc7e1 21961 res = false;
047b2264 21962
dda8d76d 21963 if (! process_arch_specific (filedata))
015dc7e1 21964 res = false;
252b5132 21965
4de91c10 21966 out:
13acb58d 21967 free_filedata (filedata);
e4b17d5c 21968
19e6b90e 21969 free_debug_memory ();
18bd398b 21970
32ec8896 21971 return res;
252b5132
RH
21972}
21973
2cf0635d 21974/* Process an ELF archive.
32ec8896
NC
21975 On entry the file is positioned just after the ARMAG string.
21976 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21977
015dc7e1
AM
21978static bool
21979process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
21980{
21981 struct archive_info arch;
21982 struct archive_info nested_arch;
21983 size_t got;
015dc7e1 21984 bool ret = true;
2cf0635d 21985
015dc7e1 21986 show_name = true;
2cf0635d
NC
21987
21988 /* The ARCH structure is used to hold information about this archive. */
21989 arch.file_name = NULL;
21990 arch.file = NULL;
21991 arch.index_array = NULL;
21992 arch.sym_table = NULL;
21993 arch.longnames = NULL;
21994
21995 /* The NESTED_ARCH structure is used as a single-item cache of information
21996 about a nested archive (when members of a thin archive reside within
21997 another regular archive file). */
21998 nested_arch.file_name = NULL;
21999 nested_arch.file = NULL;
22000 nested_arch.index_array = NULL;
22001 nested_arch.sym_table = NULL;
22002 nested_arch.longnames = NULL;
22003
dda8d76d 22004 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22005 filedata->file_size, is_thin_archive,
22006 do_archive_index) != 0)
2cf0635d 22007 {
015dc7e1 22008 ret = false;
2cf0635d 22009 goto out;
4145f1d5 22010 }
fb52b2f4 22011
4145f1d5
NC
22012 if (do_archive_index)
22013 {
2cf0635d 22014 if (arch.sym_table == NULL)
1cb7d8b1
AM
22015 error (_("%s: unable to dump the index as none was found\n"),
22016 filedata->file_name);
4145f1d5
NC
22017 else
22018 {
591f7597 22019 unsigned long i, l;
4145f1d5
NC
22020 unsigned long current_pos;
22021
1cb7d8b1
AM
22022 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22023 "in the symbol table)\n"),
22024 filedata->file_name, (unsigned long) arch.index_num,
22025 arch.sym_size);
dda8d76d
NC
22026
22027 current_pos = ftell (filedata->handle);
4145f1d5 22028
2cf0635d 22029 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22030 {
1cb7d8b1
AM
22031 if (i == 0
22032 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22033 {
22034 char * member_name
22035 = get_archive_member_name_at (&arch, arch.index_array[i],
22036 &nested_arch);
2cf0635d 22037
1cb7d8b1
AM
22038 if (member_name != NULL)
22039 {
22040 char * qualified_name
22041 = make_qualified_name (&arch, &nested_arch,
22042 member_name);
2cf0635d 22043
1cb7d8b1
AM
22044 if (qualified_name != NULL)
22045 {
22046 printf (_("Contents of binary %s at offset "),
22047 qualified_name);
c2a7d3f5
NC
22048 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22049 putchar ('\n');
1cb7d8b1
AM
22050 free (qualified_name);
22051 }
fd486f32 22052 free (member_name);
4145f1d5
NC
22053 }
22054 }
2cf0635d
NC
22055
22056 if (l >= arch.sym_size)
4145f1d5 22057 {
1cb7d8b1
AM
22058 error (_("%s: end of the symbol table reached "
22059 "before the end of the index\n"),
dda8d76d 22060 filedata->file_name);
015dc7e1 22061 ret = false;
cb8f3167 22062 break;
4145f1d5 22063 }
591f7597 22064 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22065 printf ("\t%.*s\n",
22066 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22067 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22068 }
22069
67ce483b 22070 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22071 l = (l + 7) & ~ 7;
22072 else
22073 l += l & 1;
22074
2cf0635d 22075 if (l < arch.sym_size)
32ec8896 22076 {
d3a49aa8
AM
22077 error (ngettext ("%s: %ld byte remains in the symbol table, "
22078 "but without corresponding entries in "
22079 "the index table\n",
22080 "%s: %ld bytes remain in the symbol table, "
22081 "but without corresponding entries in "
22082 "the index table\n",
22083 arch.sym_size - l),
dda8d76d 22084 filedata->file_name, arch.sym_size - l);
015dc7e1 22085 ret = false;
32ec8896 22086 }
4145f1d5 22087
dda8d76d 22088 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22089 {
1cb7d8b1
AM
22090 error (_("%s: failed to seek back to start of object files "
22091 "in the archive\n"),
dda8d76d 22092 filedata->file_name);
015dc7e1 22093 ret = false;
2cf0635d 22094 goto out;
4145f1d5 22095 }
fb52b2f4 22096 }
4145f1d5
NC
22097
22098 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22099 && !do_segments && !do_header && !do_dump && !do_version
22100 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22101 && !do_section_groups && !do_dyn_syms)
2cf0635d 22102 {
015dc7e1 22103 ret = true; /* Archive index only. */
2cf0635d
NC
22104 goto out;
22105 }
fb52b2f4
NC
22106 }
22107
fb52b2f4
NC
22108 while (1)
22109 {
2cf0635d
NC
22110 char * name;
22111 size_t namelen;
22112 char * qualified_name;
22113
22114 /* Read the next archive header. */
dda8d76d 22115 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22116 {
22117 error (_("%s: failed to seek to next archive header\n"),
22118 arch.file_name);
015dc7e1 22119 ret = false;
1cb7d8b1
AM
22120 break;
22121 }
dda8d76d 22122 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22123 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22124 {
22125 if (got == 0)
2cf0635d 22126 break;
28e817cc
NC
22127 /* PR 24049 - we cannot use filedata->file_name as this will
22128 have already been freed. */
22129 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22130
015dc7e1 22131 ret = false;
1cb7d8b1
AM
22132 break;
22133 }
2cf0635d 22134 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22135 {
22136 error (_("%s: did not find a valid archive header\n"),
22137 arch.file_name);
015dc7e1 22138 ret = false;
1cb7d8b1
AM
22139 break;
22140 }
2cf0635d
NC
22141
22142 arch.next_arhdr_offset += sizeof arch.arhdr;
22143
978c4450 22144 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22145
22146 name = get_archive_member_name (&arch, &nested_arch);
22147 if (name == NULL)
fb52b2f4 22148 {
28e817cc 22149 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22150 ret = false;
d989285c 22151 break;
fb52b2f4 22152 }
2cf0635d 22153 namelen = strlen (name);
fb52b2f4 22154
2cf0635d
NC
22155 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22156 if (qualified_name == NULL)
fb52b2f4 22157 {
28e817cc 22158 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22159 free (name);
015dc7e1 22160 ret = false;
d989285c 22161 break;
fb52b2f4
NC
22162 }
22163
2cf0635d 22164 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22165 {
22166 /* This is a proxy for an external member of a thin archive. */
22167 Filedata * member_filedata;
22168 char * member_file_name = adjust_relative_path
dda8d76d 22169 (filedata->file_name, name, namelen);
32ec8896 22170
fd486f32 22171 free (name);
1cb7d8b1
AM
22172 if (member_file_name == NULL)
22173 {
fd486f32 22174 free (qualified_name);
015dc7e1 22175 ret = false;
1cb7d8b1
AM
22176 break;
22177 }
2cf0635d 22178
015dc7e1 22179 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22180 if (member_filedata == NULL)
22181 {
22182 error (_("Input file '%s' is not readable.\n"), member_file_name);
22183 free (member_file_name);
fd486f32 22184 free (qualified_name);
015dc7e1 22185 ret = false;
1cb7d8b1
AM
22186 break;
22187 }
2cf0635d 22188
978c4450 22189 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22190 member_filedata->file_name = qualified_name;
2cf0635d 22191
75a2da57
AH
22192 /* The call to process_object() expects the file to be at the beginning. */
22193 rewind (member_filedata->handle);
22194
1cb7d8b1 22195 if (! process_object (member_filedata))
015dc7e1 22196 ret = false;
2cf0635d 22197
1cb7d8b1
AM
22198 close_file (member_filedata);
22199 free (member_file_name);
1cb7d8b1 22200 }
2cf0635d 22201 else if (is_thin_archive)
1cb7d8b1
AM
22202 {
22203 Filedata thin_filedata;
eb02c04d 22204
1cb7d8b1 22205 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22206
a043396b
NC
22207 /* PR 15140: Allow for corrupt thin archives. */
22208 if (nested_arch.file == NULL)
22209 {
22210 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22211 qualified_name, name);
fd486f32
AM
22212 free (qualified_name);
22213 free (name);
015dc7e1 22214 ret = false;
a043396b
NC
22215 break;
22216 }
fd486f32 22217 free (name);
a043396b 22218
1cb7d8b1 22219 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22220 filedata->archive_file_offset
22221 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22222
1cb7d8b1
AM
22223 /* The nested archive file will have been opened and setup by
22224 get_archive_member_name. */
978c4450
AM
22225 if (fseek (nested_arch.file, filedata->archive_file_offset,
22226 SEEK_SET) != 0)
1cb7d8b1
AM
22227 {
22228 error (_("%s: failed to seek to archive member.\n"),
22229 nested_arch.file_name);
fd486f32 22230 free (qualified_name);
015dc7e1 22231 ret = false;
1cb7d8b1
AM
22232 break;
22233 }
2cf0635d 22234
dda8d76d
NC
22235 thin_filedata.handle = nested_arch.file;
22236 thin_filedata.file_name = qualified_name;
9abca702 22237
1cb7d8b1 22238 if (! process_object (& thin_filedata))
015dc7e1 22239 ret = false;
1cb7d8b1 22240 }
2cf0635d 22241 else
1cb7d8b1 22242 {
fd486f32 22243 free (name);
978c4450 22244 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22245 filedata->file_name = qualified_name;
1cb7d8b1 22246 if (! process_object (filedata))
015dc7e1 22247 ret = false;
237877b8 22248 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22249 /* Stop looping with "negative" archive_file_size. */
978c4450 22250 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22251 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22252 }
fb52b2f4 22253
2cf0635d 22254 free (qualified_name);
fb52b2f4
NC
22255 }
22256
4145f1d5 22257 out:
2cf0635d
NC
22258 if (nested_arch.file != NULL)
22259 fclose (nested_arch.file);
22260 release_archive (&nested_arch);
22261 release_archive (&arch);
fb52b2f4 22262
d989285c 22263 return ret;
fb52b2f4
NC
22264}
22265
015dc7e1 22266static bool
2cf0635d 22267process_file (char * file_name)
fb52b2f4 22268{
dda8d76d 22269 Filedata * filedata = NULL;
fb52b2f4
NC
22270 struct stat statbuf;
22271 char armag[SARMAG];
015dc7e1 22272 bool ret = true;
fb52b2f4
NC
22273
22274 if (stat (file_name, &statbuf) < 0)
22275 {
f24ddbdd
NC
22276 if (errno == ENOENT)
22277 error (_("'%s': No such file\n"), file_name);
22278 else
22279 error (_("Could not locate '%s'. System error message: %s\n"),
22280 file_name, strerror (errno));
015dc7e1 22281 return false;
f24ddbdd
NC
22282 }
22283
22284 if (! S_ISREG (statbuf.st_mode))
22285 {
22286 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22287 return false;
fb52b2f4
NC
22288 }
22289
dda8d76d
NC
22290 filedata = calloc (1, sizeof * filedata);
22291 if (filedata == NULL)
22292 {
22293 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22294 return false;
dda8d76d
NC
22295 }
22296
22297 filedata->file_name = file_name;
22298 filedata->handle = fopen (file_name, "rb");
22299 if (filedata->handle == NULL)
fb52b2f4 22300 {
f24ddbdd 22301 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22302 free (filedata);
015dc7e1 22303 return false;
fb52b2f4
NC
22304 }
22305
dda8d76d 22306 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22307 {
4145f1d5 22308 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22309 fclose (filedata->handle);
22310 free (filedata);
015dc7e1 22311 return false;
fb52b2f4
NC
22312 }
22313
dda8d76d 22314 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 22315 filedata->is_separate = false;
f54498b4 22316
fb52b2f4 22317 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22318 {
015dc7e1
AM
22319 if (! process_archive (filedata, false))
22320 ret = false;
32ec8896 22321 }
2cf0635d 22322 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22323 {
015dc7e1
AM
22324 if ( ! process_archive (filedata, true))
22325 ret = false;
32ec8896 22326 }
fb52b2f4
NC
22327 else
22328 {
1b513401 22329 if (do_archive_index && !check_all)
4145f1d5
NC
22330 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22331 file_name);
22332
dda8d76d 22333 rewind (filedata->handle);
978c4450 22334 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22335
dda8d76d 22336 if (! process_object (filedata))
015dc7e1 22337 ret = false;
fb52b2f4
NC
22338 }
22339
dda8d76d 22340 fclose (filedata->handle);
8fb879cd
AM
22341 free (filedata->section_headers);
22342 free (filedata->program_headers);
22343 free (filedata->string_table);
6431e409 22344 free (filedata->dump.dump_sects);
dda8d76d 22345 free (filedata);
32ec8896 22346
fd486f32 22347 free (ba_cache.strtab);
1bd6175a 22348 ba_cache.strtab = NULL;
fd486f32 22349 free (ba_cache.symtab);
1bd6175a 22350 ba_cache.symtab = NULL;
fd486f32
AM
22351 ba_cache.filedata = NULL;
22352
fb52b2f4
NC
22353 return ret;
22354}
22355
252b5132
RH
22356#ifdef SUPPORT_DISASSEMBLY
22357/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22358 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22359 symbols. */
252b5132
RH
22360
22361void
2cf0635d 22362print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22363{
22364 fprintf (outfile,"0x%8.8x", addr);
22365}
22366
e3c8793a 22367/* Needed by the i386 disassembler. */
dda8d76d 22368
252b5132
RH
22369void
22370db_task_printsym (unsigned int addr)
22371{
22372 print_address (addr, stderr);
22373}
22374#endif
22375
22376int
2cf0635d 22377main (int argc, char ** argv)
252b5132 22378{
ff78d6d6
L
22379 int err;
22380
87b9f255 22381#ifdef HAVE_LC_MESSAGES
252b5132 22382 setlocale (LC_MESSAGES, "");
3882b010 22383#endif
3882b010 22384 setlocale (LC_CTYPE, "");
252b5132
RH
22385 bindtextdomain (PACKAGE, LOCALEDIR);
22386 textdomain (PACKAGE);
22387
869b9d07
MM
22388 expandargv (&argc, &argv);
22389
dda8d76d 22390 parse_args (& cmdline, argc, argv);
59f14fc0 22391
18bd398b 22392 if (optind < (argc - 1))
1b513401
NC
22393 /* When displaying information for more than one file,
22394 prefix the information with the file name. */
015dc7e1 22395 show_name = true;
5656ba2c
L
22396 else if (optind >= argc)
22397 {
1b513401 22398 /* Ensure that the warning is always displayed. */
015dc7e1 22399 do_checks = true;
1b513401 22400
5656ba2c
L
22401 warn (_("Nothing to do.\n"));
22402 usage (stderr);
22403 }
18bd398b 22404
015dc7e1 22405 err = false;
252b5132 22406 while (optind < argc)
32ec8896 22407 if (! process_file (argv[optind++]))
015dc7e1 22408 err = true;
252b5132 22409
9db70fc3 22410 free (cmdline.dump_sects);
252b5132 22411
7d9813f1
NA
22412 free (dump_ctf_symtab_name);
22413 free (dump_ctf_strtab_name);
22414 free (dump_ctf_parent_name);
22415
32ec8896 22416 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22417}