]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
readelf: cmdline data
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
b3adc24a 2 Copyright (C) 1998-2020 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>
3bfcb652 47#ifdef HAVE_WCHAR_H
7bfd842d 48#include <wchar.h>
3bfcb652 49#endif
252b5132 50
a952a375 51#if __GNUC__ >= 2
19936277 52/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 53 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 54 Only do this if we believe that the compiler can support a 64 bit
a952a375 55 data type. For now we only rely on GCC being able to do this. */
19936277 56#define BFD64
a952a375
NC
57#endif
58
3db64b00
AM
59#include "bfd.h"
60#include "bucomm.h"
3284fe0c 61#include "elfcomm.h"
19e6b90e 62#include "dwarf.h"
7d9813f1 63#include "ctf-api.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"
252b5132 166
252b5132 167#include "getopt.h"
566b0d53 168#include "libiberty.h"
09c11c86 169#include "safe-ctype.h"
2cf0635d 170#include "filenames.h"
252b5132 171
15b42fb0
AM
172#ifndef offsetof
173#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
174#endif
175
6a40cf0c
NC
176typedef struct elf_section_list
177{
dda8d76d
NC
178 Elf_Internal_Shdr * hdr;
179 struct elf_section_list * next;
6a40cf0c
NC
180} elf_section_list;
181
dda8d76d
NC
182/* Flag bits indicating particular types of dump. */
183#define HEX_DUMP (1 << 0) /* The -x command line switch. */
184#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
185#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
186#define STRING_DUMP (1 << 3) /* The -p command line switch. */
187#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 188#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
189
190typedef unsigned char dump_type;
191
192/* A linked list of the section names for which dumps were requested. */
193struct dump_list_entry
194{
195 char * name;
196 dump_type type;
197 struct dump_list_entry * next;
198};
199
6431e409
AM
200/* A dynamic array of flags indicating for which sections a dump
201 has been requested via command line switches. */
202struct dump_data {
203 dump_type * dump_sects;
204 unsigned int num_dump_sects;
205};
206
207static struct dump_data cmdline;
208
209static struct dump_list_entry * dump_sects_byname;
210
dda8d76d
NC
211typedef struct filedata
212{
213 const char * file_name;
214 FILE * handle;
215 bfd_size_type file_size;
216 Elf_Internal_Ehdr file_header;
217 Elf_Internal_Shdr * section_headers;
218 Elf_Internal_Phdr * program_headers;
219 char * string_table;
220 unsigned long string_table_length;
221 /* A dynamic array of flags indicating for which sections a dump of
222 some kind has been requested. It is reset on a per-object file
223 basis and then initialised from the cmdline_dump_sects array,
224 the results of interpreting the -w switch, and the
225 dump_sects_byname list. */
6431e409 226 struct dump_data dump;
dda8d76d
NC
227} Filedata;
228
2cf0635d 229char * program_name = "readelf";
dda8d76d 230
c9c1d674 231static unsigned long archive_file_offset;
85b1c36d
BE
232static unsigned long archive_file_size;
233static unsigned long dynamic_addr;
234static bfd_size_type dynamic_size;
8b73c356 235static size_t dynamic_nent;
2cf0635d 236static char * dynamic_strings;
85b1c36d 237static unsigned long dynamic_strings_length;
85b1c36d 238static unsigned long num_dynamic_syms;
10ca4b04
L
239static bfd_size_type nbuckets;
240static bfd_size_type nchains;
241static bfd_vma *buckets;
242static bfd_vma *chains;
243static bfd_vma ngnubuckets;
244static bfd_vma *gnubuckets;
245static bfd_vma *gnuchains;
246static bfd_vma *mipsxlat;
247static bfd_size_type ngnuchains;
248static bfd_vma gnusymidx;
2cf0635d
NC
249static Elf_Internal_Sym * dynamic_symbols;
250static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
251static unsigned long dynamic_syminfo_offset;
252static unsigned int dynamic_syminfo_nent;
f8eae8b2 253static char program_interpreter[PATH_MAX];
bb8a0291 254static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 255static bfd_vma dynamic_info_DT_GNU_HASH;
f16a9783 256static bfd_vma dynamic_info_DT_MIPS_XHASH;
85b1c36d 257static bfd_vma version_info[16];
2cf0635d 258static Elf_Internal_Dyn * dynamic_section;
6a40cf0c 259static elf_section_list * symtab_shndx_list;
32ec8896
NC
260static bfd_boolean show_name = FALSE;
261static bfd_boolean do_dynamic = FALSE;
262static bfd_boolean do_syms = FALSE;
263static bfd_boolean do_dyn_syms = FALSE;
264static bfd_boolean do_reloc = FALSE;
265static bfd_boolean do_sections = FALSE;
266static bfd_boolean do_section_groups = FALSE;
267static bfd_boolean do_section_details = FALSE;
268static bfd_boolean do_segments = FALSE;
269static bfd_boolean do_unwind = FALSE;
270static bfd_boolean do_using_dynamic = FALSE;
271static bfd_boolean do_header = FALSE;
272static bfd_boolean do_dump = FALSE;
273static bfd_boolean do_version = FALSE;
274static bfd_boolean do_histogram = FALSE;
275static bfd_boolean do_debugging = FALSE;
7d9813f1 276static bfd_boolean do_ctf = FALSE;
32ec8896
NC
277static bfd_boolean do_arch = FALSE;
278static bfd_boolean do_notes = FALSE;
279static bfd_boolean do_archive_index = FALSE;
280static bfd_boolean is_32bit_elf = FALSE;
281static bfd_boolean decompress_dumps = FALSE;
252b5132 282
7d9813f1
NA
283static char *dump_ctf_parent_name;
284static char *dump_ctf_symtab_name;
285static char *dump_ctf_strtab_name;
286
e4b17d5c
L
287struct group_list
288{
dda8d76d
NC
289 struct group_list * next;
290 unsigned int section_index;
e4b17d5c
L
291};
292
293struct group
294{
dda8d76d
NC
295 struct group_list * root;
296 unsigned int group_index;
e4b17d5c
L
297};
298
dda8d76d
NC
299static size_t group_count;
300static struct group * section_groups;
301static struct group ** section_headers_groups;
aef1f6d0 302
c256ffe7 303/* How to print a vma value. */
843dd992
NC
304typedef enum print_mode
305{
306 HEX,
307 DEC,
308 DEC_5,
309 UNSIGNED,
310 PREFIX_HEX,
311 FULL_HEX,
312 LONG_HEX
313}
314print_mode;
315
bb4d2ac2
L
316/* Versioned symbol info. */
317enum versioned_symbol_info
318{
319 symbol_undefined,
320 symbol_hidden,
321 symbol_public
322};
323
32ec8896 324static const char * get_symbol_version_string
dda8d76d 325 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 326 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 327
9c19a809
NC
328#define UNKNOWN -1
329
2b692964
NC
330#define SECTION_NAME(X) \
331 ((X) == NULL ? _("<none>") \
dda8d76d
NC
332 : filedata->string_table == NULL ? _("<no-strings>") \
333 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
334 : filedata->string_table + (X)->sh_name))
252b5132 335
ee42cf8c 336#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 337
ba5cdace
NC
338#define GET_ELF_SYMBOLS(file, section, sym_count) \
339 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
340 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 341
10ca4b04
L
342#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
343 (strtab != NULL && offset < strtab_size)
344#define VALID_DYNAMIC_NAME(offset) \
345 VALID_SYMBOL_NAME (dynamic_strings, dynamic_strings_length, offset)
d79b3d50
NC
346/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
347 already been called and verified that the string exists. */
348#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 349
61865e30
NC
350#define REMOVE_ARCH_BITS(ADDR) \
351 do \
352 { \
dda8d76d 353 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
354 (ADDR) &= ~1; \
355 } \
356 while (0)
f16a9783
MS
357
358/* Get the correct GNU hash section name. */
359#define GNU_HASH_SECTION_NAME \
360 dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 361\f
66cfc0fd
AM
362/* Print a BFD_VMA to an internal buffer, for use in error messages.
363 BFD_FMA_FMT can't be used in translated strings. */
364
365static const char *
366bfd_vmatoa (char *fmtch, bfd_vma value)
367{
368 /* bfd_vmatoa is used more then once in a printf call for output.
369 Cycle through an array of buffers. */
370 static int buf_pos = 0;
371 static struct bfd_vmatoa_buf
372 {
373 char place[64];
374 } buf[4];
375 char *ret;
376 char fmt[32];
377
378 ret = buf[buf_pos++].place;
379 buf_pos %= ARRAY_SIZE (buf);
380
381 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
382 snprintf (ret, sizeof (buf[0].place), fmt, value);
383 return ret;
384}
385
dda8d76d
NC
386/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
387 OFFSET + the offset of the current archive member, if we are examining an
388 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
389 allocate a buffer using malloc and fill that. In either case return the
390 pointer to the start of the retrieved data or NULL if something went wrong.
391 If something does go wrong and REASON is not NULL then emit an error
392 message using REASON as part of the context. */
59245841 393
c256ffe7 394static void *
dda8d76d
NC
395get_data (void * var,
396 Filedata * filedata,
397 unsigned long offset,
398 bfd_size_type size,
399 bfd_size_type nmemb,
400 const char * reason)
a6e9f9df 401{
2cf0635d 402 void * mvar;
57028622 403 bfd_size_type amt = size * nmemb;
a6e9f9df 404
c256ffe7 405 if (size == 0 || nmemb == 0)
a6e9f9df
AM
406 return NULL;
407
57028622
NC
408 /* If the size_t type is smaller than the bfd_size_type, eg because
409 you are building a 32-bit tool on a 64-bit host, then make sure
410 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
411 if ((size_t) size != size
412 || (size_t) nmemb != nmemb
413 || (size_t) amt != amt)
57028622
NC
414 {
415 if (reason)
66cfc0fd
AM
416 error (_("Size truncation prevents reading %s"
417 " elements of size %s for %s\n"),
418 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
419 return NULL;
420 }
421
422 /* Check for size overflow. */
7c1c1904 423 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
424 {
425 if (reason)
66cfc0fd
AM
426 error (_("Size overflow prevents reading %s"
427 " elements of size %s for %s\n"),
428 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
429 return NULL;
430 }
431
c22b42ce 432 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 433 attempting to allocate memory when the read is bound to fail. */
c22b42ce
AM
434 if (archive_file_offset > filedata->file_size
435 || offset > filedata->file_size - archive_file_offset
436 || amt > filedata->file_size - archive_file_offset - offset)
a6e9f9df 437 {
049b0c3a 438 if (reason)
66cfc0fd
AM
439 error (_("Reading %s bytes extends past end of file for %s\n"),
440 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
441 return NULL;
442 }
443
dda8d76d 444 if (fseek (filedata->handle, archive_file_offset + offset, SEEK_SET))
071436c6
NC
445 {
446 if (reason)
c9c1d674 447 error (_("Unable to seek to 0x%lx for %s\n"),
ed754a13 448 archive_file_offset + offset, reason);
071436c6
NC
449 return NULL;
450 }
451
a6e9f9df
AM
452 mvar = var;
453 if (mvar == NULL)
454 {
7c1c1904
AM
455 /* + 1 so that we can '\0' terminate invalid string table sections. */
456 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
457
458 if (mvar == NULL)
459 {
049b0c3a 460 if (reason)
66cfc0fd
AM
461 error (_("Out of memory allocating %s bytes for %s\n"),
462 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
463 return NULL;
464 }
c256ffe7 465
c9c1d674 466 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
467 }
468
dda8d76d 469 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 470 {
049b0c3a 471 if (reason)
66cfc0fd
AM
472 error (_("Unable to read in %s bytes of %s\n"),
473 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
474 if (mvar != var)
475 free (mvar);
476 return NULL;
477 }
478
479 return mvar;
480}
481
32ec8896
NC
482/* Print a VMA value in the MODE specified.
483 Returns the number of characters displayed. */
cb8f3167 484
32ec8896 485static unsigned int
14a91970 486print_vma (bfd_vma vma, print_mode mode)
66543521 487{
32ec8896 488 unsigned int nc = 0;
66543521 489
14a91970 490 switch (mode)
66543521 491 {
14a91970
AM
492 case FULL_HEX:
493 nc = printf ("0x");
1a0670f3 494 /* Fall through. */
14a91970 495 case LONG_HEX:
f7a99963 496#ifdef BFD64
14a91970 497 if (is_32bit_elf)
437c2fb7 498 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 499#endif
14a91970
AM
500 printf_vma (vma);
501 return nc + 16;
b19aac67 502
14a91970
AM
503 case DEC_5:
504 if (vma <= 99999)
505 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 506 /* Fall through. */
14a91970
AM
507 case PREFIX_HEX:
508 nc = printf ("0x");
1a0670f3 509 /* Fall through. */
14a91970
AM
510 case HEX:
511 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 512
14a91970
AM
513 case DEC:
514 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 515
14a91970
AM
516 case UNSIGNED:
517 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
518
519 default:
520 /* FIXME: Report unrecognised mode ? */
521 return 0;
f7a99963 522 }
f7a99963
NC
523}
524
7bfd842d 525/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 526 multibye characters (assuming the host environment supports them).
31104126 527
7bfd842d
NC
528 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
529
530 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
531 padding as necessary.
171191ba
NC
532
533 Returns the number of emitted characters. */
534
535static unsigned int
32ec8896 536print_symbol (signed int width, const char *symbol)
31104126 537{
171191ba 538 bfd_boolean extra_padding = FALSE;
32ec8896 539 signed int num_printed = 0;
3bfcb652 540#ifdef HAVE_MBSTATE_T
7bfd842d 541 mbstate_t state;
3bfcb652 542#endif
32ec8896 543 unsigned int width_remaining;
961c521f 544
7bfd842d 545 if (width < 0)
961c521f 546 {
88305e1b 547 /* Keep the width positive. This helps the code below. */
961c521f 548 width = - width;
171191ba 549 extra_padding = TRUE;
0b4362b0 550 }
56d8f8a9
NC
551 else if (width == 0)
552 return 0;
961c521f 553
7bfd842d
NC
554 if (do_wide)
555 /* Set the remaining width to a very large value.
556 This simplifies the code below. */
557 width_remaining = INT_MAX;
558 else
559 width_remaining = width;
cb8f3167 560
3bfcb652 561#ifdef HAVE_MBSTATE_T
7bfd842d
NC
562 /* Initialise the multibyte conversion state. */
563 memset (& state, 0, sizeof (state));
3bfcb652 564#endif
961c521f 565
7bfd842d
NC
566 while (width_remaining)
567 {
568 size_t n;
7bfd842d 569 const char c = *symbol++;
961c521f 570
7bfd842d 571 if (c == 0)
961c521f
NC
572 break;
573
7bfd842d
NC
574 /* Do not print control characters directly as they can affect terminal
575 settings. Such characters usually appear in the names generated
576 by the assembler for local labels. */
577 if (ISCNTRL (c))
961c521f 578 {
7bfd842d 579 if (width_remaining < 2)
961c521f
NC
580 break;
581
7bfd842d
NC
582 printf ("^%c", c + 0x40);
583 width_remaining -= 2;
171191ba 584 num_printed += 2;
961c521f 585 }
7bfd842d
NC
586 else if (ISPRINT (c))
587 {
588 putchar (c);
589 width_remaining --;
590 num_printed ++;
591 }
961c521f
NC
592 else
593 {
3bfcb652
NC
594#ifdef HAVE_MBSTATE_T
595 wchar_t w;
596#endif
7bfd842d
NC
597 /* Let printf do the hard work of displaying multibyte characters. */
598 printf ("%.1s", symbol - 1);
599 width_remaining --;
600 num_printed ++;
601
3bfcb652 602#ifdef HAVE_MBSTATE_T
7bfd842d
NC
603 /* Try to find out how many bytes made up the character that was
604 just printed. Advance the symbol pointer past the bytes that
605 were displayed. */
606 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
607#else
608 n = 1;
609#endif
7bfd842d
NC
610 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
611 symbol += (n - 1);
961c521f 612 }
961c521f 613 }
171191ba 614
7bfd842d 615 if (extra_padding && num_printed < width)
171191ba
NC
616 {
617 /* Fill in the remaining spaces. */
7bfd842d
NC
618 printf ("%-*s", width - num_printed, " ");
619 num_printed = width;
171191ba
NC
620 }
621
622 return num_printed;
31104126
NC
623}
624
1449284b 625/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
626 the given section's name. Like print_symbol, except that it does not try
627 to print multibyte characters, it just interprets them as hex values. */
628
629static const char *
dda8d76d 630printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
631{
632#define MAX_PRINT_SEC_NAME_LEN 128
633 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
634 const char * name = SECTION_NAME (sec);
635 char * buf = sec_name_buf;
636 char c;
637 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
638
639 while ((c = * name ++) != 0)
640 {
641 if (ISCNTRL (c))
642 {
643 if (remaining < 2)
644 break;
948f632f 645
74e1a04b
NC
646 * buf ++ = '^';
647 * buf ++ = c + 0x40;
648 remaining -= 2;
649 }
650 else if (ISPRINT (c))
651 {
652 * buf ++ = c;
653 remaining -= 1;
654 }
655 else
656 {
657 static char hex[17] = "0123456789ABCDEF";
658
659 if (remaining < 4)
660 break;
661 * buf ++ = '<';
662 * buf ++ = hex[(c & 0xf0) >> 4];
663 * buf ++ = hex[c & 0x0f];
664 * buf ++ = '>';
665 remaining -= 4;
666 }
667
668 if (remaining == 0)
669 break;
670 }
671
672 * buf = 0;
673 return sec_name_buf;
674}
675
676static const char *
dda8d76d 677printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 678{
dda8d76d 679 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
680 return _("<corrupt>");
681
dda8d76d 682 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
683}
684
89fac5e3
RS
685/* Return a pointer to section NAME, or NULL if no such section exists. */
686
687static Elf_Internal_Shdr *
dda8d76d 688find_section (Filedata * filedata, const char * name)
89fac5e3
RS
689{
690 unsigned int i;
691
68807c3c
NC
692 if (filedata->section_headers == NULL)
693 return NULL;
dda8d76d
NC
694
695 for (i = 0; i < filedata->file_header.e_shnum; i++)
696 if (streq (SECTION_NAME (filedata->section_headers + i), name))
697 return filedata->section_headers + i;
89fac5e3
RS
698
699 return NULL;
700}
701
0b6ae522
DJ
702/* Return a pointer to a section containing ADDR, or NULL if no such
703 section exists. */
704
705static Elf_Internal_Shdr *
dda8d76d 706find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
707{
708 unsigned int i;
709
68807c3c
NC
710 if (filedata->section_headers == NULL)
711 return NULL;
712
dda8d76d 713 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 714 {
dda8d76d
NC
715 Elf_Internal_Shdr *sec = filedata->section_headers + i;
716
0b6ae522
DJ
717 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
718 return sec;
719 }
720
721 return NULL;
722}
723
071436c6 724static Elf_Internal_Shdr *
dda8d76d 725find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
726{
727 unsigned int i;
728
68807c3c
NC
729 if (filedata->section_headers == NULL)
730 return NULL;
731
dda8d76d 732 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 733 {
dda8d76d
NC
734 Elf_Internal_Shdr *sec = filedata->section_headers + i;
735
071436c6
NC
736 if (sec->sh_type == type)
737 return sec;
738 }
739
740 return NULL;
741}
742
657d0d47
CC
743/* Return a pointer to section NAME, or NULL if no such section exists,
744 restricted to the list of sections given in SET. */
745
746static Elf_Internal_Shdr *
dda8d76d 747find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
748{
749 unsigned int i;
750
68807c3c
NC
751 if (filedata->section_headers == NULL)
752 return NULL;
753
657d0d47
CC
754 if (set != NULL)
755 {
756 while ((i = *set++) > 0)
b814a36d
NC
757 {
758 /* See PR 21156 for a reproducer. */
dda8d76d 759 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
760 continue; /* FIXME: Should we issue an error message ? */
761
dda8d76d
NC
762 if (streq (SECTION_NAME (filedata->section_headers + i), name))
763 return filedata->section_headers + i;
b814a36d 764 }
657d0d47
CC
765 }
766
dda8d76d 767 return find_section (filedata, name);
657d0d47
CC
768}
769
32ec8896 770/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
771 This OS has so many departures from the ELF standard that we test it at
772 many places. */
773
32ec8896 774static inline bfd_boolean
dda8d76d 775is_ia64_vms (Filedata * filedata)
28f997cf 776{
dda8d76d
NC
777 return filedata->file_header.e_machine == EM_IA_64
778 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
779}
780
bcedfee6 781/* Guess the relocation size commonly used by the specific machines. */
252b5132 782
32ec8896 783static bfd_boolean
2dc4cec1 784guess_is_rela (unsigned int e_machine)
252b5132 785{
9c19a809 786 switch (e_machine)
252b5132
RH
787 {
788 /* Targets that use REL relocations. */
252b5132 789 case EM_386:
22abe556 790 case EM_IAMCU:
f954747f 791 case EM_960:
e9f53129 792 case EM_ARM:
2b0337b0 793 case EM_D10V:
252b5132 794 case EM_CYGNUS_D10V:
e9f53129 795 case EM_DLX:
252b5132 796 case EM_MIPS:
4fe85591 797 case EM_MIPS_RS3_LE:
e9f53129 798 case EM_CYGNUS_M32R:
1c0d3aa6 799 case EM_SCORE:
f6c1a2d5 800 case EM_XGATE:
fe944acf 801 case EM_NFP:
aca4efc7 802 case EM_BPF:
9c19a809 803 return FALSE;
103f02d3 804
252b5132
RH
805 /* Targets that use RELA relocations. */
806 case EM_68K:
f954747f 807 case EM_860:
a06ea964 808 case EM_AARCH64:
cfb8c092 809 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
810 case EM_ALPHA:
811 case EM_ALTERA_NIOS2:
886a2506
NC
812 case EM_ARC:
813 case EM_ARC_COMPACT:
814 case EM_ARC_COMPACT2:
e9f53129
AM
815 case EM_AVR:
816 case EM_AVR_OLD:
817 case EM_BLACKFIN:
60bca95a 818 case EM_CR16:
e9f53129
AM
819 case EM_CRIS:
820 case EM_CRX:
b8891f8d 821 case EM_CSKY:
2b0337b0 822 case EM_D30V:
252b5132 823 case EM_CYGNUS_D30V:
2b0337b0 824 case EM_FR30:
3f8107ab 825 case EM_FT32:
252b5132 826 case EM_CYGNUS_FR30:
5c70f934 827 case EM_CYGNUS_FRV:
e9f53129
AM
828 case EM_H8S:
829 case EM_H8_300:
830 case EM_H8_300H:
800eeca4 831 case EM_IA_64:
1e4cf259
NC
832 case EM_IP2K:
833 case EM_IP2K_OLD:
3b36097d 834 case EM_IQ2000:
84e94c90 835 case EM_LATTICEMICO32:
ff7eeb89 836 case EM_M32C_OLD:
49f58d10 837 case EM_M32C:
e9f53129
AM
838 case EM_M32R:
839 case EM_MCORE:
15ab5209 840 case EM_CYGNUS_MEP:
a3c62988 841 case EM_METAG:
e9f53129
AM
842 case EM_MMIX:
843 case EM_MN10200:
844 case EM_CYGNUS_MN10200:
845 case EM_MN10300:
846 case EM_CYGNUS_MN10300:
5506d11a 847 case EM_MOXIE:
e9f53129
AM
848 case EM_MSP430:
849 case EM_MSP430_OLD:
d031aafb 850 case EM_MT:
35c08157 851 case EM_NDS32:
64fd6348 852 case EM_NIOS32:
73589c9d 853 case EM_OR1K:
e9f53129
AM
854 case EM_PPC64:
855 case EM_PPC:
2b100bb5 856 case EM_TI_PRU:
e23eba97 857 case EM_RISCV:
99c513f6 858 case EM_RL78:
c7927a3c 859 case EM_RX:
e9f53129
AM
860 case EM_S390:
861 case EM_S390_OLD:
862 case EM_SH:
863 case EM_SPARC:
864 case EM_SPARC32PLUS:
865 case EM_SPARCV9:
866 case EM_SPU:
40b36596 867 case EM_TI_C6000:
aa137e4d
NC
868 case EM_TILEGX:
869 case EM_TILEPRO:
708e2187 870 case EM_V800:
e9f53129
AM
871 case EM_V850:
872 case EM_CYGNUS_V850:
873 case EM_VAX:
619ed720 874 case EM_VISIUM:
e9f53129 875 case EM_X86_64:
8a9036a4 876 case EM_L1OM:
7a9068fe 877 case EM_K1OM:
e9f53129
AM
878 case EM_XSTORMY16:
879 case EM_XTENSA:
880 case EM_XTENSA_OLD:
7ba29e2a
NC
881 case EM_MICROBLAZE:
882 case EM_MICROBLAZE_OLD:
f96bd6c2 883 case EM_WEBASSEMBLY:
9c19a809 884 return TRUE;
103f02d3 885
e9f53129
AM
886 case EM_68HC05:
887 case EM_68HC08:
888 case EM_68HC11:
889 case EM_68HC16:
890 case EM_FX66:
891 case EM_ME16:
d1133906 892 case EM_MMA:
d1133906
NC
893 case EM_NCPU:
894 case EM_NDR1:
e9f53129 895 case EM_PCP:
d1133906 896 case EM_ST100:
e9f53129 897 case EM_ST19:
d1133906 898 case EM_ST7:
e9f53129
AM
899 case EM_ST9PLUS:
900 case EM_STARCORE:
d1133906 901 case EM_SVX:
e9f53129 902 case EM_TINYJ:
9c19a809
NC
903 default:
904 warn (_("Don't know about relocations on this machine architecture\n"));
905 return FALSE;
906 }
907}
252b5132 908
dda8d76d 909/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
910 Returns TRUE upon success, FALSE otherwise. If successful then a
911 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
912 and the number of relocs loaded is placed in *NRELASP. It is the caller's
913 responsibility to free the allocated buffer. */
914
915static bfd_boolean
dda8d76d
NC
916slurp_rela_relocs (Filedata * filedata,
917 unsigned long rel_offset,
918 unsigned long rel_size,
919 Elf_Internal_Rela ** relasp,
920 unsigned long * nrelasp)
9c19a809 921{
2cf0635d 922 Elf_Internal_Rela * relas;
8b73c356 923 size_t nrelas;
4d6ed7c8 924 unsigned int i;
252b5132 925
4d6ed7c8
NC
926 if (is_32bit_elf)
927 {
2cf0635d 928 Elf32_External_Rela * erelas;
103f02d3 929
dda8d76d 930 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 931 rel_size, _("32-bit relocation data"));
a6e9f9df 932 if (!erelas)
32ec8896 933 return FALSE;
252b5132 934
4d6ed7c8 935 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 936
3f5e193b
NC
937 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
938 sizeof (Elf_Internal_Rela));
103f02d3 939
4d6ed7c8
NC
940 if (relas == NULL)
941 {
c256ffe7 942 free (erelas);
591a748a 943 error (_("out of memory parsing relocs\n"));
32ec8896 944 return FALSE;
4d6ed7c8 945 }
103f02d3 946
4d6ed7c8
NC
947 for (i = 0; i < nrelas; i++)
948 {
949 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
950 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 951 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 952 }
103f02d3 953
4d6ed7c8
NC
954 free (erelas);
955 }
956 else
957 {
2cf0635d 958 Elf64_External_Rela * erelas;
103f02d3 959
dda8d76d 960 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 961 rel_size, _("64-bit relocation data"));
a6e9f9df 962 if (!erelas)
32ec8896 963 return FALSE;
4d6ed7c8
NC
964
965 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 966
3f5e193b
NC
967 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
968 sizeof (Elf_Internal_Rela));
103f02d3 969
4d6ed7c8
NC
970 if (relas == NULL)
971 {
c256ffe7 972 free (erelas);
591a748a 973 error (_("out of memory parsing relocs\n"));
32ec8896 974 return FALSE;
9c19a809 975 }
4d6ed7c8
NC
976
977 for (i = 0; i < nrelas; i++)
9c19a809 978 {
66543521
AM
979 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
980 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 981 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
982
983 /* The #ifdef BFD64 below is to prevent a compile time
984 warning. We know that if we do not have a 64 bit data
985 type that we will never execute this code anyway. */
986#ifdef BFD64
dda8d76d
NC
987 if (filedata->file_header.e_machine == EM_MIPS
988 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
989 {
990 /* In little-endian objects, r_info isn't really a
991 64-bit little-endian value: it has a 32-bit
992 little-endian symbol index followed by four
993 individual byte fields. Reorder INFO
994 accordingly. */
91d6fa6a
NC
995 bfd_vma inf = relas[i].r_info;
996 inf = (((inf & 0xffffffff) << 32)
997 | ((inf >> 56) & 0xff)
998 | ((inf >> 40) & 0xff00)
999 | ((inf >> 24) & 0xff0000)
1000 | ((inf >> 8) & 0xff000000));
1001 relas[i].r_info = inf;
861fb55a
DJ
1002 }
1003#endif /* BFD64 */
4d6ed7c8 1004 }
103f02d3 1005
4d6ed7c8
NC
1006 free (erelas);
1007 }
32ec8896 1008
4d6ed7c8
NC
1009 *relasp = relas;
1010 *nrelasp = nrelas;
32ec8896 1011 return TRUE;
4d6ed7c8 1012}
103f02d3 1013
dda8d76d 1014/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1015 Returns TRUE upon success, FALSE otherwise. If successful then a
1016 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1017 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1018 responsibility to free the allocated buffer. */
1019
1020static bfd_boolean
dda8d76d
NC
1021slurp_rel_relocs (Filedata * filedata,
1022 unsigned long rel_offset,
1023 unsigned long rel_size,
1024 Elf_Internal_Rela ** relsp,
1025 unsigned long * nrelsp)
4d6ed7c8 1026{
2cf0635d 1027 Elf_Internal_Rela * rels;
8b73c356 1028 size_t nrels;
4d6ed7c8 1029 unsigned int i;
103f02d3 1030
4d6ed7c8
NC
1031 if (is_32bit_elf)
1032 {
2cf0635d 1033 Elf32_External_Rel * erels;
103f02d3 1034
dda8d76d 1035 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1036 rel_size, _("32-bit relocation data"));
a6e9f9df 1037 if (!erels)
32ec8896 1038 return FALSE;
103f02d3 1039
4d6ed7c8 1040 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1041
3f5e193b 1042 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1043
4d6ed7c8
NC
1044 if (rels == NULL)
1045 {
c256ffe7 1046 free (erels);
591a748a 1047 error (_("out of memory parsing relocs\n"));
32ec8896 1048 return FALSE;
4d6ed7c8
NC
1049 }
1050
1051 for (i = 0; i < nrels; i++)
1052 {
1053 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1054 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1055 rels[i].r_addend = 0;
9ea033b2 1056 }
4d6ed7c8
NC
1057
1058 free (erels);
9c19a809
NC
1059 }
1060 else
1061 {
2cf0635d 1062 Elf64_External_Rel * erels;
9ea033b2 1063
dda8d76d 1064 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1065 rel_size, _("64-bit relocation data"));
a6e9f9df 1066 if (!erels)
32ec8896 1067 return FALSE;
103f02d3 1068
4d6ed7c8 1069 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1070
3f5e193b 1071 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1072
4d6ed7c8 1073 if (rels == NULL)
9c19a809 1074 {
c256ffe7 1075 free (erels);
591a748a 1076 error (_("out of memory parsing relocs\n"));
32ec8896 1077 return FALSE;
4d6ed7c8 1078 }
103f02d3 1079
4d6ed7c8
NC
1080 for (i = 0; i < nrels; i++)
1081 {
66543521
AM
1082 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1083 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1084 rels[i].r_addend = 0;
861fb55a
DJ
1085
1086 /* The #ifdef BFD64 below is to prevent a compile time
1087 warning. We know that if we do not have a 64 bit data
1088 type that we will never execute this code anyway. */
1089#ifdef BFD64
dda8d76d
NC
1090 if (filedata->file_header.e_machine == EM_MIPS
1091 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1092 {
1093 /* In little-endian objects, r_info isn't really a
1094 64-bit little-endian value: it has a 32-bit
1095 little-endian symbol index followed by four
1096 individual byte fields. Reorder INFO
1097 accordingly. */
91d6fa6a
NC
1098 bfd_vma inf = rels[i].r_info;
1099 inf = (((inf & 0xffffffff) << 32)
1100 | ((inf >> 56) & 0xff)
1101 | ((inf >> 40) & 0xff00)
1102 | ((inf >> 24) & 0xff0000)
1103 | ((inf >> 8) & 0xff000000));
1104 rels[i].r_info = inf;
861fb55a
DJ
1105 }
1106#endif /* BFD64 */
4d6ed7c8 1107 }
103f02d3 1108
4d6ed7c8
NC
1109 free (erels);
1110 }
32ec8896 1111
4d6ed7c8
NC
1112 *relsp = rels;
1113 *nrelsp = nrels;
32ec8896 1114 return TRUE;
4d6ed7c8 1115}
103f02d3 1116
aca88567
NC
1117/* Returns the reloc type extracted from the reloc info field. */
1118
1119static unsigned int
dda8d76d 1120get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1121{
1122 if (is_32bit_elf)
1123 return ELF32_R_TYPE (reloc_info);
1124
dda8d76d 1125 switch (filedata->file_header.e_machine)
aca88567
NC
1126 {
1127 case EM_MIPS:
1128 /* Note: We assume that reloc_info has already been adjusted for us. */
1129 return ELF64_MIPS_R_TYPE (reloc_info);
1130
1131 case EM_SPARCV9:
1132 return ELF64_R_TYPE_ID (reloc_info);
1133
1134 default:
1135 return ELF64_R_TYPE (reloc_info);
1136 }
1137}
1138
1139/* Return the symbol index extracted from the reloc info field. */
1140
1141static bfd_vma
1142get_reloc_symindex (bfd_vma reloc_info)
1143{
1144 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1145}
1146
13761a11 1147static inline bfd_boolean
dda8d76d 1148uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1149{
1150 return
dda8d76d 1151 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1152 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1153 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1154 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1155 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1156}
1157
d3ba0551
AM
1158/* Display the contents of the relocation data found at the specified
1159 offset. */
ee42cf8c 1160
32ec8896 1161static bfd_boolean
dda8d76d
NC
1162dump_relocations (Filedata * filedata,
1163 unsigned long rel_offset,
1164 unsigned long rel_size,
1165 Elf_Internal_Sym * symtab,
1166 unsigned long nsyms,
1167 char * strtab,
1168 unsigned long strtablen,
1169 int is_rela,
1170 bfd_boolean is_dynsym)
4d6ed7c8 1171{
32ec8896 1172 unsigned long i;
2cf0635d 1173 Elf_Internal_Rela * rels;
32ec8896 1174 bfd_boolean res = TRUE;
103f02d3 1175
4d6ed7c8 1176 if (is_rela == UNKNOWN)
dda8d76d 1177 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1178
4d6ed7c8
NC
1179 if (is_rela)
1180 {
dda8d76d 1181 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1182 return FALSE;
4d6ed7c8
NC
1183 }
1184 else
1185 {
dda8d76d 1186 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1187 return FALSE;
252b5132
RH
1188 }
1189
410f7a12
L
1190 if (is_32bit_elf)
1191 {
1192 if (is_rela)
2c71103e
NC
1193 {
1194 if (do_wide)
1195 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1196 else
1197 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1198 }
410f7a12 1199 else
2c71103e
NC
1200 {
1201 if (do_wide)
1202 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1203 else
1204 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1205 }
410f7a12 1206 }
252b5132 1207 else
410f7a12
L
1208 {
1209 if (is_rela)
2c71103e
NC
1210 {
1211 if (do_wide)
8beeaeb7 1212 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1213 else
1214 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1215 }
410f7a12 1216 else
2c71103e
NC
1217 {
1218 if (do_wide)
8beeaeb7 1219 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1220 else
1221 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1222 }
410f7a12 1223 }
252b5132
RH
1224
1225 for (i = 0; i < rel_size; i++)
1226 {
2cf0635d 1227 const char * rtype;
b34976b6 1228 bfd_vma offset;
91d6fa6a 1229 bfd_vma inf;
b34976b6
AM
1230 bfd_vma symtab_index;
1231 bfd_vma type;
103f02d3 1232
b34976b6 1233 offset = rels[i].r_offset;
91d6fa6a 1234 inf = rels[i].r_info;
103f02d3 1235
dda8d76d 1236 type = get_reloc_type (filedata, inf);
91d6fa6a 1237 symtab_index = get_reloc_symindex (inf);
252b5132 1238
410f7a12
L
1239 if (is_32bit_elf)
1240 {
39dbeff8
AM
1241 printf ("%8.8lx %8.8lx ",
1242 (unsigned long) offset & 0xffffffff,
91d6fa6a 1243 (unsigned long) inf & 0xffffffff);
410f7a12
L
1244 }
1245 else
1246 {
39dbeff8
AM
1247#if BFD_HOST_64BIT_LONG
1248 printf (do_wide
1249 ? "%16.16lx %16.16lx "
1250 : "%12.12lx %12.12lx ",
91d6fa6a 1251 offset, inf);
39dbeff8 1252#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1253#ifndef __MSVCRT__
39dbeff8
AM
1254 printf (do_wide
1255 ? "%16.16llx %16.16llx "
1256 : "%12.12llx %12.12llx ",
91d6fa6a 1257 offset, inf);
6e3d6dc1
NC
1258#else
1259 printf (do_wide
1260 ? "%16.16I64x %16.16I64x "
1261 : "%12.12I64x %12.12I64x ",
91d6fa6a 1262 offset, inf);
6e3d6dc1 1263#endif
39dbeff8 1264#else
2c71103e
NC
1265 printf (do_wide
1266 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1267 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1268 _bfd_int64_high (offset),
1269 _bfd_int64_low (offset),
91d6fa6a
NC
1270 _bfd_int64_high (inf),
1271 _bfd_int64_low (inf));
9ea033b2 1272#endif
410f7a12 1273 }
103f02d3 1274
dda8d76d 1275 switch (filedata->file_header.e_machine)
252b5132
RH
1276 {
1277 default:
1278 rtype = NULL;
1279 break;
1280
a06ea964
NC
1281 case EM_AARCH64:
1282 rtype = elf_aarch64_reloc_type (type);
1283 break;
1284
2b0337b0 1285 case EM_M32R:
252b5132 1286 case EM_CYGNUS_M32R:
9ea033b2 1287 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1288 break;
1289
1290 case EM_386:
22abe556 1291 case EM_IAMCU:
9ea033b2 1292 rtype = elf_i386_reloc_type (type);
252b5132
RH
1293 break;
1294
ba2685cc
AM
1295 case EM_68HC11:
1296 case EM_68HC12:
1297 rtype = elf_m68hc11_reloc_type (type);
1298 break;
75751cd9 1299
7b4ae824
JD
1300 case EM_S12Z:
1301 rtype = elf_s12z_reloc_type (type);
1302 break;
1303
252b5132 1304 case EM_68K:
9ea033b2 1305 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1306 break;
1307
f954747f
AM
1308 case EM_960:
1309 rtype = elf_i960_reloc_type (type);
1310 break;
1311
adde6300 1312 case EM_AVR:
2b0337b0 1313 case EM_AVR_OLD:
adde6300
AM
1314 rtype = elf_avr_reloc_type (type);
1315 break;
1316
9ea033b2
NC
1317 case EM_OLD_SPARCV9:
1318 case EM_SPARC32PLUS:
1319 case EM_SPARCV9:
252b5132 1320 case EM_SPARC:
9ea033b2 1321 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1322 break;
1323
e9f53129
AM
1324 case EM_SPU:
1325 rtype = elf_spu_reloc_type (type);
1326 break;
1327
708e2187
NC
1328 case EM_V800:
1329 rtype = v800_reloc_type (type);
1330 break;
2b0337b0 1331 case EM_V850:
252b5132 1332 case EM_CYGNUS_V850:
9ea033b2 1333 rtype = v850_reloc_type (type);
252b5132
RH
1334 break;
1335
2b0337b0 1336 case EM_D10V:
252b5132 1337 case EM_CYGNUS_D10V:
9ea033b2 1338 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1339 break;
1340
2b0337b0 1341 case EM_D30V:
252b5132 1342 case EM_CYGNUS_D30V:
9ea033b2 1343 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1344 break;
1345
d172d4ba
NC
1346 case EM_DLX:
1347 rtype = elf_dlx_reloc_type (type);
1348 break;
1349
252b5132 1350 case EM_SH:
9ea033b2 1351 rtype = elf_sh_reloc_type (type);
252b5132
RH
1352 break;
1353
2b0337b0 1354 case EM_MN10300:
252b5132 1355 case EM_CYGNUS_MN10300:
9ea033b2 1356 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1357 break;
1358
2b0337b0 1359 case EM_MN10200:
252b5132 1360 case EM_CYGNUS_MN10200:
9ea033b2 1361 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1362 break;
1363
2b0337b0 1364 case EM_FR30:
252b5132 1365 case EM_CYGNUS_FR30:
9ea033b2 1366 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1367 break;
1368
ba2685cc
AM
1369 case EM_CYGNUS_FRV:
1370 rtype = elf_frv_reloc_type (type);
1371 break;
5c70f934 1372
b8891f8d
AJ
1373 case EM_CSKY:
1374 rtype = elf_csky_reloc_type (type);
1375 break;
1376
3f8107ab
AM
1377 case EM_FT32:
1378 rtype = elf_ft32_reloc_type (type);
1379 break;
1380
252b5132 1381 case EM_MCORE:
9ea033b2 1382 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1383 break;
1384
3c3bdf30
NC
1385 case EM_MMIX:
1386 rtype = elf_mmix_reloc_type (type);
1387 break;
1388
5506d11a
AM
1389 case EM_MOXIE:
1390 rtype = elf_moxie_reloc_type (type);
1391 break;
1392
2469cfa2 1393 case EM_MSP430:
dda8d76d 1394 if (uses_msp430x_relocs (filedata))
13761a11
NC
1395 {
1396 rtype = elf_msp430x_reloc_type (type);
1397 break;
1398 }
1a0670f3 1399 /* Fall through. */
2469cfa2
NC
1400 case EM_MSP430_OLD:
1401 rtype = elf_msp430_reloc_type (type);
1402 break;
1403
35c08157
KLC
1404 case EM_NDS32:
1405 rtype = elf_nds32_reloc_type (type);
1406 break;
1407
252b5132 1408 case EM_PPC:
9ea033b2 1409 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1410 break;
1411
c833c019
AM
1412 case EM_PPC64:
1413 rtype = elf_ppc64_reloc_type (type);
1414 break;
1415
252b5132 1416 case EM_MIPS:
4fe85591 1417 case EM_MIPS_RS3_LE:
9ea033b2 1418 rtype = elf_mips_reloc_type (type);
252b5132
RH
1419 break;
1420
e23eba97
NC
1421 case EM_RISCV:
1422 rtype = elf_riscv_reloc_type (type);
1423 break;
1424
252b5132 1425 case EM_ALPHA:
9ea033b2 1426 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1427 break;
1428
1429 case EM_ARM:
9ea033b2 1430 rtype = elf_arm_reloc_type (type);
252b5132
RH
1431 break;
1432
584da044 1433 case EM_ARC:
886a2506
NC
1434 case EM_ARC_COMPACT:
1435 case EM_ARC_COMPACT2:
9ea033b2 1436 rtype = elf_arc_reloc_type (type);
252b5132
RH
1437 break;
1438
1439 case EM_PARISC:
69e617ca 1440 rtype = elf_hppa_reloc_type (type);
252b5132 1441 break;
7d466069 1442
b8720f9d
JL
1443 case EM_H8_300:
1444 case EM_H8_300H:
1445 case EM_H8S:
1446 rtype = elf_h8_reloc_type (type);
1447 break;
1448
73589c9d
CS
1449 case EM_OR1K:
1450 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1451 break;
1452
7d466069 1453 case EM_PJ:
2b0337b0 1454 case EM_PJ_OLD:
7d466069
ILT
1455 rtype = elf_pj_reloc_type (type);
1456 break;
800eeca4
JW
1457 case EM_IA_64:
1458 rtype = elf_ia64_reloc_type (type);
1459 break;
1b61cf92
HPN
1460
1461 case EM_CRIS:
1462 rtype = elf_cris_reloc_type (type);
1463 break;
535c37ff 1464
f954747f
AM
1465 case EM_860:
1466 rtype = elf_i860_reloc_type (type);
1467 break;
1468
bcedfee6 1469 case EM_X86_64:
8a9036a4 1470 case EM_L1OM:
7a9068fe 1471 case EM_K1OM:
bcedfee6
NC
1472 rtype = elf_x86_64_reloc_type (type);
1473 break;
a85d7ed0 1474
f954747f
AM
1475 case EM_S370:
1476 rtype = i370_reloc_type (type);
1477 break;
1478
53c7db4b
KH
1479 case EM_S390_OLD:
1480 case EM_S390:
1481 rtype = elf_s390_reloc_type (type);
1482 break;
93fbbb04 1483
1c0d3aa6
NC
1484 case EM_SCORE:
1485 rtype = elf_score_reloc_type (type);
1486 break;
1487
93fbbb04
GK
1488 case EM_XSTORMY16:
1489 rtype = elf_xstormy16_reloc_type (type);
1490 break;
179d3252 1491
1fe1f39c
NC
1492 case EM_CRX:
1493 rtype = elf_crx_reloc_type (type);
1494 break;
1495
179d3252
JT
1496 case EM_VAX:
1497 rtype = elf_vax_reloc_type (type);
1498 break;
1e4cf259 1499
619ed720
EB
1500 case EM_VISIUM:
1501 rtype = elf_visium_reloc_type (type);
1502 break;
1503
aca4efc7
JM
1504 case EM_BPF:
1505 rtype = elf_bpf_reloc_type (type);
1506 break;
1507
cfb8c092
NC
1508 case EM_ADAPTEVA_EPIPHANY:
1509 rtype = elf_epiphany_reloc_type (type);
1510 break;
1511
1e4cf259
NC
1512 case EM_IP2K:
1513 case EM_IP2K_OLD:
1514 rtype = elf_ip2k_reloc_type (type);
1515 break;
3b36097d
SC
1516
1517 case EM_IQ2000:
1518 rtype = elf_iq2000_reloc_type (type);
1519 break;
88da6820
NC
1520
1521 case EM_XTENSA_OLD:
1522 case EM_XTENSA:
1523 rtype = elf_xtensa_reloc_type (type);
1524 break;
a34e3ecb 1525
84e94c90
NC
1526 case EM_LATTICEMICO32:
1527 rtype = elf_lm32_reloc_type (type);
1528 break;
1529
ff7eeb89 1530 case EM_M32C_OLD:
49f58d10
JB
1531 case EM_M32C:
1532 rtype = elf_m32c_reloc_type (type);
1533 break;
1534
d031aafb
NS
1535 case EM_MT:
1536 rtype = elf_mt_reloc_type (type);
a34e3ecb 1537 break;
1d65ded4
CM
1538
1539 case EM_BLACKFIN:
1540 rtype = elf_bfin_reloc_type (type);
1541 break;
15ab5209
DB
1542
1543 case EM_CYGNUS_MEP:
1544 rtype = elf_mep_reloc_type (type);
1545 break;
60bca95a
NC
1546
1547 case EM_CR16:
1548 rtype = elf_cr16_reloc_type (type);
1549 break;
dd24e3da 1550
7ba29e2a
NC
1551 case EM_MICROBLAZE:
1552 case EM_MICROBLAZE_OLD:
1553 rtype = elf_microblaze_reloc_type (type);
1554 break;
c7927a3c 1555
99c513f6
DD
1556 case EM_RL78:
1557 rtype = elf_rl78_reloc_type (type);
1558 break;
1559
c7927a3c
NC
1560 case EM_RX:
1561 rtype = elf_rx_reloc_type (type);
1562 break;
c29aca4a 1563
a3c62988
NC
1564 case EM_METAG:
1565 rtype = elf_metag_reloc_type (type);
1566 break;
1567
c29aca4a
NC
1568 case EM_XC16X:
1569 case EM_C166:
1570 rtype = elf_xc16x_reloc_type (type);
1571 break;
40b36596
JM
1572
1573 case EM_TI_C6000:
1574 rtype = elf_tic6x_reloc_type (type);
1575 break;
aa137e4d
NC
1576
1577 case EM_TILEGX:
1578 rtype = elf_tilegx_reloc_type (type);
1579 break;
1580
1581 case EM_TILEPRO:
1582 rtype = elf_tilepro_reloc_type (type);
1583 break;
f6c1a2d5 1584
f96bd6c2
PC
1585 case EM_WEBASSEMBLY:
1586 rtype = elf_wasm32_reloc_type (type);
1587 break;
1588
f6c1a2d5
NC
1589 case EM_XGATE:
1590 rtype = elf_xgate_reloc_type (type);
1591 break;
36591ba1
SL
1592
1593 case EM_ALTERA_NIOS2:
1594 rtype = elf_nios2_reloc_type (type);
1595 break;
2b100bb5
DD
1596
1597 case EM_TI_PRU:
1598 rtype = elf_pru_reloc_type (type);
1599 break;
fe944acf
FT
1600
1601 case EM_NFP:
1602 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1603 rtype = elf_nfp3200_reloc_type (type);
1604 else
1605 rtype = elf_nfp_reloc_type (type);
1606 break;
6655dba2
SB
1607
1608 case EM_Z80:
1609 rtype = elf_z80_reloc_type (type);
1610 break;
252b5132
RH
1611 }
1612
1613 if (rtype == NULL)
39dbeff8 1614 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1615 else
5c144731 1616 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1617
dda8d76d 1618 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1619 && rtype != NULL
7ace3541
RH
1620 && streq (rtype, "R_ALPHA_LITUSE")
1621 && is_rela)
1622 {
1623 switch (rels[i].r_addend)
1624 {
1625 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1626 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1627 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1628 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1629 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1630 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1631 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1632 default: rtype = NULL;
1633 }
32ec8896 1634
7ace3541
RH
1635 if (rtype)
1636 printf (" (%s)", rtype);
1637 else
1638 {
1639 putchar (' ');
1640 printf (_("<unknown addend: %lx>"),
1641 (unsigned long) rels[i].r_addend);
32ec8896 1642 res = FALSE;
7ace3541
RH
1643 }
1644 }
1645 else if (symtab_index)
252b5132 1646 {
af3fc3bc 1647 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1648 {
27a45f42
AS
1649 error (_(" bad symbol index: %08lx in reloc\n"),
1650 (unsigned long) symtab_index);
32ec8896
NC
1651 res = FALSE;
1652 }
af3fc3bc 1653 else
19936277 1654 {
2cf0635d 1655 Elf_Internal_Sym * psym;
bb4d2ac2
L
1656 const char * version_string;
1657 enum versioned_symbol_info sym_info;
1658 unsigned short vna_other;
19936277 1659
af3fc3bc 1660 psym = symtab + symtab_index;
103f02d3 1661
bb4d2ac2 1662 version_string
dda8d76d 1663 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1664 strtab, strtablen,
1665 symtab_index,
1666 psym,
1667 &sym_info,
1668 &vna_other);
1669
af3fc3bc 1670 printf (" ");
171191ba 1671
d8045f23
NC
1672 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1673 {
1674 const char * name;
1675 unsigned int len;
1676 unsigned int width = is_32bit_elf ? 8 : 14;
1677
1678 /* Relocations against GNU_IFUNC symbols do not use the value
1679 of the symbol as the address to relocate against. Instead
1680 they invoke the function named by the symbol and use its
1681 result as the address for relocation.
1682
1683 To indicate this to the user, do not display the value of
1684 the symbol in the "Symbols's Value" field. Instead show
1685 its name followed by () as a hint that the symbol is
1686 invoked. */
1687
1688 if (strtab == NULL
1689 || psym->st_name == 0
1690 || psym->st_name >= strtablen)
1691 name = "??";
1692 else
1693 name = strtab + psym->st_name;
1694
1695 len = print_symbol (width, name);
bb4d2ac2
L
1696 if (version_string)
1697 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1698 version_string);
d8045f23
NC
1699 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1700 }
1701 else
1702 {
1703 print_vma (psym->st_value, LONG_HEX);
171191ba 1704
d8045f23
NC
1705 printf (is_32bit_elf ? " " : " ");
1706 }
103f02d3 1707
af3fc3bc 1708 if (psym->st_name == 0)
f1ef08cb 1709 {
2cf0635d 1710 const char * sec_name = "<null>";
f1ef08cb
AM
1711 char name_buf[40];
1712
1713 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1714 {
dda8d76d
NC
1715 if (psym->st_shndx < filedata->file_header.e_shnum)
1716 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1717 else if (psym->st_shndx == SHN_ABS)
1718 sec_name = "ABS";
1719 else if (psym->st_shndx == SHN_COMMON)
1720 sec_name = "COMMON";
dda8d76d 1721 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1722 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1723 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1724 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1725 sec_name = "SCOMMON";
dda8d76d 1726 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1727 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1728 sec_name = "SUNDEF";
dda8d76d
NC
1729 else if ((filedata->file_header.e_machine == EM_X86_64
1730 || filedata->file_header.e_machine == EM_L1OM
1731 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1732 && psym->st_shndx == SHN_X86_64_LCOMMON)
1733 sec_name = "LARGE_COMMON";
dda8d76d
NC
1734 else if (filedata->file_header.e_machine == EM_IA_64
1735 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1736 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1737 sec_name = "ANSI_COM";
dda8d76d 1738 else if (is_ia64_vms (filedata)
148b93f2
NC
1739 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1740 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1741 else
1742 {
1743 sprintf (name_buf, "<section 0x%x>",
1744 (unsigned int) psym->st_shndx);
1745 sec_name = name_buf;
1746 }
1747 }
1748 print_symbol (22, sec_name);
1749 }
af3fc3bc 1750 else if (strtab == NULL)
d79b3d50 1751 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1752 else if (psym->st_name >= strtablen)
32ec8896 1753 {
27a45f42
AS
1754 error (_("<corrupt string table index: %3ld>\n"),
1755 psym->st_name);
32ec8896
NC
1756 res = FALSE;
1757 }
af3fc3bc 1758 else
bb4d2ac2
L
1759 {
1760 print_symbol (22, strtab + psym->st_name);
1761 if (version_string)
1762 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1763 version_string);
1764 }
103f02d3 1765
af3fc3bc 1766 if (is_rela)
171191ba 1767 {
7360e63f 1768 bfd_vma off = rels[i].r_addend;
171191ba 1769
7360e63f 1770 if ((bfd_signed_vma) off < 0)
598aaa76 1771 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1772 else
598aaa76 1773 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1774 }
19936277 1775 }
252b5132 1776 }
1b228002 1777 else if (is_rela)
f7a99963 1778 {
7360e63f 1779 bfd_vma off = rels[i].r_addend;
e04d7088
L
1780
1781 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1782 if ((bfd_signed_vma) off < 0)
e04d7088
L
1783 printf ("-%" BFD_VMA_FMT "x", - off);
1784 else
1785 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1786 }
252b5132 1787
dda8d76d 1788 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1789 && rtype != NULL
1790 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1791 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1792
252b5132 1793 putchar ('\n');
2c71103e 1794
aca88567 1795#ifdef BFD64
dda8d76d 1796 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1797 {
91d6fa6a
NC
1798 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1799 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1800 const char * rtype2 = elf_mips_reloc_type (type2);
1801 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1802
2c71103e
NC
1803 printf (" Type2: ");
1804
1805 if (rtype2 == NULL)
39dbeff8
AM
1806 printf (_("unrecognized: %-7lx"),
1807 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1808 else
1809 printf ("%-17.17s", rtype2);
1810
18bd398b 1811 printf ("\n Type3: ");
2c71103e
NC
1812
1813 if (rtype3 == NULL)
39dbeff8
AM
1814 printf (_("unrecognized: %-7lx"),
1815 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1816 else
1817 printf ("%-17.17s", rtype3);
1818
53c7db4b 1819 putchar ('\n');
2c71103e 1820 }
aca88567 1821#endif /* BFD64 */
252b5132
RH
1822 }
1823
c8286bd1 1824 free (rels);
32ec8896
NC
1825
1826 return res;
252b5132
RH
1827}
1828
37c18eed
SD
1829static const char *
1830get_aarch64_dynamic_type (unsigned long type)
1831{
1832 switch (type)
1833 {
1834 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1835 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1836 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1837 default:
1838 return NULL;
1839 }
1840}
1841
252b5132 1842static const char *
d3ba0551 1843get_mips_dynamic_type (unsigned long type)
252b5132
RH
1844{
1845 switch (type)
1846 {
1847 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1848 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1849 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1850 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1851 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1852 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1853 case DT_MIPS_MSYM: return "MIPS_MSYM";
1854 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1855 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1856 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1857 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1858 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1859 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1860 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1861 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1862 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1863 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1864 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1865 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1866 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1867 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1868 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1869 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1870 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1871 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1872 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1873 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1874 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1875 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1876 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1877 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1878 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1879 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1880 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1881 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1882 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1883 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1884 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1885 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1886 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1887 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1888 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1889 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1890 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1891 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1892 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1893 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1894 default:
1895 return NULL;
1896 }
1897}
1898
9a097730 1899static const char *
d3ba0551 1900get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1901{
1902 switch (type)
1903 {
1904 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1905 default:
1906 return NULL;
1907 }
103f02d3
UD
1908}
1909
7490d522
AM
1910static const char *
1911get_ppc_dynamic_type (unsigned long type)
1912{
1913 switch (type)
1914 {
a7f2871e 1915 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1916 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1917 default:
1918 return NULL;
1919 }
1920}
1921
f1cb7e17 1922static const char *
d3ba0551 1923get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1924{
1925 switch (type)
1926 {
a7f2871e
AM
1927 case DT_PPC64_GLINK: return "PPC64_GLINK";
1928 case DT_PPC64_OPD: return "PPC64_OPD";
1929 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1930 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1931 default:
1932 return NULL;
1933 }
1934}
1935
103f02d3 1936static const char *
d3ba0551 1937get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1938{
1939 switch (type)
1940 {
1941 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1942 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1943 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1944 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1945 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1946 case DT_HP_PREINIT: return "HP_PREINIT";
1947 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1948 case DT_HP_NEEDED: return "HP_NEEDED";
1949 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1950 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1951 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1952 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1953 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1954 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1955 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1956 case DT_HP_FILTERED: return "HP_FILTERED";
1957 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1958 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1959 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1960 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1961 case DT_PLT: return "PLT";
1962 case DT_PLT_SIZE: return "PLT_SIZE";
1963 case DT_DLT: return "DLT";
1964 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1965 default:
1966 return NULL;
1967 }
1968}
9a097730 1969
ecc51f48 1970static const char *
d3ba0551 1971get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1972{
1973 switch (type)
1974 {
148b93f2
NC
1975 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1976 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1977 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1978 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1979 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1980 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1981 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1982 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1983 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1984 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1985 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1986 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1987 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1988 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1989 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1990 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1991 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1992 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1993 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1994 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1995 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1996 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1997 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1998 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1999 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2000 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2001 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2002 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2003 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2004 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2005 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2006 default:
2007 return NULL;
2008 }
2009}
2010
fd85a6a1
NC
2011static const char *
2012get_solaris_section_type (unsigned long type)
2013{
2014 switch (type)
2015 {
2016 case 0x6fffffee: return "SUNW_ancillary";
2017 case 0x6fffffef: return "SUNW_capchain";
2018 case 0x6ffffff0: return "SUNW_capinfo";
2019 case 0x6ffffff1: return "SUNW_symsort";
2020 case 0x6ffffff2: return "SUNW_tlssort";
2021 case 0x6ffffff3: return "SUNW_LDYNSYM";
2022 case 0x6ffffff4: return "SUNW_dof";
2023 case 0x6ffffff5: return "SUNW_cap";
2024 case 0x6ffffff6: return "SUNW_SIGNATURE";
2025 case 0x6ffffff7: return "SUNW_ANNOTATE";
2026 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2027 case 0x6ffffff9: return "SUNW_DEBUG";
2028 case 0x6ffffffa: return "SUNW_move";
2029 case 0x6ffffffb: return "SUNW_COMDAT";
2030 case 0x6ffffffc: return "SUNW_syminfo";
2031 case 0x6ffffffd: return "SUNW_verdef";
2032 case 0x6ffffffe: return "SUNW_verneed";
2033 case 0x6fffffff: return "SUNW_versym";
2034 case 0x70000000: return "SPARC_GOTDATA";
2035 default: return NULL;
2036 }
2037}
2038
fabcb361
RH
2039static const char *
2040get_alpha_dynamic_type (unsigned long type)
2041{
2042 switch (type)
2043 {
2044 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2045 default: return NULL;
fabcb361
RH
2046 }
2047}
2048
1c0d3aa6
NC
2049static const char *
2050get_score_dynamic_type (unsigned long type)
2051{
2052 switch (type)
2053 {
2054 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2055 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2056 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2057 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2058 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2059 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2060 default: return NULL;
1c0d3aa6
NC
2061 }
2062}
2063
40b36596
JM
2064static const char *
2065get_tic6x_dynamic_type (unsigned long type)
2066{
2067 switch (type)
2068 {
2069 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2070 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2071 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2072 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2073 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2074 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2075 default: return NULL;
40b36596
JM
2076 }
2077}
1c0d3aa6 2078
36591ba1
SL
2079static const char *
2080get_nios2_dynamic_type (unsigned long type)
2081{
2082 switch (type)
2083 {
2084 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2085 default: return NULL;
36591ba1
SL
2086 }
2087}
2088
fd85a6a1
NC
2089static const char *
2090get_solaris_dynamic_type (unsigned long type)
2091{
2092 switch (type)
2093 {
2094 case 0x6000000d: return "SUNW_AUXILIARY";
2095 case 0x6000000e: return "SUNW_RTLDINF";
2096 case 0x6000000f: return "SUNW_FILTER";
2097 case 0x60000010: return "SUNW_CAP";
2098 case 0x60000011: return "SUNW_SYMTAB";
2099 case 0x60000012: return "SUNW_SYMSZ";
2100 case 0x60000013: return "SUNW_SORTENT";
2101 case 0x60000014: return "SUNW_SYMSORT";
2102 case 0x60000015: return "SUNW_SYMSORTSZ";
2103 case 0x60000016: return "SUNW_TLSSORT";
2104 case 0x60000017: return "SUNW_TLSSORTSZ";
2105 case 0x60000018: return "SUNW_CAPINFO";
2106 case 0x60000019: return "SUNW_STRPAD";
2107 case 0x6000001a: return "SUNW_CAPCHAIN";
2108 case 0x6000001b: return "SUNW_LDMACH";
2109 case 0x6000001d: return "SUNW_CAPCHAINENT";
2110 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2111 case 0x60000021: return "SUNW_PARENT";
2112 case 0x60000023: return "SUNW_ASLR";
2113 case 0x60000025: return "SUNW_RELAX";
2114 case 0x60000029: return "SUNW_NXHEAP";
2115 case 0x6000002b: return "SUNW_NXSTACK";
2116
2117 case 0x70000001: return "SPARC_REGISTER";
2118 case 0x7ffffffd: return "AUXILIARY";
2119 case 0x7ffffffe: return "USED";
2120 case 0x7fffffff: return "FILTER";
2121
15f205b1 2122 default: return NULL;
fd85a6a1
NC
2123 }
2124}
2125
252b5132 2126static const char *
dda8d76d 2127get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2128{
e9e44622 2129 static char buff[64];
252b5132
RH
2130
2131 switch (type)
2132 {
2133 case DT_NULL: return "NULL";
2134 case DT_NEEDED: return "NEEDED";
2135 case DT_PLTRELSZ: return "PLTRELSZ";
2136 case DT_PLTGOT: return "PLTGOT";
2137 case DT_HASH: return "HASH";
2138 case DT_STRTAB: return "STRTAB";
2139 case DT_SYMTAB: return "SYMTAB";
2140 case DT_RELA: return "RELA";
2141 case DT_RELASZ: return "RELASZ";
2142 case DT_RELAENT: return "RELAENT";
2143 case DT_STRSZ: return "STRSZ";
2144 case DT_SYMENT: return "SYMENT";
2145 case DT_INIT: return "INIT";
2146 case DT_FINI: return "FINI";
2147 case DT_SONAME: return "SONAME";
2148 case DT_RPATH: return "RPATH";
2149 case DT_SYMBOLIC: return "SYMBOLIC";
2150 case DT_REL: return "REL";
2151 case DT_RELSZ: return "RELSZ";
2152 case DT_RELENT: return "RELENT";
2153 case DT_PLTREL: return "PLTREL";
2154 case DT_DEBUG: return "DEBUG";
2155 case DT_TEXTREL: return "TEXTREL";
2156 case DT_JMPREL: return "JMPREL";
2157 case DT_BIND_NOW: return "BIND_NOW";
2158 case DT_INIT_ARRAY: return "INIT_ARRAY";
2159 case DT_FINI_ARRAY: return "FINI_ARRAY";
2160 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2161 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2162 case DT_RUNPATH: return "RUNPATH";
2163 case DT_FLAGS: return "FLAGS";
2d0e6f43 2164
d1133906
NC
2165 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2166 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2167 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2168
05107a46 2169 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2170 case DT_PLTPADSZ: return "PLTPADSZ";
2171 case DT_MOVEENT: return "MOVEENT";
2172 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2173 case DT_FEATURE: return "FEATURE";
252b5132
RH
2174 case DT_POSFLAG_1: return "POSFLAG_1";
2175 case DT_SYMINSZ: return "SYMINSZ";
2176 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2177
252b5132 2178 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2179 case DT_CONFIG: return "CONFIG";
2180 case DT_DEPAUDIT: return "DEPAUDIT";
2181 case DT_AUDIT: return "AUDIT";
2182 case DT_PLTPAD: return "PLTPAD";
2183 case DT_MOVETAB: return "MOVETAB";
252b5132 2184 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2185
252b5132 2186 case DT_VERSYM: return "VERSYM";
103f02d3 2187
67a4f2b7
AO
2188 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2189 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2190 case DT_RELACOUNT: return "RELACOUNT";
2191 case DT_RELCOUNT: return "RELCOUNT";
2192 case DT_FLAGS_1: return "FLAGS_1";
2193 case DT_VERDEF: return "VERDEF";
2194 case DT_VERDEFNUM: return "VERDEFNUM";
2195 case DT_VERNEED: return "VERNEED";
2196 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2197
019148e4 2198 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2199 case DT_USED: return "USED";
2200 case DT_FILTER: return "FILTER";
103f02d3 2201
047b2264
JJ
2202 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2203 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2204 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2205 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2206 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2207 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2208
252b5132
RH
2209 default:
2210 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2211 {
2cf0635d 2212 const char * result;
103f02d3 2213
dda8d76d 2214 switch (filedata->file_header.e_machine)
252b5132 2215 {
37c18eed
SD
2216 case EM_AARCH64:
2217 result = get_aarch64_dynamic_type (type);
2218 break;
252b5132 2219 case EM_MIPS:
4fe85591 2220 case EM_MIPS_RS3_LE:
252b5132
RH
2221 result = get_mips_dynamic_type (type);
2222 break;
9a097730
RH
2223 case EM_SPARCV9:
2224 result = get_sparc64_dynamic_type (type);
2225 break;
7490d522
AM
2226 case EM_PPC:
2227 result = get_ppc_dynamic_type (type);
2228 break;
f1cb7e17
AM
2229 case EM_PPC64:
2230 result = get_ppc64_dynamic_type (type);
2231 break;
ecc51f48
NC
2232 case EM_IA_64:
2233 result = get_ia64_dynamic_type (type);
2234 break;
fabcb361
RH
2235 case EM_ALPHA:
2236 result = get_alpha_dynamic_type (type);
2237 break;
1c0d3aa6
NC
2238 case EM_SCORE:
2239 result = get_score_dynamic_type (type);
2240 break;
40b36596
JM
2241 case EM_TI_C6000:
2242 result = get_tic6x_dynamic_type (type);
2243 break;
36591ba1
SL
2244 case EM_ALTERA_NIOS2:
2245 result = get_nios2_dynamic_type (type);
2246 break;
252b5132 2247 default:
dda8d76d 2248 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2249 result = get_solaris_dynamic_type (type);
2250 else
2251 result = NULL;
252b5132
RH
2252 break;
2253 }
2254
2255 if (result != NULL)
2256 return result;
2257
e9e44622 2258 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2259 }
eec8f817 2260 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2261 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2262 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2263 {
2cf0635d 2264 const char * result;
103f02d3 2265
dda8d76d 2266 switch (filedata->file_header.e_machine)
103f02d3
UD
2267 {
2268 case EM_PARISC:
2269 result = get_parisc_dynamic_type (type);
2270 break;
148b93f2
NC
2271 case EM_IA_64:
2272 result = get_ia64_dynamic_type (type);
2273 break;
103f02d3 2274 default:
dda8d76d 2275 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2276 result = get_solaris_dynamic_type (type);
2277 else
2278 result = NULL;
103f02d3
UD
2279 break;
2280 }
2281
2282 if (result != NULL)
2283 return result;
2284
e9e44622
JJ
2285 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2286 type);
103f02d3 2287 }
252b5132 2288 else
e9e44622 2289 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2290
252b5132
RH
2291 return buff;
2292 }
2293}
2294
2295static char *
d3ba0551 2296get_file_type (unsigned e_type)
252b5132 2297{
89246a0e 2298 static char buff[64];
252b5132
RH
2299
2300 switch (e_type)
2301 {
32ec8896
NC
2302 case ET_NONE: return _("NONE (None)");
2303 case ET_REL: return _("REL (Relocatable file)");
2304 case ET_EXEC: return _("EXEC (Executable file)");
2305 case ET_DYN: return _("DYN (Shared object file)");
2306 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2307
2308 default:
2309 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2310 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2311 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2312 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2313 else
e9e44622 2314 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2315 return buff;
2316 }
2317}
2318
2319static char *
d3ba0551 2320get_machine_name (unsigned e_machine)
252b5132 2321{
b34976b6 2322 static char buff[64]; /* XXX */
252b5132
RH
2323
2324 switch (e_machine)
2325 {
55e22ca8
NC
2326 /* Please keep this switch table sorted by increasing EM_ value. */
2327 /* 0 */
c45021f2
NC
2328 case EM_NONE: return _("None");
2329 case EM_M32: return "WE32100";
2330 case EM_SPARC: return "Sparc";
2331 case EM_386: return "Intel 80386";
2332 case EM_68K: return "MC68000";
2333 case EM_88K: return "MC88000";
22abe556 2334 case EM_IAMCU: return "Intel MCU";
fb70ec17 2335 case EM_860: return "Intel 80860";
c45021f2
NC
2336 case EM_MIPS: return "MIPS R3000";
2337 case EM_S370: return "IBM System/370";
55e22ca8 2338 /* 10 */
7036c0e1 2339 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2340 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2341 case EM_PARISC: return "HPPA";
55e22ca8 2342 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2343 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2344 case EM_960: return "Intel 80960";
c45021f2 2345 case EM_PPC: return "PowerPC";
55e22ca8 2346 /* 20 */
285d1771 2347 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2348 case EM_S390_OLD:
2349 case EM_S390: return "IBM S/390";
2350 case EM_SPU: return "SPU";
2351 /* 30 */
2352 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2353 case EM_FR20: return "Fujitsu FR20";
2354 case EM_RH32: return "TRW RH32";
b34976b6 2355 case EM_MCORE: return "MCORE";
55e22ca8 2356 /* 40 */
7036c0e1
AJ
2357 case EM_ARM: return "ARM";
2358 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2359 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2360 case EM_SPARCV9: return "Sparc v9";
2361 case EM_TRICORE: return "Siemens Tricore";
584da044 2362 case EM_ARC: return "ARC";
c2dcd04e
NC
2363 case EM_H8_300: return "Renesas H8/300";
2364 case EM_H8_300H: return "Renesas H8/300H";
2365 case EM_H8S: return "Renesas H8S";
2366 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2367 /* 50 */
30800947 2368 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2369 case EM_MIPS_X: return "Stanford MIPS-X";
2370 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2371 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2372 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2373 case EM_PCP: return "Siemens PCP";
2374 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2375 case EM_NDR1: return "Denso NDR1 microprocesspr";
2376 case EM_STARCORE: return "Motorola Star*Core processor";
2377 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2378 /* 60 */
7036c0e1
AJ
2379 case EM_ST100: return "STMicroelectronics ST100 processor";
2380 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2381 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2382 case EM_PDSP: return "Sony DSP processor";
2383 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2384 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2385 case EM_FX66: return "Siemens FX66 microcontroller";
2386 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2387 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2388 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2389 /* 70 */
7036c0e1
AJ
2390 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2391 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2392 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2393 case EM_SVX: return "Silicon Graphics SVx";
2394 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2395 case EM_VAX: return "Digital VAX";
1b61cf92 2396 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2397 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2398 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2399 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2400 /* 80 */
b34976b6 2401 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2402 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2403 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2404 case EM_AVR_OLD:
2405 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2406 case EM_CYGNUS_FR30:
2407 case EM_FR30: return "Fujitsu FR30";
2408 case EM_CYGNUS_D10V:
2409 case EM_D10V: return "d10v";
2410 case EM_CYGNUS_D30V:
2411 case EM_D30V: return "d30v";
2412 case EM_CYGNUS_V850:
2413 case EM_V850: return "Renesas V850";
2414 case EM_CYGNUS_M32R:
2415 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2416 case EM_CYGNUS_MN10300:
2417 case EM_MN10300: return "mn10300";
2418 /* 90 */
2419 case EM_CYGNUS_MN10200:
2420 case EM_MN10200: return "mn10200";
2421 case EM_PJ: return "picoJava";
73589c9d 2422 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2423 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2424 case EM_XTENSA_OLD:
2425 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2426 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2427 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2428 case EM_NS32K: return "National Semiconductor 32000 series";
2429 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2430 case EM_SNP1K: return "Trebia SNP 1000 processor";
2431 /* 100 */
9abca702 2432 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2433 case EM_IP2K_OLD:
2434 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2435 case EM_MAX: return "MAX Processor";
2436 case EM_CR: return "National Semiconductor CompactRISC";
2437 case EM_F2MC16: return "Fujitsu F2MC16";
2438 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2439 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2440 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2441 case EM_SEP: return "Sharp embedded microprocessor";
2442 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2443 /* 110 */
11636f9e
JM
2444 case EM_UNICORE: return "Unicore";
2445 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2446 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2447 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2448 case EM_CRX: return "National Semiconductor CRX microprocessor";
2449 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2450 case EM_C166:
d70c5fc7 2451 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2452 case EM_M16C: return "Renesas M16C series microprocessors";
2453 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2454 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2455 /* 120 */
2456 case EM_M32C: return "Renesas M32c";
2457 /* 130 */
11636f9e
JM
2458 case EM_TSK3000: return "Altium TSK3000 core";
2459 case EM_RS08: return "Freescale RS08 embedded processor";
2460 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2461 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2462 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2463 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2464 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2465 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2466 /* 140 */
11636f9e
JM
2467 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2468 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2469 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2470 case EM_TI_PRU: return "TI PRU I/O processor";
2471 /* 160 */
11636f9e
JM
2472 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2473 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2474 case EM_R32C: return "Renesas R32C series microprocessors";
2475 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2476 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2477 case EM_8051: return "Intel 8051 and variants";
2478 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2479 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2480 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2481 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2482 /* 170 */
11636f9e
JM
2483 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2484 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2485 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2486 case EM_RX: return "Renesas RX";
a3c62988 2487 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2488 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2489 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2490 case EM_CR16:
2491 case EM_MICROBLAZE:
2492 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2493 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2494 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2495 /* 180 */
2496 case EM_L1OM: return "Intel L1OM";
2497 case EM_K1OM: return "Intel K1OM";
2498 case EM_INTEL182: return "Intel (reserved)";
2499 case EM_AARCH64: return "AArch64";
2500 case EM_ARM184: return "ARM (reserved)";
2501 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2502 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2503 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2504 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2505 /* 190 */
11636f9e 2506 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2507 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2508 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2509 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2510 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2511 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2512 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2513 case EM_RL78: return "Renesas RL78";
6d913794 2514 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2515 case EM_78K0R: return "Renesas 78K0R";
2516 /* 200 */
6d913794 2517 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2518 case EM_BA1: return "Beyond BA1 CPU architecture";
2519 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2520 case EM_XCORE: return "XMOS xCORE processor family";
2521 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2522 /* 210 */
6d913794
NC
2523 case EM_KM32: return "KM211 KM32 32-bit processor";
2524 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2525 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2526 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2527 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2528 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2529 case EM_COGE: return "Cognitive Smart Memory Processor";
2530 case EM_COOL: return "Bluechip Systems CoolEngine";
2531 case EM_NORC: return "Nanoradio Optimized RISC";
2532 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2533 /* 220 */
15f205b1 2534 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2535 case EM_VISIUM: return "CDS VISIUMcore processor";
2536 case EM_FT32: return "FTDI Chip FT32";
2537 case EM_MOXIE: return "Moxie";
2538 case EM_AMDGPU: return "AMD GPU";
2539 case EM_RISCV: return "RISC-V";
2540 case EM_LANAI: return "Lanai 32-bit processor";
2541 case EM_BPF: return "Linux BPF";
fe944acf 2542 case EM_NFP: return "Netronome Flow Processor";
55e22ca8
NC
2543
2544 /* Large numbers... */
2545 case EM_MT: return "Morpho Techologies MT processor";
2546 case EM_ALPHA: return "Alpha";
2547 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2548 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2549 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2550 case EM_IQ2000: return "Vitesse IQ2000";
2551 case EM_M32C_OLD:
2552 case EM_NIOS32: return "Altera Nios";
2553 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2554 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2555 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2556 case EM_S12Z: return "Freescale S12Z";
b8891f8d 2557 case EM_CSKY: return "C-SKY";
55e22ca8 2558
252b5132 2559 default:
35d9dd2f 2560 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2561 return buff;
2562 }
2563}
2564
a9522a21
AB
2565static void
2566decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2567{
2568 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2569 other compilers don't a specific architecture type in the e_flags, and
2570 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2571 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2572 architectures.
2573
2574 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2575 but also sets a specific architecture type in the e_flags field.
2576
2577 However, when decoding the flags we don't worry if we see an
2578 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2579 ARCEM architecture type. */
2580
2581 switch (e_flags & EF_ARC_MACH_MSK)
2582 {
2583 /* We only expect these to occur for EM_ARC_COMPACT2. */
2584 case EF_ARC_CPU_ARCV2EM:
2585 strcat (buf, ", ARC EM");
2586 break;
2587 case EF_ARC_CPU_ARCV2HS:
2588 strcat (buf, ", ARC HS");
2589 break;
2590
2591 /* We only expect these to occur for EM_ARC_COMPACT. */
2592 case E_ARC_MACH_ARC600:
2593 strcat (buf, ", ARC600");
2594 break;
2595 case E_ARC_MACH_ARC601:
2596 strcat (buf, ", ARC601");
2597 break;
2598 case E_ARC_MACH_ARC700:
2599 strcat (buf, ", ARC700");
2600 break;
2601
2602 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2603 new ELF with new architecture being read by an old version of
2604 readelf, or (c) An ELF built with non-GNU compiler that does not
2605 set the architecture in the e_flags. */
2606 default:
2607 if (e_machine == EM_ARC_COMPACT)
2608 strcat (buf, ", Unknown ARCompact");
2609 else
2610 strcat (buf, ", Unknown ARC");
2611 break;
2612 }
2613
2614 switch (e_flags & EF_ARC_OSABI_MSK)
2615 {
2616 case E_ARC_OSABI_ORIG:
2617 strcat (buf, ", (ABI:legacy)");
2618 break;
2619 case E_ARC_OSABI_V2:
2620 strcat (buf, ", (ABI:v2)");
2621 break;
2622 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2623 case E_ARC_OSABI_V3:
2624 strcat (buf, ", v3 no-legacy-syscalls ABI");
2625 break;
53a346d8
CZ
2626 case E_ARC_OSABI_V4:
2627 strcat (buf, ", v4 ABI");
2628 break;
a9522a21
AB
2629 default:
2630 strcat (buf, ", unrecognised ARC OSABI flag");
2631 break;
2632 }
2633}
2634
f3485b74 2635static void
d3ba0551 2636decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2637{
2638 unsigned eabi;
32ec8896 2639 bfd_boolean unknown = FALSE;
f3485b74
NC
2640
2641 eabi = EF_ARM_EABI_VERSION (e_flags);
2642 e_flags &= ~ EF_ARM_EABIMASK;
2643
2644 /* Handle "generic" ARM flags. */
2645 if (e_flags & EF_ARM_RELEXEC)
2646 {
2647 strcat (buf, ", relocatable executable");
2648 e_flags &= ~ EF_ARM_RELEXEC;
2649 }
76da6bbe 2650
18a20338
CL
2651 if (e_flags & EF_ARM_PIC)
2652 {
2653 strcat (buf, ", position independent");
2654 e_flags &= ~ EF_ARM_PIC;
2655 }
2656
f3485b74
NC
2657 /* Now handle EABI specific flags. */
2658 switch (eabi)
2659 {
2660 default:
2c71103e 2661 strcat (buf, ", <unrecognized EABI>");
f3485b74 2662 if (e_flags)
32ec8896 2663 unknown = TRUE;
f3485b74
NC
2664 break;
2665
2666 case EF_ARM_EABI_VER1:
a5bcd848 2667 strcat (buf, ", Version1 EABI");
f3485b74
NC
2668 while (e_flags)
2669 {
2670 unsigned flag;
76da6bbe 2671
f3485b74
NC
2672 /* Process flags one bit at a time. */
2673 flag = e_flags & - e_flags;
2674 e_flags &= ~ flag;
76da6bbe 2675
f3485b74
NC
2676 switch (flag)
2677 {
a5bcd848 2678 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2679 strcat (buf, ", sorted symbol tables");
2680 break;
76da6bbe 2681
f3485b74 2682 default:
32ec8896 2683 unknown = TRUE;
f3485b74
NC
2684 break;
2685 }
2686 }
2687 break;
76da6bbe 2688
a5bcd848
PB
2689 case EF_ARM_EABI_VER2:
2690 strcat (buf, ", Version2 EABI");
2691 while (e_flags)
2692 {
2693 unsigned flag;
2694
2695 /* Process flags one bit at a time. */
2696 flag = e_flags & - e_flags;
2697 e_flags &= ~ flag;
2698
2699 switch (flag)
2700 {
2701 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2702 strcat (buf, ", sorted symbol tables");
2703 break;
2704
2705 case EF_ARM_DYNSYMSUSESEGIDX:
2706 strcat (buf, ", dynamic symbols use segment index");
2707 break;
2708
2709 case EF_ARM_MAPSYMSFIRST:
2710 strcat (buf, ", mapping symbols precede others");
2711 break;
2712
2713 default:
32ec8896 2714 unknown = TRUE;
a5bcd848
PB
2715 break;
2716 }
2717 }
2718 break;
2719
d507cf36
PB
2720 case EF_ARM_EABI_VER3:
2721 strcat (buf, ", Version3 EABI");
8cb51566
PB
2722 break;
2723
2724 case EF_ARM_EABI_VER4:
2725 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2726 while (e_flags)
2727 {
2728 unsigned flag;
2729
2730 /* Process flags one bit at a time. */
2731 flag = e_flags & - e_flags;
2732 e_flags &= ~ flag;
2733
2734 switch (flag)
2735 {
2736 case EF_ARM_BE8:
2737 strcat (buf, ", BE8");
2738 break;
2739
2740 case EF_ARM_LE8:
2741 strcat (buf, ", LE8");
2742 break;
2743
2744 default:
32ec8896 2745 unknown = TRUE;
3bfcb652
NC
2746 break;
2747 }
3bfcb652
NC
2748 }
2749 break;
3a4a14e9
PB
2750
2751 case EF_ARM_EABI_VER5:
2752 strcat (buf, ", Version5 EABI");
d507cf36
PB
2753 while (e_flags)
2754 {
2755 unsigned flag;
2756
2757 /* Process flags one bit at a time. */
2758 flag = e_flags & - e_flags;
2759 e_flags &= ~ flag;
2760
2761 switch (flag)
2762 {
2763 case EF_ARM_BE8:
2764 strcat (buf, ", BE8");
2765 break;
2766
2767 case EF_ARM_LE8:
2768 strcat (buf, ", LE8");
2769 break;
2770
3bfcb652
NC
2771 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2772 strcat (buf, ", soft-float ABI");
2773 break;
2774
2775 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2776 strcat (buf, ", hard-float ABI");
2777 break;
2778
d507cf36 2779 default:
32ec8896 2780 unknown = TRUE;
d507cf36
PB
2781 break;
2782 }
2783 }
2784 break;
2785
f3485b74 2786 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2787 strcat (buf, ", GNU EABI");
f3485b74
NC
2788 while (e_flags)
2789 {
2790 unsigned flag;
76da6bbe 2791
f3485b74
NC
2792 /* Process flags one bit at a time. */
2793 flag = e_flags & - e_flags;
2794 e_flags &= ~ flag;
76da6bbe 2795
f3485b74
NC
2796 switch (flag)
2797 {
a5bcd848 2798 case EF_ARM_INTERWORK:
f3485b74
NC
2799 strcat (buf, ", interworking enabled");
2800 break;
76da6bbe 2801
a5bcd848 2802 case EF_ARM_APCS_26:
f3485b74
NC
2803 strcat (buf, ", uses APCS/26");
2804 break;
76da6bbe 2805
a5bcd848 2806 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2807 strcat (buf, ", uses APCS/float");
2808 break;
76da6bbe 2809
a5bcd848 2810 case EF_ARM_PIC:
f3485b74
NC
2811 strcat (buf, ", position independent");
2812 break;
76da6bbe 2813
a5bcd848 2814 case EF_ARM_ALIGN8:
f3485b74
NC
2815 strcat (buf, ", 8 bit structure alignment");
2816 break;
76da6bbe 2817
a5bcd848 2818 case EF_ARM_NEW_ABI:
f3485b74
NC
2819 strcat (buf, ", uses new ABI");
2820 break;
76da6bbe 2821
a5bcd848 2822 case EF_ARM_OLD_ABI:
f3485b74
NC
2823 strcat (buf, ", uses old ABI");
2824 break;
76da6bbe 2825
a5bcd848 2826 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2827 strcat (buf, ", software FP");
2828 break;
76da6bbe 2829
90e01f86
ILT
2830 case EF_ARM_VFP_FLOAT:
2831 strcat (buf, ", VFP");
2832 break;
2833
fde78edd
NC
2834 case EF_ARM_MAVERICK_FLOAT:
2835 strcat (buf, ", Maverick FP");
2836 break;
2837
f3485b74 2838 default:
32ec8896 2839 unknown = TRUE;
f3485b74
NC
2840 break;
2841 }
2842 }
2843 }
f3485b74
NC
2844
2845 if (unknown)
2b692964 2846 strcat (buf,_(", <unknown>"));
f3485b74
NC
2847}
2848
343433df
AB
2849static void
2850decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2851{
2852 --size; /* Leave space for null terminator. */
2853
2854 switch (e_flags & EF_AVR_MACH)
2855 {
2856 case E_AVR_MACH_AVR1:
2857 strncat (buf, ", avr:1", size);
2858 break;
2859 case E_AVR_MACH_AVR2:
2860 strncat (buf, ", avr:2", size);
2861 break;
2862 case E_AVR_MACH_AVR25:
2863 strncat (buf, ", avr:25", size);
2864 break;
2865 case E_AVR_MACH_AVR3:
2866 strncat (buf, ", avr:3", size);
2867 break;
2868 case E_AVR_MACH_AVR31:
2869 strncat (buf, ", avr:31", size);
2870 break;
2871 case E_AVR_MACH_AVR35:
2872 strncat (buf, ", avr:35", size);
2873 break;
2874 case E_AVR_MACH_AVR4:
2875 strncat (buf, ", avr:4", size);
2876 break;
2877 case E_AVR_MACH_AVR5:
2878 strncat (buf, ", avr:5", size);
2879 break;
2880 case E_AVR_MACH_AVR51:
2881 strncat (buf, ", avr:51", size);
2882 break;
2883 case E_AVR_MACH_AVR6:
2884 strncat (buf, ", avr:6", size);
2885 break;
2886 case E_AVR_MACH_AVRTINY:
2887 strncat (buf, ", avr:100", size);
2888 break;
2889 case E_AVR_MACH_XMEGA1:
2890 strncat (buf, ", avr:101", size);
2891 break;
2892 case E_AVR_MACH_XMEGA2:
2893 strncat (buf, ", avr:102", size);
2894 break;
2895 case E_AVR_MACH_XMEGA3:
2896 strncat (buf, ", avr:103", size);
2897 break;
2898 case E_AVR_MACH_XMEGA4:
2899 strncat (buf, ", avr:104", size);
2900 break;
2901 case E_AVR_MACH_XMEGA5:
2902 strncat (buf, ", avr:105", size);
2903 break;
2904 case E_AVR_MACH_XMEGA6:
2905 strncat (buf, ", avr:106", size);
2906 break;
2907 case E_AVR_MACH_XMEGA7:
2908 strncat (buf, ", avr:107", size);
2909 break;
2910 default:
2911 strncat (buf, ", avr:<unknown>", size);
2912 break;
2913 }
2914
2915 size -= strlen (buf);
2916 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2917 strncat (buf, ", link-relax", size);
2918}
2919
35c08157
KLC
2920static void
2921decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2922{
2923 unsigned abi;
2924 unsigned arch;
2925 unsigned config;
2926 unsigned version;
32ec8896
NC
2927 bfd_boolean has_fpu = FALSE;
2928 unsigned int r = 0;
35c08157
KLC
2929
2930 static const char *ABI_STRINGS[] =
2931 {
2932 "ABI v0", /* use r5 as return register; only used in N1213HC */
2933 "ABI v1", /* use r0 as return register */
2934 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2935 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2936 "AABI",
2937 "ABI2 FP+"
35c08157
KLC
2938 };
2939 static const char *VER_STRINGS[] =
2940 {
2941 "Andes ELF V1.3 or older",
2942 "Andes ELF V1.3.1",
2943 "Andes ELF V1.4"
2944 };
2945 static const char *ARCH_STRINGS[] =
2946 {
2947 "",
2948 "Andes Star v1.0",
2949 "Andes Star v2.0",
2950 "Andes Star v3.0",
2951 "Andes Star v3.0m"
2952 };
2953
2954 abi = EF_NDS_ABI & e_flags;
2955 arch = EF_NDS_ARCH & e_flags;
2956 config = EF_NDS_INST & e_flags;
2957 version = EF_NDS32_ELF_VERSION & e_flags;
2958
2959 memset (buf, 0, size);
2960
2961 switch (abi)
2962 {
2963 case E_NDS_ABI_V0:
2964 case E_NDS_ABI_V1:
2965 case E_NDS_ABI_V2:
2966 case E_NDS_ABI_V2FP:
2967 case E_NDS_ABI_AABI:
40c7a7cb 2968 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2969 /* In case there are holes in the array. */
2970 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2971 break;
2972
2973 default:
2974 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2975 break;
2976 }
2977
2978 switch (version)
2979 {
2980 case E_NDS32_ELF_VER_1_2:
2981 case E_NDS32_ELF_VER_1_3:
2982 case E_NDS32_ELF_VER_1_4:
2983 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2984 break;
2985
2986 default:
2987 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2988 break;
2989 }
2990
2991 if (E_NDS_ABI_V0 == abi)
2992 {
2993 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2994 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2995 if (arch == E_NDS_ARCH_STAR_V1_0)
2996 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2997 return;
2998 }
2999
3000 switch (arch)
3001 {
3002 case E_NDS_ARCH_STAR_V1_0:
3003 case E_NDS_ARCH_STAR_V2_0:
3004 case E_NDS_ARCH_STAR_V3_0:
3005 case E_NDS_ARCH_STAR_V3_M:
3006 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3007 break;
3008
3009 default:
3010 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3011 /* ARCH version determines how the e_flags are interpreted.
3012 If it is unknown, we cannot proceed. */
3013 return;
3014 }
3015
3016 /* Newer ABI; Now handle architecture specific flags. */
3017 if (arch == E_NDS_ARCH_STAR_V1_0)
3018 {
3019 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3020 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3021
3022 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3023 r += snprintf (buf + r, size -r, ", MAC");
3024
3025 if (config & E_NDS32_HAS_DIV_INST)
3026 r += snprintf (buf + r, size -r, ", DIV");
3027
3028 if (config & E_NDS32_HAS_16BIT_INST)
3029 r += snprintf (buf + r, size -r, ", 16b");
3030 }
3031 else
3032 {
3033 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3034 {
3035 if (version <= E_NDS32_ELF_VER_1_3)
3036 r += snprintf (buf + r, size -r, ", [B8]");
3037 else
3038 r += snprintf (buf + r, size -r, ", EX9");
3039 }
3040
3041 if (config & E_NDS32_HAS_MAC_DX_INST)
3042 r += snprintf (buf + r, size -r, ", MAC_DX");
3043
3044 if (config & E_NDS32_HAS_DIV_DX_INST)
3045 r += snprintf (buf + r, size -r, ", DIV_DX");
3046
3047 if (config & E_NDS32_HAS_16BIT_INST)
3048 {
3049 if (version <= E_NDS32_ELF_VER_1_3)
3050 r += snprintf (buf + r, size -r, ", 16b");
3051 else
3052 r += snprintf (buf + r, size -r, ", IFC");
3053 }
3054 }
3055
3056 if (config & E_NDS32_HAS_EXT_INST)
3057 r += snprintf (buf + r, size -r, ", PERF1");
3058
3059 if (config & E_NDS32_HAS_EXT2_INST)
3060 r += snprintf (buf + r, size -r, ", PERF2");
3061
3062 if (config & E_NDS32_HAS_FPU_INST)
3063 {
32ec8896 3064 has_fpu = TRUE;
35c08157
KLC
3065 r += snprintf (buf + r, size -r, ", FPU_SP");
3066 }
3067
3068 if (config & E_NDS32_HAS_FPU_DP_INST)
3069 {
32ec8896 3070 has_fpu = TRUE;
35c08157
KLC
3071 r += snprintf (buf + r, size -r, ", FPU_DP");
3072 }
3073
3074 if (config & E_NDS32_HAS_FPU_MAC_INST)
3075 {
32ec8896 3076 has_fpu = TRUE;
35c08157
KLC
3077 r += snprintf (buf + r, size -r, ", FPU_MAC");
3078 }
3079
3080 if (has_fpu)
3081 {
3082 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3083 {
3084 case E_NDS32_FPU_REG_8SP_4DP:
3085 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3086 break;
3087 case E_NDS32_FPU_REG_16SP_8DP:
3088 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3089 break;
3090 case E_NDS32_FPU_REG_32SP_16DP:
3091 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3092 break;
3093 case E_NDS32_FPU_REG_32SP_32DP:
3094 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3095 break;
3096 }
3097 }
3098
3099 if (config & E_NDS32_HAS_AUDIO_INST)
3100 r += snprintf (buf + r, size -r, ", AUDIO");
3101
3102 if (config & E_NDS32_HAS_STRING_INST)
3103 r += snprintf (buf + r, size -r, ", STR");
3104
3105 if (config & E_NDS32_HAS_REDUCED_REGS)
3106 r += snprintf (buf + r, size -r, ", 16REG");
3107
3108 if (config & E_NDS32_HAS_VIDEO_INST)
3109 {
3110 if (version <= E_NDS32_ELF_VER_1_3)
3111 r += snprintf (buf + r, size -r, ", VIDEO");
3112 else
3113 r += snprintf (buf + r, size -r, ", SATURATION");
3114 }
3115
3116 if (config & E_NDS32_HAS_ENCRIPT_INST)
3117 r += snprintf (buf + r, size -r, ", ENCRP");
3118
3119 if (config & E_NDS32_HAS_L2C_INST)
3120 r += snprintf (buf + r, size -r, ", L2C");
3121}
3122
252b5132 3123static char *
dda8d76d 3124get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3125{
b34976b6 3126 static char buf[1024];
252b5132
RH
3127
3128 buf[0] = '\0';
76da6bbe 3129
252b5132
RH
3130 if (e_flags)
3131 {
3132 switch (e_machine)
3133 {
3134 default:
3135 break;
3136
886a2506 3137 case EM_ARC_COMPACT2:
886a2506 3138 case EM_ARC_COMPACT:
a9522a21
AB
3139 decode_ARC_machine_flags (e_flags, e_machine, buf);
3140 break;
886a2506 3141
f3485b74
NC
3142 case EM_ARM:
3143 decode_ARM_machine_flags (e_flags, buf);
3144 break;
76da6bbe 3145
343433df
AB
3146 case EM_AVR:
3147 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3148 break;
3149
781303ce
MF
3150 case EM_BLACKFIN:
3151 if (e_flags & EF_BFIN_PIC)
3152 strcat (buf, ", PIC");
3153
3154 if (e_flags & EF_BFIN_FDPIC)
3155 strcat (buf, ", FDPIC");
3156
3157 if (e_flags & EF_BFIN_CODE_IN_L1)
3158 strcat (buf, ", code in L1");
3159
3160 if (e_flags & EF_BFIN_DATA_IN_L1)
3161 strcat (buf, ", data in L1");
3162
3163 break;
3164
ec2dfb42
AO
3165 case EM_CYGNUS_FRV:
3166 switch (e_flags & EF_FRV_CPU_MASK)
3167 {
3168 case EF_FRV_CPU_GENERIC:
3169 break;
3170
3171 default:
3172 strcat (buf, ", fr???");
3173 break;
57346661 3174
ec2dfb42
AO
3175 case EF_FRV_CPU_FR300:
3176 strcat (buf, ", fr300");
3177 break;
3178
3179 case EF_FRV_CPU_FR400:
3180 strcat (buf, ", fr400");
3181 break;
3182 case EF_FRV_CPU_FR405:
3183 strcat (buf, ", fr405");
3184 break;
3185
3186 case EF_FRV_CPU_FR450:
3187 strcat (buf, ", fr450");
3188 break;
3189
3190 case EF_FRV_CPU_FR500:
3191 strcat (buf, ", fr500");
3192 break;
3193 case EF_FRV_CPU_FR550:
3194 strcat (buf, ", fr550");
3195 break;
3196
3197 case EF_FRV_CPU_SIMPLE:
3198 strcat (buf, ", simple");
3199 break;
3200 case EF_FRV_CPU_TOMCAT:
3201 strcat (buf, ", tomcat");
3202 break;
3203 }
1c877e87 3204 break;
ec2dfb42 3205
53c7db4b 3206 case EM_68K:
425c6cb0 3207 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3208 strcat (buf, ", m68000");
425c6cb0 3209 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3210 strcat (buf, ", cpu32");
3211 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3212 strcat (buf, ", fido_a");
425c6cb0 3213 else
266abb8f 3214 {
2cf0635d
NC
3215 char const * isa = _("unknown");
3216 char const * mac = _("unknown mac");
3217 char const * additional = NULL;
0112cd26 3218
c694fd50 3219 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3220 {
c694fd50 3221 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3222 isa = "A";
3223 additional = ", nodiv";
3224 break;
c694fd50 3225 case EF_M68K_CF_ISA_A:
266abb8f
NS
3226 isa = "A";
3227 break;
c694fd50 3228 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3229 isa = "A+";
3230 break;
c694fd50 3231 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3232 isa = "B";
3233 additional = ", nousp";
3234 break;
c694fd50 3235 case EF_M68K_CF_ISA_B:
266abb8f
NS
3236 isa = "B";
3237 break;
f608cd77
NS
3238 case EF_M68K_CF_ISA_C:
3239 isa = "C";
3240 break;
3241 case EF_M68K_CF_ISA_C_NODIV:
3242 isa = "C";
3243 additional = ", nodiv";
3244 break;
266abb8f
NS
3245 }
3246 strcat (buf, ", cf, isa ");
3247 strcat (buf, isa);
0b2e31dc
NS
3248 if (additional)
3249 strcat (buf, additional);
c694fd50 3250 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3251 strcat (buf, ", float");
c694fd50 3252 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3253 {
3254 case 0:
3255 mac = NULL;
3256 break;
c694fd50 3257 case EF_M68K_CF_MAC:
266abb8f
NS
3258 mac = "mac";
3259 break;
c694fd50 3260 case EF_M68K_CF_EMAC:
266abb8f
NS
3261 mac = "emac";
3262 break;
f608cd77
NS
3263 case EF_M68K_CF_EMAC_B:
3264 mac = "emac_b";
3265 break;
266abb8f
NS
3266 }
3267 if (mac)
3268 {
3269 strcat (buf, ", ");
3270 strcat (buf, mac);
3271 }
266abb8f 3272 }
53c7db4b 3273 break;
33c63f9d 3274
153a2776
NC
3275 case EM_CYGNUS_MEP:
3276 switch (e_flags & EF_MEP_CPU_MASK)
3277 {
3278 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3279 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3280 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3281 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3282 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3283 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3284 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3285 }
3286
3287 switch (e_flags & EF_MEP_COP_MASK)
3288 {
3289 case EF_MEP_COP_NONE: break;
3290 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3291 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3292 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3293 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3294 default: strcat (buf, _("<unknown MeP copro type>")); break;
3295 }
3296
3297 if (e_flags & EF_MEP_LIBRARY)
3298 strcat (buf, ", Built for Library");
3299
3300 if (e_flags & EF_MEP_INDEX_MASK)
3301 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3302 e_flags & EF_MEP_INDEX_MASK);
3303
3304 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3305 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3306 e_flags & ~ EF_MEP_ALL_FLAGS);
3307 break;
3308
252b5132
RH
3309 case EM_PPC:
3310 if (e_flags & EF_PPC_EMB)
3311 strcat (buf, ", emb");
3312
3313 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3314 strcat (buf, _(", relocatable"));
252b5132
RH
3315
3316 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3317 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3318 break;
3319
ee67d69a
AM
3320 case EM_PPC64:
3321 if (e_flags & EF_PPC64_ABI)
3322 {
3323 char abi[] = ", abiv0";
3324
3325 abi[6] += e_flags & EF_PPC64_ABI;
3326 strcat (buf, abi);
3327 }
3328 break;
3329
708e2187
NC
3330 case EM_V800:
3331 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3332 strcat (buf, ", RH850 ABI");
0b4362b0 3333
708e2187
NC
3334 if (e_flags & EF_V800_850E3)
3335 strcat (buf, ", V3 architecture");
3336
3337 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3338 strcat (buf, ", FPU not used");
3339
3340 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3341 strcat (buf, ", regmode: COMMON");
3342
3343 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3344 strcat (buf, ", r4 not used");
3345
3346 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3347 strcat (buf, ", r30 not used");
3348
3349 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3350 strcat (buf, ", r5 not used");
3351
3352 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3353 strcat (buf, ", r2 not used");
3354
3355 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3356 {
3357 switch (e_flags & - e_flags)
3358 {
3359 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3360 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3361 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3362 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3363 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3364 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3365 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3366 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3367 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3368 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3369 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3370 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3371 default: break;
3372 }
3373 }
3374 break;
3375
2b0337b0 3376 case EM_V850:
252b5132
RH
3377 case EM_CYGNUS_V850:
3378 switch (e_flags & EF_V850_ARCH)
3379 {
78c8d46c
NC
3380 case E_V850E3V5_ARCH:
3381 strcat (buf, ", v850e3v5");
3382 break;
1cd986c5
NC
3383 case E_V850E2V3_ARCH:
3384 strcat (buf, ", v850e2v3");
3385 break;
3386 case E_V850E2_ARCH:
3387 strcat (buf, ", v850e2");
3388 break;
3389 case E_V850E1_ARCH:
3390 strcat (buf, ", v850e1");
8ad30312 3391 break;
252b5132
RH
3392 case E_V850E_ARCH:
3393 strcat (buf, ", v850e");
3394 break;
252b5132
RH
3395 case E_V850_ARCH:
3396 strcat (buf, ", v850");
3397 break;
3398 default:
2b692964 3399 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3400 break;
3401 }
3402 break;
3403
2b0337b0 3404 case EM_M32R:
252b5132
RH
3405 case EM_CYGNUS_M32R:
3406 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3407 strcat (buf, ", m32r");
252b5132
RH
3408 break;
3409
3410 case EM_MIPS:
4fe85591 3411 case EM_MIPS_RS3_LE:
252b5132
RH
3412 if (e_flags & EF_MIPS_NOREORDER)
3413 strcat (buf, ", noreorder");
3414
3415 if (e_flags & EF_MIPS_PIC)
3416 strcat (buf, ", pic");
3417
3418 if (e_flags & EF_MIPS_CPIC)
3419 strcat (buf, ", cpic");
3420
d1bdd336
TS
3421 if (e_flags & EF_MIPS_UCODE)
3422 strcat (buf, ", ugen_reserved");
3423
252b5132
RH
3424 if (e_flags & EF_MIPS_ABI2)
3425 strcat (buf, ", abi2");
3426
43521d43
TS
3427 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3428 strcat (buf, ", odk first");
3429
a5d22d2a
TS
3430 if (e_flags & EF_MIPS_32BITMODE)
3431 strcat (buf, ", 32bitmode");
3432
ba92f887
MR
3433 if (e_flags & EF_MIPS_NAN2008)
3434 strcat (buf, ", nan2008");
3435
fef1b0b3
SE
3436 if (e_flags & EF_MIPS_FP64)
3437 strcat (buf, ", fp64");
3438
156c2f8b
NC
3439 switch ((e_flags & EF_MIPS_MACH))
3440 {
3441 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3442 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3443 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3444 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3445 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3446 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3447 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3448 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3449 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3450 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3451 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3452 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3453 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3454 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3455 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3456 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3457 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3458 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3459 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3460 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3461 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3462 case 0:
3463 /* We simply ignore the field in this case to avoid confusion:
3464 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3465 extension. */
3466 break;
2b692964 3467 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3468 }
43521d43
TS
3469
3470 switch ((e_flags & EF_MIPS_ABI))
3471 {
3472 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3473 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3474 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3475 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3476 case 0:
3477 /* We simply ignore the field in this case to avoid confusion:
3478 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3479 This means it is likely to be an o32 file, but not for
3480 sure. */
3481 break;
2b692964 3482 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3483 }
3484
3485 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3486 strcat (buf, ", mdmx");
3487
3488 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3489 strcat (buf, ", mips16");
3490
df58fc94
RS
3491 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3492 strcat (buf, ", micromips");
3493
43521d43
TS
3494 switch ((e_flags & EF_MIPS_ARCH))
3495 {
3496 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3497 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3498 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3499 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3500 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3501 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3502 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3503 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3504 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3505 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3506 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3507 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3508 }
252b5132 3509 break;
351b4b40 3510
35c08157
KLC
3511 case EM_NDS32:
3512 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3513 break;
3514
fe944acf
FT
3515 case EM_NFP:
3516 switch (EF_NFP_MACH (e_flags))
3517 {
3518 case E_NFP_MACH_3200:
3519 strcat (buf, ", NFP-32xx");
3520 break;
3521 case E_NFP_MACH_6000:
3522 strcat (buf, ", NFP-6xxx");
3523 break;
3524 }
3525 break;
3526
e23eba97
NC
3527 case EM_RISCV:
3528 if (e_flags & EF_RISCV_RVC)
3529 strcat (buf, ", RVC");
2922d21d 3530
7f999549
JW
3531 if (e_flags & EF_RISCV_RVE)
3532 strcat (buf, ", RVE");
3533
2922d21d
AW
3534 switch (e_flags & EF_RISCV_FLOAT_ABI)
3535 {
3536 case EF_RISCV_FLOAT_ABI_SOFT:
3537 strcat (buf, ", soft-float ABI");
3538 break;
3539
3540 case EF_RISCV_FLOAT_ABI_SINGLE:
3541 strcat (buf, ", single-float ABI");
3542 break;
3543
3544 case EF_RISCV_FLOAT_ABI_DOUBLE:
3545 strcat (buf, ", double-float ABI");
3546 break;
3547
3548 case EF_RISCV_FLOAT_ABI_QUAD:
3549 strcat (buf, ", quad-float ABI");
3550 break;
3551 }
e23eba97
NC
3552 break;
3553
ccde1100
AO
3554 case EM_SH:
3555 switch ((e_flags & EF_SH_MACH_MASK))
3556 {
3557 case EF_SH1: strcat (buf, ", sh1"); break;
3558 case EF_SH2: strcat (buf, ", sh2"); break;
3559 case EF_SH3: strcat (buf, ", sh3"); break;
3560 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3561 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3562 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3563 case EF_SH3E: strcat (buf, ", sh3e"); break;
3564 case EF_SH4: strcat (buf, ", sh4"); break;
3565 case EF_SH5: strcat (buf, ", sh5"); break;
3566 case EF_SH2E: strcat (buf, ", sh2e"); break;
3567 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3568 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3569 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3570 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3571 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3572 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3573 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3574 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3575 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3576 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3577 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3578 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3579 }
3580
cec6a5b8
MR
3581 if (e_flags & EF_SH_PIC)
3582 strcat (buf, ", pic");
3583
3584 if (e_flags & EF_SH_FDPIC)
3585 strcat (buf, ", fdpic");
ccde1100 3586 break;
948f632f 3587
73589c9d
CS
3588 case EM_OR1K:
3589 if (e_flags & EF_OR1K_NODELAY)
3590 strcat (buf, ", no delay");
3591 break;
57346661 3592
351b4b40
RH
3593 case EM_SPARCV9:
3594 if (e_flags & EF_SPARC_32PLUS)
3595 strcat (buf, ", v8+");
3596
3597 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3598 strcat (buf, ", ultrasparcI");
3599
3600 if (e_flags & EF_SPARC_SUN_US3)
3601 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3602
3603 if (e_flags & EF_SPARC_HAL_R1)
3604 strcat (buf, ", halr1");
3605
3606 if (e_flags & EF_SPARC_LEDATA)
3607 strcat (buf, ", ledata");
3608
3609 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3610 strcat (buf, ", tso");
3611
3612 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3613 strcat (buf, ", pso");
3614
3615 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3616 strcat (buf, ", rmo");
3617 break;
7d466069 3618
103f02d3
UD
3619 case EM_PARISC:
3620 switch (e_flags & EF_PARISC_ARCH)
3621 {
3622 case EFA_PARISC_1_0:
3623 strcpy (buf, ", PA-RISC 1.0");
3624 break;
3625 case EFA_PARISC_1_1:
3626 strcpy (buf, ", PA-RISC 1.1");
3627 break;
3628 case EFA_PARISC_2_0:
3629 strcpy (buf, ", PA-RISC 2.0");
3630 break;
3631 default:
3632 break;
3633 }
3634 if (e_flags & EF_PARISC_TRAPNIL)
3635 strcat (buf, ", trapnil");
3636 if (e_flags & EF_PARISC_EXT)
3637 strcat (buf, ", ext");
3638 if (e_flags & EF_PARISC_LSB)
3639 strcat (buf, ", lsb");
3640 if (e_flags & EF_PARISC_WIDE)
3641 strcat (buf, ", wide");
3642 if (e_flags & EF_PARISC_NO_KABP)
3643 strcat (buf, ", no kabp");
3644 if (e_flags & EF_PARISC_LAZYSWAP)
3645 strcat (buf, ", lazyswap");
30800947 3646 break;
76da6bbe 3647
7d466069 3648 case EM_PJ:
2b0337b0 3649 case EM_PJ_OLD:
7d466069
ILT
3650 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3651 strcat (buf, ", new calling convention");
3652
3653 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3654 strcat (buf, ", gnu calling convention");
3655 break;
4d6ed7c8
NC
3656
3657 case EM_IA_64:
3658 if ((e_flags & EF_IA_64_ABI64))
3659 strcat (buf, ", 64-bit");
3660 else
3661 strcat (buf, ", 32-bit");
3662 if ((e_flags & EF_IA_64_REDUCEDFP))
3663 strcat (buf, ", reduced fp model");
3664 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3665 strcat (buf, ", no function descriptors, constant gp");
3666 else if ((e_flags & EF_IA_64_CONS_GP))
3667 strcat (buf, ", constant gp");
3668 if ((e_flags & EF_IA_64_ABSOLUTE))
3669 strcat (buf, ", absolute");
dda8d76d 3670 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3671 {
3672 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3673 strcat (buf, ", vms_linkages");
3674 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3675 {
3676 case EF_IA_64_VMS_COMCOD_SUCCESS:
3677 break;
3678 case EF_IA_64_VMS_COMCOD_WARNING:
3679 strcat (buf, ", warning");
3680 break;
3681 case EF_IA_64_VMS_COMCOD_ERROR:
3682 strcat (buf, ", error");
3683 break;
3684 case EF_IA_64_VMS_COMCOD_ABORT:
3685 strcat (buf, ", abort");
3686 break;
3687 default:
bee0ee85
NC
3688 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3689 e_flags & EF_IA_64_VMS_COMCOD);
3690 strcat (buf, ", <unknown>");
28f997cf
TG
3691 }
3692 }
4d6ed7c8 3693 break;
179d3252
JT
3694
3695 case EM_VAX:
3696 if ((e_flags & EF_VAX_NONPIC))
3697 strcat (buf, ", non-PIC");
3698 if ((e_flags & EF_VAX_DFLOAT))
3699 strcat (buf, ", D-Float");
3700 if ((e_flags & EF_VAX_GFLOAT))
3701 strcat (buf, ", G-Float");
3702 break;
c7927a3c 3703
619ed720
EB
3704 case EM_VISIUM:
3705 if (e_flags & EF_VISIUM_ARCH_MCM)
3706 strcat (buf, ", mcm");
3707 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3708 strcat (buf, ", mcm24");
3709 if (e_flags & EF_VISIUM_ARCH_GR6)
3710 strcat (buf, ", gr6");
3711 break;
3712
4046d87a 3713 case EM_RL78:
1740ba0c
NC
3714 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3715 {
3716 case E_FLAG_RL78_ANY_CPU: break;
3717 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3718 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3719 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3720 }
856ea05c
KP
3721 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3722 strcat (buf, ", 64-bit doubles");
4046d87a 3723 break;
0b4362b0 3724
c7927a3c
NC
3725 case EM_RX:
3726 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3727 strcat (buf, ", 64-bit doubles");
3728 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3729 strcat (buf, ", dsp");
d4cb0ea0 3730 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3731 strcat (buf, ", pid");
708e2187
NC
3732 if (e_flags & E_FLAG_RX_ABI)
3733 strcat (buf, ", RX ABI");
3525236c
NC
3734 if (e_flags & E_FLAG_RX_SINSNS_SET)
3735 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3736 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3737 if (e_flags & E_FLAG_RX_V2)
3738 strcat (buf, ", V2");
f87673e0
YS
3739 if (e_flags & E_FLAG_RX_V3)
3740 strcat (buf, ", V3");
d4cb0ea0 3741 break;
55786da2
AK
3742
3743 case EM_S390:
3744 if (e_flags & EF_S390_HIGH_GPRS)
3745 strcat (buf, ", highgprs");
d4cb0ea0 3746 break;
40b36596
JM
3747
3748 case EM_TI_C6000:
3749 if ((e_flags & EF_C6000_REL))
3750 strcat (buf, ", relocatable module");
d4cb0ea0 3751 break;
13761a11
NC
3752
3753 case EM_MSP430:
3754 strcat (buf, _(": architecture variant: "));
3755 switch (e_flags & EF_MSP430_MACH)
3756 {
3757 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3758 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3759 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3760 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3761 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3762 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3763 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3764 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3765 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3766 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3767 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3768 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3769 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3770 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3771 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3772 default:
3773 strcat (buf, _(": unknown")); break;
3774 }
3775
3776 if (e_flags & ~ EF_MSP430_MACH)
3777 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3778 break;
3779
3780 case EM_Z80:
3781 switch (e_flags & EF_Z80_MACH_MSK)
3782 {
3783 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3784 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3785 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3786 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3787 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3788 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3789 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3790 default:
3791 strcat (buf, _(", unknown")); break;
3792 }
3793 break;
252b5132
RH
3794 }
3795 }
3796
3797 return buf;
3798}
3799
252b5132 3800static const char *
dda8d76d 3801get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3802{
3803 static char buff[32];
3804
3805 switch (osabi)
3806 {
3807 case ELFOSABI_NONE: return "UNIX - System V";
3808 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3809 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3810 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3811 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3812 case ELFOSABI_AIX: return "UNIX - AIX";
3813 case ELFOSABI_IRIX: return "UNIX - IRIX";
3814 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3815 case ELFOSABI_TRU64: return "UNIX - TRU64";
3816 case ELFOSABI_MODESTO: return "Novell - Modesto";
3817 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3818 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3819 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3820 case ELFOSABI_AROS: return "AROS";
11636f9e 3821 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3822 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3823 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3824 default:
40b36596 3825 if (osabi >= 64)
dda8d76d 3826 switch (filedata->file_header.e_machine)
40b36596
JM
3827 {
3828 case EM_ARM:
3829 switch (osabi)
3830 {
3831 case ELFOSABI_ARM: return "ARM";
18a20338 3832 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3833 default:
3834 break;
3835 }
3836 break;
3837
3838 case EM_MSP430:
3839 case EM_MSP430_OLD:
619ed720 3840 case EM_VISIUM:
40b36596
JM
3841 switch (osabi)
3842 {
3843 case ELFOSABI_STANDALONE: return _("Standalone App");
3844 default:
3845 break;
3846 }
3847 break;
3848
3849 case EM_TI_C6000:
3850 switch (osabi)
3851 {
3852 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3853 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3854 default:
3855 break;
3856 }
3857 break;
3858
3859 default:
3860 break;
3861 }
e9e44622 3862 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3863 return buff;
3864 }
3865}
3866
a06ea964
NC
3867static const char *
3868get_aarch64_segment_type (unsigned long type)
3869{
3870 switch (type)
3871 {
32ec8896
NC
3872 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3873 default: return NULL;
a06ea964 3874 }
a06ea964
NC
3875}
3876
b294bdf8
MM
3877static const char *
3878get_arm_segment_type (unsigned long type)
3879{
3880 switch (type)
3881 {
32ec8896
NC
3882 case PT_ARM_EXIDX: return "EXIDX";
3883 default: return NULL;
b294bdf8 3884 }
b294bdf8
MM
3885}
3886
b4cbbe8f
AK
3887static const char *
3888get_s390_segment_type (unsigned long type)
3889{
3890 switch (type)
3891 {
3892 case PT_S390_PGSTE: return "S390_PGSTE";
3893 default: return NULL;
3894 }
3895}
3896
d3ba0551
AM
3897static const char *
3898get_mips_segment_type (unsigned long type)
252b5132
RH
3899{
3900 switch (type)
3901 {
32ec8896
NC
3902 case PT_MIPS_REGINFO: return "REGINFO";
3903 case PT_MIPS_RTPROC: return "RTPROC";
3904 case PT_MIPS_OPTIONS: return "OPTIONS";
3905 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3906 default: return NULL;
252b5132 3907 }
252b5132
RH
3908}
3909
103f02d3 3910static const char *
d3ba0551 3911get_parisc_segment_type (unsigned long type)
103f02d3
UD
3912{
3913 switch (type)
3914 {
103f02d3
UD
3915 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3916 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3917 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3918 default: return NULL;
103f02d3 3919 }
103f02d3
UD
3920}
3921
4d6ed7c8 3922static const char *
d3ba0551 3923get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3924{
3925 switch (type)
3926 {
3927 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3928 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3929 default: return NULL;
4d6ed7c8 3930 }
4d6ed7c8
NC
3931}
3932
40b36596
JM
3933static const char *
3934get_tic6x_segment_type (unsigned long type)
3935{
3936 switch (type)
3937 {
32ec8896
NC
3938 case PT_C6000_PHATTR: return "C6000_PHATTR";
3939 default: return NULL;
40b36596 3940 }
40b36596
JM
3941}
3942
df3a023b
AM
3943static const char *
3944get_hpux_segment_type (unsigned long type, unsigned e_machine)
3945{
3946 if (e_machine == EM_PARISC)
3947 switch (type)
3948 {
3949 case PT_HP_TLS: return "HP_TLS";
3950 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3951 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3952 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3953 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3954 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3955 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3956 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3957 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3958 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3959 case PT_HP_PARALLEL: return "HP_PARALLEL";
3960 case PT_HP_FASTBIND: return "HP_FASTBIND";
3961 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3962 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3963 case PT_HP_STACK: return "HP_STACK";
3964 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
3965 default: return NULL;
3966 }
3967
3968 if (e_machine == EM_IA_64)
3969 switch (type)
3970 {
3971 case PT_HP_TLS: return "HP_TLS";
3972 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3973 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3974 case PT_IA_64_HP_STACK: return "HP_STACK";
3975 default: return NULL;
3976 }
3977
3978 return NULL;
3979}
3980
5522f910
NC
3981static const char *
3982get_solaris_segment_type (unsigned long type)
3983{
3984 switch (type)
3985 {
3986 case 0x6464e550: return "PT_SUNW_UNWIND";
3987 case 0x6474e550: return "PT_SUNW_EH_FRAME";
3988 case 0x6ffffff7: return "PT_LOSUNW";
3989 case 0x6ffffffa: return "PT_SUNWBSS";
3990 case 0x6ffffffb: return "PT_SUNWSTACK";
3991 case 0x6ffffffc: return "PT_SUNWDTRACE";
3992 case 0x6ffffffd: return "PT_SUNWCAP";
3993 case 0x6fffffff: return "PT_HISUNW";
32ec8896 3994 default: return NULL;
5522f910
NC
3995 }
3996}
3997
252b5132 3998static const char *
dda8d76d 3999get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4000{
b34976b6 4001 static char buff[32];
252b5132
RH
4002
4003 switch (p_type)
4004 {
b34976b6
AM
4005 case PT_NULL: return "NULL";
4006 case PT_LOAD: return "LOAD";
252b5132 4007 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4008 case PT_INTERP: return "INTERP";
4009 case PT_NOTE: return "NOTE";
4010 case PT_SHLIB: return "SHLIB";
4011 case PT_PHDR: return "PHDR";
13ae64f3 4012 case PT_TLS: return "TLS";
32ec8896 4013 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4014 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4015 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4016 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4017
252b5132 4018 default:
df3a023b 4019 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4020 {
2cf0635d 4021 const char * result;
103f02d3 4022
dda8d76d 4023 switch (filedata->file_header.e_machine)
252b5132 4024 {
a06ea964
NC
4025 case EM_AARCH64:
4026 result = get_aarch64_segment_type (p_type);
4027 break;
b294bdf8
MM
4028 case EM_ARM:
4029 result = get_arm_segment_type (p_type);
4030 break;
252b5132 4031 case EM_MIPS:
4fe85591 4032 case EM_MIPS_RS3_LE:
252b5132
RH
4033 result = get_mips_segment_type (p_type);
4034 break;
103f02d3
UD
4035 case EM_PARISC:
4036 result = get_parisc_segment_type (p_type);
4037 break;
4d6ed7c8
NC
4038 case EM_IA_64:
4039 result = get_ia64_segment_type (p_type);
4040 break;
40b36596
JM
4041 case EM_TI_C6000:
4042 result = get_tic6x_segment_type (p_type);
4043 break;
b4cbbe8f
AK
4044 case EM_S390:
4045 case EM_S390_OLD:
4046 result = get_s390_segment_type (p_type);
4047 break;
252b5132
RH
4048 default:
4049 result = NULL;
4050 break;
4051 }
103f02d3 4052
252b5132
RH
4053 if (result != NULL)
4054 return result;
103f02d3 4055
1a9ccd70 4056 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4057 }
4058 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4059 {
df3a023b 4060 const char * result = NULL;
103f02d3 4061
df3a023b 4062 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4063 {
df3a023b
AM
4064 case ELFOSABI_GNU:
4065 case ELFOSABI_FREEBSD:
4066 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4067 {
4068 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4069 result = buff;
4070 }
103f02d3 4071 break;
df3a023b
AM
4072 case ELFOSABI_HPUX:
4073 result = get_hpux_segment_type (p_type,
4074 filedata->file_header.e_machine);
4075 break;
4076 case ELFOSABI_SOLARIS:
4077 result = get_solaris_segment_type (p_type);
00428cca 4078 break;
103f02d3 4079 default:
103f02d3
UD
4080 break;
4081 }
103f02d3
UD
4082 if (result != NULL)
4083 return result;
4084
1a9ccd70 4085 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4086 }
252b5132 4087 else
e9e44622 4088 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4089
4090 return buff;
4091 }
4092}
4093
53a346d8
CZ
4094static const char *
4095get_arc_section_type_name (unsigned int sh_type)
4096{
4097 switch (sh_type)
4098 {
4099 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4100 default:
4101 break;
4102 }
4103 return NULL;
4104}
4105
252b5132 4106static const char *
d3ba0551 4107get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4108{
4109 switch (sh_type)
4110 {
b34976b6
AM
4111 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4112 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4113 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4114 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4115 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4116 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4117 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4118 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4119 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4120 case SHT_MIPS_RELD: return "MIPS_RELD";
4121 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4122 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4123 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4124 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4125 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4126 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4127 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4128 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4129 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4130 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4131 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4132 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4133 case SHT_MIPS_LINE: return "MIPS_LINE";
4134 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4135 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4136 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4137 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4138 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4139 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4140 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4141 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4142 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4143 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4144 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4145 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4146 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4147 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4148 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4149 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4150 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4151 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4152 default:
4153 break;
4154 }
4155 return NULL;
4156}
4157
103f02d3 4158static const char *
d3ba0551 4159get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4160{
4161 switch (sh_type)
4162 {
4163 case SHT_PARISC_EXT: return "PARISC_EXT";
4164 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4165 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4166 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4167 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4168 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4169 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4170 default: return NULL;
103f02d3 4171 }
103f02d3
UD
4172}
4173
4d6ed7c8 4174static const char *
dda8d76d 4175get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4176{
18bd398b 4177 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4178 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4179 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4180
4d6ed7c8
NC
4181 switch (sh_type)
4182 {
148b93f2
NC
4183 case SHT_IA_64_EXT: return "IA_64_EXT";
4184 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4185 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4186 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4187 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4188 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4189 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4190 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4191 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4192 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4193 default:
4194 break;
4195 }
4196 return NULL;
4197}
4198
d2b2c203
DJ
4199static const char *
4200get_x86_64_section_type_name (unsigned int sh_type)
4201{
4202 switch (sh_type)
4203 {
4204 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4205 default: return NULL;
d2b2c203 4206 }
d2b2c203
DJ
4207}
4208
a06ea964
NC
4209static const char *
4210get_aarch64_section_type_name (unsigned int sh_type)
4211{
4212 switch (sh_type)
4213 {
32ec8896
NC
4214 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4215 default: return NULL;
a06ea964 4216 }
a06ea964
NC
4217}
4218
40a18ebd
NC
4219static const char *
4220get_arm_section_type_name (unsigned int sh_type)
4221{
4222 switch (sh_type)
4223 {
7f6fed87
NC
4224 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4225 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4226 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4227 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4228 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4229 default: return NULL;
40a18ebd 4230 }
40a18ebd
NC
4231}
4232
40b36596
JM
4233static const char *
4234get_tic6x_section_type_name (unsigned int sh_type)
4235{
4236 switch (sh_type)
4237 {
32ec8896
NC
4238 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4239 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4240 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4241 case SHT_TI_ICODE: return "TI_ICODE";
4242 case SHT_TI_XREF: return "TI_XREF";
4243 case SHT_TI_HANDLER: return "TI_HANDLER";
4244 case SHT_TI_INITINFO: return "TI_INITINFO";
4245 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4246 default: return NULL;
40b36596 4247 }
40b36596
JM
4248}
4249
13761a11
NC
4250static const char *
4251get_msp430x_section_type_name (unsigned int sh_type)
4252{
4253 switch (sh_type)
4254 {
32ec8896
NC
4255 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4256 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4257 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4258 default: return NULL;
13761a11
NC
4259 }
4260}
4261
fe944acf
FT
4262static const char *
4263get_nfp_section_type_name (unsigned int sh_type)
4264{
4265 switch (sh_type)
4266 {
4267 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4268 case SHT_NFP_INITREG: return "NFP_INITREG";
4269 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4270 default: return NULL;
4271 }
4272}
4273
685080f2
NC
4274static const char *
4275get_v850_section_type_name (unsigned int sh_type)
4276{
4277 switch (sh_type)
4278 {
32ec8896
NC
4279 case SHT_V850_SCOMMON: return "V850 Small Common";
4280 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4281 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4282 case SHT_RENESAS_IOP: return "RENESAS IOP";
4283 case SHT_RENESAS_INFO: return "RENESAS INFO";
4284 default: return NULL;
685080f2
NC
4285 }
4286}
4287
2dc8dd17
JW
4288static const char *
4289get_riscv_section_type_name (unsigned int sh_type)
4290{
4291 switch (sh_type)
4292 {
4293 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4294 default: return NULL;
4295 }
4296}
4297
252b5132 4298static const char *
dda8d76d 4299get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4300{
b34976b6 4301 static char buff[32];
9fb71ee4 4302 const char * result;
252b5132
RH
4303
4304 switch (sh_type)
4305 {
4306 case SHT_NULL: return "NULL";
4307 case SHT_PROGBITS: return "PROGBITS";
4308 case SHT_SYMTAB: return "SYMTAB";
4309 case SHT_STRTAB: return "STRTAB";
4310 case SHT_RELA: return "RELA";
4311 case SHT_HASH: return "HASH";
4312 case SHT_DYNAMIC: return "DYNAMIC";
4313 case SHT_NOTE: return "NOTE";
4314 case SHT_NOBITS: return "NOBITS";
4315 case SHT_REL: return "REL";
4316 case SHT_SHLIB: return "SHLIB";
4317 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4318 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4319 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4320 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4321 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4322 case SHT_GROUP: return "GROUP";
67ce483b 4323 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4324 case SHT_GNU_verdef: return "VERDEF";
4325 case SHT_GNU_verneed: return "VERNEED";
4326 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4327 case 0x6ffffff0: return "VERSYM";
4328 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4329 case 0x7ffffffd: return "AUXILIARY";
4330 case 0x7fffffff: return "FILTER";
047b2264 4331 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4332
4333 default:
4334 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4335 {
dda8d76d 4336 switch (filedata->file_header.e_machine)
252b5132 4337 {
53a346d8
CZ
4338 case EM_ARC:
4339 case EM_ARC_COMPACT:
4340 case EM_ARC_COMPACT2:
4341 result = get_arc_section_type_name (sh_type);
4342 break;
252b5132 4343 case EM_MIPS:
4fe85591 4344 case EM_MIPS_RS3_LE:
252b5132
RH
4345 result = get_mips_section_type_name (sh_type);
4346 break;
103f02d3
UD
4347 case EM_PARISC:
4348 result = get_parisc_section_type_name (sh_type);
4349 break;
4d6ed7c8 4350 case EM_IA_64:
dda8d76d 4351 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4352 break;
d2b2c203 4353 case EM_X86_64:
8a9036a4 4354 case EM_L1OM:
7a9068fe 4355 case EM_K1OM:
d2b2c203
DJ
4356 result = get_x86_64_section_type_name (sh_type);
4357 break;
a06ea964
NC
4358 case EM_AARCH64:
4359 result = get_aarch64_section_type_name (sh_type);
4360 break;
40a18ebd
NC
4361 case EM_ARM:
4362 result = get_arm_section_type_name (sh_type);
4363 break;
40b36596
JM
4364 case EM_TI_C6000:
4365 result = get_tic6x_section_type_name (sh_type);
4366 break;
13761a11
NC
4367 case EM_MSP430:
4368 result = get_msp430x_section_type_name (sh_type);
4369 break;
fe944acf
FT
4370 case EM_NFP:
4371 result = get_nfp_section_type_name (sh_type);
4372 break;
685080f2
NC
4373 case EM_V800:
4374 case EM_V850:
4375 case EM_CYGNUS_V850:
4376 result = get_v850_section_type_name (sh_type);
4377 break;
2dc8dd17
JW
4378 case EM_RISCV:
4379 result = get_riscv_section_type_name (sh_type);
4380 break;
252b5132
RH
4381 default:
4382 result = NULL;
4383 break;
4384 }
4385
4386 if (result != NULL)
4387 return result;
4388
9fb71ee4 4389 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4390 }
4391 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4392 {
dda8d76d 4393 switch (filedata->file_header.e_machine)
148b93f2
NC
4394 {
4395 case EM_IA_64:
dda8d76d 4396 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4397 break;
4398 default:
dda8d76d 4399 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4400 result = get_solaris_section_type (sh_type);
4401 else
1b4b80bf
NC
4402 {
4403 switch (sh_type)
4404 {
4405 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4406 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4407 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4408 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4409 default:
4410 result = NULL;
4411 break;
4412 }
4413 }
148b93f2
NC
4414 break;
4415 }
4416
4417 if (result != NULL)
4418 return result;
4419
9fb71ee4 4420 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4421 }
252b5132 4422 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4423 {
dda8d76d 4424 switch (filedata->file_header.e_machine)
685080f2
NC
4425 {
4426 case EM_V800:
4427 case EM_V850:
4428 case EM_CYGNUS_V850:
9fb71ee4 4429 result = get_v850_section_type_name (sh_type);
a9fb83be 4430 break;
685080f2 4431 default:
9fb71ee4 4432 result = NULL;
685080f2
NC
4433 break;
4434 }
4435
9fb71ee4
NC
4436 if (result != NULL)
4437 return result;
4438
4439 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4440 }
252b5132 4441 else
a7dbfd1c
NC
4442 /* This message is probably going to be displayed in a 15
4443 character wide field, so put the hex value first. */
4444 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4445
252b5132
RH
4446 return buff;
4447 }
4448}
4449
2979dc34 4450#define OPTION_DEBUG_DUMP 512
2c610e4b 4451#define OPTION_DYN_SYMS 513
fd2f0033
TT
4452#define OPTION_DWARF_DEPTH 514
4453#define OPTION_DWARF_START 515
4723351a 4454#define OPTION_DWARF_CHECK 516
7d9813f1
NA
4455#define OPTION_CTF_DUMP 517
4456#define OPTION_CTF_PARENT 518
4457#define OPTION_CTF_SYMBOLS 519
4458#define OPTION_CTF_STRINGS 520
2979dc34 4459
85b1c36d 4460static struct option options[] =
252b5132 4461{
b34976b6 4462 {"all", no_argument, 0, 'a'},
252b5132
RH
4463 {"file-header", no_argument, 0, 'h'},
4464 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4465 {"headers", no_argument, 0, 'e'},
4466 {"histogram", no_argument, 0, 'I'},
4467 {"segments", no_argument, 0, 'l'},
4468 {"sections", no_argument, 0, 'S'},
252b5132 4469 {"section-headers", no_argument, 0, 'S'},
f5842774 4470 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4471 {"section-details", no_argument, 0, 't'},
595cf52e 4472 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4473 {"symbols", no_argument, 0, 's'},
4474 {"syms", no_argument, 0, 's'},
2c610e4b 4475 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4476 {"relocs", no_argument, 0, 'r'},
4477 {"notes", no_argument, 0, 'n'},
4478 {"dynamic", no_argument, 0, 'd'},
a952a375 4479 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4480 {"version-info", no_argument, 0, 'V'},
4481 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4482 {"unwind", no_argument, 0, 'u'},
4145f1d5 4483 {"archive-index", no_argument, 0, 'c'},
b34976b6 4484 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4485 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4486 {"string-dump", required_argument, 0, 'p'},
0e602686 4487 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4488#ifdef SUPPORT_DISASSEMBLY
4489 {"instruction-dump", required_argument, 0, 'i'},
4490#endif
cf13d699 4491 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4492
fd2f0033
TT
4493 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4494 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4495 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4496
d344b407 4497 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4498
4499 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4500 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4501 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
4502
b34976b6
AM
4503 {"version", no_argument, 0, 'v'},
4504 {"wide", no_argument, 0, 'W'},
4505 {"help", no_argument, 0, 'H'},
4506 {0, no_argument, 0, 0}
252b5132
RH
4507};
4508
4509static void
2cf0635d 4510usage (FILE * stream)
252b5132 4511{
92f01d61
JM
4512 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4513 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4514 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4515 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4516 -h --file-header Display the ELF file header\n\
4517 -l --program-headers Display the program headers\n\
4518 --segments An alias for --program-headers\n\
4519 -S --section-headers Display the sections' header\n\
4520 --sections An alias for --section-headers\n\
f5842774 4521 -g --section-groups Display the section groups\n\
5477e8a0 4522 -t --section-details Display the section details\n\
8b53311e
NC
4523 -e --headers Equivalent to: -h -l -S\n\
4524 -s --syms Display the symbol table\n\
3f08eb35 4525 --symbols An alias for --syms\n\
2c610e4b 4526 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4527 -n --notes Display the core notes (if present)\n\
4528 -r --relocs Display the relocations (if present)\n\
4529 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4530 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4531 -V --version-info Display the version sections (if present)\n\
1b31d05e 4532 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4533 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4534 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
4535 -x --hex-dump=<number|name>\n\
4536 Dump the contents of section <number|name> as bytes\n\
4537 -p --string-dump=<number|name>\n\
4538 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4539 -R --relocated-dump=<number|name>\n\
4540 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4541 -z --decompress Decompress section before dumping it\n\
dda8d76d 4542 -w[lLiaprmfFsoRtUuTgAckK] or\n\
1ed06042 4543 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4544 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47 4545 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4546 =addr,=cu_index,=links,=follow-links]\n\
4547 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4548 fprintf (stream, _("\
4549 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4550 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4551 or deeper\n"));
7d9813f1
NA
4552 fprintf (stream, _("\
4553 --ctf=<number|name> Display CTF info from section <number|name>\n\
4554 --ctf-parent=<number|name>\n\
4555 Use section <number|name> as the CTF parent\n\n\
4556 --ctf-symbols=<number|name>\n\
4557 Use section <number|name> as the CTF external symtab\n\n\
4558 --ctf-strings=<number|name>\n\
4559 Use section <number|name> as the CTF external strtab\n\n"));
4560
252b5132 4561#ifdef SUPPORT_DISASSEMBLY
92f01d61 4562 fprintf (stream, _("\
09c11c86
NC
4563 -i --instruction-dump=<number|name>\n\
4564 Disassemble the contents of section <number|name>\n"));
252b5132 4565#endif
92f01d61 4566 fprintf (stream, _("\
8b53311e
NC
4567 -I --histogram Display histogram of bucket list lengths\n\
4568 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4569 @<file> Read options from <file>\n\
8b53311e
NC
4570 -H --help Display this information\n\
4571 -v --version Display the version number of readelf\n"));
1118d252 4572
92f01d61
JM
4573 if (REPORT_BUGS_TO[0] && stream == stdout)
4574 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4575
92f01d61 4576 exit (stream == stdout ? 0 : 1);
252b5132
RH
4577}
4578
18bd398b
NC
4579/* Record the fact that the user wants the contents of section number
4580 SECTION to be displayed using the method(s) encoded as flags bits
4581 in TYPE. Note, TYPE can be zero if we are creating the array for
4582 the first time. */
4583
252b5132 4584static void
6431e409
AM
4585request_dump_bynumber (struct dump_data *dumpdata,
4586 unsigned int section, dump_type type)
252b5132 4587{
6431e409 4588 if (section >= dumpdata->num_dump_sects)
252b5132 4589 {
2cf0635d 4590 dump_type * new_dump_sects;
252b5132 4591
3f5e193b 4592 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4593 sizeof (* new_dump_sects));
252b5132
RH
4594
4595 if (new_dump_sects == NULL)
591a748a 4596 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4597 else
4598 {
6431e409 4599 if (dumpdata->dump_sects)
21b65bac
NC
4600 {
4601 /* Copy current flag settings. */
6431e409
AM
4602 memcpy (new_dump_sects, dumpdata->dump_sects,
4603 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4604
6431e409 4605 free (dumpdata->dump_sects);
21b65bac 4606 }
252b5132 4607
6431e409
AM
4608 dumpdata->dump_sects = new_dump_sects;
4609 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4610 }
4611 }
4612
6431e409
AM
4613 if (dumpdata->dump_sects)
4614 dumpdata->dump_sects[section] |= type;
252b5132
RH
4615}
4616
aef1f6d0
DJ
4617/* Request a dump by section name. */
4618
4619static void
2cf0635d 4620request_dump_byname (const char * section, dump_type type)
aef1f6d0 4621{
2cf0635d 4622 struct dump_list_entry * new_request;
aef1f6d0 4623
3f5e193b
NC
4624 new_request = (struct dump_list_entry *)
4625 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4626 if (!new_request)
591a748a 4627 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4628
4629 new_request->name = strdup (section);
4630 if (!new_request->name)
591a748a 4631 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4632
4633 new_request->type = type;
4634
4635 new_request->next = dump_sects_byname;
4636 dump_sects_byname = new_request;
4637}
4638
cf13d699 4639static inline void
6431e409 4640request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4641{
4642 int section;
4643 char * cp;
4644
4645 do_dump++;
4646 section = strtoul (optarg, & cp, 0);
4647
4648 if (! *cp && section >= 0)
6431e409 4649 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4650 else
4651 request_dump_byname (optarg, type);
4652}
4653
252b5132 4654static void
6431e409 4655parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4656{
4657 int c;
4658
4659 if (argc < 2)
92f01d61 4660 usage (stderr);
252b5132
RH
4661
4662 while ((c = getopt_long
0e602686 4663 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4664 {
252b5132
RH
4665 switch (c)
4666 {
4667 case 0:
4668 /* Long options. */
4669 break;
4670 case 'H':
92f01d61 4671 usage (stdout);
252b5132
RH
4672 break;
4673
4674 case 'a':
32ec8896
NC
4675 do_syms = TRUE;
4676 do_reloc = TRUE;
4677 do_unwind = TRUE;
4678 do_dynamic = TRUE;
4679 do_header = TRUE;
4680 do_sections = TRUE;
4681 do_section_groups = TRUE;
4682 do_segments = TRUE;
4683 do_version = TRUE;
4684 do_histogram = TRUE;
4685 do_arch = TRUE;
4686 do_notes = TRUE;
252b5132 4687 break;
f5842774 4688 case 'g':
32ec8896 4689 do_section_groups = TRUE;
f5842774 4690 break;
5477e8a0 4691 case 't':
595cf52e 4692 case 'N':
32ec8896
NC
4693 do_sections = TRUE;
4694 do_section_details = TRUE;
595cf52e 4695 break;
252b5132 4696 case 'e':
32ec8896
NC
4697 do_header = TRUE;
4698 do_sections = TRUE;
4699 do_segments = TRUE;
252b5132 4700 break;
a952a375 4701 case 'A':
32ec8896 4702 do_arch = TRUE;
a952a375 4703 break;
252b5132 4704 case 'D':
32ec8896 4705 do_using_dynamic = TRUE;
252b5132
RH
4706 break;
4707 case 'r':
32ec8896 4708 do_reloc = TRUE;
252b5132 4709 break;
4d6ed7c8 4710 case 'u':
32ec8896 4711 do_unwind = TRUE;
4d6ed7c8 4712 break;
252b5132 4713 case 'h':
32ec8896 4714 do_header = TRUE;
252b5132
RH
4715 break;
4716 case 'l':
32ec8896 4717 do_segments = TRUE;
252b5132
RH
4718 break;
4719 case 's':
32ec8896 4720 do_syms = TRUE;
252b5132
RH
4721 break;
4722 case 'S':
32ec8896 4723 do_sections = TRUE;
252b5132
RH
4724 break;
4725 case 'd':
32ec8896 4726 do_dynamic = TRUE;
252b5132 4727 break;
a952a375 4728 case 'I':
32ec8896 4729 do_histogram = TRUE;
a952a375 4730 break;
779fe533 4731 case 'n':
32ec8896 4732 do_notes = TRUE;
779fe533 4733 break;
4145f1d5 4734 case 'c':
32ec8896 4735 do_archive_index = TRUE;
4145f1d5 4736 break;
252b5132 4737 case 'x':
6431e409 4738 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4739 break;
09c11c86 4740 case 'p':
6431e409 4741 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4742 break;
4743 case 'R':
6431e409 4744 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4745 break;
0e602686 4746 case 'z':
32ec8896 4747 decompress_dumps = TRUE;
0e602686 4748 break;
252b5132 4749 case 'w':
32ec8896 4750 do_dump = TRUE;
252b5132 4751 if (optarg == 0)
613ff48b 4752 {
32ec8896 4753 do_debugging = TRUE;
613ff48b
CC
4754 dwarf_select_sections_all ();
4755 }
252b5132
RH
4756 else
4757 {
32ec8896 4758 do_debugging = FALSE;
4cb93e3b 4759 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4760 }
4761 break;
2979dc34 4762 case OPTION_DEBUG_DUMP:
32ec8896 4763 do_dump = TRUE;
2979dc34 4764 if (optarg == 0)
32ec8896 4765 do_debugging = TRUE;
2979dc34
JJ
4766 else
4767 {
32ec8896 4768 do_debugging = FALSE;
4cb93e3b 4769 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4770 }
4771 break;
fd2f0033
TT
4772 case OPTION_DWARF_DEPTH:
4773 {
4774 char *cp;
4775
4776 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4777 }
4778 break;
4779 case OPTION_DWARF_START:
4780 {
4781 char *cp;
4782
4783 dwarf_start_die = strtoul (optarg, & cp, 0);
4784 }
4785 break;
4723351a 4786 case OPTION_DWARF_CHECK:
32ec8896 4787 dwarf_check = TRUE;
4723351a 4788 break;
7d9813f1
NA
4789 case OPTION_CTF_DUMP:
4790 do_ctf = TRUE;
6431e409 4791 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4792 break;
4793 case OPTION_CTF_SYMBOLS:
4794 dump_ctf_symtab_name = strdup (optarg);
4795 break;
4796 case OPTION_CTF_STRINGS:
4797 dump_ctf_strtab_name = strdup (optarg);
4798 break;
4799 case OPTION_CTF_PARENT:
4800 dump_ctf_parent_name = strdup (optarg);
4801 break;
2c610e4b 4802 case OPTION_DYN_SYMS:
32ec8896 4803 do_dyn_syms = TRUE;
2c610e4b 4804 break;
252b5132
RH
4805#ifdef SUPPORT_DISASSEMBLY
4806 case 'i':
6431e409 4807 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4808 break;
252b5132
RH
4809#endif
4810 case 'v':
4811 print_version (program_name);
4812 break;
4813 case 'V':
32ec8896 4814 do_version = TRUE;
252b5132 4815 break;
d974e256 4816 case 'W':
32ec8896 4817 do_wide = TRUE;
d974e256 4818 break;
252b5132 4819 default:
252b5132
RH
4820 /* xgettext:c-format */
4821 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4822 /* Fall through. */
252b5132 4823 case '?':
92f01d61 4824 usage (stderr);
252b5132
RH
4825 }
4826 }
4827
4d6ed7c8 4828 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4829 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4830 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4831 && !do_section_groups && !do_archive_index
4832 && !do_dyn_syms)
92f01d61 4833 usage (stderr);
252b5132
RH
4834}
4835
4836static const char *
d3ba0551 4837get_elf_class (unsigned int elf_class)
252b5132 4838{
b34976b6 4839 static char buff[32];
103f02d3 4840
252b5132
RH
4841 switch (elf_class)
4842 {
4843 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4844 case ELFCLASS32: return "ELF32";
4845 case ELFCLASS64: return "ELF64";
ab5e7794 4846 default:
e9e44622 4847 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4848 return buff;
252b5132
RH
4849 }
4850}
4851
4852static const char *
d3ba0551 4853get_data_encoding (unsigned int encoding)
252b5132 4854{
b34976b6 4855 static char buff[32];
103f02d3 4856
252b5132
RH
4857 switch (encoding)
4858 {
4859 case ELFDATANONE: return _("none");
33c63f9d
CM
4860 case ELFDATA2LSB: return _("2's complement, little endian");
4861 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4862 default:
e9e44622 4863 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4864 return buff;
252b5132
RH
4865 }
4866}
4867
dda8d76d 4868/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4869
32ec8896 4870static bfd_boolean
dda8d76d 4871process_file_header (Filedata * filedata)
252b5132 4872{
dda8d76d
NC
4873 Elf_Internal_Ehdr * header = & filedata->file_header;
4874
4875 if ( header->e_ident[EI_MAG0] != ELFMAG0
4876 || header->e_ident[EI_MAG1] != ELFMAG1
4877 || header->e_ident[EI_MAG2] != ELFMAG2
4878 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4879 {
4880 error
4881 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4882 return FALSE;
252b5132
RH
4883 }
4884
955ff7fc 4885 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 4886
252b5132
RH
4887 if (do_header)
4888 {
32ec8896 4889 unsigned i;
252b5132
RH
4890
4891 printf (_("ELF Header:\n"));
4892 printf (_(" Magic: "));
b34976b6 4893 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4894 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4895 printf ("\n");
4896 printf (_(" Class: %s\n"),
dda8d76d 4897 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4898 printf (_(" Data: %s\n"),
dda8d76d 4899 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 4900 printf (_(" Version: %d%s\n"),
dda8d76d
NC
4901 header->e_ident[EI_VERSION],
4902 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 4903 ? _(" (current)")
dda8d76d 4904 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 4905 ? _(" <unknown>")
789be9f7 4906 : "")));
252b5132 4907 printf (_(" OS/ABI: %s\n"),
dda8d76d 4908 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 4909 printf (_(" ABI Version: %d\n"),
dda8d76d 4910 header->e_ident[EI_ABIVERSION]);
252b5132 4911 printf (_(" Type: %s\n"),
dda8d76d 4912 get_file_type (header->e_type));
252b5132 4913 printf (_(" Machine: %s\n"),
dda8d76d 4914 get_machine_name (header->e_machine));
252b5132 4915 printf (_(" Version: 0x%lx\n"),
e8a64888 4916 header->e_version);
76da6bbe 4917
f7a99963 4918 printf (_(" Entry point address: "));
e8a64888 4919 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 4920 printf (_("\n Start of program headers: "));
e8a64888 4921 print_vma (header->e_phoff, DEC);
f7a99963 4922 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 4923 print_vma (header->e_shoff, DEC);
f7a99963 4924 printf (_(" (bytes into file)\n"));
76da6bbe 4925
252b5132 4926 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 4927 header->e_flags,
dda8d76d 4928 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
4929 printf (_(" Size of this header: %u (bytes)\n"),
4930 header->e_ehsize);
4931 printf (_(" Size of program headers: %u (bytes)\n"),
4932 header->e_phentsize);
4933 printf (_(" Number of program headers: %u"),
4934 header->e_phnum);
dda8d76d
NC
4935 if (filedata->section_headers != NULL
4936 && header->e_phnum == PN_XNUM
4937 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
4938 {
4939 header->e_phnum = filedata->section_headers[0].sh_info;
4940 printf (" (%u)", header->e_phnum);
4941 }
2046a35d 4942 putc ('\n', stdout);
e8a64888
AM
4943 printf (_(" Size of section headers: %u (bytes)\n"),
4944 header->e_shentsize);
4945 printf (_(" Number of section headers: %u"),
4946 header->e_shnum);
dda8d76d 4947 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
4948 {
4949 header->e_shnum = filedata->section_headers[0].sh_size;
4950 printf (" (%u)", header->e_shnum);
4951 }
560f3c1c 4952 putc ('\n', stdout);
e8a64888
AM
4953 printf (_(" Section header string table index: %u"),
4954 header->e_shstrndx);
dda8d76d
NC
4955 if (filedata->section_headers != NULL
4956 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
4957 {
4958 header->e_shstrndx = filedata->section_headers[0].sh_link;
4959 printf (" (%u)", header->e_shstrndx);
4960 }
4961 if (header->e_shstrndx != SHN_UNDEF
4962 && header->e_shstrndx >= header->e_shnum)
4963 {
4964 header->e_shstrndx = SHN_UNDEF;
4965 printf (_(" <corrupt: out of range>"));
4966 }
560f3c1c
AM
4967 putc ('\n', stdout);
4968 }
4969
dda8d76d 4970 if (filedata->section_headers != NULL)
560f3c1c 4971 {
dda8d76d
NC
4972 if (header->e_phnum == PN_XNUM
4973 && filedata->section_headers[0].sh_info != 0)
4974 header->e_phnum = filedata->section_headers[0].sh_info;
4975 if (header->e_shnum == SHN_UNDEF)
4976 header->e_shnum = filedata->section_headers[0].sh_size;
4977 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
4978 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 4979 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
4980 header->e_shstrndx = SHN_UNDEF;
4981 free (filedata->section_headers);
4982 filedata->section_headers = NULL;
252b5132 4983 }
103f02d3 4984
32ec8896 4985 return TRUE;
9ea033b2
NC
4986}
4987
dda8d76d
NC
4988/* Read in the program headers from FILEDATA and store them in PHEADERS.
4989 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
4990
e0a31db1 4991static bfd_boolean
dda8d76d 4992get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4993{
2cf0635d
NC
4994 Elf32_External_Phdr * phdrs;
4995 Elf32_External_Phdr * external;
4996 Elf_Internal_Phdr * internal;
b34976b6 4997 unsigned int i;
dda8d76d
NC
4998 unsigned int size = filedata->file_header.e_phentsize;
4999 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5000
5001 /* PR binutils/17531: Cope with unexpected section header sizes. */
5002 if (size == 0 || num == 0)
5003 return FALSE;
5004 if (size < sizeof * phdrs)
5005 {
5006 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5007 return FALSE;
5008 }
5009 if (size > sizeof * phdrs)
5010 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5011
dda8d76d 5012 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5013 size, num, _("program headers"));
5014 if (phdrs == NULL)
5015 return FALSE;
9ea033b2 5016
91d6fa6a 5017 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5018 i < filedata->file_header.e_phnum;
b34976b6 5019 i++, internal++, external++)
252b5132 5020 {
9ea033b2
NC
5021 internal->p_type = BYTE_GET (external->p_type);
5022 internal->p_offset = BYTE_GET (external->p_offset);
5023 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5024 internal->p_paddr = BYTE_GET (external->p_paddr);
5025 internal->p_filesz = BYTE_GET (external->p_filesz);
5026 internal->p_memsz = BYTE_GET (external->p_memsz);
5027 internal->p_flags = BYTE_GET (external->p_flags);
5028 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5029 }
5030
9ea033b2 5031 free (phdrs);
e0a31db1 5032 return TRUE;
252b5132
RH
5033}
5034
dda8d76d
NC
5035/* Read in the program headers from FILEDATA and store them in PHEADERS.
5036 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5037
e0a31db1 5038static bfd_boolean
dda8d76d 5039get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5040{
2cf0635d
NC
5041 Elf64_External_Phdr * phdrs;
5042 Elf64_External_Phdr * external;
5043 Elf_Internal_Phdr * internal;
b34976b6 5044 unsigned int i;
dda8d76d
NC
5045 unsigned int size = filedata->file_header.e_phentsize;
5046 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5047
5048 /* PR binutils/17531: Cope with unexpected section header sizes. */
5049 if (size == 0 || num == 0)
5050 return FALSE;
5051 if (size < sizeof * phdrs)
5052 {
5053 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5054 return FALSE;
5055 }
5056 if (size > sizeof * phdrs)
5057 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5058
dda8d76d 5059 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5060 size, num, _("program headers"));
a6e9f9df 5061 if (!phdrs)
e0a31db1 5062 return FALSE;
9ea033b2 5063
91d6fa6a 5064 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5065 i < filedata->file_header.e_phnum;
b34976b6 5066 i++, internal++, external++)
9ea033b2
NC
5067 {
5068 internal->p_type = BYTE_GET (external->p_type);
5069 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5070 internal->p_offset = BYTE_GET (external->p_offset);
5071 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5072 internal->p_paddr = BYTE_GET (external->p_paddr);
5073 internal->p_filesz = BYTE_GET (external->p_filesz);
5074 internal->p_memsz = BYTE_GET (external->p_memsz);
5075 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5076 }
5077
5078 free (phdrs);
e0a31db1 5079 return TRUE;
9ea033b2 5080}
252b5132 5081
32ec8896 5082/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5083
32ec8896 5084static bfd_boolean
dda8d76d 5085get_program_headers (Filedata * filedata)
d93f0186 5086{
2cf0635d 5087 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5088
5089 /* Check cache of prior read. */
dda8d76d 5090 if (filedata->program_headers != NULL)
32ec8896 5091 return TRUE;
d93f0186 5092
82156ab7
NC
5093 /* Be kind to memory checkers by looking for
5094 e_phnum values which we know must be invalid. */
dda8d76d 5095 if (filedata->file_header.e_phnum
82156ab7 5096 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5097 >= filedata->file_size)
82156ab7
NC
5098 {
5099 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5100 filedata->file_header.e_phnum);
82156ab7
NC
5101 return FALSE;
5102 }
d93f0186 5103
dda8d76d 5104 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5105 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5106 if (phdrs == NULL)
5107 {
8b73c356 5108 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5109 filedata->file_header.e_phnum);
32ec8896 5110 return FALSE;
d93f0186
NC
5111 }
5112
5113 if (is_32bit_elf
dda8d76d
NC
5114 ? get_32bit_program_headers (filedata, phdrs)
5115 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5116 {
dda8d76d 5117 filedata->program_headers = phdrs;
32ec8896 5118 return TRUE;
d93f0186
NC
5119 }
5120
5121 free (phdrs);
32ec8896 5122 return FALSE;
d93f0186
NC
5123}
5124
32ec8896 5125/* Returns TRUE if the program headers were loaded. */
2f62977e 5126
32ec8896 5127static bfd_boolean
dda8d76d 5128process_program_headers (Filedata * filedata)
252b5132 5129{
2cf0635d 5130 Elf_Internal_Phdr * segment;
b34976b6 5131 unsigned int i;
1a9ccd70 5132 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5133
663f67df
AM
5134 dynamic_addr = 0;
5135 dynamic_size = 0;
5136
dda8d76d 5137 if (filedata->file_header.e_phnum == 0)
252b5132 5138 {
82f2dbf7 5139 /* PR binutils/12467. */
dda8d76d 5140 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5141 {
5142 warn (_("possibly corrupt ELF header - it has a non-zero program"
5143 " header offset, but no program headers\n"));
5144 return FALSE;
5145 }
82f2dbf7 5146 else if (do_segments)
252b5132 5147 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5148 return TRUE;
252b5132
RH
5149 }
5150
5151 if (do_segments && !do_header)
5152 {
dda8d76d
NC
5153 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5154 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5155 printf (ngettext ("There is %d program header, starting at offset %s\n",
5156 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5157 filedata->file_header.e_phnum),
5158 filedata->file_header.e_phnum,
5159 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5160 }
5161
dda8d76d 5162 if (! get_program_headers (filedata))
6b4bf3bc 5163 return TRUE;
103f02d3 5164
252b5132
RH
5165 if (do_segments)
5166 {
dda8d76d 5167 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5168 printf (_("\nProgram Headers:\n"));
5169 else
5170 printf (_("\nProgram Headers:\n"));
76da6bbe 5171
f7a99963
NC
5172 if (is_32bit_elf)
5173 printf
5174 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5175 else if (do_wide)
5176 printf
5177 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5178 else
5179 {
5180 printf
5181 (_(" Type Offset VirtAddr PhysAddr\n"));
5182 printf
5183 (_(" FileSiz MemSiz Flags Align\n"));
5184 }
252b5132
RH
5185 }
5186
dda8d76d
NC
5187 for (i = 0, segment = filedata->program_headers;
5188 i < filedata->file_header.e_phnum;
b34976b6 5189 i++, segment++)
252b5132
RH
5190 {
5191 if (do_segments)
5192 {
dda8d76d 5193 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5194
5195 if (is_32bit_elf)
5196 {
5197 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5198 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5199 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5200 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5201 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5202 printf ("%c%c%c ",
5203 (segment->p_flags & PF_R ? 'R' : ' '),
5204 (segment->p_flags & PF_W ? 'W' : ' '),
5205 (segment->p_flags & PF_X ? 'E' : ' '));
5206 printf ("%#lx", (unsigned long) segment->p_align);
5207 }
d974e256
JJ
5208 else if (do_wide)
5209 {
5210 if ((unsigned long) segment->p_offset == segment->p_offset)
5211 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5212 else
5213 {
5214 print_vma (segment->p_offset, FULL_HEX);
5215 putchar (' ');
5216 }
5217
5218 print_vma (segment->p_vaddr, FULL_HEX);
5219 putchar (' ');
5220 print_vma (segment->p_paddr, FULL_HEX);
5221 putchar (' ');
5222
5223 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5224 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5225 else
5226 {
5227 print_vma (segment->p_filesz, FULL_HEX);
5228 putchar (' ');
5229 }
5230
5231 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5232 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5233 else
5234 {
f48e6c45 5235 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5236 }
5237
5238 printf (" %c%c%c ",
5239 (segment->p_flags & PF_R ? 'R' : ' '),
5240 (segment->p_flags & PF_W ? 'W' : ' '),
5241 (segment->p_flags & PF_X ? 'E' : ' '));
5242
5243 if ((unsigned long) segment->p_align == segment->p_align)
5244 printf ("%#lx", (unsigned long) segment->p_align);
5245 else
5246 {
5247 print_vma (segment->p_align, PREFIX_HEX);
5248 }
5249 }
f7a99963
NC
5250 else
5251 {
5252 print_vma (segment->p_offset, FULL_HEX);
5253 putchar (' ');
5254 print_vma (segment->p_vaddr, FULL_HEX);
5255 putchar (' ');
5256 print_vma (segment->p_paddr, FULL_HEX);
5257 printf ("\n ");
5258 print_vma (segment->p_filesz, FULL_HEX);
5259 putchar (' ');
5260 print_vma (segment->p_memsz, FULL_HEX);
5261 printf (" %c%c%c ",
5262 (segment->p_flags & PF_R ? 'R' : ' '),
5263 (segment->p_flags & PF_W ? 'W' : ' '),
5264 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5265 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5266 }
252b5132 5267
1a9ccd70
NC
5268 putc ('\n', stdout);
5269 }
f54498b4 5270
252b5132
RH
5271 switch (segment->p_type)
5272 {
1a9ccd70 5273 case PT_LOAD:
502d895c
NC
5274#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5275 required by the ELF standard, several programs, including the Linux
5276 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5277 if (previous_load
5278 && previous_load->p_vaddr > segment->p_vaddr)
5279 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5280#endif
1a9ccd70
NC
5281 if (segment->p_memsz < segment->p_filesz)
5282 error (_("the segment's file size is larger than its memory size\n"));
5283 previous_load = segment;
5284 break;
5285
5286 case PT_PHDR:
5287 /* PR 20815 - Verify that the program header is loaded into memory. */
5288 if (i > 0 && previous_load != NULL)
5289 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5290 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5291 {
5292 unsigned int j;
5293
dda8d76d 5294 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5295 {
5296 Elf_Internal_Phdr *load = filedata->program_headers + j;
5297 if (load->p_type == PT_LOAD
5298 && load->p_offset <= segment->p_offset
5299 && (load->p_offset + load->p_filesz
5300 >= segment->p_offset + segment->p_filesz)
5301 && load->p_vaddr <= segment->p_vaddr
5302 && (load->p_vaddr + load->p_filesz
5303 >= segment->p_vaddr + segment->p_filesz))
5304 break;
5305 }
dda8d76d 5306 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5307 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5308 }
5309 break;
5310
252b5132
RH
5311 case PT_DYNAMIC:
5312 if (dynamic_addr)
5313 error (_("more than one dynamic segment\n"));
5314
20737c13
AM
5315 /* By default, assume that the .dynamic section is the first
5316 section in the DYNAMIC segment. */
5317 dynamic_addr = segment->p_offset;
5318 dynamic_size = segment->p_filesz;
5319
b2d38a17
NC
5320 /* Try to locate the .dynamic section. If there is
5321 a section header table, we can easily locate it. */
dda8d76d 5322 if (filedata->section_headers != NULL)
b2d38a17 5323 {
2cf0635d 5324 Elf_Internal_Shdr * sec;
b2d38a17 5325
dda8d76d 5326 sec = find_section (filedata, ".dynamic");
89fac5e3 5327 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5328 {
28f997cf
TG
5329 /* A corresponding .dynamic section is expected, but on
5330 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5331 if (!is_ia64_vms (filedata))
28f997cf 5332 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5333 break;
5334 }
5335
42bb2e33 5336 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
5337 {
5338 dynamic_size = 0;
5339 break;
5340 }
42bb2e33 5341
b2d38a17
NC
5342 dynamic_addr = sec->sh_offset;
5343 dynamic_size = sec->sh_size;
5344
5345 if (dynamic_addr < segment->p_offset
5346 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
5347 warn (_("the .dynamic section is not contained"
5348 " within the dynamic segment\n"));
b2d38a17 5349 else if (dynamic_addr > segment->p_offset)
20737c13
AM
5350 warn (_("the .dynamic section is not the first section"
5351 " in the dynamic segment.\n"));
b2d38a17 5352 }
39e224f6
MW
5353
5354 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5355 segment. Check this after matching against the section headers
5356 so we don't warn on debuginfo file (which have NOBITS .dynamic
5357 sections). */
c22b42ce
AM
5358 if (dynamic_addr > filedata->file_size
5359 || dynamic_size > filedata->file_size - dynamic_addr)
39e224f6
MW
5360 {
5361 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
5362 dynamic_addr = dynamic_size = 0;
5363 }
252b5132
RH
5364 break;
5365
5366 case PT_INTERP:
dda8d76d 5367 if (fseek (filedata->handle, archive_file_offset + (long) segment->p_offset,
fb52b2f4 5368 SEEK_SET))
252b5132
RH
5369 error (_("Unable to find program interpreter name\n"));
5370 else
5371 {
f8eae8b2 5372 char fmt [32];
9495b2e6 5373 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5374
5375 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5376 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5377
252b5132 5378 program_interpreter[0] = 0;
dda8d76d 5379 if (fscanf (filedata->handle, fmt, program_interpreter) <= 0)
7bd7b3ef 5380 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5381
5382 if (do_segments)
f54498b4 5383 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
5384 program_interpreter);
5385 }
5386 break;
5387 }
252b5132
RH
5388 }
5389
dda8d76d
NC
5390 if (do_segments
5391 && filedata->section_headers != NULL
5392 && filedata->string_table != NULL)
252b5132
RH
5393 {
5394 printf (_("\n Section to Segment mapping:\n"));
5395 printf (_(" Segment Sections...\n"));
5396
dda8d76d 5397 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5398 {
9ad5cbcf 5399 unsigned int j;
2cf0635d 5400 Elf_Internal_Shdr * section;
252b5132 5401
dda8d76d
NC
5402 segment = filedata->program_headers + i;
5403 section = filedata->section_headers + 1;
252b5132
RH
5404
5405 printf (" %2.2d ", i);
5406
dda8d76d 5407 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5408 {
f4638467
AM
5409 if (!ELF_TBSS_SPECIAL (section, segment)
5410 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5411 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5412 }
5413
5414 putc ('\n',stdout);
5415 }
5416 }
5417
32ec8896 5418 return TRUE;
252b5132
RH
5419}
5420
5421
d93f0186
NC
5422/* Find the file offset corresponding to VMA by using the program headers. */
5423
5424static long
dda8d76d 5425offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5426{
2cf0635d 5427 Elf_Internal_Phdr * seg;
d93f0186 5428
dda8d76d 5429 if (! get_program_headers (filedata))
d93f0186
NC
5430 {
5431 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5432 return (long) vma;
5433 }
5434
dda8d76d
NC
5435 for (seg = filedata->program_headers;
5436 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5437 ++seg)
5438 {
5439 if (seg->p_type != PT_LOAD)
5440 continue;
5441
5442 if (vma >= (seg->p_vaddr & -seg->p_align)
5443 && vma + size <= seg->p_vaddr + seg->p_filesz)
5444 return vma - seg->p_vaddr + seg->p_offset;
5445 }
5446
5447 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5448 (unsigned long) vma);
d93f0186
NC
5449 return (long) vma;
5450}
5451
5452
dda8d76d
NC
5453/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5454 If PROBE is true, this is just a probe and we do not generate any error
5455 messages if the load fails. */
049b0c3a
NC
5456
5457static bfd_boolean
dda8d76d 5458get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5459{
2cf0635d
NC
5460 Elf32_External_Shdr * shdrs;
5461 Elf_Internal_Shdr * internal;
dda8d76d
NC
5462 unsigned int i;
5463 unsigned int size = filedata->file_header.e_shentsize;
5464 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5465
5466 /* PR binutils/17531: Cope with unexpected section header sizes. */
5467 if (size == 0 || num == 0)
5468 return FALSE;
5469 if (size < sizeof * shdrs)
5470 {
5471 if (! probe)
5472 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5473 return FALSE;
5474 }
5475 if (!probe && size > sizeof * shdrs)
5476 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5477
dda8d76d 5478 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5479 size, num,
5480 probe ? NULL : _("section headers"));
5481 if (shdrs == NULL)
5482 return FALSE;
252b5132 5483
dda8d76d
NC
5484 free (filedata->section_headers);
5485 filedata->section_headers = (Elf_Internal_Shdr *)
5486 cmalloc (num, sizeof (Elf_Internal_Shdr));
5487 if (filedata->section_headers == NULL)
252b5132 5488 {
049b0c3a 5489 if (!probe)
8b73c356 5490 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5491 free (shdrs);
049b0c3a 5492 return FALSE;
252b5132
RH
5493 }
5494
dda8d76d 5495 for (i = 0, internal = filedata->section_headers;
560f3c1c 5496 i < num;
b34976b6 5497 i++, internal++)
252b5132
RH
5498 {
5499 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5500 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5501 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5502 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5503 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5504 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5505 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5506 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5507 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5508 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5509 if (!probe && internal->sh_link > num)
5510 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5511 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5512 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5513 }
5514
5515 free (shdrs);
049b0c3a 5516 return TRUE;
252b5132
RH
5517}
5518
dda8d76d
NC
5519/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5520
049b0c3a 5521static bfd_boolean
dda8d76d 5522get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5523{
dda8d76d
NC
5524 Elf64_External_Shdr * shdrs;
5525 Elf_Internal_Shdr * internal;
5526 unsigned int i;
5527 unsigned int size = filedata->file_header.e_shentsize;
5528 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5529
5530 /* PR binutils/17531: Cope with unexpected section header sizes. */
5531 if (size == 0 || num == 0)
5532 return FALSE;
dda8d76d 5533
049b0c3a
NC
5534 if (size < sizeof * shdrs)
5535 {
5536 if (! probe)
5537 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5538 return FALSE;
5539 }
dda8d76d 5540
049b0c3a
NC
5541 if (! probe && size > sizeof * shdrs)
5542 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5543
dda8d76d
NC
5544 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5545 filedata->file_header.e_shoff,
049b0c3a
NC
5546 size, num,
5547 probe ? NULL : _("section headers"));
5548 if (shdrs == NULL)
5549 return FALSE;
9ea033b2 5550
dda8d76d
NC
5551 free (filedata->section_headers);
5552 filedata->section_headers = (Elf_Internal_Shdr *)
5553 cmalloc (num, sizeof (Elf_Internal_Shdr));
5554 if (filedata->section_headers == NULL)
9ea033b2 5555 {
049b0c3a 5556 if (! probe)
8b73c356 5557 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5558 free (shdrs);
049b0c3a 5559 return FALSE;
9ea033b2
NC
5560 }
5561
dda8d76d 5562 for (i = 0, internal = filedata->section_headers;
560f3c1c 5563 i < num;
b34976b6 5564 i++, internal++)
9ea033b2
NC
5565 {
5566 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5567 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5568 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5569 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5570 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5571 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5572 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5573 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5574 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5575 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5576 if (!probe && internal->sh_link > num)
5577 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5578 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5579 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5580 }
5581
5582 free (shdrs);
049b0c3a 5583 return TRUE;
9ea033b2
NC
5584}
5585
252b5132 5586static Elf_Internal_Sym *
dda8d76d
NC
5587get_32bit_elf_symbols (Filedata * filedata,
5588 Elf_Internal_Shdr * section,
5589 unsigned long * num_syms_return)
252b5132 5590{
ba5cdace 5591 unsigned long number = 0;
dd24e3da 5592 Elf32_External_Sym * esyms = NULL;
ba5cdace 5593 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5594 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5595 Elf_Internal_Sym * psym;
b34976b6 5596 unsigned int j;
e3d39609 5597 elf_section_list * entry;
252b5132 5598
c9c1d674
EG
5599 if (section->sh_size == 0)
5600 {
5601 if (num_syms_return != NULL)
5602 * num_syms_return = 0;
5603 return NULL;
5604 }
5605
dd24e3da 5606 /* Run some sanity checks first. */
c9c1d674 5607 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5608 {
c9c1d674 5609 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5610 printable_section_name (filedata, section),
5611 (unsigned long) section->sh_entsize);
ba5cdace 5612 goto exit_point;
dd24e3da
NC
5613 }
5614
dda8d76d 5615 if (section->sh_size > filedata->file_size)
f54498b4
NC
5616 {
5617 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5618 printable_section_name (filedata, section),
5619 (unsigned long) section->sh_size);
f54498b4
NC
5620 goto exit_point;
5621 }
5622
dd24e3da
NC
5623 number = section->sh_size / section->sh_entsize;
5624
5625 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5626 {
c9c1d674 5627 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5628 (unsigned long) section->sh_size,
dda8d76d 5629 printable_section_name (filedata, section),
8066deb1 5630 (unsigned long) section->sh_entsize);
ba5cdace 5631 goto exit_point;
dd24e3da
NC
5632 }
5633
dda8d76d 5634 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5635 section->sh_size, _("symbols"));
dd24e3da 5636 if (esyms == NULL)
ba5cdace 5637 goto exit_point;
252b5132 5638
e3d39609
NC
5639 shndx = NULL;
5640 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5641 {
5642 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5643 continue;
5644
5645 if (shndx != NULL)
5646 {
5647 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5648 free (shndx);
5649 }
5650
5651 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5652 entry->hdr->sh_offset,
5653 1, entry->hdr->sh_size,
5654 _("symbol table section indices"));
5655 if (shndx == NULL)
5656 goto exit_point;
5657
5658 /* PR17531: file: heap-buffer-overflow */
5659 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5660 {
5661 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5662 printable_section_name (filedata, entry->hdr),
5663 (unsigned long) entry->hdr->sh_size,
5664 (unsigned long) section->sh_size);
5665 goto exit_point;
c9c1d674 5666 }
e3d39609 5667 }
9ad5cbcf 5668
3f5e193b 5669 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5670
5671 if (isyms == NULL)
5672 {
8b73c356
NC
5673 error (_("Out of memory reading %lu symbols\n"),
5674 (unsigned long) number);
dd24e3da 5675 goto exit_point;
252b5132
RH
5676 }
5677
dd24e3da 5678 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5679 {
5680 psym->st_name = BYTE_GET (esyms[j].st_name);
5681 psym->st_value = BYTE_GET (esyms[j].st_value);
5682 psym->st_size = BYTE_GET (esyms[j].st_size);
5683 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5684 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5685 psym->st_shndx
5686 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5687 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5688 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5689 psym->st_info = BYTE_GET (esyms[j].st_info);
5690 psym->st_other = BYTE_GET (esyms[j].st_other);
5691 }
5692
dd24e3da 5693 exit_point:
e3d39609
NC
5694 free (shndx);
5695 free (esyms);
252b5132 5696
ba5cdace
NC
5697 if (num_syms_return != NULL)
5698 * num_syms_return = isyms == NULL ? 0 : number;
5699
252b5132
RH
5700 return isyms;
5701}
5702
9ea033b2 5703static Elf_Internal_Sym *
dda8d76d
NC
5704get_64bit_elf_symbols (Filedata * filedata,
5705 Elf_Internal_Shdr * section,
5706 unsigned long * num_syms_return)
9ea033b2 5707{
ba5cdace
NC
5708 unsigned long number = 0;
5709 Elf64_External_Sym * esyms = NULL;
5710 Elf_External_Sym_Shndx * shndx = NULL;
5711 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5712 Elf_Internal_Sym * psym;
b34976b6 5713 unsigned int j;
e3d39609 5714 elf_section_list * entry;
9ea033b2 5715
c9c1d674
EG
5716 if (section->sh_size == 0)
5717 {
5718 if (num_syms_return != NULL)
5719 * num_syms_return = 0;
5720 return NULL;
5721 }
5722
dd24e3da 5723 /* Run some sanity checks first. */
c9c1d674 5724 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5725 {
c9c1d674 5726 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5727 printable_section_name (filedata, section),
8066deb1 5728 (unsigned long) section->sh_entsize);
ba5cdace 5729 goto exit_point;
dd24e3da
NC
5730 }
5731
dda8d76d 5732 if (section->sh_size > filedata->file_size)
f54498b4
NC
5733 {
5734 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5735 printable_section_name (filedata, section),
8066deb1 5736 (unsigned long) section->sh_size);
f54498b4
NC
5737 goto exit_point;
5738 }
5739
dd24e3da
NC
5740 number = section->sh_size / section->sh_entsize;
5741
5742 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5743 {
c9c1d674 5744 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5745 (unsigned long) section->sh_size,
dda8d76d 5746 printable_section_name (filedata, section),
8066deb1 5747 (unsigned long) section->sh_entsize);
ba5cdace 5748 goto exit_point;
dd24e3da
NC
5749 }
5750
dda8d76d 5751 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5752 section->sh_size, _("symbols"));
a6e9f9df 5753 if (!esyms)
ba5cdace 5754 goto exit_point;
9ea033b2 5755
e3d39609
NC
5756 shndx = NULL;
5757 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5758 {
5759 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5760 continue;
5761
5762 if (shndx != NULL)
5763 {
5764 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5765 free (shndx);
c9c1d674 5766 }
e3d39609
NC
5767
5768 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5769 entry->hdr->sh_offset,
5770 1, entry->hdr->sh_size,
5771 _("symbol table section indices"));
5772 if (shndx == NULL)
5773 goto exit_point;
5774
5775 /* PR17531: file: heap-buffer-overflow */
5776 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5777 {
5778 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5779 printable_section_name (filedata, entry->hdr),
5780 (unsigned long) entry->hdr->sh_size,
5781 (unsigned long) section->sh_size);
5782 goto exit_point;
5783 }
5784 }
9ad5cbcf 5785
3f5e193b 5786 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5787
5788 if (isyms == NULL)
5789 {
8b73c356
NC
5790 error (_("Out of memory reading %lu symbols\n"),
5791 (unsigned long) number);
ba5cdace 5792 goto exit_point;
9ea033b2
NC
5793 }
5794
ba5cdace 5795 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5796 {
5797 psym->st_name = BYTE_GET (esyms[j].st_name);
5798 psym->st_info = BYTE_GET (esyms[j].st_info);
5799 psym->st_other = BYTE_GET (esyms[j].st_other);
5800 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5801
4fbb74a6 5802 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5803 psym->st_shndx
5804 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5805 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5806 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5807
66543521
AM
5808 psym->st_value = BYTE_GET (esyms[j].st_value);
5809 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5810 }
5811
ba5cdace 5812 exit_point:
e3d39609
NC
5813 free (shndx);
5814 free (esyms);
ba5cdace
NC
5815
5816 if (num_syms_return != NULL)
5817 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5818
5819 return isyms;
5820}
5821
d1133906 5822static const char *
dda8d76d 5823get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5824{
5477e8a0 5825 static char buff[1024];
2cf0635d 5826 char * p = buff;
32ec8896
NC
5827 unsigned int field_size = is_32bit_elf ? 8 : 16;
5828 signed int sindex;
5829 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5830 bfd_vma os_flags = 0;
5831 bfd_vma proc_flags = 0;
5832 bfd_vma unknown_flags = 0;
148b93f2 5833 static const struct
5477e8a0 5834 {
2cf0635d 5835 const char * str;
32ec8896 5836 unsigned int len;
5477e8a0
L
5837 }
5838 flags [] =
5839 {
cfcac11d
NC
5840 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5841 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5842 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5843 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5844 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5845 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5846 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5847 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5848 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5849 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5850 /* IA-64 specific. */
5851 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5852 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5853 /* IA-64 OpenVMS specific. */
5854 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5855 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5856 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5857 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5858 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5859 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5860 /* Generic. */
cfcac11d 5861 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5862 /* SPARC specific. */
77115a4a 5863 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5864 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5865 /* ARM specific. */
5866 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5867 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5868 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5869 /* GNU specific. */
5870 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5871 /* VLE specific. */
5872 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5873 };
5874
5875 if (do_section_details)
5876 {
8d5ff12c
L
5877 sprintf (buff, "[%*.*lx]: ",
5878 field_size, field_size, (unsigned long) sh_flags);
5879 p += field_size + 4;
5477e8a0 5880 }
76da6bbe 5881
d1133906
NC
5882 while (sh_flags)
5883 {
5884 bfd_vma flag;
5885
5886 flag = sh_flags & - sh_flags;
5887 sh_flags &= ~ flag;
76da6bbe 5888
5477e8a0 5889 if (do_section_details)
d1133906 5890 {
5477e8a0
L
5891 switch (flag)
5892 {
91d6fa6a
NC
5893 case SHF_WRITE: sindex = 0; break;
5894 case SHF_ALLOC: sindex = 1; break;
5895 case SHF_EXECINSTR: sindex = 2; break;
5896 case SHF_MERGE: sindex = 3; break;
5897 case SHF_STRINGS: sindex = 4; break;
5898 case SHF_INFO_LINK: sindex = 5; break;
5899 case SHF_LINK_ORDER: sindex = 6; break;
5900 case SHF_OS_NONCONFORMING: sindex = 7; break;
5901 case SHF_GROUP: sindex = 8; break;
5902 case SHF_TLS: sindex = 9; break;
18ae9cc1 5903 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5904 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5905 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 5906
5477e8a0 5907 default:
91d6fa6a 5908 sindex = -1;
dda8d76d 5909 switch (filedata->file_header.e_machine)
148b93f2 5910 {
cfcac11d 5911 case EM_IA_64:
148b93f2 5912 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5913 sindex = 10;
148b93f2 5914 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5915 sindex = 11;
148b93f2 5916#ifdef BFD64
dda8d76d 5917 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
5918 switch (flag)
5919 {
91d6fa6a
NC
5920 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5921 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5922 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5923 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5924 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5925 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5926 default: break;
5927 }
5928#endif
cfcac11d
NC
5929 break;
5930
caa83f8b 5931 case EM_386:
22abe556 5932 case EM_IAMCU:
caa83f8b 5933 case EM_X86_64:
7f502d6c 5934 case EM_L1OM:
7a9068fe 5935 case EM_K1OM:
cfcac11d
NC
5936 case EM_OLD_SPARCV9:
5937 case EM_SPARC32PLUS:
5938 case EM_SPARCV9:
5939 case EM_SPARC:
18ae9cc1 5940 if (flag == SHF_ORDERED)
91d6fa6a 5941 sindex = 19;
cfcac11d 5942 break;
ac4c9b04
MG
5943
5944 case EM_ARM:
5945 switch (flag)
5946 {
5947 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5948 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5949 case SHF_COMDEF: sindex = 23; break;
5950 default: break;
5951 }
5952 break;
83eef883
AFB
5953 case EM_PPC:
5954 if (flag == SHF_PPC_VLE)
5955 sindex = 25;
5956 break;
ac4c9b04 5957
cfcac11d
NC
5958 default:
5959 break;
148b93f2 5960 }
5477e8a0
L
5961 }
5962
91d6fa6a 5963 if (sindex != -1)
5477e8a0 5964 {
8d5ff12c
L
5965 if (p != buff + field_size + 4)
5966 {
5967 if (size < (10 + 2))
bee0ee85
NC
5968 {
5969 warn (_("Internal error: not enough buffer room for section flag info"));
5970 return _("<unknown>");
5971 }
8d5ff12c
L
5972 size -= 2;
5973 *p++ = ',';
5974 *p++ = ' ';
5975 }
5976
91d6fa6a
NC
5977 size -= flags [sindex].len;
5978 p = stpcpy (p, flags [sindex].str);
5477e8a0 5979 }
3b22753a 5980 else if (flag & SHF_MASKOS)
8d5ff12c 5981 os_flags |= flag;
d1133906 5982 else if (flag & SHF_MASKPROC)
8d5ff12c 5983 proc_flags |= flag;
d1133906 5984 else
8d5ff12c 5985 unknown_flags |= flag;
5477e8a0
L
5986 }
5987 else
5988 {
5989 switch (flag)
5990 {
5991 case SHF_WRITE: *p = 'W'; break;
5992 case SHF_ALLOC: *p = 'A'; break;
5993 case SHF_EXECINSTR: *p = 'X'; break;
5994 case SHF_MERGE: *p = 'M'; break;
5995 case SHF_STRINGS: *p = 'S'; break;
5996 case SHF_INFO_LINK: *p = 'I'; break;
5997 case SHF_LINK_ORDER: *p = 'L'; break;
5998 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5999 case SHF_GROUP: *p = 'G'; break;
6000 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6001 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6002 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 6003 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
6004
6005 default:
dda8d76d
NC
6006 if ((filedata->file_header.e_machine == EM_X86_64
6007 || filedata->file_header.e_machine == EM_L1OM
6008 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6009 && flag == SHF_X86_64_LARGE)
6010 *p = 'l';
dda8d76d 6011 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6012 && flag == SHF_ARM_PURECODE)
91f68a68 6013 *p = 'y';
dda8d76d 6014 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
6015 && flag == SHF_PPC_VLE)
6016 *p = 'v';
5477e8a0
L
6017 else if (flag & SHF_MASKOS)
6018 {
6019 *p = 'o';
6020 sh_flags &= ~ SHF_MASKOS;
6021 }
6022 else if (flag & SHF_MASKPROC)
6023 {
6024 *p = 'p';
6025 sh_flags &= ~ SHF_MASKPROC;
6026 }
6027 else
6028 *p = 'x';
6029 break;
6030 }
6031 p++;
d1133906
NC
6032 }
6033 }
76da6bbe 6034
8d5ff12c
L
6035 if (do_section_details)
6036 {
6037 if (os_flags)
6038 {
6039 size -= 5 + field_size;
6040 if (p != buff + field_size + 4)
6041 {
6042 if (size < (2 + 1))
bee0ee85
NC
6043 {
6044 warn (_("Internal error: not enough buffer room for section flag info"));
6045 return _("<unknown>");
6046 }
8d5ff12c
L
6047 size -= 2;
6048 *p++ = ',';
6049 *p++ = ' ';
6050 }
6051 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6052 (unsigned long) os_flags);
6053 p += 5 + field_size;
6054 }
6055 if (proc_flags)
6056 {
6057 size -= 7 + field_size;
6058 if (p != buff + field_size + 4)
6059 {
6060 if (size < (2 + 1))
bee0ee85
NC
6061 {
6062 warn (_("Internal error: not enough buffer room for section flag info"));
6063 return _("<unknown>");
6064 }
8d5ff12c
L
6065 size -= 2;
6066 *p++ = ',';
6067 *p++ = ' ';
6068 }
6069 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6070 (unsigned long) proc_flags);
6071 p += 7 + field_size;
6072 }
6073 if (unknown_flags)
6074 {
6075 size -= 10 + field_size;
6076 if (p != buff + field_size + 4)
6077 {
6078 if (size < (2 + 1))
bee0ee85
NC
6079 {
6080 warn (_("Internal error: not enough buffer room for section flag info"));
6081 return _("<unknown>");
6082 }
8d5ff12c
L
6083 size -= 2;
6084 *p++ = ',';
6085 *p++ = ' ';
6086 }
2b692964 6087 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6088 (unsigned long) unknown_flags);
6089 p += 10 + field_size;
6090 }
6091 }
6092
e9e44622 6093 *p = '\0';
d1133906
NC
6094 return buff;
6095}
6096
5844b465 6097static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6098get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6099{
6100 if (is_32bit_elf)
6101 {
6102 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6103
ebdf1ebf
NC
6104 if (size < sizeof (* echdr))
6105 {
6106 error (_("Compressed section is too small even for a compression header\n"));
6107 return 0;
6108 }
6109
77115a4a
L
6110 chdr->ch_type = BYTE_GET (echdr->ch_type);
6111 chdr->ch_size = BYTE_GET (echdr->ch_size);
6112 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6113 return sizeof (*echdr);
6114 }
6115 else
6116 {
6117 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6118
ebdf1ebf
NC
6119 if (size < sizeof (* echdr))
6120 {
6121 error (_("Compressed section is too small even for a compression header\n"));
6122 return 0;
6123 }
6124
77115a4a
L
6125 chdr->ch_type = BYTE_GET (echdr->ch_type);
6126 chdr->ch_size = BYTE_GET (echdr->ch_size);
6127 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6128 return sizeof (*echdr);
6129 }
6130}
6131
32ec8896 6132static bfd_boolean
dda8d76d 6133process_section_headers (Filedata * filedata)
252b5132 6134{
2cf0635d 6135 Elf_Internal_Shdr * section;
b34976b6 6136 unsigned int i;
252b5132 6137
8fb879cd 6138 free (filedata->section_headers);
dda8d76d 6139 filedata->section_headers = NULL;
8ff66993
AM
6140 free (dynamic_symbols);
6141 dynamic_symbols = NULL;
6142 num_dynamic_syms = 0;
6143 free (dynamic_strings);
6144 dynamic_strings = NULL;
6145 dynamic_strings_length = 0;
6146 free (dynamic_syminfo);
6147 dynamic_syminfo = NULL;
6148 while (symtab_shndx_list != NULL)
6149 {
6150 elf_section_list *next = symtab_shndx_list->next;
6151 free (symtab_shndx_list);
6152 symtab_shndx_list = next;
6153 }
252b5132 6154
dda8d76d 6155 if (filedata->file_header.e_shnum == 0)
252b5132 6156 {
82f2dbf7 6157 /* PR binutils/12467. */
dda8d76d 6158 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6159 {
6160 warn (_("possibly corrupt ELF file header - it has a non-zero"
6161 " section header offset, but no section headers\n"));
6162 return FALSE;
6163 }
82f2dbf7 6164 else if (do_sections)
252b5132
RH
6165 printf (_("\nThere are no sections in this file.\n"));
6166
32ec8896 6167 return TRUE;
252b5132
RH
6168 }
6169
6170 if (do_sections && !do_header)
d3a49aa8
AM
6171 printf (ngettext ("There is %d section header, "
6172 "starting at offset 0x%lx:\n",
6173 "There are %d section headers, "
6174 "starting at offset 0x%lx:\n",
dda8d76d
NC
6175 filedata->file_header.e_shnum),
6176 filedata->file_header.e_shnum,
6177 (unsigned long) filedata->file_header.e_shoff);
252b5132 6178
9ea033b2
NC
6179 if (is_32bit_elf)
6180 {
dda8d76d 6181 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6182 return FALSE;
6183 }
6184 else
6185 {
dda8d76d 6186 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6187 return FALSE;
9ea033b2 6188 }
252b5132
RH
6189
6190 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6191 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6192 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6193 {
dda8d76d 6194 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6195
c256ffe7
JJ
6196 if (section->sh_size != 0)
6197 {
dda8d76d
NC
6198 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6199 1, section->sh_size,
6200 _("string table"));
0de14b54 6201
dda8d76d 6202 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6203 }
252b5132
RH
6204 }
6205
6206 /* Scan the sections for the dynamic symbol table
e3c8793a 6207 and dynamic string table and debug sections. */
89fac5e3 6208 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6209 switch (filedata->file_header.e_machine)
89fac5e3
RS
6210 {
6211 case EM_MIPS:
6212 case EM_MIPS_RS3_LE:
6213 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6214 FDE addresses. However, the ABI also has a semi-official ILP32
6215 variant for which the normal FDE address size rules apply.
6216
6217 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6218 section, where XX is the size of longs in bits. Unfortunately,
6219 earlier compilers provided no way of distinguishing ILP32 objects
6220 from LP64 objects, so if there's any doubt, we should assume that
6221 the official LP64 form is being used. */
dda8d76d
NC
6222 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6223 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6224 eh_addr_size = 8;
6225 break;
0f56a26a
DD
6226
6227 case EM_H8_300:
6228 case EM_H8_300H:
dda8d76d 6229 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6230 {
6231 case E_H8_MACH_H8300:
6232 case E_H8_MACH_H8300HN:
6233 case E_H8_MACH_H8300SN:
6234 case E_H8_MACH_H8300SXN:
6235 eh_addr_size = 2;
6236 break;
6237 case E_H8_MACH_H8300H:
6238 case E_H8_MACH_H8300S:
6239 case E_H8_MACH_H8300SX:
6240 eh_addr_size = 4;
6241 break;
6242 }
f4236fe4
DD
6243 break;
6244
ff7eeb89 6245 case EM_M32C_OLD:
f4236fe4 6246 case EM_M32C:
dda8d76d 6247 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6248 {
6249 case EF_M32C_CPU_M16C:
6250 eh_addr_size = 2;
6251 break;
6252 }
6253 break;
89fac5e3
RS
6254 }
6255
76ca31c0
NC
6256#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6257 do \
6258 { \
6259 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6260 if (section->sh_entsize != expected_entsize) \
9dd3a467 6261 { \
76ca31c0
NC
6262 char buf[40]; \
6263 sprintf_vma (buf, section->sh_entsize); \
6264 /* Note: coded this way so that there is a single string for \
6265 translation. */ \
6266 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6267 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6268 (unsigned) expected_entsize); \
9dd3a467 6269 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6270 } \
6271 } \
08d8fa11 6272 while (0)
9dd3a467
NC
6273
6274#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
6275 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
6276 sizeof (Elf64_External_##type))
6277
dda8d76d
NC
6278 for (i = 0, section = filedata->section_headers;
6279 i < filedata->file_header.e_shnum;
b34976b6 6280 i++, section++)
252b5132 6281 {
2cf0635d 6282 char * name = SECTION_NAME (section);
252b5132
RH
6283
6284 if (section->sh_type == SHT_DYNSYM)
6285 {
6286 if (dynamic_symbols != NULL)
6287 {
6288 error (_("File contains multiple dynamic symbol tables\n"));
6289 continue;
6290 }
6291
08d8fa11 6292 CHECK_ENTSIZE (section, i, Sym);
dda8d76d 6293 dynamic_symbols = GET_ELF_SYMBOLS (filedata, section, & num_dynamic_syms);
252b5132
RH
6294 }
6295 else if (section->sh_type == SHT_STRTAB
18bd398b 6296 && streq (name, ".dynstr"))
252b5132
RH
6297 {
6298 if (dynamic_strings != NULL)
6299 {
6300 error (_("File contains multiple dynamic string tables\n"));
6301 continue;
6302 }
6303
dda8d76d 6304 dynamic_strings = (char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6305 1, section->sh_size,
6306 _("dynamic strings"));
59245841 6307 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 6308 }
9ad5cbcf
AM
6309 else if (section->sh_type == SHT_SYMTAB_SHNDX)
6310 {
6a40cf0c 6311 elf_section_list * entry = xmalloc (sizeof * entry);
dda8d76d 6312
6a40cf0c
NC
6313 entry->hdr = section;
6314 entry->next = symtab_shndx_list;
6315 symtab_shndx_list = entry;
9ad5cbcf 6316 }
08d8fa11
JJ
6317 else if (section->sh_type == SHT_SYMTAB)
6318 CHECK_ENTSIZE (section, i, Sym);
6319 else if (section->sh_type == SHT_GROUP)
6320 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6321 else if (section->sh_type == SHT_REL)
6322 CHECK_ENTSIZE (section, i, Rel);
6323 else if (section->sh_type == SHT_RELA)
6324 CHECK_ENTSIZE (section, i, Rela);
252b5132 6325 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 6326 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 6327 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47 6328 || do_debug_str || do_debug_loc || do_debug_ranges
d85bf2ba 6329 || do_debug_addr || do_debug_cu_index || do_debug_links)
1b315056
CS
6330 && (const_strneq (name, ".debug_")
6331 || const_strneq (name, ".zdebug_")))
252b5132 6332 {
1b315056
CS
6333 if (name[1] == 'z')
6334 name += sizeof (".zdebug_") - 1;
6335 else
6336 name += sizeof (".debug_") - 1;
252b5132
RH
6337
6338 if (do_debugging
4723351a
CC
6339 || (do_debug_info && const_strneq (name, "info"))
6340 || (do_debug_info && const_strneq (name, "types"))
6341 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6342 || (do_debug_lines && strcmp (name, "line") == 0)
6343 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6344 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6345 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6346 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6347 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6348 || (do_debug_aranges && const_strneq (name, "aranges"))
6349 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6350 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6351 || (do_debug_frames && const_strneq (name, "frame"))
6352 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6353 || (do_debug_macinfo && const_strneq (name, "macro"))
6354 || (do_debug_str && const_strneq (name, "str"))
6355 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6356 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6357 || (do_debug_addr && const_strneq (name, "addr"))
6358 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6359 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6360 )
6431e409 6361 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6362 }
a262ae96 6363 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6364 else if ((do_debugging || do_debug_info)
0112cd26 6365 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6366 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6367 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6368 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6369 else if (do_gdb_index && (streq (name, ".gdb_index")
6370 || streq (name, ".debug_names")))
6431e409 6371 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6372 /* Trace sections for Itanium VMS. */
6373 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6374 || do_trace_aranges)
6375 && const_strneq (name, ".trace_"))
6376 {
6377 name += sizeof (".trace_") - 1;
6378
6379 if (do_debugging
6380 || (do_trace_info && streq (name, "info"))
6381 || (do_trace_abbrevs && streq (name, "abbrev"))
6382 || (do_trace_aranges && streq (name, "aranges"))
6383 )
6431e409 6384 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6385 }
dda8d76d
NC
6386 else if ((do_debugging || do_debug_links)
6387 && (const_strneq (name, ".gnu_debuglink")
6388 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6389 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6390 }
6391
6392 if (! do_sections)
32ec8896 6393 return TRUE;
252b5132 6394
dda8d76d 6395 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6396 printf (_("\nSection Headers:\n"));
6397 else
6398 printf (_("\nSection Header:\n"));
76da6bbe 6399
f7a99963 6400 if (is_32bit_elf)
595cf52e 6401 {
5477e8a0 6402 if (do_section_details)
595cf52e
L
6403 {
6404 printf (_(" [Nr] Name\n"));
5477e8a0 6405 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6406 }
6407 else
6408 printf
6409 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6410 }
d974e256 6411 else if (do_wide)
595cf52e 6412 {
5477e8a0 6413 if (do_section_details)
595cf52e
L
6414 {
6415 printf (_(" [Nr] Name\n"));
5477e8a0 6416 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6417 }
6418 else
6419 printf
6420 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6421 }
f7a99963
NC
6422 else
6423 {
5477e8a0 6424 if (do_section_details)
595cf52e
L
6425 {
6426 printf (_(" [Nr] Name\n"));
5477e8a0
L
6427 printf (_(" Type Address Offset Link\n"));
6428 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6429 }
6430 else
6431 {
6432 printf (_(" [Nr] Name Type Address Offset\n"));
6433 printf (_(" Size EntSize Flags Link Info Align\n"));
6434 }
f7a99963 6435 }
252b5132 6436
5477e8a0
L
6437 if (do_section_details)
6438 printf (_(" Flags\n"));
6439
dda8d76d
NC
6440 for (i = 0, section = filedata->section_headers;
6441 i < filedata->file_header.e_shnum;
b34976b6 6442 i++, section++)
252b5132 6443 {
dd905818
NC
6444 /* Run some sanity checks on the section header. */
6445
6446 /* Check the sh_link field. */
6447 switch (section->sh_type)
6448 {
285e3f99
AM
6449 case SHT_REL:
6450 case SHT_RELA:
6451 if (section->sh_link == 0
6452 && (filedata->file_header.e_type == ET_EXEC
6453 || filedata->file_header.e_type == ET_DYN))
6454 /* A dynamic relocation section where all entries use a
6455 zero symbol index need not specify a symtab section. */
6456 break;
6457 /* Fall through. */
dd905818
NC
6458 case SHT_SYMTAB_SHNDX:
6459 case SHT_GROUP:
6460 case SHT_HASH:
6461 case SHT_GNU_HASH:
6462 case SHT_GNU_versym:
285e3f99 6463 if (section->sh_link == 0
dda8d76d
NC
6464 || section->sh_link >= filedata->file_header.e_shnum
6465 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6466 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6467 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6468 i, section->sh_link);
6469 break;
6470
6471 case SHT_DYNAMIC:
6472 case SHT_SYMTAB:
6473 case SHT_DYNSYM:
6474 case SHT_GNU_verneed:
6475 case SHT_GNU_verdef:
6476 case SHT_GNU_LIBLIST:
285e3f99 6477 if (section->sh_link == 0
dda8d76d
NC
6478 || section->sh_link >= filedata->file_header.e_shnum
6479 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6480 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6481 i, section->sh_link);
6482 break;
6483
6484 case SHT_INIT_ARRAY:
6485 case SHT_FINI_ARRAY:
6486 case SHT_PREINIT_ARRAY:
6487 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6488 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6489 i, section->sh_link);
6490 break;
6491
6492 default:
6493 /* FIXME: Add support for target specific section types. */
6494#if 0 /* Currently we do not check other section types as there are too
6495 many special cases. Stab sections for example have a type
6496 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6497 section. */
6498 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6499 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6500 i, section->sh_link);
6501#endif
6502 break;
6503 }
6504
6505 /* Check the sh_info field. */
6506 switch (section->sh_type)
6507 {
6508 case SHT_REL:
6509 case SHT_RELA:
285e3f99
AM
6510 if (section->sh_info == 0
6511 && (filedata->file_header.e_type == ET_EXEC
6512 || filedata->file_header.e_type == ET_DYN))
6513 /* Dynamic relocations apply to segments, so they do not
6514 need to specify the section they relocate. */
6515 break;
6516 if (section->sh_info == 0
dda8d76d
NC
6517 || section->sh_info >= filedata->file_header.e_shnum
6518 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6519 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6520 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6521 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6522 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6523 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6524 /* FIXME: Are other section types valid ? */
dda8d76d 6525 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6526 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6527 i, section->sh_info);
dd905818
NC
6528 break;
6529
6530 case SHT_DYNAMIC:
6531 case SHT_HASH:
6532 case SHT_SYMTAB_SHNDX:
6533 case SHT_INIT_ARRAY:
6534 case SHT_FINI_ARRAY:
6535 case SHT_PREINIT_ARRAY:
6536 if (section->sh_info != 0)
6537 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6538 i, section->sh_info);
6539 break;
6540
6541 case SHT_GROUP:
6542 case SHT_SYMTAB:
6543 case SHT_DYNSYM:
6544 /* A symbol index - we assume that it is valid. */
6545 break;
6546
6547 default:
6548 /* FIXME: Add support for target specific section types. */
6549 if (section->sh_type == SHT_NOBITS)
6550 /* NOBITS section headers with non-zero sh_info fields can be
6551 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6552 information. The stripped sections have their headers
6553 preserved but their types set to SHT_NOBITS. So do not check
6554 this type of section. */
dd905818
NC
6555 ;
6556 else if (section->sh_flags & SHF_INFO_LINK)
6557 {
dda8d76d 6558 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6559 warn (_("[%2u]: Expected link to another section in info field"), i);
6560 }
a91e1603
L
6561 else if (section->sh_type < SHT_LOOS
6562 && (section->sh_flags & SHF_GNU_MBIND) == 0
6563 && section->sh_info != 0)
dd905818
NC
6564 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6565 i, section->sh_info);
6566 break;
6567 }
6568
3e6b6445 6569 /* Check the sh_size field. */
dda8d76d 6570 if (section->sh_size > filedata->file_size
3e6b6445
NC
6571 && section->sh_type != SHT_NOBITS
6572 && section->sh_type != SHT_NULL
6573 && section->sh_type < SHT_LOOS)
6574 warn (_("Size of section %u is larger than the entire file!\n"), i);
6575
7bfd842d 6576 printf (" [%2u] ", i);
5477e8a0 6577 if (do_section_details)
dda8d76d 6578 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6579 else
74e1a04b 6580 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6581
ea52a088 6582 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6583 get_section_type_name (filedata, section->sh_type));
0b4362b0 6584
f7a99963
NC
6585 if (is_32bit_elf)
6586 {
cfcac11d
NC
6587 const char * link_too_big = NULL;
6588
f7a99963 6589 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6590
f7a99963
NC
6591 printf ( " %6.6lx %6.6lx %2.2lx",
6592 (unsigned long) section->sh_offset,
6593 (unsigned long) section->sh_size,
6594 (unsigned long) section->sh_entsize);
d1133906 6595
5477e8a0
L
6596 if (do_section_details)
6597 fputs (" ", stdout);
6598 else
dda8d76d 6599 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6600
dda8d76d 6601 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6602 {
6603 link_too_big = "";
6604 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6605 an error but it can have special values in Solaris binaries. */
dda8d76d 6606 switch (filedata->file_header.e_machine)
cfcac11d 6607 {
caa83f8b 6608 case EM_386:
22abe556 6609 case EM_IAMCU:
caa83f8b 6610 case EM_X86_64:
7f502d6c 6611 case EM_L1OM:
7a9068fe 6612 case EM_K1OM:
cfcac11d
NC
6613 case EM_OLD_SPARCV9:
6614 case EM_SPARC32PLUS:
6615 case EM_SPARCV9:
6616 case EM_SPARC:
6617 if (section->sh_link == (SHN_BEFORE & 0xffff))
6618 link_too_big = "BEFORE";
6619 else if (section->sh_link == (SHN_AFTER & 0xffff))
6620 link_too_big = "AFTER";
6621 break;
6622 default:
6623 break;
6624 }
6625 }
6626
6627 if (do_section_details)
6628 {
6629 if (link_too_big != NULL && * link_too_big)
6630 printf ("<%s> ", link_too_big);
6631 else
6632 printf ("%2u ", section->sh_link);
6633 printf ("%3u %2lu\n", section->sh_info,
6634 (unsigned long) section->sh_addralign);
6635 }
6636 else
6637 printf ("%2u %3u %2lu\n",
6638 section->sh_link,
6639 section->sh_info,
6640 (unsigned long) section->sh_addralign);
6641
6642 if (link_too_big && ! * link_too_big)
6643 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6644 i, section->sh_link);
f7a99963 6645 }
d974e256
JJ
6646 else if (do_wide)
6647 {
6648 print_vma (section->sh_addr, LONG_HEX);
6649
6650 if ((long) section->sh_offset == section->sh_offset)
6651 printf (" %6.6lx", (unsigned long) section->sh_offset);
6652 else
6653 {
6654 putchar (' ');
6655 print_vma (section->sh_offset, LONG_HEX);
6656 }
6657
6658 if ((unsigned long) section->sh_size == section->sh_size)
6659 printf (" %6.6lx", (unsigned long) section->sh_size);
6660 else
6661 {
6662 putchar (' ');
6663 print_vma (section->sh_size, LONG_HEX);
6664 }
6665
6666 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6667 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6668 else
6669 {
6670 putchar (' ');
6671 print_vma (section->sh_entsize, LONG_HEX);
6672 }
6673
5477e8a0
L
6674 if (do_section_details)
6675 fputs (" ", stdout);
6676 else
dda8d76d 6677 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6678
72de5009 6679 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6680
6681 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6682 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6683 else
6684 {
6685 print_vma (section->sh_addralign, DEC);
6686 putchar ('\n');
6687 }
6688 }
5477e8a0 6689 else if (do_section_details)
595cf52e 6690 {
55cc53e9 6691 putchar (' ');
595cf52e
L
6692 print_vma (section->sh_addr, LONG_HEX);
6693 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6694 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6695 else
6696 {
6697 printf (" ");
6698 print_vma (section->sh_offset, LONG_HEX);
6699 }
72de5009 6700 printf (" %u\n ", section->sh_link);
595cf52e 6701 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6702 putchar (' ');
595cf52e
L
6703 print_vma (section->sh_entsize, LONG_HEX);
6704
72de5009
AM
6705 printf (" %-16u %lu\n",
6706 section->sh_info,
595cf52e
L
6707 (unsigned long) section->sh_addralign);
6708 }
f7a99963
NC
6709 else
6710 {
6711 putchar (' ');
6712 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6713 if ((long) section->sh_offset == section->sh_offset)
6714 printf (" %8.8lx", (unsigned long) section->sh_offset);
6715 else
6716 {
6717 printf (" ");
6718 print_vma (section->sh_offset, LONG_HEX);
6719 }
f7a99963
NC
6720 printf ("\n ");
6721 print_vma (section->sh_size, LONG_HEX);
6722 printf (" ");
6723 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6724
dda8d76d 6725 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6726
72de5009
AM
6727 printf (" %2u %3u %lu\n",
6728 section->sh_link,
6729 section->sh_info,
f7a99963
NC
6730 (unsigned long) section->sh_addralign);
6731 }
5477e8a0
L
6732
6733 if (do_section_details)
77115a4a 6734 {
dda8d76d 6735 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6736 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6737 {
6738 /* Minimum section size is 12 bytes for 32-bit compression
6739 header + 12 bytes for compressed data header. */
6740 unsigned char buf[24];
d8024a91 6741
77115a4a 6742 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6743 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6744 sizeof (buf), _("compression header")))
6745 {
6746 Elf_Internal_Chdr chdr;
d8024a91 6747
5844b465
NC
6748 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
6749 printf (_(" [<corrupt>]\n"));
77115a4a 6750 else
5844b465
NC
6751 {
6752 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6753 printf (" ZLIB, ");
6754 else
6755 printf (_(" [<unknown>: 0x%x], "),
6756 chdr.ch_type);
6757 print_vma (chdr.ch_size, LONG_HEX);
6758 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6759 }
77115a4a
L
6760 }
6761 }
6762 }
252b5132
RH
6763 }
6764
5477e8a0 6765 if (!do_section_details)
3dbcc61d 6766 {
9fb71ee4
NC
6767 /* The ordering of the letters shown here matches the ordering of the
6768 corresponding SHF_xxx values, and hence the order in which these
6769 letters will be displayed to the user. */
6770 printf (_("Key to Flags:\n\
6771 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6772 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6773 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6774 if (filedata->file_header.e_machine == EM_X86_64
6775 || filedata->file_header.e_machine == EM_L1OM
6776 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6777 printf (_("l (large), "));
dda8d76d 6778 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6779 printf (_("y (purecode), "));
dda8d76d 6780 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6781 printf (_("v (VLE), "));
9fb71ee4 6782 printf ("p (processor specific)\n");
0b4362b0 6783 }
d1133906 6784
32ec8896 6785 return TRUE;
252b5132
RH
6786}
6787
28d13567
AM
6788static bfd_boolean
6789get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
6790 Elf_Internal_Sym **symtab, unsigned long *nsyms,
6791 char **strtab, unsigned long *strtablen)
6792{
6793 *strtab = NULL;
6794 *strtablen = 0;
6795 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
6796
6797 if (*symtab == NULL)
6798 return FALSE;
6799
6800 if (symsec->sh_link != 0)
6801 {
6802 Elf_Internal_Shdr *strsec;
6803
6804 if (symsec->sh_link >= filedata->file_header.e_shnum)
6805 {
6806 error (_("Bad sh_link in symbol table section\n"));
6807 free (*symtab);
6808 *symtab = NULL;
6809 *nsyms = 0;
6810 return FALSE;
6811 }
6812
6813 strsec = filedata->section_headers + symsec->sh_link;
6814
6815 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
6816 1, strsec->sh_size, _("string table"));
6817 if (*strtab == NULL)
6818 {
6819 free (*symtab);
6820 *symtab = NULL;
6821 *nsyms = 0;
6822 return FALSE;
6823 }
6824 *strtablen = strsec->sh_size;
6825 }
6826 return TRUE;
6827}
6828
f5842774
L
6829static const char *
6830get_group_flags (unsigned int flags)
6831{
1449284b 6832 static char buff[128];
220453ec 6833
6d913794
NC
6834 if (flags == 0)
6835 return "";
6836 else if (flags == GRP_COMDAT)
6837 return "COMDAT ";
f5842774 6838
89246a0e
AM
6839 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
6840 flags,
6841 flags & GRP_MASKOS ? _("<OS specific>") : "",
6842 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
6843 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
6844 ? _("<unknown>") : ""));
6d913794 6845
f5842774
L
6846 return buff;
6847}
6848
32ec8896 6849static bfd_boolean
dda8d76d 6850process_section_groups (Filedata * filedata)
f5842774 6851{
2cf0635d 6852 Elf_Internal_Shdr * section;
f5842774 6853 unsigned int i;
2cf0635d
NC
6854 struct group * group;
6855 Elf_Internal_Shdr * symtab_sec;
6856 Elf_Internal_Shdr * strtab_sec;
6857 Elf_Internal_Sym * symtab;
ba5cdace 6858 unsigned long num_syms;
2cf0635d 6859 char * strtab;
c256ffe7 6860 size_t strtab_size;
d1f5c6e3
L
6861
6862 /* Don't process section groups unless needed. */
6863 if (!do_unwind && !do_section_groups)
32ec8896 6864 return TRUE;
f5842774 6865
dda8d76d 6866 if (filedata->file_header.e_shnum == 0)
f5842774
L
6867 {
6868 if (do_section_groups)
82f2dbf7 6869 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 6870
32ec8896 6871 return TRUE;
f5842774
L
6872 }
6873
dda8d76d 6874 if (filedata->section_headers == NULL)
f5842774
L
6875 {
6876 error (_("Section headers are not available!\n"));
fa1908fd 6877 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 6878 return FALSE;
f5842774
L
6879 }
6880
dda8d76d 6881 section_headers_groups = (struct group **) calloc (filedata->file_header.e_shnum,
3f5e193b 6882 sizeof (struct group *));
e4b17d5c
L
6883
6884 if (section_headers_groups == NULL)
6885 {
8b73c356 6886 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 6887 filedata->file_header.e_shnum);
32ec8896 6888 return FALSE;
e4b17d5c
L
6889 }
6890
f5842774 6891 /* Scan the sections for the group section. */
d1f5c6e3 6892 group_count = 0;
dda8d76d
NC
6893 for (i = 0, section = filedata->section_headers;
6894 i < filedata->file_header.e_shnum;
f5842774 6895 i++, section++)
e4b17d5c
L
6896 if (section->sh_type == SHT_GROUP)
6897 group_count++;
6898
d1f5c6e3
L
6899 if (group_count == 0)
6900 {
6901 if (do_section_groups)
6902 printf (_("\nThere are no section groups in this file.\n"));
6903
32ec8896 6904 return TRUE;
d1f5c6e3
L
6905 }
6906
3f5e193b 6907 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
6908
6909 if (section_groups == NULL)
6910 {
8b73c356
NC
6911 error (_("Out of memory reading %lu groups\n"),
6912 (unsigned long) group_count);
32ec8896 6913 return FALSE;
e4b17d5c
L
6914 }
6915
d1f5c6e3
L
6916 symtab_sec = NULL;
6917 strtab_sec = NULL;
6918 symtab = NULL;
ba5cdace 6919 num_syms = 0;
d1f5c6e3 6920 strtab = NULL;
c256ffe7 6921 strtab_size = 0;
dda8d76d
NC
6922 for (i = 0, section = filedata->section_headers, group = section_groups;
6923 i < filedata->file_header.e_shnum;
e4b17d5c 6924 i++, section++)
f5842774
L
6925 {
6926 if (section->sh_type == SHT_GROUP)
6927 {
dda8d76d 6928 const char * name = printable_section_name (filedata, section);
74e1a04b 6929 const char * group_name;
2cf0635d
NC
6930 unsigned char * start;
6931 unsigned char * indices;
f5842774 6932 unsigned int entry, j, size;
2cf0635d
NC
6933 Elf_Internal_Shdr * sec;
6934 Elf_Internal_Sym * sym;
f5842774
L
6935
6936 /* Get the symbol table. */
dda8d76d
NC
6937 if (section->sh_link >= filedata->file_header.e_shnum
6938 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 6939 != SHT_SYMTAB))
f5842774
L
6940 {
6941 error (_("Bad sh_link in group section `%s'\n"), name);
6942 continue;
6943 }
d1f5c6e3
L
6944
6945 if (symtab_sec != sec)
6946 {
6947 symtab_sec = sec;
6948 if (symtab)
6949 free (symtab);
dda8d76d 6950 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 6951 }
f5842774 6952
dd24e3da
NC
6953 if (symtab == NULL)
6954 {
6955 error (_("Corrupt header in group section `%s'\n"), name);
6956 continue;
6957 }
6958
ba5cdace
NC
6959 if (section->sh_info >= num_syms)
6960 {
6961 error (_("Bad sh_info in group section `%s'\n"), name);
6962 continue;
6963 }
6964
f5842774
L
6965 sym = symtab + section->sh_info;
6966
6967 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6968 {
4fbb74a6 6969 if (sym->st_shndx == 0
dda8d76d 6970 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
6971 {
6972 error (_("Bad sh_info in group section `%s'\n"), name);
6973 continue;
6974 }
ba2685cc 6975
dda8d76d 6976 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7
JJ
6977 strtab_sec = NULL;
6978 if (strtab)
6979 free (strtab);
f5842774 6980 strtab = NULL;
c256ffe7 6981 strtab_size = 0;
f5842774
L
6982 }
6983 else
6984 {
6985 /* Get the string table. */
dda8d76d 6986 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
6987 {
6988 strtab_sec = NULL;
6989 if (strtab)
6990 free (strtab);
6991 strtab = NULL;
6992 strtab_size = 0;
6993 }
6994 else if (strtab_sec
dda8d76d 6995 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
6996 {
6997 strtab_sec = sec;
6998 if (strtab)
6999 free (strtab);
071436c6 7000
dda8d76d 7001 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7002 1, strtab_sec->sh_size,
7003 _("string table"));
c256ffe7 7004 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7005 }
c256ffe7 7006 group_name = sym->st_name < strtab_size
2b692964 7007 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7008 }
7009
c9c1d674
EG
7010 /* PR 17531: file: loop. */
7011 if (section->sh_entsize > section->sh_size)
7012 {
7013 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7014 printable_section_name (filedata, section),
8066deb1
AM
7015 (unsigned long) section->sh_entsize,
7016 (unsigned long) section->sh_size);
61dd8e19 7017 continue;
c9c1d674
EG
7018 }
7019
dda8d76d 7020 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7021 1, section->sh_size,
7022 _("section data"));
59245841
NC
7023 if (start == NULL)
7024 continue;
f5842774
L
7025
7026 indices = start;
7027 size = (section->sh_size / section->sh_entsize) - 1;
7028 entry = byte_get (indices, 4);
7029 indices += 4;
e4b17d5c
L
7030
7031 if (do_section_groups)
7032 {
2b692964 7033 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7034 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7035
e4b17d5c
L
7036 printf (_(" [Index] Name\n"));
7037 }
7038
7039 group->group_index = i;
7040
f5842774
L
7041 for (j = 0; j < size; j++)
7042 {
2cf0635d 7043 struct group_list * g;
e4b17d5c 7044
f5842774
L
7045 entry = byte_get (indices, 4);
7046 indices += 4;
7047
dda8d76d 7048 if (entry >= filedata->file_header.e_shnum)
391cb864 7049 {
57028622
NC
7050 static unsigned num_group_errors = 0;
7051
7052 if (num_group_errors ++ < 10)
7053 {
7054 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7055 entry, i, filedata->file_header.e_shnum - 1);
57028622 7056 if (num_group_errors == 10)
67ce483b 7057 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7058 }
391cb864
L
7059 continue;
7060 }
391cb864 7061
4fbb74a6 7062 if (section_headers_groups [entry] != NULL)
e4b17d5c 7063 {
d1f5c6e3
L
7064 if (entry)
7065 {
57028622
NC
7066 static unsigned num_errs = 0;
7067
7068 if (num_errs ++ < 10)
7069 {
7070 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7071 entry, i,
7072 section_headers_groups [entry]->group_index);
7073 if (num_errs == 10)
7074 warn (_("Further error messages about already contained group sections suppressed\n"));
7075 }
d1f5c6e3
L
7076 continue;
7077 }
7078 else
7079 {
7080 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7081 section group. We just warn it the first time
d1f5c6e3 7082 and ignore it afterwards. */
32ec8896 7083 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7084 if (!warned)
7085 {
7086 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 7087 section_headers_groups [entry]->group_index);
32ec8896 7088 warned = TRUE;
d1f5c6e3
L
7089 }
7090 }
e4b17d5c
L
7091 }
7092
4fbb74a6 7093 section_headers_groups [entry] = group;
e4b17d5c
L
7094
7095 if (do_section_groups)
7096 {
dda8d76d
NC
7097 sec = filedata->section_headers + entry;
7098 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7099 }
7100
3f5e193b 7101 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7102 g->section_index = entry;
7103 g->next = group->root;
7104 group->root = g;
f5842774
L
7105 }
7106
f5842774
L
7107 if (start)
7108 free (start);
e4b17d5c
L
7109
7110 group++;
f5842774
L
7111 }
7112 }
7113
d1f5c6e3
L
7114 if (symtab)
7115 free (symtab);
7116 if (strtab)
7117 free (strtab);
32ec8896 7118 return TRUE;
f5842774
L
7119}
7120
28f997cf
TG
7121/* Data used to display dynamic fixups. */
7122
7123struct ia64_vms_dynfixup
7124{
7125 bfd_vma needed_ident; /* Library ident number. */
7126 bfd_vma needed; /* Index in the dstrtab of the library name. */
7127 bfd_vma fixup_needed; /* Index of the library. */
7128 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7129 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7130};
7131
7132/* Data used to display dynamic relocations. */
7133
7134struct ia64_vms_dynimgrela
7135{
7136 bfd_vma img_rela_cnt; /* Number of relocations. */
7137 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7138};
7139
7140/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7141 library). */
7142
32ec8896 7143static bfd_boolean
dda8d76d
NC
7144dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7145 struct ia64_vms_dynfixup * fixup,
7146 const char * strtab,
7147 unsigned int strtab_sz)
28f997cf 7148{
32ec8896 7149 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7150 long i;
32ec8896 7151 const char * lib_name;
28f997cf 7152
dda8d76d 7153 imfs = get_data (NULL, filedata, dynamic_addr + fixup->fixup_rela_off,
95099889 7154 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7155 _("dynamic section image fixups"));
7156 if (!imfs)
32ec8896 7157 return FALSE;
28f997cf
TG
7158
7159 if (fixup->needed < strtab_sz)
7160 lib_name = strtab + fixup->needed;
7161 else
7162 {
32ec8896 7163 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7164 (unsigned long) fixup->needed);
28f997cf
TG
7165 lib_name = "???";
7166 }
736990c4 7167
28f997cf
TG
7168 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7169 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7170 printf
7171 (_("Seg Offset Type SymVec DataType\n"));
7172
7173 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7174 {
7175 unsigned int type;
7176 const char *rtype;
7177
7178 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7179 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7180 type = BYTE_GET (imfs [i].type);
7181 rtype = elf_ia64_reloc_type (type);
7182 if (rtype == NULL)
7183 printf (" 0x%08x ", type);
7184 else
7185 printf (" %-32s ", rtype);
7186 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7187 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7188 }
7189
7190 free (imfs);
32ec8896 7191 return TRUE;
28f997cf
TG
7192}
7193
7194/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7195
32ec8896 7196static bfd_boolean
dda8d76d 7197dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7198{
7199 Elf64_External_VMS_IMAGE_RELA *imrs;
7200 long i;
7201
dda8d76d 7202 imrs = get_data (NULL, filedata, dynamic_addr + imgrela->img_rela_off,
95099889 7203 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7204 _("dynamic section image relocations"));
28f997cf 7205 if (!imrs)
32ec8896 7206 return FALSE;
28f997cf
TG
7207
7208 printf (_("\nImage relocs\n"));
7209 printf
7210 (_("Seg Offset Type Addend Seg Sym Off\n"));
7211
7212 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7213 {
7214 unsigned int type;
7215 const char *rtype;
7216
7217 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7218 printf ("%08" BFD_VMA_FMT "x ",
7219 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7220 type = BYTE_GET (imrs [i].type);
7221 rtype = elf_ia64_reloc_type (type);
7222 if (rtype == NULL)
7223 printf ("0x%08x ", type);
7224 else
7225 printf ("%-31s ", rtype);
7226 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7227 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7228 printf ("%08" BFD_VMA_FMT "x\n",
7229 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7230 }
7231
7232 free (imrs);
32ec8896 7233 return TRUE;
28f997cf
TG
7234}
7235
7236/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7237
32ec8896 7238static bfd_boolean
dda8d76d 7239process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7240{
7241 struct ia64_vms_dynfixup fixup;
7242 struct ia64_vms_dynimgrela imgrela;
7243 Elf_Internal_Dyn *entry;
28f997cf
TG
7244 bfd_vma strtab_off = 0;
7245 bfd_vma strtab_sz = 0;
7246 char *strtab = NULL;
32ec8896 7247 bfd_boolean res = TRUE;
28f997cf
TG
7248
7249 memset (&fixup, 0, sizeof (fixup));
7250 memset (&imgrela, 0, sizeof (imgrela));
7251
7252 /* Note: the order of the entries is specified by the OpenVMS specs. */
7253 for (entry = dynamic_section;
7254 entry < dynamic_section + dynamic_nent;
7255 entry++)
7256 {
7257 switch (entry->d_tag)
7258 {
7259 case DT_IA_64_VMS_STRTAB_OFFSET:
7260 strtab_off = entry->d_un.d_val;
7261 break;
7262 case DT_STRSZ:
7263 strtab_sz = entry->d_un.d_val;
7264 if (strtab == NULL)
dda8d76d 7265 strtab = get_data (NULL, filedata, dynamic_addr + strtab_off,
28f997cf 7266 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7267 if (strtab == NULL)
7268 strtab_sz = 0;
28f997cf
TG
7269 break;
7270
7271 case DT_IA_64_VMS_NEEDED_IDENT:
7272 fixup.needed_ident = entry->d_un.d_val;
7273 break;
7274 case DT_NEEDED:
7275 fixup.needed = entry->d_un.d_val;
7276 break;
7277 case DT_IA_64_VMS_FIXUP_NEEDED:
7278 fixup.fixup_needed = entry->d_un.d_val;
7279 break;
7280 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7281 fixup.fixup_rela_cnt = entry->d_un.d_val;
7282 break;
7283 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7284 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7285 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7286 res = FALSE;
28f997cf 7287 break;
28f997cf
TG
7288 case DT_IA_64_VMS_IMG_RELA_CNT:
7289 imgrela.img_rela_cnt = entry->d_un.d_val;
7290 break;
7291 case DT_IA_64_VMS_IMG_RELA_OFF:
7292 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7293 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7294 res = FALSE;
28f997cf
TG
7295 break;
7296
7297 default:
7298 break;
7299 }
7300 }
7301
7302 if (strtab != NULL)
7303 free (strtab);
7304
7305 return res;
7306}
7307
85b1c36d 7308static struct
566b0d53 7309{
2cf0635d 7310 const char * name;
566b0d53
L
7311 int reloc;
7312 int size;
7313 int rela;
32ec8896
NC
7314}
7315 dynamic_relocations [] =
566b0d53 7316{
32ec8896
NC
7317 { "REL", DT_REL, DT_RELSZ, FALSE },
7318 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7319 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7320};
7321
252b5132 7322/* Process the reloc section. */
18bd398b 7323
32ec8896 7324static bfd_boolean
dda8d76d 7325process_relocs (Filedata * filedata)
252b5132 7326{
b34976b6
AM
7327 unsigned long rel_size;
7328 unsigned long rel_offset;
252b5132 7329
252b5132 7330 if (!do_reloc)
32ec8896 7331 return TRUE;
252b5132
RH
7332
7333 if (do_using_dynamic)
7334 {
32ec8896 7335 int is_rela;
2cf0635d 7336 const char * name;
32ec8896 7337 bfd_boolean has_dynamic_reloc;
566b0d53 7338 unsigned int i;
0de14b54 7339
32ec8896 7340 has_dynamic_reloc = FALSE;
252b5132 7341
566b0d53 7342 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7343 {
566b0d53
L
7344 is_rela = dynamic_relocations [i].rela;
7345 name = dynamic_relocations [i].name;
7346 rel_size = dynamic_info [dynamic_relocations [i].size];
7347 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 7348
32ec8896
NC
7349 if (rel_size)
7350 has_dynamic_reloc = TRUE;
566b0d53
L
7351
7352 if (is_rela == UNKNOWN)
aa903cfb 7353 {
566b0d53
L
7354 if (dynamic_relocations [i].reloc == DT_JMPREL)
7355 switch (dynamic_info[DT_PLTREL])
7356 {
7357 case DT_REL:
7358 is_rela = FALSE;
7359 break;
7360 case DT_RELA:
7361 is_rela = TRUE;
7362 break;
7363 }
aa903cfb 7364 }
252b5132 7365
566b0d53
L
7366 if (rel_size)
7367 {
7368 printf
7369 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7370 name, rel_offset, rel_size);
252b5132 7371
dda8d76d
NC
7372 dump_relocations (filedata,
7373 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7374 rel_size,
566b0d53 7375 dynamic_symbols, num_dynamic_syms,
bb4d2ac2 7376 dynamic_strings, dynamic_strings_length,
32ec8896 7377 is_rela, TRUE /* is_dynamic */);
566b0d53 7378 }
252b5132 7379 }
566b0d53 7380
dda8d76d
NC
7381 if (is_ia64_vms (filedata))
7382 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7383 has_dynamic_reloc = TRUE;
28f997cf 7384
566b0d53 7385 if (! has_dynamic_reloc)
252b5132
RH
7386 printf (_("\nThere are no dynamic relocations in this file.\n"));
7387 }
7388 else
7389 {
2cf0635d 7390 Elf_Internal_Shdr * section;
b34976b6 7391 unsigned long i;
32ec8896 7392 bfd_boolean found = FALSE;
252b5132 7393
dda8d76d
NC
7394 for (i = 0, section = filedata->section_headers;
7395 i < filedata->file_header.e_shnum;
b34976b6 7396 i++, section++)
252b5132
RH
7397 {
7398 if ( section->sh_type != SHT_RELA
7399 && section->sh_type != SHT_REL)
7400 continue;
7401
7402 rel_offset = section->sh_offset;
7403 rel_size = section->sh_size;
7404
7405 if (rel_size)
7406 {
b34976b6 7407 int is_rela;
d3a49aa8 7408 unsigned long num_rela;
103f02d3 7409
252b5132
RH
7410 printf (_("\nRelocation section "));
7411
dda8d76d 7412 if (filedata->string_table == NULL)
19936277 7413 printf ("%d", section->sh_name);
252b5132 7414 else
dda8d76d 7415 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7416
d3a49aa8
AM
7417 num_rela = rel_size / section->sh_entsize;
7418 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7419 " at offset 0x%lx contains %lu entries:\n",
7420 num_rela),
7421 rel_offset, num_rela);
252b5132 7422
d79b3d50
NC
7423 is_rela = section->sh_type == SHT_RELA;
7424
4fbb74a6 7425 if (section->sh_link != 0
dda8d76d 7426 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7427 {
2cf0635d
NC
7428 Elf_Internal_Shdr * symsec;
7429 Elf_Internal_Sym * symtab;
d79b3d50 7430 unsigned long nsyms;
c256ffe7 7431 unsigned long strtablen = 0;
2cf0635d 7432 char * strtab = NULL;
57346661 7433
dda8d76d 7434 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7435 if (symsec->sh_type != SHT_SYMTAB
7436 && symsec->sh_type != SHT_DYNSYM)
7437 continue;
7438
28d13567
AM
7439 if (!get_symtab (filedata, symsec,
7440 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7441 continue;
252b5132 7442
dda8d76d 7443 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7444 symtab, nsyms, strtab, strtablen,
7445 is_rela,
7446 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
7447 if (strtab)
7448 free (strtab);
7449 free (symtab);
7450 }
7451 else
dda8d76d 7452 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7453 NULL, 0, NULL, 0, is_rela,
7454 FALSE /* is_dynamic */);
252b5132 7455
32ec8896 7456 found = TRUE;
252b5132
RH
7457 }
7458 }
7459
7460 if (! found)
45ac8f4f
NC
7461 {
7462 /* Users sometimes forget the -D option, so try to be helpful. */
7463 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7464 {
7465 if (dynamic_info [dynamic_relocations [i].size])
7466 {
7467 printf (_("\nThere are no static relocations in this file."));
7468 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7469
7470 break;
7471 }
7472 }
7473 if (i == ARRAY_SIZE (dynamic_relocations))
7474 printf (_("\nThere are no relocations in this file.\n"));
7475 }
252b5132
RH
7476 }
7477
32ec8896 7478 return TRUE;
252b5132
RH
7479}
7480
4d6ed7c8
NC
7481/* An absolute address consists of a section and an offset. If the
7482 section is NULL, the offset itself is the address, otherwise, the
7483 address equals to LOAD_ADDRESS(section) + offset. */
7484
7485struct absaddr
948f632f
DA
7486{
7487 unsigned short section;
7488 bfd_vma offset;
7489};
4d6ed7c8 7490
948f632f
DA
7491/* Find the nearest symbol at or below ADDR. Returns the symbol
7492 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7493
4d6ed7c8 7494static void
dda8d76d
NC
7495find_symbol_for_address (Filedata * filedata,
7496 Elf_Internal_Sym * symtab,
7497 unsigned long nsyms,
7498 const char * strtab,
7499 unsigned long strtab_size,
7500 struct absaddr addr,
7501 const char ** symname,
7502 bfd_vma * offset)
4d6ed7c8 7503{
d3ba0551 7504 bfd_vma dist = 0x100000;
2cf0635d 7505 Elf_Internal_Sym * sym;
948f632f
DA
7506 Elf_Internal_Sym * beg;
7507 Elf_Internal_Sym * end;
2cf0635d 7508 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7509
0b6ae522 7510 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7511 beg = symtab;
7512 end = symtab + nsyms;
0b6ae522 7513
948f632f 7514 while (beg < end)
4d6ed7c8 7515 {
948f632f
DA
7516 bfd_vma value;
7517
7518 sym = beg + (end - beg) / 2;
0b6ae522 7519
948f632f 7520 value = sym->st_value;
0b6ae522
DJ
7521 REMOVE_ARCH_BITS (value);
7522
948f632f 7523 if (sym->st_name != 0
4d6ed7c8 7524 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7525 && addr.offset >= value
7526 && addr.offset - value < dist)
4d6ed7c8
NC
7527 {
7528 best = sym;
0b6ae522 7529 dist = addr.offset - value;
4d6ed7c8
NC
7530 if (!dist)
7531 break;
7532 }
948f632f
DA
7533
7534 if (addr.offset < value)
7535 end = sym;
7536 else
7537 beg = sym + 1;
4d6ed7c8 7538 }
1b31d05e 7539
4d6ed7c8
NC
7540 if (best)
7541 {
57346661 7542 *symname = (best->st_name >= strtab_size
2b692964 7543 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7544 *offset = dist;
7545 return;
7546 }
1b31d05e 7547
4d6ed7c8
NC
7548 *symname = NULL;
7549 *offset = addr.offset;
7550}
7551
32ec8896 7552static /* signed */ int
948f632f
DA
7553symcmp (const void *p, const void *q)
7554{
7555 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7556 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7557
7558 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7559}
7560
7561/* Process the unwind section. */
7562
7563#include "unwind-ia64.h"
7564
7565struct ia64_unw_table_entry
7566{
7567 struct absaddr start;
7568 struct absaddr end;
7569 struct absaddr info;
7570};
7571
7572struct ia64_unw_aux_info
7573{
32ec8896
NC
7574 struct ia64_unw_table_entry * table; /* Unwind table. */
7575 unsigned long table_len; /* Length of unwind table. */
7576 unsigned char * info; /* Unwind info. */
7577 unsigned long info_size; /* Size of unwind info. */
7578 bfd_vma info_addr; /* Starting address of unwind info. */
7579 bfd_vma seg_base; /* Starting address of segment. */
7580 Elf_Internal_Sym * symtab; /* The symbol table. */
7581 unsigned long nsyms; /* Number of symbols. */
7582 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7583 unsigned long nfuns; /* Number of entries in funtab. */
7584 char * strtab; /* The string table. */
7585 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7586};
7587
32ec8896 7588static bfd_boolean
dda8d76d 7589dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7590{
2cf0635d 7591 struct ia64_unw_table_entry * tp;
948f632f 7592 unsigned long j, nfuns;
4d6ed7c8 7593 int in_body;
32ec8896 7594 bfd_boolean res = TRUE;
7036c0e1 7595
948f632f
DA
7596 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7597 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7598 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7599 aux->funtab[nfuns++] = aux->symtab[j];
7600 aux->nfuns = nfuns;
7601 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7602
4d6ed7c8
NC
7603 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7604 {
7605 bfd_vma stamp;
7606 bfd_vma offset;
2cf0635d
NC
7607 const unsigned char * dp;
7608 const unsigned char * head;
53774b7e 7609 const unsigned char * end;
2cf0635d 7610 const char * procname;
4d6ed7c8 7611
dda8d76d 7612 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7613 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7614
7615 fputs ("\n<", stdout);
7616
7617 if (procname)
7618 {
7619 fputs (procname, stdout);
7620
7621 if (offset)
7622 printf ("+%lx", (unsigned long) offset);
7623 }
7624
7625 fputs (">: [", stdout);
7626 print_vma (tp->start.offset, PREFIX_HEX);
7627 fputc ('-', stdout);
7628 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7629 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7630 (unsigned long) (tp->info.offset - aux->seg_base));
7631
53774b7e
NC
7632 /* PR 17531: file: 86232b32. */
7633 if (aux->info == NULL)
7634 continue;
7635
97c0a079
AM
7636 offset = tp->info.offset;
7637 if (tp->info.section)
7638 {
7639 if (tp->info.section >= filedata->file_header.e_shnum)
7640 {
7641 warn (_("Invalid section %u in table entry %ld\n"),
7642 tp->info.section, (long) (tp - aux->table));
7643 res = FALSE;
7644 continue;
7645 }
7646 offset += filedata->section_headers[tp->info.section].sh_addr;
7647 }
7648 offset -= aux->info_addr;
53774b7e 7649 /* PR 17531: file: 0997b4d1. */
90679903
AM
7650 if (offset >= aux->info_size
7651 || aux->info_size - offset < 8)
53774b7e
NC
7652 {
7653 warn (_("Invalid offset %lx in table entry %ld\n"),
7654 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7655 res = FALSE;
53774b7e
NC
7656 continue;
7657 }
7658
97c0a079 7659 head = aux->info + offset;
a4a00738 7660 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7661
86f55779 7662 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7663 (unsigned) UNW_VER (stamp),
7664 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7665 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7666 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7667 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7668
7669 if (UNW_VER (stamp) != 1)
7670 {
2b692964 7671 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7672 continue;
7673 }
7674
7675 in_body = 0;
53774b7e
NC
7676 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7677 /* PR 17531: file: 16ceda89. */
7678 if (end > aux->info + aux->info_size)
7679 end = aux->info + aux->info_size;
7680 for (dp = head + 8; dp < end;)
b4477bc8 7681 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7682 }
948f632f
DA
7683
7684 free (aux->funtab);
32ec8896
NC
7685
7686 return res;
4d6ed7c8
NC
7687}
7688
53774b7e 7689static bfd_boolean
dda8d76d
NC
7690slurp_ia64_unwind_table (Filedata * filedata,
7691 struct ia64_unw_aux_info * aux,
7692 Elf_Internal_Shdr * sec)
4d6ed7c8 7693{
89fac5e3 7694 unsigned long size, nrelas, i;
2cf0635d
NC
7695 Elf_Internal_Phdr * seg;
7696 struct ia64_unw_table_entry * tep;
7697 Elf_Internal_Shdr * relsec;
7698 Elf_Internal_Rela * rela;
7699 Elf_Internal_Rela * rp;
7700 unsigned char * table;
7701 unsigned char * tp;
7702 Elf_Internal_Sym * sym;
7703 const char * relname;
4d6ed7c8 7704
53774b7e
NC
7705 aux->table_len = 0;
7706
4d6ed7c8
NC
7707 /* First, find the starting address of the segment that includes
7708 this section: */
7709
dda8d76d 7710 if (filedata->file_header.e_phnum)
4d6ed7c8 7711 {
dda8d76d 7712 if (! get_program_headers (filedata))
53774b7e 7713 return FALSE;
4d6ed7c8 7714
dda8d76d
NC
7715 for (seg = filedata->program_headers;
7716 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7717 ++seg)
4d6ed7c8
NC
7718 {
7719 if (seg->p_type != PT_LOAD)
7720 continue;
7721
7722 if (sec->sh_addr >= seg->p_vaddr
7723 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7724 {
7725 aux->seg_base = seg->p_vaddr;
7726 break;
7727 }
7728 }
4d6ed7c8
NC
7729 }
7730
7731 /* Second, build the unwind table from the contents of the unwind section: */
7732 size = sec->sh_size;
dda8d76d 7733 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7734 _("unwind table"));
a6e9f9df 7735 if (!table)
53774b7e 7736 return FALSE;
4d6ed7c8 7737
53774b7e 7738 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7739 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7740 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7741 tep = aux->table;
53774b7e
NC
7742
7743 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7744 {
7745 tep->start.section = SHN_UNDEF;
7746 tep->end.section = SHN_UNDEF;
7747 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7748 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7749 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7750 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7751 tep->start.offset += aux->seg_base;
7752 tep->end.offset += aux->seg_base;
7753 tep->info.offset += aux->seg_base;
7754 }
7755 free (table);
7756
41e92641 7757 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7758 for (relsec = filedata->section_headers;
7759 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7760 ++relsec)
7761 {
7762 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7763 || relsec->sh_info >= filedata->file_header.e_shnum
7764 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7765 continue;
7766
dda8d76d 7767 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7768 & rela, & nrelas))
53774b7e
NC
7769 {
7770 free (aux->table);
7771 aux->table = NULL;
7772 aux->table_len = 0;
7773 return FALSE;
7774 }
4d6ed7c8
NC
7775
7776 for (rp = rela; rp < rela + nrelas; ++rp)
7777 {
4770fb94 7778 unsigned int sym_ndx;
726bd37d
AM
7779 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
7780 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 7781
82b1b41b
NC
7782 /* PR 17531: file: 9fa67536. */
7783 if (relname == NULL)
7784 {
726bd37d 7785 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
7786 continue;
7787 }
948f632f 7788
0112cd26 7789 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7790 {
82b1b41b 7791 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7792 continue;
7793 }
7794
89fac5e3 7795 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7796
53774b7e
NC
7797 /* PR 17531: file: 5bc8d9bf. */
7798 if (i >= aux->table_len)
7799 {
7800 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7801 continue;
7802 }
7803
4770fb94
AM
7804 sym_ndx = get_reloc_symindex (rp->r_info);
7805 if (sym_ndx >= aux->nsyms)
7806 {
7807 warn (_("Skipping reloc with invalid symbol index: %u\n"),
7808 sym_ndx);
7809 continue;
7810 }
7811 sym = aux->symtab + sym_ndx;
7812
53774b7e 7813 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7814 {
7815 case 0:
7816 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7817 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7818 break;
7819 case 1:
7820 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7821 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7822 break;
7823 case 2:
7824 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7825 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7826 break;
7827 default:
7828 break;
7829 }
7830 }
7831
7832 free (rela);
7833 }
7834
53774b7e 7835 return TRUE;
4d6ed7c8
NC
7836}
7837
32ec8896 7838static bfd_boolean
dda8d76d 7839ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7840{
2cf0635d
NC
7841 Elf_Internal_Shdr * sec;
7842 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 7843 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7844 struct ia64_unw_aux_info aux;
32ec8896 7845 bfd_boolean res = TRUE;
f1467e33 7846
4d6ed7c8
NC
7847 memset (& aux, 0, sizeof (aux));
7848
dda8d76d 7849 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7850 {
28d13567 7851 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 7852 {
28d13567 7853 if (aux.symtab)
4082ef84 7854 {
28d13567
AM
7855 error (_("Multiple symbol tables encountered\n"));
7856 free (aux.symtab);
7857 aux.symtab = NULL;
4082ef84 7858 free (aux.strtab);
28d13567 7859 aux.strtab = NULL;
4082ef84 7860 }
28d13567
AM
7861 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
7862 &aux.strtab, &aux.strtab_size))
7863 return FALSE;
4d6ed7c8
NC
7864 }
7865 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7866 unwcount++;
7867 }
7868
7869 if (!unwcount)
7870 printf (_("\nThere are no unwind sections in this file.\n"));
7871
7872 while (unwcount-- > 0)
7873 {
2cf0635d 7874 char * suffix;
579f31ac
JJ
7875 size_t len, len2;
7876
dda8d76d
NC
7877 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
7878 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
7879 if (sec->sh_type == SHT_IA_64_UNWIND)
7880 {
7881 unwsec = sec;
7882 break;
7883 }
4082ef84
NC
7884 /* We have already counted the number of SHT_IA64_UNWIND
7885 sections so the loop above should never fail. */
7886 assert (unwsec != NULL);
579f31ac
JJ
7887
7888 unwstart = i + 1;
7889 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7890
e4b17d5c
L
7891 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7892 {
7893 /* We need to find which section group it is in. */
4082ef84 7894 struct group_list * g;
e4b17d5c 7895
4082ef84
NC
7896 if (section_headers_groups == NULL
7897 || section_headers_groups [i] == NULL)
dda8d76d 7898 i = filedata->file_header.e_shnum;
4082ef84 7899 else
e4b17d5c 7900 {
4082ef84 7901 g = section_headers_groups [i]->root;
18bd398b 7902
4082ef84
NC
7903 for (; g != NULL; g = g->next)
7904 {
dda8d76d 7905 sec = filedata->section_headers + g->section_index;
e4b17d5c 7906
4082ef84
NC
7907 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7908 break;
7909 }
7910
7911 if (g == NULL)
dda8d76d 7912 i = filedata->file_header.e_shnum;
4082ef84 7913 }
e4b17d5c 7914 }
18bd398b 7915 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7916 {
18bd398b 7917 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7918 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7919 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7920 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7921 ++i, ++sec)
18bd398b
NC
7922 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7923 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7924 break;
7925 }
7926 else
7927 {
7928 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7929 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7930 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7931 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7932 suffix = "";
18bd398b 7933 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 7934 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7935 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7936 ++i, ++sec)
18bd398b
NC
7937 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
7938 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7939 break;
7940 }
7941
dda8d76d 7942 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
7943 {
7944 printf (_("\nCould not find unwind info section for "));
7945
dda8d76d 7946 if (filedata->string_table == NULL)
579f31ac
JJ
7947 printf ("%d", unwsec->sh_name);
7948 else
dda8d76d 7949 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
7950 }
7951 else
4d6ed7c8 7952 {
4d6ed7c8 7953 aux.info_addr = sec->sh_addr;
dda8d76d 7954 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
7955 sec->sh_size,
7956 _("unwind info"));
59245841 7957 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 7958
579f31ac 7959 printf (_("\nUnwind section "));
4d6ed7c8 7960
dda8d76d 7961 if (filedata->string_table == NULL)
579f31ac
JJ
7962 printf ("%d", unwsec->sh_name);
7963 else
dda8d76d 7964 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 7965
579f31ac 7966 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 7967 (unsigned long) unwsec->sh_offset,
89fac5e3 7968 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 7969
dda8d76d 7970 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 7971 && aux.table_len > 0)
dda8d76d 7972 dump_ia64_unwind (filedata, & aux);
579f31ac
JJ
7973
7974 if (aux.table)
7975 free ((char *) aux.table);
7976 if (aux.info)
7977 free ((char *) aux.info);
7978 aux.table = NULL;
7979 aux.info = NULL;
7980 }
4d6ed7c8 7981 }
4d6ed7c8 7982
4d6ed7c8
NC
7983 if (aux.symtab)
7984 free (aux.symtab);
7985 if (aux.strtab)
7986 free ((char *) aux.strtab);
32ec8896
NC
7987
7988 return res;
4d6ed7c8
NC
7989}
7990
3f5e193b 7991struct hppa_unw_table_entry
32ec8896
NC
7992{
7993 struct absaddr start;
7994 struct absaddr end;
7995 unsigned int Cannot_unwind:1; /* 0 */
7996 unsigned int Millicode:1; /* 1 */
7997 unsigned int Millicode_save_sr0:1; /* 2 */
7998 unsigned int Region_description:2; /* 3..4 */
7999 unsigned int reserved1:1; /* 5 */
8000 unsigned int Entry_SR:1; /* 6 */
8001 unsigned int Entry_FR:4; /* Number saved 7..10 */
8002 unsigned int Entry_GR:5; /* Number saved 11..15 */
8003 unsigned int Args_stored:1; /* 16 */
8004 unsigned int Variable_Frame:1; /* 17 */
8005 unsigned int Separate_Package_Body:1; /* 18 */
8006 unsigned int Frame_Extension_Millicode:1; /* 19 */
8007 unsigned int Stack_Overflow_Check:1; /* 20 */
8008 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8009 unsigned int Ada_Region:1; /* 22 */
8010 unsigned int cxx_info:1; /* 23 */
8011 unsigned int cxx_try_catch:1; /* 24 */
8012 unsigned int sched_entry_seq:1; /* 25 */
8013 unsigned int reserved2:1; /* 26 */
8014 unsigned int Save_SP:1; /* 27 */
8015 unsigned int Save_RP:1; /* 28 */
8016 unsigned int Save_MRP_in_frame:1; /* 29 */
8017 unsigned int extn_ptr_defined:1; /* 30 */
8018 unsigned int Cleanup_defined:1; /* 31 */
8019
8020 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8021 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8022 unsigned int Large_frame:1; /* 2 */
8023 unsigned int Pseudo_SP_Set:1; /* 3 */
8024 unsigned int reserved4:1; /* 4 */
8025 unsigned int Total_frame_size:27; /* 5..31 */
8026};
3f5e193b 8027
57346661 8028struct hppa_unw_aux_info
948f632f 8029{
32ec8896
NC
8030 struct hppa_unw_table_entry * table; /* Unwind table. */
8031 unsigned long table_len; /* Length of unwind table. */
8032 bfd_vma seg_base; /* Starting address of segment. */
8033 Elf_Internal_Sym * symtab; /* The symbol table. */
8034 unsigned long nsyms; /* Number of symbols. */
8035 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8036 unsigned long nfuns; /* Number of entries in funtab. */
8037 char * strtab; /* The string table. */
8038 unsigned long strtab_size; /* Size of string table. */
948f632f 8039};
57346661 8040
32ec8896 8041static bfd_boolean
dda8d76d 8042dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8043{
2cf0635d 8044 struct hppa_unw_table_entry * tp;
948f632f 8045 unsigned long j, nfuns;
32ec8896 8046 bfd_boolean res = TRUE;
948f632f
DA
8047
8048 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8049 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8050 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8051 aux->funtab[nfuns++] = aux->symtab[j];
8052 aux->nfuns = nfuns;
8053 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8054
57346661
AM
8055 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8056 {
8057 bfd_vma offset;
2cf0635d 8058 const char * procname;
57346661 8059
dda8d76d 8060 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8061 aux->strtab_size, tp->start, &procname,
8062 &offset);
8063
8064 fputs ("\n<", stdout);
8065
8066 if (procname)
8067 {
8068 fputs (procname, stdout);
8069
8070 if (offset)
8071 printf ("+%lx", (unsigned long) offset);
8072 }
8073
8074 fputs (">: [", stdout);
8075 print_vma (tp->start.offset, PREFIX_HEX);
8076 fputc ('-', stdout);
8077 print_vma (tp->end.offset, PREFIX_HEX);
8078 printf ("]\n\t");
8079
18bd398b
NC
8080#define PF(_m) if (tp->_m) printf (#_m " ");
8081#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8082 PF(Cannot_unwind);
8083 PF(Millicode);
8084 PF(Millicode_save_sr0);
18bd398b 8085 /* PV(Region_description); */
57346661
AM
8086 PF(Entry_SR);
8087 PV(Entry_FR);
8088 PV(Entry_GR);
8089 PF(Args_stored);
8090 PF(Variable_Frame);
8091 PF(Separate_Package_Body);
8092 PF(Frame_Extension_Millicode);
8093 PF(Stack_Overflow_Check);
8094 PF(Two_Instruction_SP_Increment);
8095 PF(Ada_Region);
8096 PF(cxx_info);
8097 PF(cxx_try_catch);
8098 PF(sched_entry_seq);
8099 PF(Save_SP);
8100 PF(Save_RP);
8101 PF(Save_MRP_in_frame);
8102 PF(extn_ptr_defined);
8103 PF(Cleanup_defined);
8104 PF(MPE_XL_interrupt_marker);
8105 PF(HP_UX_interrupt_marker);
8106 PF(Large_frame);
8107 PF(Pseudo_SP_Set);
8108 PV(Total_frame_size);
8109#undef PF
8110#undef PV
8111 }
8112
18bd398b 8113 printf ("\n");
948f632f
DA
8114
8115 free (aux->funtab);
32ec8896
NC
8116
8117 return res;
57346661
AM
8118}
8119
32ec8896 8120static bfd_boolean
dda8d76d
NC
8121slurp_hppa_unwind_table (Filedata * filedata,
8122 struct hppa_unw_aux_info * aux,
8123 Elf_Internal_Shdr * sec)
57346661 8124{
1c0751b2 8125 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8126 Elf_Internal_Phdr * seg;
8127 struct hppa_unw_table_entry * tep;
8128 Elf_Internal_Shdr * relsec;
8129 Elf_Internal_Rela * rela;
8130 Elf_Internal_Rela * rp;
8131 unsigned char * table;
8132 unsigned char * tp;
8133 Elf_Internal_Sym * sym;
8134 const char * relname;
57346661 8135
57346661
AM
8136 /* First, find the starting address of the segment that includes
8137 this section. */
dda8d76d 8138 if (filedata->file_header.e_phnum)
57346661 8139 {
dda8d76d 8140 if (! get_program_headers (filedata))
32ec8896 8141 return FALSE;
57346661 8142
dda8d76d
NC
8143 for (seg = filedata->program_headers;
8144 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8145 ++seg)
8146 {
8147 if (seg->p_type != PT_LOAD)
8148 continue;
8149
8150 if (sec->sh_addr >= seg->p_vaddr
8151 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8152 {
8153 aux->seg_base = seg->p_vaddr;
8154 break;
8155 }
8156 }
8157 }
8158
8159 /* Second, build the unwind table from the contents of the unwind
8160 section. */
8161 size = sec->sh_size;
dda8d76d 8162 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8163 _("unwind table"));
57346661 8164 if (!table)
32ec8896 8165 return FALSE;
57346661 8166
1c0751b2
DA
8167 unw_ent_size = 16;
8168 nentries = size / unw_ent_size;
8169 size = unw_ent_size * nentries;
57346661 8170
3f5e193b
NC
8171 tep = aux->table = (struct hppa_unw_table_entry *)
8172 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8173
1c0751b2 8174 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8175 {
8176 unsigned int tmp1, tmp2;
8177
8178 tep->start.section = SHN_UNDEF;
8179 tep->end.section = SHN_UNDEF;
8180
1c0751b2
DA
8181 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8182 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8183 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8184 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8185
8186 tep->start.offset += aux->seg_base;
8187 tep->end.offset += aux->seg_base;
57346661
AM
8188
8189 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8190 tep->Millicode = (tmp1 >> 30) & 0x1;
8191 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8192 tep->Region_description = (tmp1 >> 27) & 0x3;
8193 tep->reserved1 = (tmp1 >> 26) & 0x1;
8194 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8195 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8196 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8197 tep->Args_stored = (tmp1 >> 15) & 0x1;
8198 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8199 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8200 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8201 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8202 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8203 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8204 tep->cxx_info = (tmp1 >> 8) & 0x1;
8205 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8206 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8207 tep->reserved2 = (tmp1 >> 5) & 0x1;
8208 tep->Save_SP = (tmp1 >> 4) & 0x1;
8209 tep->Save_RP = (tmp1 >> 3) & 0x1;
8210 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8211 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8212 tep->Cleanup_defined = tmp1 & 0x1;
8213
8214 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8215 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8216 tep->Large_frame = (tmp2 >> 29) & 0x1;
8217 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8218 tep->reserved4 = (tmp2 >> 27) & 0x1;
8219 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8220 }
8221 free (table);
8222
8223 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8224 for (relsec = filedata->section_headers;
8225 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8226 ++relsec)
8227 {
8228 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8229 || relsec->sh_info >= filedata->file_header.e_shnum
8230 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8231 continue;
8232
dda8d76d 8233 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8234 & rela, & nrelas))
32ec8896 8235 return FALSE;
57346661
AM
8236
8237 for (rp = rela; rp < rela + nrelas; ++rp)
8238 {
4770fb94 8239 unsigned int sym_ndx;
726bd37d
AM
8240 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8241 relname = elf_hppa_reloc_type (r_type);
57346661 8242
726bd37d
AM
8243 if (relname == NULL)
8244 {
8245 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8246 continue;
8247 }
8248
57346661 8249 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8250 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8251 {
726bd37d 8252 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8253 continue;
8254 }
8255
8256 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8257 if (i >= aux->table_len)
8258 {
8259 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8260 continue;
8261 }
57346661 8262
4770fb94
AM
8263 sym_ndx = get_reloc_symindex (rp->r_info);
8264 if (sym_ndx >= aux->nsyms)
8265 {
8266 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8267 sym_ndx);
8268 continue;
8269 }
8270 sym = aux->symtab + sym_ndx;
8271
43f6cd05 8272 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8273 {
8274 case 0:
8275 aux->table[i].start.section = sym->st_shndx;
1e456d54 8276 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8277 break;
8278 case 1:
8279 aux->table[i].end.section = sym->st_shndx;
1e456d54 8280 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8281 break;
8282 default:
8283 break;
8284 }
8285 }
8286
8287 free (rela);
8288 }
8289
1c0751b2 8290 aux->table_len = nentries;
57346661 8291
32ec8896 8292 return TRUE;
57346661
AM
8293}
8294
32ec8896 8295static bfd_boolean
dda8d76d 8296hppa_process_unwind (Filedata * filedata)
57346661 8297{
57346661 8298 struct hppa_unw_aux_info aux;
2cf0635d 8299 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8300 Elf_Internal_Shdr * sec;
18bd398b 8301 unsigned long i;
32ec8896 8302 bfd_boolean res = TRUE;
57346661 8303
dda8d76d 8304 if (filedata->string_table == NULL)
32ec8896 8305 return FALSE;
1b31d05e
NC
8306
8307 memset (& aux, 0, sizeof (aux));
57346661 8308
dda8d76d 8309 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8310 {
28d13567 8311 if (sec->sh_type == SHT_SYMTAB)
57346661 8312 {
28d13567 8313 if (aux.symtab)
4082ef84 8314 {
28d13567
AM
8315 error (_("Multiple symbol tables encountered\n"));
8316 free (aux.symtab);
8317 aux.symtab = NULL;
4082ef84 8318 free (aux.strtab);
28d13567 8319 aux.strtab = NULL;
4082ef84 8320 }
28d13567
AM
8321 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8322 &aux.strtab, &aux.strtab_size))
8323 return FALSE;
57346661 8324 }
18bd398b 8325 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8326 unwsec = sec;
8327 }
8328
8329 if (!unwsec)
8330 printf (_("\nThere are no unwind sections in this file.\n"));
8331
dda8d76d 8332 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8333 {
18bd398b 8334 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8335 {
43f6cd05 8336 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8337
d3a49aa8
AM
8338 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8339 "contains %lu entry:\n",
8340 "\nUnwind section '%s' at offset 0x%lx "
8341 "contains %lu entries:\n",
8342 num_unwind),
dda8d76d 8343 printable_section_name (filedata, sec),
57346661 8344 (unsigned long) sec->sh_offset,
d3a49aa8 8345 num_unwind);
57346661 8346
dda8d76d 8347 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8348 res = FALSE;
66b09c7e
S
8349
8350 if (res && aux.table_len > 0)
32ec8896 8351 {
dda8d76d 8352 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8353 res = FALSE;
8354 }
57346661
AM
8355
8356 if (aux.table)
8357 free ((char *) aux.table);
8358 aux.table = NULL;
8359 }
8360 }
8361
8362 if (aux.symtab)
8363 free (aux.symtab);
8364 if (aux.strtab)
8365 free ((char *) aux.strtab);
32ec8896
NC
8366
8367 return res;
57346661
AM
8368}
8369
0b6ae522
DJ
8370struct arm_section
8371{
a734115a
NC
8372 unsigned char * data; /* The unwind data. */
8373 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8374 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8375 unsigned long nrelas; /* The number of relocations. */
8376 unsigned int rel_type; /* REL or RELA ? */
8377 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8378};
8379
8380struct arm_unw_aux_info
8381{
dda8d76d 8382 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8383 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8384 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8385 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8386 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8387 char * strtab; /* The file's string table. */
8388 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8389};
8390
8391static const char *
dda8d76d
NC
8392arm_print_vma_and_name (Filedata * filedata,
8393 struct arm_unw_aux_info * aux,
8394 bfd_vma fn,
8395 struct absaddr addr)
0b6ae522
DJ
8396{
8397 const char *procname;
8398 bfd_vma sym_offset;
8399
8400 if (addr.section == SHN_UNDEF)
8401 addr.offset = fn;
8402
dda8d76d 8403 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8404 aux->strtab_size, addr, &procname,
8405 &sym_offset);
8406
8407 print_vma (fn, PREFIX_HEX);
8408
8409 if (procname)
8410 {
8411 fputs (" <", stdout);
8412 fputs (procname, stdout);
8413
8414 if (sym_offset)
8415 printf ("+0x%lx", (unsigned long) sym_offset);
8416 fputc ('>', stdout);
8417 }
8418
8419 return procname;
8420}
8421
8422static void
8423arm_free_section (struct arm_section *arm_sec)
8424{
8425 if (arm_sec->data != NULL)
8426 free (arm_sec->data);
8427
8428 if (arm_sec->rela != NULL)
8429 free (arm_sec->rela);
8430}
8431
a734115a
NC
8432/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8433 cached section and install SEC instead.
8434 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8435 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8436 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8437 relocation's offset in ADDR.
1b31d05e
NC
8438 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8439 into the string table of the symbol associated with the reloc. If no
8440 reloc was applied store -1 there.
8441 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8442
8443static bfd_boolean
dda8d76d
NC
8444get_unwind_section_word (Filedata * filedata,
8445 struct arm_unw_aux_info * aux,
1b31d05e
NC
8446 struct arm_section * arm_sec,
8447 Elf_Internal_Shdr * sec,
8448 bfd_vma word_offset,
8449 unsigned int * wordp,
8450 struct absaddr * addr,
8451 bfd_vma * sym_name)
0b6ae522
DJ
8452{
8453 Elf_Internal_Rela *rp;
8454 Elf_Internal_Sym *sym;
8455 const char * relname;
8456 unsigned int word;
8457 bfd_boolean wrapped;
8458
e0a31db1
NC
8459 if (sec == NULL || arm_sec == NULL)
8460 return FALSE;
8461
0b6ae522
DJ
8462 addr->section = SHN_UNDEF;
8463 addr->offset = 0;
8464
1b31d05e
NC
8465 if (sym_name != NULL)
8466 *sym_name = (bfd_vma) -1;
8467
a734115a 8468 /* If necessary, update the section cache. */
0b6ae522
DJ
8469 if (sec != arm_sec->sec)
8470 {
8471 Elf_Internal_Shdr *relsec;
8472
8473 arm_free_section (arm_sec);
8474
8475 arm_sec->sec = sec;
dda8d76d 8476 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8477 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8478 arm_sec->rela = NULL;
8479 arm_sec->nrelas = 0;
8480
dda8d76d
NC
8481 for (relsec = filedata->section_headers;
8482 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8483 ++relsec)
8484 {
dda8d76d
NC
8485 if (relsec->sh_info >= filedata->file_header.e_shnum
8486 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8487 /* PR 15745: Check the section type as well. */
8488 || (relsec->sh_type != SHT_REL
8489 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8490 continue;
8491
a734115a 8492 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8493 if (relsec->sh_type == SHT_REL)
8494 {
dda8d76d 8495 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8496 relsec->sh_size,
8497 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8498 return FALSE;
0b6ae522 8499 }
1ae40aa4 8500 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8501 {
dda8d76d 8502 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8503 relsec->sh_size,
8504 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8505 return FALSE;
0b6ae522 8506 }
1ae40aa4 8507 break;
0b6ae522
DJ
8508 }
8509
8510 arm_sec->next_rela = arm_sec->rela;
8511 }
8512
a734115a 8513 /* If there is no unwind data we can do nothing. */
0b6ae522 8514 if (arm_sec->data == NULL)
a734115a 8515 return FALSE;
0b6ae522 8516
e0a31db1 8517 /* If the offset is invalid then fail. */
f32ba729
NC
8518 if (/* PR 21343 *//* PR 18879 */
8519 sec->sh_size < 4
8520 || word_offset > (sec->sh_size - 4)
1a915552 8521 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8522 return FALSE;
8523
a734115a 8524 /* Get the word at the required offset. */
0b6ae522
DJ
8525 word = byte_get (arm_sec->data + word_offset, 4);
8526
0eff7165
NC
8527 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8528 if (arm_sec->rela == NULL)
8529 {
8530 * wordp = word;
8531 return TRUE;
8532 }
8533
a734115a 8534 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8535 wrapped = FALSE;
8536 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8537 {
8538 bfd_vma prelval, offset;
8539
8540 if (rp->r_offset > word_offset && !wrapped)
8541 {
8542 rp = arm_sec->rela;
8543 wrapped = TRUE;
8544 }
8545 if (rp->r_offset > word_offset)
8546 break;
8547
8548 if (rp->r_offset & 3)
8549 {
8550 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8551 (unsigned long) rp->r_offset);
8552 continue;
8553 }
8554
8555 if (rp->r_offset < word_offset)
8556 continue;
8557
74e1a04b
NC
8558 /* PR 17531: file: 027-161405-0.004 */
8559 if (aux->symtab == NULL)
8560 continue;
8561
0b6ae522
DJ
8562 if (arm_sec->rel_type == SHT_REL)
8563 {
8564 offset = word & 0x7fffffff;
8565 if (offset & 0x40000000)
8566 offset |= ~ (bfd_vma) 0x7fffffff;
8567 }
a734115a 8568 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8569 offset = rp->r_addend;
a734115a 8570 else
74e1a04b
NC
8571 {
8572 error (_("Unknown section relocation type %d encountered\n"),
8573 arm_sec->rel_type);
8574 break;
8575 }
0b6ae522 8576
071436c6
NC
8577 /* PR 17531 file: 027-1241568-0.004. */
8578 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8579 {
8580 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8581 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8582 break;
8583 }
8584
8585 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8586 offset += sym->st_value;
8587 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8588
a734115a 8589 /* Check that we are processing the expected reloc type. */
dda8d76d 8590 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8591 {
8592 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8593 if (relname == NULL)
8594 {
8595 warn (_("Skipping unknown ARM relocation type: %d\n"),
8596 (int) ELF32_R_TYPE (rp->r_info));
8597 continue;
8598 }
a734115a
NC
8599
8600 if (streq (relname, "R_ARM_NONE"))
8601 continue;
0b4362b0 8602
a734115a
NC
8603 if (! streq (relname, "R_ARM_PREL31"))
8604 {
071436c6 8605 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8606 continue;
8607 }
8608 }
dda8d76d 8609 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8610 {
8611 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8612 if (relname == NULL)
8613 {
8614 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8615 (int) ELF32_R_TYPE (rp->r_info));
8616 continue;
8617 }
0b4362b0 8618
a734115a
NC
8619 if (streq (relname, "R_C6000_NONE"))
8620 continue;
8621
8622 if (! streq (relname, "R_C6000_PREL31"))
8623 {
071436c6 8624 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8625 continue;
8626 }
8627
8628 prelval >>= 1;
8629 }
8630 else
74e1a04b
NC
8631 {
8632 /* This function currently only supports ARM and TI unwinders. */
8633 warn (_("Only TI and ARM unwinders are currently supported\n"));
8634 break;
8635 }
fa197c1c 8636
0b6ae522
DJ
8637 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8638 addr->section = sym->st_shndx;
8639 addr->offset = offset;
74e1a04b 8640
1b31d05e
NC
8641 if (sym_name)
8642 * sym_name = sym->st_name;
0b6ae522
DJ
8643 break;
8644 }
8645
8646 *wordp = word;
8647 arm_sec->next_rela = rp;
8648
a734115a 8649 return TRUE;
0b6ae522
DJ
8650}
8651
a734115a
NC
8652static const char *tic6x_unwind_regnames[16] =
8653{
0b4362b0
RM
8654 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8655 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8656 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8657};
fa197c1c 8658
0b6ae522 8659static void
fa197c1c 8660decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8661{
fa197c1c
PB
8662 int i;
8663
8664 for (i = 12; mask; mask >>= 1, i--)
8665 {
8666 if (mask & 1)
8667 {
8668 fputs (tic6x_unwind_regnames[i], stdout);
8669 if (mask > 1)
8670 fputs (", ", stdout);
8671 }
8672 }
8673}
0b6ae522
DJ
8674
8675#define ADVANCE \
8676 if (remaining == 0 && more_words) \
8677 { \
8678 data_offset += 4; \
dda8d76d 8679 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8680 data_offset, & word, & addr, NULL)) \
32ec8896 8681 return FALSE; \
0b6ae522
DJ
8682 remaining = 4; \
8683 more_words--; \
8684 } \
8685
8686#define GET_OP(OP) \
8687 ADVANCE; \
8688 if (remaining) \
8689 { \
8690 remaining--; \
8691 (OP) = word >> 24; \
8692 word <<= 8; \
8693 } \
8694 else \
8695 { \
2b692964 8696 printf (_("[Truncated opcode]\n")); \
32ec8896 8697 return FALSE; \
0b6ae522 8698 } \
cc5914eb 8699 printf ("0x%02x ", OP)
0b6ae522 8700
32ec8896 8701static bfd_boolean
dda8d76d
NC
8702decode_arm_unwind_bytecode (Filedata * filedata,
8703 struct arm_unw_aux_info * aux,
948f632f
DA
8704 unsigned int word,
8705 unsigned int remaining,
8706 unsigned int more_words,
8707 bfd_vma data_offset,
8708 Elf_Internal_Shdr * data_sec,
8709 struct arm_section * data_arm_sec)
fa197c1c
PB
8710{
8711 struct absaddr addr;
32ec8896 8712 bfd_boolean res = TRUE;
0b6ae522
DJ
8713
8714 /* Decode the unwinding instructions. */
8715 while (1)
8716 {
8717 unsigned int op, op2;
8718
8719 ADVANCE;
8720 if (remaining == 0)
8721 break;
8722 remaining--;
8723 op = word >> 24;
8724 word <<= 8;
8725
cc5914eb 8726 printf (" 0x%02x ", op);
0b6ae522
DJ
8727
8728 if ((op & 0xc0) == 0x00)
8729 {
8730 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8731
cc5914eb 8732 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8733 }
8734 else if ((op & 0xc0) == 0x40)
8735 {
8736 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8737
cc5914eb 8738 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8739 }
8740 else if ((op & 0xf0) == 0x80)
8741 {
8742 GET_OP (op2);
8743 if (op == 0x80 && op2 == 0)
8744 printf (_("Refuse to unwind"));
8745 else
8746 {
8747 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8748 bfd_boolean first = TRUE;
0b6ae522 8749 int i;
2b692964 8750
0b6ae522
DJ
8751 printf ("pop {");
8752 for (i = 0; i < 12; i++)
8753 if (mask & (1 << i))
8754 {
8755 if (first)
32ec8896 8756 first = FALSE;
0b6ae522
DJ
8757 else
8758 printf (", ");
8759 printf ("r%d", 4 + i);
8760 }
8761 printf ("}");
8762 }
8763 }
8764 else if ((op & 0xf0) == 0x90)
8765 {
8766 if (op == 0x9d || op == 0x9f)
8767 printf (_(" [Reserved]"));
8768 else
cc5914eb 8769 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8770 }
8771 else if ((op & 0xf0) == 0xa0)
8772 {
8773 int end = 4 + (op & 0x07);
32ec8896 8774 bfd_boolean first = TRUE;
0b6ae522 8775 int i;
61865e30 8776
0b6ae522
DJ
8777 printf (" pop {");
8778 for (i = 4; i <= end; i++)
8779 {
8780 if (first)
32ec8896 8781 first = FALSE;
0b6ae522
DJ
8782 else
8783 printf (", ");
8784 printf ("r%d", i);
8785 }
8786 if (op & 0x08)
8787 {
1b31d05e 8788 if (!first)
0b6ae522
DJ
8789 printf (", ");
8790 printf ("r14");
8791 }
8792 printf ("}");
8793 }
8794 else if (op == 0xb0)
8795 printf (_(" finish"));
8796 else if (op == 0xb1)
8797 {
8798 GET_OP (op2);
8799 if (op2 == 0 || (op2 & 0xf0) != 0)
8800 printf (_("[Spare]"));
8801 else
8802 {
8803 unsigned int mask = op2 & 0x0f;
32ec8896 8804 bfd_boolean first = TRUE;
0b6ae522 8805 int i;
61865e30 8806
0b6ae522
DJ
8807 printf ("pop {");
8808 for (i = 0; i < 12; i++)
8809 if (mask & (1 << i))
8810 {
8811 if (first)
32ec8896 8812 first = FALSE;
0b6ae522
DJ
8813 else
8814 printf (", ");
8815 printf ("r%d", i);
8816 }
8817 printf ("}");
8818 }
8819 }
8820 else if (op == 0xb2)
8821 {
b115cf96 8822 unsigned char buf[9];
0b6ae522
DJ
8823 unsigned int i, len;
8824 unsigned long offset;
61865e30 8825
b115cf96 8826 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8827 {
8828 GET_OP (buf[i]);
8829 if ((buf[i] & 0x80) == 0)
8830 break;
8831 }
4082ef84 8832 if (i == sizeof (buf))
32ec8896 8833 {
27a45f42 8834 error (_("corrupt change to vsp\n"));
32ec8896
NC
8835 res = FALSE;
8836 }
4082ef84
NC
8837 else
8838 {
cd30bcef 8839 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
8840 assert (len == i + 1);
8841 offset = offset * 4 + 0x204;
8842 printf ("vsp = vsp + %ld", offset);
8843 }
0b6ae522 8844 }
61865e30 8845 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8846 {
61865e30
NC
8847 unsigned int first, last;
8848
8849 GET_OP (op2);
8850 first = op2 >> 4;
8851 last = op2 & 0x0f;
8852 if (op == 0xc8)
8853 first = first + 16;
8854 printf ("pop {D%d", first);
8855 if (last)
8856 printf ("-D%d", first + last);
8857 printf ("}");
8858 }
8859 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8860 {
8861 unsigned int count = op & 0x07;
8862
8863 printf ("pop {D8");
8864 if (count)
8865 printf ("-D%d", 8 + count);
8866 printf ("}");
8867 }
8868 else if (op >= 0xc0 && op <= 0xc5)
8869 {
8870 unsigned int count = op & 0x07;
8871
8872 printf (" pop {wR10");
8873 if (count)
8874 printf ("-wR%d", 10 + count);
8875 printf ("}");
8876 }
8877 else if (op == 0xc6)
8878 {
8879 unsigned int first, last;
8880
8881 GET_OP (op2);
8882 first = op2 >> 4;
8883 last = op2 & 0x0f;
8884 printf ("pop {wR%d", first);
8885 if (last)
8886 printf ("-wR%d", first + last);
8887 printf ("}");
8888 }
8889 else if (op == 0xc7)
8890 {
8891 GET_OP (op2);
8892 if (op2 == 0 || (op2 & 0xf0) != 0)
8893 printf (_("[Spare]"));
0b6ae522
DJ
8894 else
8895 {
61865e30 8896 unsigned int mask = op2 & 0x0f;
32ec8896 8897 bfd_boolean first = TRUE;
61865e30
NC
8898 int i;
8899
8900 printf ("pop {");
8901 for (i = 0; i < 4; i++)
8902 if (mask & (1 << i))
8903 {
8904 if (first)
32ec8896 8905 first = FALSE;
61865e30
NC
8906 else
8907 printf (", ");
8908 printf ("wCGR%d", i);
8909 }
8910 printf ("}");
0b6ae522
DJ
8911 }
8912 }
61865e30 8913 else
32ec8896
NC
8914 {
8915 printf (_(" [unsupported opcode]"));
8916 res = FALSE;
8917 }
8918
0b6ae522
DJ
8919 printf ("\n");
8920 }
32ec8896
NC
8921
8922 return res;
fa197c1c
PB
8923}
8924
32ec8896 8925static bfd_boolean
dda8d76d
NC
8926decode_tic6x_unwind_bytecode (Filedata * filedata,
8927 struct arm_unw_aux_info * aux,
948f632f
DA
8928 unsigned int word,
8929 unsigned int remaining,
8930 unsigned int more_words,
8931 bfd_vma data_offset,
8932 Elf_Internal_Shdr * data_sec,
8933 struct arm_section * data_arm_sec)
fa197c1c
PB
8934{
8935 struct absaddr addr;
8936
8937 /* Decode the unwinding instructions. */
8938 while (1)
8939 {
8940 unsigned int op, op2;
8941
8942 ADVANCE;
8943 if (remaining == 0)
8944 break;
8945 remaining--;
8946 op = word >> 24;
8947 word <<= 8;
8948
9cf03b7e 8949 printf (" 0x%02x ", op);
fa197c1c
PB
8950
8951 if ((op & 0xc0) == 0x00)
8952 {
8953 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 8954 printf (" sp = sp + %d", offset);
fa197c1c
PB
8955 }
8956 else if ((op & 0xc0) == 0x80)
8957 {
8958 GET_OP (op2);
8959 if (op == 0x80 && op2 == 0)
8960 printf (_("Refuse to unwind"));
8961 else
8962 {
8963 unsigned int mask = ((op & 0x1f) << 8) | op2;
8964 if (op & 0x20)
8965 printf ("pop compact {");
8966 else
8967 printf ("pop {");
8968
8969 decode_tic6x_unwind_regmask (mask);
8970 printf("}");
8971 }
8972 }
8973 else if ((op & 0xf0) == 0xc0)
8974 {
8975 unsigned int reg;
8976 unsigned int nregs;
8977 unsigned int i;
8978 const char *name;
a734115a
NC
8979 struct
8980 {
32ec8896
NC
8981 unsigned int offset;
8982 unsigned int reg;
fa197c1c
PB
8983 } regpos[16];
8984
8985 /* Scan entire instruction first so that GET_OP output is not
8986 interleaved with disassembly. */
8987 nregs = 0;
8988 for (i = 0; nregs < (op & 0xf); i++)
8989 {
8990 GET_OP (op2);
8991 reg = op2 >> 4;
8992 if (reg != 0xf)
8993 {
8994 regpos[nregs].offset = i * 2;
8995 regpos[nregs].reg = reg;
8996 nregs++;
8997 }
8998
8999 reg = op2 & 0xf;
9000 if (reg != 0xf)
9001 {
9002 regpos[nregs].offset = i * 2 + 1;
9003 regpos[nregs].reg = reg;
9004 nregs++;
9005 }
9006 }
9007
9008 printf (_("pop frame {"));
18344509 9009 if (nregs == 0)
fa197c1c 9010 {
18344509
NC
9011 printf (_("*corrupt* - no registers specified"));
9012 }
9013 else
9014 {
9015 reg = nregs - 1;
9016 for (i = i * 2; i > 0; i--)
fa197c1c 9017 {
18344509
NC
9018 if (regpos[reg].offset == i - 1)
9019 {
9020 name = tic6x_unwind_regnames[regpos[reg].reg];
9021 if (reg > 0)
9022 reg--;
9023 }
9024 else
9025 name = _("[pad]");
fa197c1c 9026
18344509
NC
9027 fputs (name, stdout);
9028 if (i > 1)
9029 printf (", ");
9030 }
fa197c1c
PB
9031 }
9032
9033 printf ("}");
9034 }
9035 else if (op == 0xd0)
9036 printf (" MOV FP, SP");
9037 else if (op == 0xd1)
9038 printf (" __c6xabi_pop_rts");
9039 else if (op == 0xd2)
9040 {
9041 unsigned char buf[9];
9042 unsigned int i, len;
9043 unsigned long offset;
a734115a 9044
fa197c1c
PB
9045 for (i = 0; i < sizeof (buf); i++)
9046 {
9047 GET_OP (buf[i]);
9048 if ((buf[i] & 0x80) == 0)
9049 break;
9050 }
0eff7165
NC
9051 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9052 if (i == sizeof (buf))
9053 {
0eff7165 9054 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9055 return FALSE;
0eff7165 9056 }
948f632f 9057
cd30bcef 9058 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9059 assert (len == i + 1);
9060 offset = offset * 8 + 0x408;
9061 printf (_("sp = sp + %ld"), offset);
9062 }
9063 else if ((op & 0xf0) == 0xe0)
9064 {
9065 if ((op & 0x0f) == 7)
9066 printf (" RETURN");
9067 else
9068 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9069 }
9070 else
9071 {
9072 printf (_(" [unsupported opcode]"));
9073 }
9074 putchar ('\n');
9075 }
32ec8896
NC
9076
9077 return TRUE;
fa197c1c
PB
9078}
9079
9080static bfd_vma
dda8d76d 9081arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9082{
9083 bfd_vma offset;
9084
9085 offset = word & 0x7fffffff;
9086 if (offset & 0x40000000)
9087 offset |= ~ (bfd_vma) 0x7fffffff;
9088
dda8d76d 9089 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9090 offset <<= 1;
9091
9092 return offset + where;
9093}
9094
32ec8896 9095static bfd_boolean
dda8d76d
NC
9096decode_arm_unwind (Filedata * filedata,
9097 struct arm_unw_aux_info * aux,
1b31d05e
NC
9098 unsigned int word,
9099 unsigned int remaining,
9100 bfd_vma data_offset,
9101 Elf_Internal_Shdr * data_sec,
9102 struct arm_section * data_arm_sec)
fa197c1c
PB
9103{
9104 int per_index;
9105 unsigned int more_words = 0;
37e14bc3 9106 struct absaddr addr;
1b31d05e 9107 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9108 bfd_boolean res = TRUE;
fa197c1c
PB
9109
9110 if (remaining == 0)
9111 {
1b31d05e
NC
9112 /* Fetch the first word.
9113 Note - when decoding an object file the address extracted
9114 here will always be 0. So we also pass in the sym_name
9115 parameter so that we can find the symbol associated with
9116 the personality routine. */
dda8d76d 9117 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9118 & word, & addr, & sym_name))
32ec8896 9119 return FALSE;
1b31d05e 9120
fa197c1c
PB
9121 remaining = 4;
9122 }
c93dbb25
CZ
9123 else
9124 {
9125 addr.section = SHN_UNDEF;
9126 addr.offset = 0;
9127 }
fa197c1c
PB
9128
9129 if ((word & 0x80000000) == 0)
9130 {
9131 /* Expand prel31 for personality routine. */
9132 bfd_vma fn;
9133 const char *procname;
9134
dda8d76d 9135 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9136 printf (_(" Personality routine: "));
1b31d05e
NC
9137 if (fn == 0
9138 && addr.section == SHN_UNDEF && addr.offset == 0
9139 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9140 {
9141 procname = aux->strtab + sym_name;
9142 print_vma (fn, PREFIX_HEX);
9143 if (procname)
9144 {
9145 fputs (" <", stdout);
9146 fputs (procname, stdout);
9147 fputc ('>', stdout);
9148 }
9149 }
9150 else
dda8d76d 9151 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9152 fputc ('\n', stdout);
9153
9154 /* The GCC personality routines use the standard compact
9155 encoding, starting with one byte giving the number of
9156 words. */
9157 if (procname != NULL
9158 && (const_strneq (procname, "__gcc_personality_v0")
9159 || const_strneq (procname, "__gxx_personality_v0")
9160 || const_strneq (procname, "__gcj_personality_v0")
9161 || const_strneq (procname, "__gnu_objc_personality_v0")))
9162 {
9163 remaining = 0;
9164 more_words = 1;
9165 ADVANCE;
9166 if (!remaining)
9167 {
9168 printf (_(" [Truncated data]\n"));
32ec8896 9169 return FALSE;
fa197c1c
PB
9170 }
9171 more_words = word >> 24;
9172 word <<= 8;
9173 remaining--;
9174 per_index = -1;
9175 }
9176 else
32ec8896 9177 return TRUE;
fa197c1c
PB
9178 }
9179 else
9180 {
1b31d05e 9181 /* ARM EHABI Section 6.3:
0b4362b0 9182
1b31d05e 9183 An exception-handling table entry for the compact model looks like:
0b4362b0 9184
1b31d05e
NC
9185 31 30-28 27-24 23-0
9186 -- ----- ----- ----
9187 1 0 index Data for personalityRoutine[index] */
9188
dda8d76d 9189 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9190 && (word & 0x70000000))
32ec8896
NC
9191 {
9192 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9193 res = FALSE;
9194 }
1b31d05e 9195
fa197c1c 9196 per_index = (word >> 24) & 0x7f;
1b31d05e 9197 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9198 if (per_index == 0)
9199 {
9200 more_words = 0;
9201 word <<= 8;
9202 remaining--;
9203 }
9204 else if (per_index < 3)
9205 {
9206 more_words = (word >> 16) & 0xff;
9207 word <<= 16;
9208 remaining -= 2;
9209 }
9210 }
9211
dda8d76d 9212 switch (filedata->file_header.e_machine)
fa197c1c
PB
9213 {
9214 case EM_ARM:
9215 if (per_index < 3)
9216 {
dda8d76d 9217 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9218 data_offset, data_sec, data_arm_sec))
9219 res = FALSE;
fa197c1c
PB
9220 }
9221 else
1b31d05e
NC
9222 {
9223 warn (_("Unknown ARM compact model index encountered\n"));
9224 printf (_(" [reserved]\n"));
32ec8896 9225 res = FALSE;
1b31d05e 9226 }
fa197c1c
PB
9227 break;
9228
9229 case EM_TI_C6000:
9230 if (per_index < 3)
9231 {
dda8d76d 9232 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9233 data_offset, data_sec, data_arm_sec))
9234 res = FALSE;
fa197c1c
PB
9235 }
9236 else if (per_index < 5)
9237 {
9238 if (((word >> 17) & 0x7f) == 0x7f)
9239 printf (_(" Restore stack from frame pointer\n"));
9240 else
9241 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9242 printf (_(" Registers restored: "));
9243 if (per_index == 4)
9244 printf (" (compact) ");
9245 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9246 putchar ('\n');
9247 printf (_(" Return register: %s\n"),
9248 tic6x_unwind_regnames[word & 0xf]);
9249 }
9250 else
1b31d05e 9251 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9252 break;
9253
9254 default:
74e1a04b 9255 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9256 filedata->file_header.e_machine);
32ec8896 9257 res = FALSE;
fa197c1c 9258 }
0b6ae522
DJ
9259
9260 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9261
9262 return res;
0b6ae522
DJ
9263}
9264
32ec8896 9265static bfd_boolean
dda8d76d
NC
9266dump_arm_unwind (Filedata * filedata,
9267 struct arm_unw_aux_info * aux,
9268 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9269{
9270 struct arm_section exidx_arm_sec, extab_arm_sec;
9271 unsigned int i, exidx_len;
948f632f 9272 unsigned long j, nfuns;
32ec8896 9273 bfd_boolean res = TRUE;
0b6ae522
DJ
9274
9275 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9276 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9277 exidx_len = exidx_sec->sh_size / 8;
9278
948f632f
DA
9279 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9280 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9281 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9282 aux->funtab[nfuns++] = aux->symtab[j];
9283 aux->nfuns = nfuns;
9284 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9285
0b6ae522
DJ
9286 for (i = 0; i < exidx_len; i++)
9287 {
9288 unsigned int exidx_fn, exidx_entry;
9289 struct absaddr fn_addr, entry_addr;
9290 bfd_vma fn;
9291
9292 fputc ('\n', stdout);
9293
dda8d76d 9294 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9295 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9296 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9297 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9298 {
948f632f 9299 free (aux->funtab);
1b31d05e
NC
9300 arm_free_section (& exidx_arm_sec);
9301 arm_free_section (& extab_arm_sec);
32ec8896 9302 return FALSE;
0b6ae522
DJ
9303 }
9304
83c257ca
NC
9305 /* ARM EHABI, Section 5:
9306 An index table entry consists of 2 words.
9307 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9308 if (exidx_fn & 0x80000000)
32ec8896
NC
9309 {
9310 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9311 res = FALSE;
9312 }
83c257ca 9313
dda8d76d 9314 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9315
dda8d76d 9316 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9317 fputs (": ", stdout);
9318
9319 if (exidx_entry == 1)
9320 {
9321 print_vma (exidx_entry, PREFIX_HEX);
9322 fputs (" [cantunwind]\n", stdout);
9323 }
9324 else if (exidx_entry & 0x80000000)
9325 {
9326 print_vma (exidx_entry, PREFIX_HEX);
9327 fputc ('\n', stdout);
dda8d76d 9328 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9329 }
9330 else
9331 {
8f73510c 9332 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9333 Elf_Internal_Shdr *table_sec;
9334
9335 fputs ("@", stdout);
dda8d76d 9336 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9337 print_vma (table, PREFIX_HEX);
9338 printf ("\n");
9339
9340 /* Locate the matching .ARM.extab. */
9341 if (entry_addr.section != SHN_UNDEF
dda8d76d 9342 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9343 {
dda8d76d 9344 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9345 table_offset = entry_addr.offset;
1a915552
NC
9346 /* PR 18879 */
9347 if (table_offset > table_sec->sh_size
9348 || ((bfd_signed_vma) table_offset) < 0)
9349 {
9350 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9351 (unsigned long) table_offset,
dda8d76d 9352 printable_section_name (filedata, table_sec));
32ec8896 9353 res = FALSE;
1a915552
NC
9354 continue;
9355 }
0b6ae522
DJ
9356 }
9357 else
9358 {
dda8d76d 9359 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9360 if (table_sec != NULL)
9361 table_offset = table - table_sec->sh_addr;
9362 }
32ec8896 9363
0b6ae522
DJ
9364 if (table_sec == NULL)
9365 {
9366 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9367 (unsigned long) table);
32ec8896 9368 res = FALSE;
0b6ae522
DJ
9369 continue;
9370 }
32ec8896 9371
dda8d76d 9372 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9373 &extab_arm_sec))
9374 res = FALSE;
0b6ae522
DJ
9375 }
9376 }
9377
9378 printf ("\n");
9379
948f632f 9380 free (aux->funtab);
0b6ae522
DJ
9381 arm_free_section (&exidx_arm_sec);
9382 arm_free_section (&extab_arm_sec);
32ec8896
NC
9383
9384 return res;
0b6ae522
DJ
9385}
9386
fa197c1c 9387/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9388
32ec8896 9389static bfd_boolean
dda8d76d 9390arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9391{
9392 struct arm_unw_aux_info aux;
9393 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9394 Elf_Internal_Shdr *sec;
9395 unsigned long i;
fa197c1c 9396 unsigned int sec_type;
32ec8896 9397 bfd_boolean res = TRUE;
0b6ae522 9398
dda8d76d 9399 switch (filedata->file_header.e_machine)
fa197c1c
PB
9400 {
9401 case EM_ARM:
9402 sec_type = SHT_ARM_EXIDX;
9403 break;
9404
9405 case EM_TI_C6000:
9406 sec_type = SHT_C6000_UNWIND;
9407 break;
9408
0b4362b0 9409 default:
74e1a04b 9410 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9411 filedata->file_header.e_machine);
32ec8896 9412 return FALSE;
fa197c1c
PB
9413 }
9414
dda8d76d 9415 if (filedata->string_table == NULL)
32ec8896 9416 return FALSE;
1b31d05e
NC
9417
9418 memset (& aux, 0, sizeof (aux));
dda8d76d 9419 aux.filedata = filedata;
0b6ae522 9420
dda8d76d 9421 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9422 {
28d13567 9423 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9424 {
28d13567 9425 if (aux.symtab)
74e1a04b 9426 {
28d13567
AM
9427 error (_("Multiple symbol tables encountered\n"));
9428 free (aux.symtab);
9429 aux.symtab = NULL;
74e1a04b 9430 free (aux.strtab);
28d13567 9431 aux.strtab = NULL;
74e1a04b 9432 }
28d13567
AM
9433 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9434 &aux.strtab, &aux.strtab_size))
9435 return FALSE;
0b6ae522 9436 }
fa197c1c 9437 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9438 unwsec = sec;
9439 }
9440
1b31d05e 9441 if (unwsec == NULL)
0b6ae522 9442 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9443 else
dda8d76d 9444 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9445 {
9446 if (sec->sh_type == sec_type)
9447 {
d3a49aa8
AM
9448 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9449 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9450 "contains %lu entry:\n",
9451 "\nUnwind section '%s' at offset 0x%lx "
9452 "contains %lu entries:\n",
9453 num_unwind),
dda8d76d 9454 printable_section_name (filedata, sec),
1b31d05e 9455 (unsigned long) sec->sh_offset,
d3a49aa8 9456 num_unwind);
0b6ae522 9457
dda8d76d 9458 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9459 res = FALSE;
1b31d05e
NC
9460 }
9461 }
0b6ae522
DJ
9462
9463 if (aux.symtab)
9464 free (aux.symtab);
9465 if (aux.strtab)
9466 free ((char *) aux.strtab);
32ec8896
NC
9467
9468 return res;
0b6ae522
DJ
9469}
9470
32ec8896 9471static bfd_boolean
dda8d76d 9472process_unwind (Filedata * filedata)
57346661 9473{
2cf0635d
NC
9474 struct unwind_handler
9475 {
32ec8896 9476 unsigned int machtype;
dda8d76d 9477 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9478 } handlers[] =
9479 {
0b6ae522 9480 { EM_ARM, arm_process_unwind },
57346661
AM
9481 { EM_IA_64, ia64_process_unwind },
9482 { EM_PARISC, hppa_process_unwind },
fa197c1c 9483 { EM_TI_C6000, arm_process_unwind },
32ec8896 9484 { 0, NULL }
57346661
AM
9485 };
9486 int i;
9487
9488 if (!do_unwind)
32ec8896 9489 return TRUE;
57346661
AM
9490
9491 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9492 if (filedata->file_header.e_machine == handlers[i].machtype)
9493 return handlers[i].handler (filedata);
57346661 9494
1b31d05e 9495 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9496 get_machine_name (filedata->file_header.e_machine));
32ec8896 9497 return TRUE;
57346661
AM
9498}
9499
37c18eed
SD
9500static void
9501dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9502{
9503 switch (entry->d_tag)
9504 {
9505 case DT_AARCH64_BTI_PLT:
1dbade74 9506 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9507 break;
9508 default:
9509 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9510 break;
9511 }
9512 putchar ('\n');
9513}
9514
252b5132 9515static void
2cf0635d 9516dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
9517{
9518 switch (entry->d_tag)
9519 {
9520 case DT_MIPS_FLAGS:
9521 if (entry->d_un.d_val == 0)
4b68bca3 9522 printf (_("NONE"));
252b5132
RH
9523 else
9524 {
9525 static const char * opts[] =
9526 {
9527 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9528 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9529 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9530 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9531 "RLD_ORDER_SAFE"
9532 };
9533 unsigned int cnt;
32ec8896 9534 bfd_boolean first = TRUE;
2b692964 9535
60bca95a 9536 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9537 if (entry->d_un.d_val & (1 << cnt))
9538 {
9539 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9540 first = FALSE;
252b5132 9541 }
252b5132
RH
9542 }
9543 break;
103f02d3 9544
252b5132 9545 case DT_MIPS_IVERSION:
d79b3d50 9546 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 9547 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9548 else
76ca31c0
NC
9549 {
9550 char buf[40];
9551 sprintf_vma (buf, entry->d_un.d_ptr);
9552 /* Note: coded this way so that there is a single string for translation. */
9553 printf (_("<corrupt: %s>"), buf);
9554 }
252b5132 9555 break;
103f02d3 9556
252b5132
RH
9557 case DT_MIPS_TIME_STAMP:
9558 {
d5b07ef4 9559 char timebuf[128];
2cf0635d 9560 struct tm * tmp;
91d6fa6a 9561 time_t atime = entry->d_un.d_val;
82b1b41b 9562
91d6fa6a 9563 tmp = gmtime (&atime);
82b1b41b
NC
9564 /* PR 17531: file: 6accc532. */
9565 if (tmp == NULL)
9566 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9567 else
9568 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9569 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9570 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9571 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9572 }
9573 break;
103f02d3 9574
252b5132
RH
9575 case DT_MIPS_RLD_VERSION:
9576 case DT_MIPS_LOCAL_GOTNO:
9577 case DT_MIPS_CONFLICTNO:
9578 case DT_MIPS_LIBLISTNO:
9579 case DT_MIPS_SYMTABNO:
9580 case DT_MIPS_UNREFEXTNO:
9581 case DT_MIPS_HIPAGENO:
9582 case DT_MIPS_DELTA_CLASS_NO:
9583 case DT_MIPS_DELTA_INSTANCE_NO:
9584 case DT_MIPS_DELTA_RELOC_NO:
9585 case DT_MIPS_DELTA_SYM_NO:
9586 case DT_MIPS_DELTA_CLASSSYM_NO:
9587 case DT_MIPS_COMPACT_SIZE:
c69075ac 9588 print_vma (entry->d_un.d_val, DEC);
252b5132 9589 break;
103f02d3 9590
f16a9783
MS
9591 case DT_MIPS_XHASH:
9592 dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9593 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9594 /* Falls through. */
9595
103f02d3 9596 default:
4b68bca3 9597 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9598 }
4b68bca3 9599 putchar ('\n');
103f02d3
UD
9600}
9601
103f02d3 9602static void
2cf0635d 9603dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9604{
9605 switch (entry->d_tag)
9606 {
9607 case DT_HP_DLD_FLAGS:
9608 {
9609 static struct
9610 {
9611 long int bit;
2cf0635d 9612 const char * str;
5e220199
NC
9613 }
9614 flags[] =
9615 {
9616 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9617 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9618 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9619 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9620 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9621 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9622 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9623 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9624 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9625 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9626 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9627 { DT_HP_GST, "HP_GST" },
9628 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9629 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9630 { DT_HP_NODELETE, "HP_NODELETE" },
9631 { DT_HP_GROUP, "HP_GROUP" },
9632 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9633 };
32ec8896 9634 bfd_boolean first = TRUE;
5e220199 9635 size_t cnt;
f7a99963 9636 bfd_vma val = entry->d_un.d_val;
103f02d3 9637
60bca95a 9638 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9639 if (val & flags[cnt].bit)
30800947
NC
9640 {
9641 if (! first)
9642 putchar (' ');
9643 fputs (flags[cnt].str, stdout);
32ec8896 9644 first = FALSE;
30800947
NC
9645 val ^= flags[cnt].bit;
9646 }
76da6bbe 9647
103f02d3 9648 if (val != 0 || first)
f7a99963
NC
9649 {
9650 if (! first)
9651 putchar (' ');
9652 print_vma (val, HEX);
9653 }
103f02d3
UD
9654 }
9655 break;
76da6bbe 9656
252b5132 9657 default:
f7a99963
NC
9658 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9659 break;
252b5132 9660 }
35b1837e 9661 putchar ('\n');
252b5132
RH
9662}
9663
28f997cf
TG
9664#ifdef BFD64
9665
9666/* VMS vs Unix time offset and factor. */
9667
9668#define VMS_EPOCH_OFFSET 35067168000000000LL
9669#define VMS_GRANULARITY_FACTOR 10000000
9670
9671/* Display a VMS time in a human readable format. */
9672
9673static void
9674print_vms_time (bfd_int64_t vmstime)
9675{
9676 struct tm *tm;
9677 time_t unxtime;
9678
9679 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9680 tm = gmtime (&unxtime);
9681 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9682 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9683 tm->tm_hour, tm->tm_min, tm->tm_sec);
9684}
9685#endif /* BFD64 */
9686
ecc51f48 9687static void
2cf0635d 9688dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9689{
9690 switch (entry->d_tag)
9691 {
0de14b54 9692 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9693 /* First 3 slots reserved. */
ecc51f48
NC
9694 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9695 printf (" -- ");
9696 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9697 break;
9698
28f997cf
TG
9699 case DT_IA_64_VMS_LINKTIME:
9700#ifdef BFD64
9701 print_vms_time (entry->d_un.d_val);
9702#endif
9703 break;
9704
9705 case DT_IA_64_VMS_LNKFLAGS:
9706 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9707 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9708 printf (" CALL_DEBUG");
9709 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9710 printf (" NOP0BUFS");
9711 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9712 printf (" P0IMAGE");
9713 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9714 printf (" MKTHREADS");
9715 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9716 printf (" UPCALLS");
9717 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9718 printf (" IMGSTA");
9719 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9720 printf (" INITIALIZE");
9721 if (entry->d_un.d_val & VMS_LF_MAIN)
9722 printf (" MAIN");
9723 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9724 printf (" EXE_INIT");
9725 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9726 printf (" TBK_IN_IMG");
9727 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9728 printf (" DBG_IN_IMG");
9729 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9730 printf (" TBK_IN_DSF");
9731 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9732 printf (" DBG_IN_DSF");
9733 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9734 printf (" SIGNATURES");
9735 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9736 printf (" REL_SEG_OFF");
9737 break;
9738
bdf4d63a
JJ
9739 default:
9740 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9741 break;
ecc51f48 9742 }
bdf4d63a 9743 putchar ('\n');
ecc51f48
NC
9744}
9745
32ec8896 9746static bfd_boolean
dda8d76d 9747get_32bit_dynamic_section (Filedata * filedata)
252b5132 9748{
2cf0635d
NC
9749 Elf32_External_Dyn * edyn;
9750 Elf32_External_Dyn * ext;
9751 Elf_Internal_Dyn * entry;
103f02d3 9752
dda8d76d 9753 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9754 dynamic_size, _("dynamic section"));
a6e9f9df 9755 if (!edyn)
32ec8896 9756 return FALSE;
103f02d3 9757
071436c6
NC
9758 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9759 might not have the luxury of section headers. Look for the DT_NULL
9760 terminator to determine the number of entries. */
ba2685cc 9761 for (ext = edyn, dynamic_nent = 0;
53c3012c 9762 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9763 ext++)
9764 {
9765 dynamic_nent++;
9766 if (BYTE_GET (ext->d_tag) == DT_NULL)
9767 break;
9768 }
252b5132 9769
3f5e193b
NC
9770 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9771 sizeof (* entry));
b2d38a17 9772 if (dynamic_section == NULL)
252b5132 9773 {
8b73c356
NC
9774 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9775 (unsigned long) dynamic_nent);
9ea033b2 9776 free (edyn);
32ec8896 9777 return FALSE;
9ea033b2 9778 }
252b5132 9779
fb514b26 9780 for (ext = edyn, entry = dynamic_section;
ba2685cc 9781 entry < dynamic_section + dynamic_nent;
fb514b26 9782 ext++, entry++)
9ea033b2 9783 {
fb514b26
AM
9784 entry->d_tag = BYTE_GET (ext->d_tag);
9785 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9786 }
9787
9ea033b2
NC
9788 free (edyn);
9789
32ec8896 9790 return TRUE;
9ea033b2
NC
9791}
9792
32ec8896 9793static bfd_boolean
dda8d76d 9794get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9795{
2cf0635d
NC
9796 Elf64_External_Dyn * edyn;
9797 Elf64_External_Dyn * ext;
9798 Elf_Internal_Dyn * entry;
103f02d3 9799
071436c6 9800 /* Read in the data. */
dda8d76d 9801 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9802 dynamic_size, _("dynamic section"));
a6e9f9df 9803 if (!edyn)
32ec8896 9804 return FALSE;
103f02d3 9805
071436c6
NC
9806 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9807 might not have the luxury of section headers. Look for the DT_NULL
9808 terminator to determine the number of entries. */
ba2685cc 9809 for (ext = edyn, dynamic_nent = 0;
53c3012c
AM
9810 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
9811 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9812 ext++)
9813 {
9814 dynamic_nent++;
66543521 9815 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9816 break;
9817 }
252b5132 9818
3f5e193b
NC
9819 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9820 sizeof (* entry));
b2d38a17 9821 if (dynamic_section == NULL)
252b5132 9822 {
8b73c356
NC
9823 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9824 (unsigned long) dynamic_nent);
252b5132 9825 free (edyn);
32ec8896 9826 return FALSE;
252b5132
RH
9827 }
9828
071436c6 9829 /* Convert from external to internal formats. */
fb514b26 9830 for (ext = edyn, entry = dynamic_section;
ba2685cc 9831 entry < dynamic_section + dynamic_nent;
fb514b26 9832 ext++, entry++)
252b5132 9833 {
66543521
AM
9834 entry->d_tag = BYTE_GET (ext->d_tag);
9835 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9836 }
9837
9838 free (edyn);
9839
32ec8896 9840 return TRUE;
9ea033b2
NC
9841}
9842
e9e44622
JJ
9843static void
9844print_dynamic_flags (bfd_vma flags)
d1133906 9845{
32ec8896 9846 bfd_boolean first = TRUE;
13ae64f3 9847
d1133906
NC
9848 while (flags)
9849 {
9850 bfd_vma flag;
9851
9852 flag = flags & - flags;
9853 flags &= ~ flag;
9854
e9e44622 9855 if (first)
32ec8896 9856 first = FALSE;
e9e44622
JJ
9857 else
9858 putc (' ', stdout);
13ae64f3 9859
d1133906
NC
9860 switch (flag)
9861 {
e9e44622
JJ
9862 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9863 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9864 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9865 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9866 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9867 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9868 }
9869 }
e9e44622 9870 puts ("");
d1133906
NC
9871}
9872
10ca4b04
L
9873static bfd_vma *
9874get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
9875{
9876 unsigned char * e_data;
9877 bfd_vma * i_data;
9878
9879 /* If the size_t type is smaller than the bfd_size_type, eg because
9880 you are building a 32-bit tool on a 64-bit host, then make sure
9881 that when (number) is cast to (size_t) no information is lost. */
9882 if (sizeof (size_t) < sizeof (bfd_size_type)
9883 && (bfd_size_type) ((size_t) number) != number)
9884 {
9885 error (_("Size truncation prevents reading %s elements of size %u\n"),
9886 bfd_vmatoa ("u", number), ent_size);
9887 return NULL;
9888 }
9889
9890 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
9891 attempting to allocate memory when the read is bound to fail. */
9892 if (ent_size * number > filedata->file_size)
9893 {
9894 error (_("Invalid number of dynamic entries: %s\n"),
9895 bfd_vmatoa ("u", number));
9896 return NULL;
9897 }
9898
9899 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
9900 if (e_data == NULL)
9901 {
9902 error (_("Out of memory reading %s dynamic entries\n"),
9903 bfd_vmatoa ("u", number));
9904 return NULL;
9905 }
9906
9907 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
9908 {
9909 error (_("Unable to read in %s bytes of dynamic data\n"),
9910 bfd_vmatoa ("u", number * ent_size));
9911 free (e_data);
9912 return NULL;
9913 }
9914
9915 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
9916 if (i_data == NULL)
9917 {
9918 error (_("Out of memory allocating space for %s dynamic entries\n"),
9919 bfd_vmatoa ("u", number));
9920 free (e_data);
9921 return NULL;
9922 }
9923
9924 while (number--)
9925 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
9926
9927 free (e_data);
9928
9929 return i_data;
9930}
9931
9932static unsigned long
9933get_num_dynamic_syms (Filedata * filedata)
9934{
9935 unsigned long num_of_syms = 0;
9936
9937 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
9938 return num_of_syms;
9939
9940 if (dynamic_info[DT_HASH])
9941 {
9942 unsigned char nb[8];
9943 unsigned char nc[8];
9944 unsigned int hash_ent_size = 4;
9945
9946 if ((filedata->file_header.e_machine == EM_ALPHA
9947 || filedata->file_header.e_machine == EM_S390
9948 || filedata->file_header.e_machine == EM_S390_OLD)
9949 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
9950 hash_ent_size = 8;
9951
9952 if (fseek (filedata->handle,
9953 (archive_file_offset
9954 + offset_from_vma (filedata, dynamic_info[DT_HASH],
9955 sizeof nb + sizeof nc)),
9956 SEEK_SET))
9957 {
9958 error (_("Unable to seek to start of dynamic information\n"));
9959 goto no_hash;
9960 }
9961
9962 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
9963 {
9964 error (_("Failed to read in number of buckets\n"));
9965 goto no_hash;
9966 }
9967
9968 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
9969 {
9970 error (_("Failed to read in number of chains\n"));
9971 goto no_hash;
9972 }
9973
9974 nbuckets = byte_get (nb, hash_ent_size);
9975 nchains = byte_get (nc, hash_ent_size);
10ca4b04
L
9976
9977 buckets = get_dynamic_data (filedata, nbuckets, hash_ent_size);
9978 chains = get_dynamic_data (filedata, nchains, hash_ent_size);
9979
001890e1
AM
9980 if (buckets != NULL && chains != NULL)
9981 num_of_syms = nchains;
9982
ceb9bf11 9983 no_hash:
10ca4b04
L
9984 if (num_of_syms == 0)
9985 {
9986 if (buckets)
9987 {
9988 free (buckets);
9989 buckets = NULL;
9990 }
9991 if (chains)
9992 {
9993 free (chains);
c98a4545 9994 chains = NULL;
10ca4b04
L
9995 }
9996 nbuckets = 0;
9997 }
9998 }
9999
10000 if (dynamic_info_DT_GNU_HASH)
10001 {
10002 unsigned char nb[16];
10003 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10004 bfd_vma buckets_vma;
10005 unsigned long hn;
10006 bfd_boolean gnu_hash_error = FALSE;
10007
10008 if (fseek (filedata->handle,
10009 (archive_file_offset
10010 + offset_from_vma (filedata, dynamic_info_DT_GNU_HASH,
10011 sizeof nb)),
10012 SEEK_SET))
10013 {
10014 error (_("Unable to seek to start of dynamic information\n"));
10015 gnu_hash_error = TRUE;
10016 goto no_gnu_hash;
10017 }
10018
10019 if (fread (nb, 16, 1, filedata->handle) != 1)
10020 {
10021 error (_("Failed to read in number of buckets\n"));
10022 gnu_hash_error = TRUE;
10023 goto no_gnu_hash;
10024 }
10025
10026 ngnubuckets = byte_get (nb, 4);
10027 gnusymidx = byte_get (nb + 4, 4);
10028 bitmaskwords = byte_get (nb + 8, 4);
10029 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
10030 if (is_32bit_elf)
10031 buckets_vma += bitmaskwords * 4;
10032 else
10033 buckets_vma += bitmaskwords * 8;
10034
10035 if (fseek (filedata->handle,
10036 (archive_file_offset
10037 + offset_from_vma (filedata, buckets_vma, 4)),
10038 SEEK_SET))
10039 {
10040 error (_("Unable to seek to start of dynamic information\n"));
10041 gnu_hash_error = TRUE;
10042 goto no_gnu_hash;
10043 }
10044
10045 gnubuckets = get_dynamic_data (filedata, ngnubuckets, 4);
10046
10047 if (gnubuckets == NULL)
10048 {
10049 gnu_hash_error = TRUE;
10050 goto no_gnu_hash;
10051 }
10052
10053 for (i = 0; i < ngnubuckets; i++)
10054 if (gnubuckets[i] != 0)
10055 {
10056 if (gnubuckets[i] < gnusymidx)
10057 {
10058 gnu_hash_error = TRUE;
ceb9bf11 10059 goto no_gnu_hash;
10ca4b04
L
10060 }
10061
10062 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
10063 maxchain = gnubuckets[i];
10064 }
10065
10066 if (maxchain == 0xffffffff)
10067 {
10068 gnu_hash_error = TRUE;
10069 goto no_gnu_hash;
10070 }
10071
10072 maxchain -= gnusymidx;
10073
10074 if (fseek (filedata->handle,
10075 (archive_file_offset
10076 + offset_from_vma (filedata, buckets_vma
10077 + 4 * (ngnubuckets + maxchain), 4)),
10078 SEEK_SET))
10079 {
10080 error (_("Unable to seek to start of dynamic information\n"));
10081 gnu_hash_error = TRUE;
10082 goto no_gnu_hash;
10083 }
10084
10085 do
10086 {
10087 if (fread (nb, 4, 1, filedata->handle) != 1)
10088 {
10089 error (_("Failed to determine last chain length\n"));
ceb9bf11 10090 gnu_hash_error = TRUE;
10ca4b04
L
10091 goto no_gnu_hash;
10092 }
10093
10094 if (maxchain + 1 == 0)
10095 {
10096 gnu_hash_error = TRUE;
10097 goto no_gnu_hash;
10098 }
10099
10100 ++maxchain;
10101 }
10102 while ((byte_get (nb, 4) & 1) == 0);
10103
10104 if (fseek (filedata->handle,
10105 (archive_file_offset
10106 + offset_from_vma (filedata, buckets_vma + 4 * ngnubuckets, 4)),
10107 SEEK_SET))
10108 {
10109 error (_("Unable to seek to start of dynamic information\n"));
10110 gnu_hash_error = TRUE;
10111 goto no_gnu_hash;
10112 }
10113
10114 gnuchains = get_dynamic_data (filedata, maxchain, 4);
10115 ngnuchains = maxchain;
10116
10117 if (gnuchains == NULL)
10118 {
10119 gnu_hash_error = TRUE;
10120 goto no_gnu_hash;
10121 }
10122
10123 if (dynamic_info_DT_MIPS_XHASH)
10124 {
10125 if (fseek (filedata->handle,
10126 (archive_file_offset
10127 + offset_from_vma (filedata, (buckets_vma
10128 + 4 * (ngnubuckets
10129 + maxchain)), 4)),
10130 SEEK_SET))
10131 {
10132 error (_("Unable to seek to start of dynamic information\n"));
10133 gnu_hash_error = TRUE;
10134 goto no_gnu_hash;
10135 }
10136
10137 mipsxlat = get_dynamic_data (filedata, maxchain, 4);
10138 }
10139
10140 for (hn = 0; hn < ngnubuckets; ++hn)
10141 if (gnubuckets[hn] != 0)
10142 {
10143 bfd_vma si = gnubuckets[hn];
10144 bfd_vma off = si - gnusymidx;
10145
10146 do
10147 {
10148 if (dynamic_info_DT_MIPS_XHASH)
10149 {
10150 if (mipsxlat[off] >= num_of_syms)
10151 num_of_syms = mipsxlat[off] + 1;
10152 }
10153 else
10154 {
10155 if (si >= num_of_syms)
10156 num_of_syms = si + 1;
10157 }
10158 si++;
10159 }
10160 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
10161 }
10162
ceb9bf11 10163 no_gnu_hash:
10ca4b04
L
10164 if (gnu_hash_error)
10165 {
10166 if (mipsxlat)
10167 {
10168 free (mipsxlat);
10169 mipsxlat = NULL;
10170 }
10171 if (gnuchains)
10172 {
10173 free (gnuchains);
10174 gnuchains = NULL;
10175 }
10176 if (gnubuckets)
10177 {
10178 free (gnubuckets);
10179 gnubuckets = NULL;
10180 }
10181 ngnubuckets = 0;
10182 ngnuchains = 0;
10183 }
10184 }
10185
10186 return num_of_syms;
10187}
10188
b2d38a17
NC
10189/* Parse and display the contents of the dynamic section. */
10190
32ec8896 10191static bfd_boolean
dda8d76d 10192process_dynamic_section (Filedata * filedata)
9ea033b2 10193{
2cf0635d 10194 Elf_Internal_Dyn * entry;
9ea033b2
NC
10195
10196 if (dynamic_size == 0)
10197 {
10198 if (do_dynamic)
b2d38a17 10199 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 10200
32ec8896 10201 return TRUE;
9ea033b2
NC
10202 }
10203
10204 if (is_32bit_elf)
10205 {
dda8d76d 10206 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10207 return FALSE;
10208 }
10209 else
10210 {
dda8d76d 10211 if (! get_64bit_dynamic_section (filedata))
32ec8896 10212 return FALSE;
9ea033b2 10213 }
9ea033b2 10214
252b5132 10215 /* Find the appropriate symbol table. */
10ca4b04 10216 if (dynamic_symbols == NULL || do_histogram)
252b5132 10217 {
86dba8ee
AM
10218 for (entry = dynamic_section;
10219 entry < dynamic_section + dynamic_nent;
10220 ++entry)
10ca4b04
L
10221 if (entry->d_tag == DT_SYMTAB)
10222 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10223 else if (entry->d_tag == DT_SYMENT)
10224 dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10225 else if (entry->d_tag == DT_HASH)
10226 dynamic_info[DT_HASH] = entry->d_un.d_val;
10227 else if (entry->d_tag == DT_GNU_HASH)
10228 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10229 else if ((filedata->file_header.e_machine == EM_MIPS
10230 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10231 && entry->d_tag == DT_MIPS_XHASH)
10232 {
10233 dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10234 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10235 }
252b5132 10236
10ca4b04
L
10237 if (dynamic_info[DT_SYMTAB] && dynamic_info[DT_SYMENT])
10238 {
10239 Elf_Internal_Phdr *seg;
10240 bfd_vma vma = dynamic_info[DT_SYMTAB];
252b5132 10241
10ca4b04
L
10242 if (! get_program_headers (filedata))
10243 {
10244 error (_("Cannot interpret virtual addresses without program headers.\n"));
10245 return FALSE;
10246 }
252b5132 10247
10ca4b04
L
10248 for (seg = filedata->program_headers;
10249 seg < filedata->program_headers + filedata->file_header.e_phnum;
10250 ++seg)
10251 {
10252 unsigned long num_of_syms;
252b5132 10253
10ca4b04
L
10254 if (seg->p_type != PT_LOAD)
10255 continue;
252b5132 10256
10ca4b04
L
10257 if ((seg->p_offset + seg->p_filesz)
10258 > filedata->file_size)
10259 {
10260 /* See PR 21379 for a reproducer. */
10261 error (_("Invalid PT_LOAD entry\n"));
10262 return FALSE;
10263 }
252b5132 10264
10ca4b04
L
10265 if (vma >= (seg->p_vaddr & -seg->p_align)
10266 && vma <= seg->p_vaddr + seg->p_filesz
ceb9bf11
AM
10267 && (num_of_syms = get_num_dynamic_syms (filedata)) != 0
10268 && dynamic_symbols == NULL)
10ca4b04
L
10269 {
10270 /* Since we do not know how big the symbol table is,
10271 we default to reading in up to the end of PT_LOAD
10272 segment and processing that. This is overkill, I
10273 know, but it should work. */
10274 Elf_Internal_Shdr section;
10275 section.sh_offset = (vma - seg->p_vaddr
10276 + seg->p_offset);
10277 section.sh_size = (num_of_syms
10278 * dynamic_info[DT_SYMENT]);
10279 section.sh_entsize = dynamic_info[DT_SYMENT];
10280 section.sh_name = filedata->string_table_length;
10281 dynamic_symbols = GET_ELF_SYMBOLS (filedata,
10282 &section,
10283 & num_dynamic_syms);
10284 if (dynamic_symbols == NULL
10285 || num_dynamic_syms != num_of_syms)
10286 {
10287 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10288 return FALSE;
10289 }
10290 }
10291 }
10292 }
10293 }
252b5132
RH
10294
10295 /* Similarly find a string table. */
10296 if (dynamic_strings == NULL)
10ca4b04
L
10297 for (entry = dynamic_section;
10298 entry < dynamic_section + dynamic_nent;
10299 ++entry)
10300 {
10301 if (entry->d_tag == DT_STRTAB)
252b5132
RH
10302 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
10303
10ca4b04
L
10304 if (entry->d_tag == DT_STRSZ)
10305 dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10306
10ca4b04
L
10307 if (dynamic_info[DT_STRTAB] && dynamic_info[DT_STRSZ])
10308 {
10309 unsigned long offset;
10310 bfd_size_type str_tab_len = dynamic_info[DT_STRSZ];
10311
10312 offset = offset_from_vma (filedata,
10313 dynamic_info[DT_STRTAB],
10314 str_tab_len);
10315 dynamic_strings = (char *) get_data (NULL, filedata, offset, 1,
10316 str_tab_len,
10317 _("dynamic string table"));
10318 if (dynamic_strings == NULL)
10319 {
10320 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10321 break;
10322 }
e3d39609 10323
10ca4b04
L
10324 dynamic_strings_length = str_tab_len;
10325 break;
10326 }
10327 }
252b5132
RH
10328
10329 /* And find the syminfo section if available. */
10330 if (dynamic_syminfo == NULL)
10331 {
3e8bba36 10332 unsigned long syminsz = 0;
252b5132 10333
86dba8ee
AM
10334 for (entry = dynamic_section;
10335 entry < dynamic_section + dynamic_nent;
10336 ++entry)
252b5132
RH
10337 {
10338 if (entry->d_tag == DT_SYMINENT)
10339 {
10340 /* Note: these braces are necessary to avoid a syntax
10341 error from the SunOS4 C compiler. */
049b0c3a
NC
10342 /* PR binutils/17531: A corrupt file can trigger this test.
10343 So do not use an assert, instead generate an error message. */
10344 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10345 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10346 (int) entry->d_un.d_val);
252b5132
RH
10347 }
10348 else if (entry->d_tag == DT_SYMINSZ)
10349 syminsz = entry->d_un.d_val;
10350 else if (entry->d_tag == DT_SYMINFO)
dda8d76d 10351 dynamic_syminfo_offset = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 10352 syminsz);
252b5132
RH
10353 }
10354
10355 if (dynamic_syminfo_offset != 0 && syminsz != 0)
10356 {
2cf0635d
NC
10357 Elf_External_Syminfo * extsyminfo;
10358 Elf_External_Syminfo * extsym;
10359 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10360
10361 /* There is a syminfo section. Read the data. */
3f5e193b 10362 extsyminfo = (Elf_External_Syminfo *)
dda8d76d 10363 get_data (NULL, filedata, dynamic_syminfo_offset, 1, syminsz,
3f5e193b 10364 _("symbol information"));
a6e9f9df 10365 if (!extsyminfo)
32ec8896 10366 return FALSE;
252b5132 10367
e3d39609
NC
10368 if (dynamic_syminfo != NULL)
10369 {
10370 error (_("Multiple dynamic symbol information sections found\n"));
10371 free (dynamic_syminfo);
10372 }
3f5e193b 10373 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
10374 if (dynamic_syminfo == NULL)
10375 {
8b73c356
NC
10376 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
10377 (unsigned long) syminsz);
32ec8896 10378 return FALSE;
252b5132
RH
10379 }
10380
10381 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
10382 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
10383 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
10384 ++syminfo, ++extsym)
252b5132 10385 {
86dba8ee
AM
10386 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10387 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10388 }
10389
10390 free (extsyminfo);
10391 }
10392 }
10393
10394 if (do_dynamic && dynamic_addr)
d3a49aa8
AM
10395 printf (ngettext ("\nDynamic section at offset 0x%lx "
10396 "contains %lu entry:\n",
10397 "\nDynamic section at offset 0x%lx "
10398 "contains %lu entries:\n",
10399 dynamic_nent),
8b73c356 10400 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
10401 if (do_dynamic)
10402 printf (_(" Tag Type Name/Value\n"));
10403
86dba8ee
AM
10404 for (entry = dynamic_section;
10405 entry < dynamic_section + dynamic_nent;
10406 entry++)
252b5132
RH
10407 {
10408 if (do_dynamic)
f7a99963 10409 {
2cf0635d 10410 const char * dtype;
e699b9ff 10411
f7a99963
NC
10412 putchar (' ');
10413 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10414 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10415 printf (" (%s)%*s", dtype,
32ec8896 10416 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10417 }
252b5132
RH
10418
10419 switch (entry->d_tag)
10420 {
d1133906
NC
10421 case DT_FLAGS:
10422 if (do_dynamic)
e9e44622 10423 print_dynamic_flags (entry->d_un.d_val);
d1133906 10424 break;
76da6bbe 10425
252b5132
RH
10426 case DT_AUXILIARY:
10427 case DT_FILTER:
019148e4
L
10428 case DT_CONFIG:
10429 case DT_DEPAUDIT:
10430 case DT_AUDIT:
252b5132
RH
10431 if (do_dynamic)
10432 {
019148e4 10433 switch (entry->d_tag)
b34976b6 10434 {
019148e4
L
10435 case DT_AUXILIARY:
10436 printf (_("Auxiliary library"));
10437 break;
10438
10439 case DT_FILTER:
10440 printf (_("Filter library"));
10441 break;
10442
b34976b6 10443 case DT_CONFIG:
019148e4
L
10444 printf (_("Configuration file"));
10445 break;
10446
10447 case DT_DEPAUDIT:
10448 printf (_("Dependency audit library"));
10449 break;
10450
10451 case DT_AUDIT:
10452 printf (_("Audit library"));
10453 break;
10454 }
252b5132 10455
d79b3d50
NC
10456 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
10457 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 10458 else
f7a99963
NC
10459 {
10460 printf (": ");
10461 print_vma (entry->d_un.d_val, PREFIX_HEX);
10462 putchar ('\n');
10463 }
252b5132
RH
10464 }
10465 break;
10466
dcefbbbd 10467 case DT_FEATURE:
252b5132
RH
10468 if (do_dynamic)
10469 {
10470 printf (_("Flags:"));
86f55779 10471
252b5132
RH
10472 if (entry->d_un.d_val == 0)
10473 printf (_(" None\n"));
10474 else
10475 {
10476 unsigned long int val = entry->d_un.d_val;
86f55779 10477
252b5132
RH
10478 if (val & DTF_1_PARINIT)
10479 {
10480 printf (" PARINIT");
10481 val ^= DTF_1_PARINIT;
10482 }
dcefbbbd
L
10483 if (val & DTF_1_CONFEXP)
10484 {
10485 printf (" CONFEXP");
10486 val ^= DTF_1_CONFEXP;
10487 }
252b5132
RH
10488 if (val != 0)
10489 printf (" %lx", val);
10490 puts ("");
10491 }
10492 }
10493 break;
10494
10495 case DT_POSFLAG_1:
10496 if (do_dynamic)
10497 {
10498 printf (_("Flags:"));
86f55779 10499
252b5132
RH
10500 if (entry->d_un.d_val == 0)
10501 printf (_(" None\n"));
10502 else
10503 {
10504 unsigned long int val = entry->d_un.d_val;
86f55779 10505
252b5132
RH
10506 if (val & DF_P1_LAZYLOAD)
10507 {
10508 printf (" LAZYLOAD");
10509 val ^= DF_P1_LAZYLOAD;
10510 }
10511 if (val & DF_P1_GROUPPERM)
10512 {
10513 printf (" GROUPPERM");
10514 val ^= DF_P1_GROUPPERM;
10515 }
10516 if (val != 0)
10517 printf (" %lx", val);
10518 puts ("");
10519 }
10520 }
10521 break;
10522
10523 case DT_FLAGS_1:
10524 if (do_dynamic)
10525 {
10526 printf (_("Flags:"));
10527 if (entry->d_un.d_val == 0)
10528 printf (_(" None\n"));
10529 else
10530 {
10531 unsigned long int val = entry->d_un.d_val;
86f55779 10532
252b5132
RH
10533 if (val & DF_1_NOW)
10534 {
10535 printf (" NOW");
10536 val ^= DF_1_NOW;
10537 }
10538 if (val & DF_1_GLOBAL)
10539 {
10540 printf (" GLOBAL");
10541 val ^= DF_1_GLOBAL;
10542 }
10543 if (val & DF_1_GROUP)
10544 {
10545 printf (" GROUP");
10546 val ^= DF_1_GROUP;
10547 }
10548 if (val & DF_1_NODELETE)
10549 {
10550 printf (" NODELETE");
10551 val ^= DF_1_NODELETE;
10552 }
10553 if (val & DF_1_LOADFLTR)
10554 {
10555 printf (" LOADFLTR");
10556 val ^= DF_1_LOADFLTR;
10557 }
10558 if (val & DF_1_INITFIRST)
10559 {
10560 printf (" INITFIRST");
10561 val ^= DF_1_INITFIRST;
10562 }
10563 if (val & DF_1_NOOPEN)
10564 {
10565 printf (" NOOPEN");
10566 val ^= DF_1_NOOPEN;
10567 }
10568 if (val & DF_1_ORIGIN)
10569 {
10570 printf (" ORIGIN");
10571 val ^= DF_1_ORIGIN;
10572 }
10573 if (val & DF_1_DIRECT)
10574 {
10575 printf (" DIRECT");
10576 val ^= DF_1_DIRECT;
10577 }
10578 if (val & DF_1_TRANS)
10579 {
10580 printf (" TRANS");
10581 val ^= DF_1_TRANS;
10582 }
10583 if (val & DF_1_INTERPOSE)
10584 {
10585 printf (" INTERPOSE");
10586 val ^= DF_1_INTERPOSE;
10587 }
f7db6139 10588 if (val & DF_1_NODEFLIB)
dcefbbbd 10589 {
f7db6139
L
10590 printf (" NODEFLIB");
10591 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10592 }
10593 if (val & DF_1_NODUMP)
10594 {
10595 printf (" NODUMP");
10596 val ^= DF_1_NODUMP;
10597 }
34b60028 10598 if (val & DF_1_CONFALT)
dcefbbbd 10599 {
34b60028
L
10600 printf (" CONFALT");
10601 val ^= DF_1_CONFALT;
10602 }
10603 if (val & DF_1_ENDFILTEE)
10604 {
10605 printf (" ENDFILTEE");
10606 val ^= DF_1_ENDFILTEE;
10607 }
10608 if (val & DF_1_DISPRELDNE)
10609 {
10610 printf (" DISPRELDNE");
10611 val ^= DF_1_DISPRELDNE;
10612 }
10613 if (val & DF_1_DISPRELPND)
10614 {
10615 printf (" DISPRELPND");
10616 val ^= DF_1_DISPRELPND;
10617 }
10618 if (val & DF_1_NODIRECT)
10619 {
10620 printf (" NODIRECT");
10621 val ^= DF_1_NODIRECT;
10622 }
10623 if (val & DF_1_IGNMULDEF)
10624 {
10625 printf (" IGNMULDEF");
10626 val ^= DF_1_IGNMULDEF;
10627 }
10628 if (val & DF_1_NOKSYMS)
10629 {
10630 printf (" NOKSYMS");
10631 val ^= DF_1_NOKSYMS;
10632 }
10633 if (val & DF_1_NOHDR)
10634 {
10635 printf (" NOHDR");
10636 val ^= DF_1_NOHDR;
10637 }
10638 if (val & DF_1_EDITED)
10639 {
10640 printf (" EDITED");
10641 val ^= DF_1_EDITED;
10642 }
10643 if (val & DF_1_NORELOC)
10644 {
10645 printf (" NORELOC");
10646 val ^= DF_1_NORELOC;
10647 }
10648 if (val & DF_1_SYMINTPOSE)
10649 {
10650 printf (" SYMINTPOSE");
10651 val ^= DF_1_SYMINTPOSE;
10652 }
10653 if (val & DF_1_GLOBAUDIT)
10654 {
10655 printf (" GLOBAUDIT");
10656 val ^= DF_1_GLOBAUDIT;
10657 }
10658 if (val & DF_1_SINGLETON)
10659 {
10660 printf (" SINGLETON");
10661 val ^= DF_1_SINGLETON;
dcefbbbd 10662 }
5c383f02
RO
10663 if (val & DF_1_STUB)
10664 {
10665 printf (" STUB");
10666 val ^= DF_1_STUB;
10667 }
10668 if (val & DF_1_PIE)
10669 {
10670 printf (" PIE");
10671 val ^= DF_1_PIE;
10672 }
b1202ffa
L
10673 if (val & DF_1_KMOD)
10674 {
10675 printf (" KMOD");
10676 val ^= DF_1_KMOD;
10677 }
10678 if (val & DF_1_WEAKFILTER)
10679 {
10680 printf (" WEAKFILTER");
10681 val ^= DF_1_WEAKFILTER;
10682 }
10683 if (val & DF_1_NOCOMMON)
10684 {
10685 printf (" NOCOMMON");
10686 val ^= DF_1_NOCOMMON;
10687 }
252b5132
RH
10688 if (val != 0)
10689 printf (" %lx", val);
10690 puts ("");
10691 }
10692 }
10693 break;
10694
10695 case DT_PLTREL:
566b0d53 10696 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10697 if (do_dynamic)
dda8d76d 10698 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10699 break;
10700
10701 case DT_NULL :
10702 case DT_NEEDED :
10703 case DT_PLTGOT :
10704 case DT_HASH :
10705 case DT_STRTAB :
10706 case DT_SYMTAB :
10707 case DT_RELA :
10708 case DT_INIT :
10709 case DT_FINI :
10710 case DT_SONAME :
10711 case DT_RPATH :
10712 case DT_SYMBOLIC:
10713 case DT_REL :
10714 case DT_DEBUG :
10715 case DT_TEXTREL :
10716 case DT_JMPREL :
019148e4 10717 case DT_RUNPATH :
252b5132
RH
10718 dynamic_info[entry->d_tag] = entry->d_un.d_val;
10719
10720 if (do_dynamic)
10721 {
2cf0635d 10722 char * name;
252b5132 10723
d79b3d50
NC
10724 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
10725 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10726 else
d79b3d50 10727 name = NULL;
252b5132
RH
10728
10729 if (name)
10730 {
10731 switch (entry->d_tag)
10732 {
10733 case DT_NEEDED:
10734 printf (_("Shared library: [%s]"), name);
10735
18bd398b 10736 if (streq (name, program_interpreter))
f7a99963 10737 printf (_(" program interpreter"));
252b5132
RH
10738 break;
10739
10740 case DT_SONAME:
f7a99963 10741 printf (_("Library soname: [%s]"), name);
252b5132
RH
10742 break;
10743
10744 case DT_RPATH:
f7a99963 10745 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10746 break;
10747
019148e4
L
10748 case DT_RUNPATH:
10749 printf (_("Library runpath: [%s]"), name);
10750 break;
10751
252b5132 10752 default:
f7a99963
NC
10753 print_vma (entry->d_un.d_val, PREFIX_HEX);
10754 break;
252b5132
RH
10755 }
10756 }
10757 else
f7a99963
NC
10758 print_vma (entry->d_un.d_val, PREFIX_HEX);
10759
10760 putchar ('\n');
252b5132
RH
10761 }
10762 break;
10763
10764 case DT_PLTRELSZ:
10765 case DT_RELASZ :
10766 case DT_STRSZ :
10767 case DT_RELSZ :
10768 case DT_RELAENT :
10769 case DT_SYMENT :
10770 case DT_RELENT :
566b0d53 10771 dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10772 /* Fall through. */
252b5132
RH
10773 case DT_PLTPADSZ:
10774 case DT_MOVEENT :
10775 case DT_MOVESZ :
10776 case DT_INIT_ARRAYSZ:
10777 case DT_FINI_ARRAYSZ:
047b2264
JJ
10778 case DT_GNU_CONFLICTSZ:
10779 case DT_GNU_LIBLISTSZ:
252b5132 10780 if (do_dynamic)
f7a99963
NC
10781 {
10782 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10783 printf (_(" (bytes)\n"));
f7a99963 10784 }
252b5132
RH
10785 break;
10786
10787 case DT_VERDEFNUM:
10788 case DT_VERNEEDNUM:
10789 case DT_RELACOUNT:
10790 case DT_RELCOUNT:
10791 if (do_dynamic)
f7a99963
NC
10792 {
10793 print_vma (entry->d_un.d_val, UNSIGNED);
10794 putchar ('\n');
10795 }
252b5132
RH
10796 break;
10797
10798 case DT_SYMINSZ:
10799 case DT_SYMINENT:
10800 case DT_SYMINFO:
10801 case DT_USED:
10802 case DT_INIT_ARRAY:
10803 case DT_FINI_ARRAY:
10804 if (do_dynamic)
10805 {
d79b3d50
NC
10806 if (entry->d_tag == DT_USED
10807 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 10808 {
2cf0635d 10809 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10810
b34976b6 10811 if (*name)
252b5132
RH
10812 {
10813 printf (_("Not needed object: [%s]\n"), name);
10814 break;
10815 }
10816 }
103f02d3 10817
f7a99963
NC
10818 print_vma (entry->d_un.d_val, PREFIX_HEX);
10819 putchar ('\n');
252b5132
RH
10820 }
10821 break;
10822
10823 case DT_BIND_NOW:
10824 /* The value of this entry is ignored. */
35b1837e
AM
10825 if (do_dynamic)
10826 putchar ('\n');
252b5132 10827 break;
103f02d3 10828
047b2264
JJ
10829 case DT_GNU_PRELINKED:
10830 if (do_dynamic)
10831 {
2cf0635d 10832 struct tm * tmp;
91d6fa6a 10833 time_t atime = entry->d_un.d_val;
047b2264 10834
91d6fa6a 10835 tmp = gmtime (&atime);
071436c6
NC
10836 /* PR 17533 file: 041-1244816-0.004. */
10837 if (tmp == NULL)
5a2cbcf4
L
10838 printf (_("<corrupt time val: %lx"),
10839 (unsigned long) atime);
071436c6
NC
10840 else
10841 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10842 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10843 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10844
10845 }
10846 break;
10847
fdc90cb4
JJ
10848 case DT_GNU_HASH:
10849 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10850 if (do_dynamic)
10851 {
10852 print_vma (entry->d_un.d_val, PREFIX_HEX);
10853 putchar ('\n');
10854 }
10855 break;
10856
252b5132
RH
10857 default:
10858 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 10859 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
10860 entry->d_un.d_val;
10861
10862 if (do_dynamic)
10863 {
dda8d76d 10864 switch (filedata->file_header.e_machine)
252b5132 10865 {
37c18eed
SD
10866 case EM_AARCH64:
10867 dynamic_section_aarch64_val (entry);
10868 break;
252b5132 10869 case EM_MIPS:
4fe85591 10870 case EM_MIPS_RS3_LE:
b2d38a17 10871 dynamic_section_mips_val (entry);
252b5132 10872 break;
103f02d3 10873 case EM_PARISC:
b2d38a17 10874 dynamic_section_parisc_val (entry);
103f02d3 10875 break;
ecc51f48 10876 case EM_IA_64:
b2d38a17 10877 dynamic_section_ia64_val (entry);
ecc51f48 10878 break;
252b5132 10879 default:
f7a99963
NC
10880 print_vma (entry->d_un.d_val, PREFIX_HEX);
10881 putchar ('\n');
252b5132
RH
10882 }
10883 }
10884 break;
10885 }
10886 }
10887
32ec8896 10888 return TRUE;
252b5132
RH
10889}
10890
10891static char *
d3ba0551 10892get_ver_flags (unsigned int flags)
252b5132 10893{
6d4f21f6 10894 static char buff[128];
252b5132
RH
10895
10896 buff[0] = 0;
10897
10898 if (flags == 0)
10899 return _("none");
10900
10901 if (flags & VER_FLG_BASE)
7bb1ad17 10902 strcat (buff, "BASE");
252b5132
RH
10903
10904 if (flags & VER_FLG_WEAK)
10905 {
10906 if (flags & VER_FLG_BASE)
7bb1ad17 10907 strcat (buff, " | ");
252b5132 10908
7bb1ad17 10909 strcat (buff, "WEAK");
252b5132
RH
10910 }
10911
44ec90b9
RO
10912 if (flags & VER_FLG_INFO)
10913 {
10914 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 10915 strcat (buff, " | ");
44ec90b9 10916
7bb1ad17 10917 strcat (buff, "INFO");
44ec90b9
RO
10918 }
10919
10920 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
10921 {
10922 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
10923 strcat (buff, " | ");
10924
10925 strcat (buff, _("<unknown>"));
10926 }
252b5132
RH
10927
10928 return buff;
10929}
10930
10931/* Display the contents of the version sections. */
98fb390a 10932
32ec8896 10933static bfd_boolean
dda8d76d 10934process_version_sections (Filedata * filedata)
252b5132 10935{
2cf0635d 10936 Elf_Internal_Shdr * section;
b34976b6 10937 unsigned i;
32ec8896 10938 bfd_boolean found = FALSE;
252b5132
RH
10939
10940 if (! do_version)
32ec8896 10941 return TRUE;
252b5132 10942
dda8d76d
NC
10943 for (i = 0, section = filedata->section_headers;
10944 i < filedata->file_header.e_shnum;
b34976b6 10945 i++, section++)
252b5132
RH
10946 {
10947 switch (section->sh_type)
10948 {
10949 case SHT_GNU_verdef:
10950 {
2cf0635d 10951 Elf_External_Verdef * edefs;
452bf675
AM
10952 unsigned long idx;
10953 unsigned long cnt;
2cf0635d 10954 char * endbuf;
252b5132 10955
32ec8896 10956 found = TRUE;
252b5132 10957
d3a49aa8
AM
10958 printf (ngettext ("\nVersion definition section '%s' "
10959 "contains %u entry:\n",
10960 "\nVersion definition section '%s' "
10961 "contains %u entries:\n",
10962 section->sh_info),
dda8d76d 10963 printable_section_name (filedata, section),
74e1a04b 10964 section->sh_info);
252b5132 10965
ae9ac79e 10966 printf (_(" Addr: 0x"));
252b5132 10967 printf_vma (section->sh_addr);
233f82cf 10968 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10969 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10970 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10971
3f5e193b 10972 edefs = (Elf_External_Verdef *)
dda8d76d 10973 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 10974 _("version definition section"));
a6e9f9df
AM
10975 if (!edefs)
10976 break;
59245841 10977 endbuf = (char *) edefs + section->sh_size;
252b5132 10978
1445030f 10979 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 10980 {
2cf0635d
NC
10981 char * vstart;
10982 Elf_External_Verdef * edef;
b34976b6 10983 Elf_Internal_Verdef ent;
2cf0635d 10984 Elf_External_Verdaux * eaux;
b34976b6 10985 Elf_Internal_Verdaux aux;
452bf675 10986 unsigned long isum;
b34976b6 10987 int j;
103f02d3 10988
252b5132 10989 vstart = ((char *) edefs) + idx;
54806181
AM
10990 if (vstart + sizeof (*edef) > endbuf)
10991 break;
252b5132
RH
10992
10993 edef = (Elf_External_Verdef *) vstart;
10994
10995 ent.vd_version = BYTE_GET (edef->vd_version);
10996 ent.vd_flags = BYTE_GET (edef->vd_flags);
10997 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
10998 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
10999 ent.vd_hash = BYTE_GET (edef->vd_hash);
11000 ent.vd_aux = BYTE_GET (edef->vd_aux);
11001 ent.vd_next = BYTE_GET (edef->vd_next);
11002
452bf675 11003 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11004 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11005
11006 printf (_(" Index: %d Cnt: %d "),
11007 ent.vd_ndx, ent.vd_cnt);
11008
452bf675 11009 /* Check for overflow. */
1445030f 11010 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11011 break;
11012
252b5132
RH
11013 vstart += ent.vd_aux;
11014
1445030f
AM
11015 if (vstart + sizeof (*eaux) > endbuf)
11016 break;
252b5132
RH
11017 eaux = (Elf_External_Verdaux *) vstart;
11018
11019 aux.vda_name = BYTE_GET (eaux->vda_name);
11020 aux.vda_next = BYTE_GET (eaux->vda_next);
11021
d79b3d50
NC
11022 if (VALID_DYNAMIC_NAME (aux.vda_name))
11023 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
11024 else
11025 printf (_("Name index: %ld\n"), aux.vda_name);
11026
11027 isum = idx + ent.vd_aux;
11028
b34976b6 11029 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11030 {
1445030f
AM
11031 if (aux.vda_next < sizeof (*eaux)
11032 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11033 {
11034 warn (_("Invalid vda_next field of %lx\n"),
11035 aux.vda_next);
11036 j = ent.vd_cnt;
11037 break;
11038 }
dd24e3da 11039 /* Check for overflow. */
7e26601c 11040 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11041 break;
11042
252b5132
RH
11043 isum += aux.vda_next;
11044 vstart += aux.vda_next;
11045
54806181
AM
11046 if (vstart + sizeof (*eaux) > endbuf)
11047 break;
1445030f 11048 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11049
11050 aux.vda_name = BYTE_GET (eaux->vda_name);
11051 aux.vda_next = BYTE_GET (eaux->vda_next);
11052
d79b3d50 11053 if (VALID_DYNAMIC_NAME (aux.vda_name))
452bf675 11054 printf (_(" %#06lx: Parent %d: %s\n"),
d79b3d50 11055 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132 11056 else
452bf675 11057 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11058 isum, j, aux.vda_name);
11059 }
dd24e3da 11060
54806181
AM
11061 if (j < ent.vd_cnt)
11062 printf (_(" Version def aux past end of section\n"));
252b5132 11063
c9f02c3e
MR
11064 /* PR 17531:
11065 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11066 if (ent.vd_next < sizeof (*edef)
11067 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11068 {
11069 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11070 cnt = section->sh_info;
11071 break;
11072 }
452bf675 11073 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11074 break;
11075
252b5132
RH
11076 idx += ent.vd_next;
11077 }
dd24e3da 11078
54806181
AM
11079 if (cnt < section->sh_info)
11080 printf (_(" Version definition past end of section\n"));
252b5132
RH
11081
11082 free (edefs);
11083 }
11084 break;
103f02d3 11085
252b5132
RH
11086 case SHT_GNU_verneed:
11087 {
2cf0635d 11088 Elf_External_Verneed * eneed;
452bf675
AM
11089 unsigned long idx;
11090 unsigned long cnt;
2cf0635d 11091 char * endbuf;
252b5132 11092
32ec8896 11093 found = TRUE;
252b5132 11094
d3a49aa8
AM
11095 printf (ngettext ("\nVersion needs section '%s' "
11096 "contains %u entry:\n",
11097 "\nVersion needs section '%s' "
11098 "contains %u entries:\n",
11099 section->sh_info),
dda8d76d 11100 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11101
11102 printf (_(" Addr: 0x"));
11103 printf_vma (section->sh_addr);
72de5009 11104 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11105 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11106 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11107
dda8d76d 11108 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11109 section->sh_offset, 1,
11110 section->sh_size,
9cf03b7e 11111 _("Version Needs section"));
a6e9f9df
AM
11112 if (!eneed)
11113 break;
59245841 11114 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11115
11116 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11117 {
2cf0635d 11118 Elf_External_Verneed * entry;
b34976b6 11119 Elf_Internal_Verneed ent;
452bf675 11120 unsigned long isum;
b34976b6 11121 int j;
2cf0635d 11122 char * vstart;
252b5132
RH
11123
11124 vstart = ((char *) eneed) + idx;
54806181
AM
11125 if (vstart + sizeof (*entry) > endbuf)
11126 break;
252b5132
RH
11127
11128 entry = (Elf_External_Verneed *) vstart;
11129
11130 ent.vn_version = BYTE_GET (entry->vn_version);
11131 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11132 ent.vn_file = BYTE_GET (entry->vn_file);
11133 ent.vn_aux = BYTE_GET (entry->vn_aux);
11134 ent.vn_next = BYTE_GET (entry->vn_next);
11135
452bf675 11136 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11137
d79b3d50
NC
11138 if (VALID_DYNAMIC_NAME (ent.vn_file))
11139 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
11140 else
11141 printf (_(" File: %lx"), ent.vn_file);
11142
11143 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11144
dd24e3da 11145 /* Check for overflow. */
7e26601c 11146 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11147 break;
252b5132
RH
11148 vstart += ent.vn_aux;
11149
11150 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11151 {
2cf0635d 11152 Elf_External_Vernaux * eaux;
b34976b6 11153 Elf_Internal_Vernaux aux;
252b5132 11154
54806181
AM
11155 if (vstart + sizeof (*eaux) > endbuf)
11156 break;
252b5132
RH
11157 eaux = (Elf_External_Vernaux *) vstart;
11158
11159 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11160 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11161 aux.vna_other = BYTE_GET (eaux->vna_other);
11162 aux.vna_name = BYTE_GET (eaux->vna_name);
11163 aux.vna_next = BYTE_GET (eaux->vna_next);
11164
d79b3d50 11165 if (VALID_DYNAMIC_NAME (aux.vna_name))
452bf675 11166 printf (_(" %#06lx: Name: %s"),
d79b3d50 11167 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 11168 else
452bf675 11169 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11170 isum, aux.vna_name);
11171
11172 printf (_(" Flags: %s Version: %d\n"),
11173 get_ver_flags (aux.vna_flags), aux.vna_other);
11174
1445030f
AM
11175 if (aux.vna_next < sizeof (*eaux)
11176 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11177 {
11178 warn (_("Invalid vna_next field of %lx\n"),
11179 aux.vna_next);
11180 j = ent.vn_cnt;
11181 break;
11182 }
1445030f
AM
11183 /* Check for overflow. */
11184 if (aux.vna_next > (size_t) (endbuf - vstart))
11185 break;
252b5132
RH
11186 isum += aux.vna_next;
11187 vstart += aux.vna_next;
11188 }
9cf03b7e 11189
54806181 11190 if (j < ent.vn_cnt)
9cf03b7e 11191 warn (_("Missing Version Needs auxillary information\n"));
252b5132 11192
1445030f
AM
11193 if (ent.vn_next < sizeof (*entry)
11194 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11195 {
452bf675 11196 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11197 cnt = section->sh_info;
11198 break;
11199 }
1445030f
AM
11200 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11201 break;
252b5132
RH
11202 idx += ent.vn_next;
11203 }
9cf03b7e 11204
54806181 11205 if (cnt < section->sh_info)
9cf03b7e 11206 warn (_("Missing Version Needs information\n"));
103f02d3 11207
252b5132
RH
11208 free (eneed);
11209 }
11210 break;
11211
11212 case SHT_GNU_versym:
11213 {
2cf0635d 11214 Elf_Internal_Shdr * link_section;
8b73c356
NC
11215 size_t total;
11216 unsigned int cnt;
2cf0635d
NC
11217 unsigned char * edata;
11218 unsigned short * data;
11219 char * strtab;
11220 Elf_Internal_Sym * symbols;
11221 Elf_Internal_Shdr * string_sec;
ba5cdace 11222 unsigned long num_syms;
d3ba0551 11223 long off;
252b5132 11224
dda8d76d 11225 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11226 break;
11227
dda8d76d 11228 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11229 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11230
dda8d76d 11231 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11232 break;
11233
32ec8896 11234 found = TRUE;
252b5132 11235
dda8d76d 11236 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11237 if (symbols == NULL)
11238 break;
252b5132 11239
dda8d76d 11240 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11241
dda8d76d 11242 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11243 string_sec->sh_size,
11244 _("version string table"));
a6e9f9df 11245 if (!strtab)
0429c154
MS
11246 {
11247 free (symbols);
11248 break;
11249 }
252b5132 11250
d3a49aa8
AM
11251 printf (ngettext ("\nVersion symbols section '%s' "
11252 "contains %lu entry:\n",
11253 "\nVersion symbols section '%s' "
11254 "contains %lu entries:\n",
11255 total),
dda8d76d 11256 printable_section_name (filedata, section), (unsigned long) total);
252b5132 11257
ae9ac79e 11258 printf (_(" Addr: 0x"));
252b5132 11259 printf_vma (section->sh_addr);
72de5009 11260 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11261 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11262 printable_section_name (filedata, link_section));
252b5132 11263
dda8d76d 11264 off = offset_from_vma (filedata,
d3ba0551
AM
11265 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
11266 total * sizeof (short));
95099889
AM
11267 edata = (unsigned char *) get_data (NULL, filedata, off,
11268 sizeof (short), total,
11269 _("version symbol data"));
a6e9f9df
AM
11270 if (!edata)
11271 {
11272 free (strtab);
0429c154 11273 free (symbols);
a6e9f9df
AM
11274 break;
11275 }
252b5132 11276
3f5e193b 11277 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11278
11279 for (cnt = total; cnt --;)
b34976b6
AM
11280 data[cnt] = byte_get (edata + cnt * sizeof (short),
11281 sizeof (short));
252b5132
RH
11282
11283 free (edata);
11284
11285 for (cnt = 0; cnt < total; cnt += 4)
11286 {
11287 int j, nn;
ab273396
AM
11288 char *name;
11289 char *invalid = _("*invalid*");
252b5132
RH
11290
11291 printf (" %03x:", cnt);
11292
11293 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11294 switch (data[cnt + j])
252b5132
RH
11295 {
11296 case 0:
11297 fputs (_(" 0 (*local*) "), stdout);
11298 break;
11299
11300 case 1:
11301 fputs (_(" 1 (*global*) "), stdout);
11302 break;
11303
11304 default:
c244d050
NC
11305 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11306 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11307
dd24e3da 11308 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11309 array, break to avoid an out-of-bounds read. */
11310 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11311 {
11312 warn (_("invalid index into symbol array\n"));
11313 break;
11314 }
11315
ab273396
AM
11316 name = NULL;
11317 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11318 {
b34976b6
AM
11319 Elf_Internal_Verneed ivn;
11320 unsigned long offset;
252b5132 11321
d93f0186 11322 offset = offset_from_vma
dda8d76d 11323 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11324 sizeof (Elf_External_Verneed));
252b5132 11325
b34976b6 11326 do
252b5132 11327 {
b34976b6
AM
11328 Elf_Internal_Vernaux ivna;
11329 Elf_External_Verneed evn;
11330 Elf_External_Vernaux evna;
11331 unsigned long a_off;
252b5132 11332
dda8d76d 11333 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11334 _("version need")) == NULL)
11335 break;
0b4362b0 11336
252b5132
RH
11337 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11338 ivn.vn_next = BYTE_GET (evn.vn_next);
11339
11340 a_off = offset + ivn.vn_aux;
11341
11342 do
11343 {
dda8d76d 11344 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11345 1, _("version need aux (2)")) == NULL)
11346 {
11347 ivna.vna_next = 0;
11348 ivna.vna_other = 0;
11349 }
11350 else
11351 {
11352 ivna.vna_next = BYTE_GET (evna.vna_next);
11353 ivna.vna_other = BYTE_GET (evna.vna_other);
11354 }
252b5132
RH
11355
11356 a_off += ivna.vna_next;
11357 }
b34976b6 11358 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11359 && ivna.vna_next != 0);
11360
b34976b6 11361 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11362 {
11363 ivna.vna_name = BYTE_GET (evna.vna_name);
11364
54806181 11365 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11366 name = invalid;
54806181
AM
11367 else
11368 name = strtab + ivna.vna_name;
252b5132
RH
11369 break;
11370 }
11371
11372 offset += ivn.vn_next;
11373 }
11374 while (ivn.vn_next);
11375 }
00d93f34 11376
ab273396 11377 if (data[cnt + j] != 0x8001
b34976b6 11378 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11379 {
b34976b6
AM
11380 Elf_Internal_Verdef ivd;
11381 Elf_External_Verdef evd;
11382 unsigned long offset;
252b5132 11383
d93f0186 11384 offset = offset_from_vma
dda8d76d 11385 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11386 sizeof evd);
252b5132
RH
11387
11388 do
11389 {
dda8d76d 11390 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11391 _("version def")) == NULL)
11392 {
11393 ivd.vd_next = 0;
948f632f 11394 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11395 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11396 break;
59245841
NC
11397 }
11398 else
11399 {
11400 ivd.vd_next = BYTE_GET (evd.vd_next);
11401 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11402 }
252b5132
RH
11403
11404 offset += ivd.vd_next;
11405 }
c244d050 11406 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11407 && ivd.vd_next != 0);
11408
c244d050 11409 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11410 {
b34976b6
AM
11411 Elf_External_Verdaux evda;
11412 Elf_Internal_Verdaux ivda;
252b5132
RH
11413
11414 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11415
dda8d76d 11416 if (get_data (&evda, filedata,
59245841
NC
11417 offset - ivd.vd_next + ivd.vd_aux,
11418 sizeof (evda), 1,
11419 _("version def aux")) == NULL)
11420 break;
252b5132
RH
11421
11422 ivda.vda_name = BYTE_GET (evda.vda_name);
11423
54806181 11424 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11425 name = invalid;
11426 else if (name != NULL && name != invalid)
11427 name = _("*both*");
54806181
AM
11428 else
11429 name = strtab + ivda.vda_name;
252b5132
RH
11430 }
11431 }
ab273396
AM
11432 if (name != NULL)
11433 nn += printf ("(%s%-*s",
11434 name,
11435 12 - (int) strlen (name),
11436 ")");
252b5132
RH
11437
11438 if (nn < 18)
11439 printf ("%*c", 18 - nn, ' ');
11440 }
11441
11442 putchar ('\n');
11443 }
11444
11445 free (data);
11446 free (strtab);
11447 free (symbols);
11448 }
11449 break;
103f02d3 11450
252b5132
RH
11451 default:
11452 break;
11453 }
11454 }
11455
11456 if (! found)
11457 printf (_("\nNo version information found in this file.\n"));
11458
32ec8896 11459 return TRUE;
252b5132
RH
11460}
11461
d1133906 11462static const char *
dda8d76d 11463get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11464{
89246a0e 11465 static char buff[64];
252b5132
RH
11466
11467 switch (binding)
11468 {
b34976b6
AM
11469 case STB_LOCAL: return "LOCAL";
11470 case STB_GLOBAL: return "GLOBAL";
11471 case STB_WEAK: return "WEAK";
252b5132
RH
11472 default:
11473 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11474 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11475 binding);
252b5132 11476 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11477 {
11478 if (binding == STB_GNU_UNIQUE
df3a023b 11479 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11480 return "UNIQUE";
11481 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11482 }
252b5132 11483 else
e9e44622 11484 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11485 return buff;
11486 }
11487}
11488
d1133906 11489static const char *
dda8d76d 11490get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11491{
89246a0e 11492 static char buff[64];
252b5132
RH
11493
11494 switch (type)
11495 {
b34976b6
AM
11496 case STT_NOTYPE: return "NOTYPE";
11497 case STT_OBJECT: return "OBJECT";
11498 case STT_FUNC: return "FUNC";
11499 case STT_SECTION: return "SECTION";
11500 case STT_FILE: return "FILE";
11501 case STT_COMMON: return "COMMON";
11502 case STT_TLS: return "TLS";
15ab5209
DB
11503 case STT_RELC: return "RELC";
11504 case STT_SRELC: return "SRELC";
252b5132
RH
11505 default:
11506 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11507 {
dda8d76d 11508 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11509 return "THUMB_FUNC";
103f02d3 11510
dda8d76d 11511 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11512 return "REGISTER";
11513
dda8d76d 11514 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11515 return "PARISC_MILLI";
11516
e9e44622 11517 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11518 }
252b5132 11519 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11520 {
dda8d76d 11521 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11522 {
11523 if (type == STT_HP_OPAQUE)
11524 return "HP_OPAQUE";
11525 if (type == STT_HP_STUB)
11526 return "HP_STUB";
11527 }
11528
d8045f23 11529 if (type == STT_GNU_IFUNC
dda8d76d 11530 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11531 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11532 return "IFUNC";
11533
e9e44622 11534 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11535 }
252b5132 11536 else
e9e44622 11537 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11538 return buff;
11539 }
11540}
11541
d1133906 11542static const char *
d3ba0551 11543get_symbol_visibility (unsigned int visibility)
d1133906
NC
11544{
11545 switch (visibility)
11546 {
b34976b6
AM
11547 case STV_DEFAULT: return "DEFAULT";
11548 case STV_INTERNAL: return "INTERNAL";
11549 case STV_HIDDEN: return "HIDDEN";
d1133906 11550 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11551 default:
27a45f42 11552 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11553 return _("<unknown>");
d1133906
NC
11554 }
11555}
11556
2057d69d
CZ
11557static const char *
11558get_alpha_symbol_other (unsigned int other)
9abca702 11559{
2057d69d
CZ
11560 switch (other)
11561 {
11562 case STO_ALPHA_NOPV: return "NOPV";
11563 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11564 default:
27a45f42 11565 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11566 return _("<unknown>");
9abca702 11567 }
2057d69d
CZ
11568}
11569
fd85a6a1
NC
11570static const char *
11571get_solaris_symbol_visibility (unsigned int visibility)
11572{
11573 switch (visibility)
11574 {
11575 case 4: return "EXPORTED";
11576 case 5: return "SINGLETON";
11577 case 6: return "ELIMINATE";
11578 default: return get_symbol_visibility (visibility);
11579 }
11580}
11581
2301ed1c
SN
11582static const char *
11583get_aarch64_symbol_other (unsigned int other)
11584{
11585 static char buf[32];
11586
11587 if (other & STO_AARCH64_VARIANT_PCS)
11588 {
11589 other &= ~STO_AARCH64_VARIANT_PCS;
11590 if (other == 0)
11591 return "VARIANT_PCS";
11592 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
11593 return buf;
11594 }
11595 return NULL;
11596}
11597
5e2b0d47
NC
11598static const char *
11599get_mips_symbol_other (unsigned int other)
11600{
11601 switch (other)
11602 {
32ec8896
NC
11603 case STO_OPTIONAL: return "OPTIONAL";
11604 case STO_MIPS_PLT: return "MIPS PLT";
11605 case STO_MIPS_PIC: return "MIPS PIC";
11606 case STO_MICROMIPS: return "MICROMIPS";
11607 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11608 case STO_MIPS16: return "MIPS16";
11609 default: return NULL;
5e2b0d47
NC
11610 }
11611}
11612
28f997cf 11613static const char *
dda8d76d 11614get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11615{
dda8d76d 11616 if (is_ia64_vms (filedata))
28f997cf
TG
11617 {
11618 static char res[32];
11619
11620 res[0] = 0;
11621
11622 /* Function types is for images and .STB files only. */
dda8d76d 11623 switch (filedata->file_header.e_type)
28f997cf
TG
11624 {
11625 case ET_DYN:
11626 case ET_EXEC:
11627 switch (VMS_ST_FUNC_TYPE (other))
11628 {
11629 case VMS_SFT_CODE_ADDR:
11630 strcat (res, " CA");
11631 break;
11632 case VMS_SFT_SYMV_IDX:
11633 strcat (res, " VEC");
11634 break;
11635 case VMS_SFT_FD:
11636 strcat (res, " FD");
11637 break;
11638 case VMS_SFT_RESERVE:
11639 strcat (res, " RSV");
11640 break;
11641 default:
bee0ee85
NC
11642 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11643 VMS_ST_FUNC_TYPE (other));
11644 strcat (res, " <unknown>");
11645 break;
28f997cf
TG
11646 }
11647 break;
11648 default:
11649 break;
11650 }
11651 switch (VMS_ST_LINKAGE (other))
11652 {
11653 case VMS_STL_IGNORE:
11654 strcat (res, " IGN");
11655 break;
11656 case VMS_STL_RESERVE:
11657 strcat (res, " RSV");
11658 break;
11659 case VMS_STL_STD:
11660 strcat (res, " STD");
11661 break;
11662 case VMS_STL_LNK:
11663 strcat (res, " LNK");
11664 break;
11665 default:
bee0ee85
NC
11666 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11667 VMS_ST_LINKAGE (other));
11668 strcat (res, " <unknown>");
11669 break;
28f997cf
TG
11670 }
11671
11672 if (res[0] != 0)
11673 return res + 1;
11674 else
11675 return res;
11676 }
11677 return NULL;
11678}
11679
6911b7dc
AM
11680static const char *
11681get_ppc64_symbol_other (unsigned int other)
11682{
14732552
AM
11683 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11684 return NULL;
11685
11686 other >>= STO_PPC64_LOCAL_BIT;
11687 if (other <= 6)
6911b7dc 11688 {
89246a0e 11689 static char buf[64];
14732552
AM
11690 if (other >= 2)
11691 other = ppc64_decode_local_entry (other);
11692 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11693 return buf;
11694 }
11695 return NULL;
11696}
11697
5e2b0d47 11698static const char *
dda8d76d 11699get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11700{
11701 const char * result = NULL;
89246a0e 11702 static char buff [64];
5e2b0d47
NC
11703
11704 if (other == 0)
11705 return "";
11706
dda8d76d 11707 switch (filedata->file_header.e_machine)
5e2b0d47 11708 {
2057d69d
CZ
11709 case EM_ALPHA:
11710 result = get_alpha_symbol_other (other);
11711 break;
2301ed1c
SN
11712 case EM_AARCH64:
11713 result = get_aarch64_symbol_other (other);
11714 break;
5e2b0d47
NC
11715 case EM_MIPS:
11716 result = get_mips_symbol_other (other);
28f997cf
TG
11717 break;
11718 case EM_IA_64:
dda8d76d 11719 result = get_ia64_symbol_other (filedata, other);
28f997cf 11720 break;
6911b7dc
AM
11721 case EM_PPC64:
11722 result = get_ppc64_symbol_other (other);
11723 break;
5e2b0d47 11724 default:
fd85a6a1 11725 result = NULL;
5e2b0d47
NC
11726 break;
11727 }
11728
11729 if (result)
11730 return result;
11731
11732 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11733 return buff;
11734}
11735
d1133906 11736static const char *
dda8d76d 11737get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11738{
b34976b6 11739 static char buff[32];
5cf1065c 11740
252b5132
RH
11741 switch (type)
11742 {
b34976b6
AM
11743 case SHN_UNDEF: return "UND";
11744 case SHN_ABS: return "ABS";
11745 case SHN_COMMON: return "COM";
252b5132 11746 default:
9ce701e2 11747 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
11748 && filedata->file_header.e_machine == EM_IA_64
11749 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
11750 return "ANSI_COM";
11751 else if ((filedata->file_header.e_machine == EM_X86_64
11752 || filedata->file_header.e_machine == EM_L1OM
11753 || filedata->file_header.e_machine == EM_K1OM)
11754 && type == SHN_X86_64_LCOMMON)
11755 return "LARGE_COM";
11756 else if ((type == SHN_MIPS_SCOMMON
11757 && filedata->file_header.e_machine == EM_MIPS)
11758 || (type == SHN_TIC6X_SCOMMON
11759 && filedata->file_header.e_machine == EM_TI_C6000))
11760 return "SCOM";
11761 else if (type == SHN_MIPS_SUNDEFINED
11762 && filedata->file_header.e_machine == EM_MIPS)
11763 return "SUND";
11764 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
11765 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
11766 else if (type >= SHN_LOOS && type <= SHN_HIOS)
11767 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11768 else if (type >= SHN_LORESERVE)
11769 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
11770 else if (filedata->file_header.e_shnum != 0
11771 && type >= filedata->file_header.e_shnum)
11772 sprintf (buff, _("bad section index[%3d]"), type);
11773 else
11774 sprintf (buff, "%3d", type);
11775 break;
fd85a6a1
NC
11776 }
11777
10ca4b04 11778 return buff;
6bd1a22c
L
11779}
11780
bb4d2ac2 11781static const char *
dda8d76d 11782get_symbol_version_string (Filedata * filedata,
1449284b
NC
11783 bfd_boolean is_dynsym,
11784 const char * strtab,
11785 unsigned long int strtab_size,
11786 unsigned int si,
11787 Elf_Internal_Sym * psym,
11788 enum versioned_symbol_info * sym_info,
11789 unsigned short * vna_other)
bb4d2ac2 11790{
ab273396
AM
11791 unsigned char data[2];
11792 unsigned short vers_data;
11793 unsigned long offset;
7a815dd5 11794 unsigned short max_vd_ndx;
bb4d2ac2 11795
ab273396
AM
11796 if (!is_dynsym
11797 || version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
11798 return NULL;
bb4d2ac2 11799
dda8d76d 11800 offset = offset_from_vma (filedata, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11801 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11802
dda8d76d 11803 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11804 sizeof (data), 1, _("version data")) == NULL)
11805 return NULL;
11806
11807 vers_data = byte_get (data, 2);
bb4d2ac2 11808
1f6f5dba 11809 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11810 return NULL;
bb4d2ac2 11811
0b8b7609 11812 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
11813 max_vd_ndx = 0;
11814
ab273396
AM
11815 /* Usually we'd only see verdef for defined symbols, and verneed for
11816 undefined symbols. However, symbols defined by the linker in
11817 .dynbss for variables copied from a shared library in order to
11818 avoid text relocations are defined yet have verneed. We could
11819 use a heuristic to detect the special case, for example, check
11820 for verneed first on symbols defined in SHT_NOBITS sections, but
11821 it is simpler and more reliable to just look for both verdef and
11822 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11823
ab273396
AM
11824 if (psym->st_shndx != SHN_UNDEF
11825 && vers_data != 0x8001
11826 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
11827 {
11828 Elf_Internal_Verdef ivd;
11829 Elf_Internal_Verdaux ivda;
11830 Elf_External_Verdaux evda;
11831 unsigned long off;
bb4d2ac2 11832
dda8d76d 11833 off = offset_from_vma (filedata,
ab273396
AM
11834 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
11835 sizeof (Elf_External_Verdef));
11836
11837 do
bb4d2ac2 11838 {
ab273396
AM
11839 Elf_External_Verdef evd;
11840
dda8d76d 11841 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11842 _("version def")) == NULL)
11843 {
11844 ivd.vd_ndx = 0;
11845 ivd.vd_aux = 0;
11846 ivd.vd_next = 0;
1f6f5dba 11847 ivd.vd_flags = 0;
ab273396
AM
11848 }
11849 else
bb4d2ac2 11850 {
ab273396
AM
11851 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11852 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11853 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 11854 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 11855 }
bb4d2ac2 11856
7a815dd5
L
11857 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
11858 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
11859
ab273396
AM
11860 off += ivd.vd_next;
11861 }
11862 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11863
ab273396
AM
11864 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11865 {
9abca702 11866 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
11867 return NULL;
11868
ab273396
AM
11869 off -= ivd.vd_next;
11870 off += ivd.vd_aux;
bb4d2ac2 11871
dda8d76d 11872 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
11873 _("version def aux")) != NULL)
11874 {
11875 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 11876
ab273396 11877 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
11878 return (ivda.vda_name < strtab_size
11879 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
11880 }
11881 }
11882 }
bb4d2ac2 11883
ab273396
AM
11884 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
11885 {
11886 Elf_External_Verneed evn;
11887 Elf_Internal_Verneed ivn;
11888 Elf_Internal_Vernaux ivna;
bb4d2ac2 11889
dda8d76d 11890 offset = offset_from_vma (filedata,
ab273396
AM
11891 version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
11892 sizeof evn);
11893 do
11894 {
11895 unsigned long vna_off;
bb4d2ac2 11896
dda8d76d 11897 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
11898 _("version need")) == NULL)
11899 {
11900 ivna.vna_next = 0;
11901 ivna.vna_other = 0;
11902 ivna.vna_name = 0;
11903 break;
11904 }
bb4d2ac2 11905
ab273396
AM
11906 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11907 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 11908
ab273396 11909 vna_off = offset + ivn.vn_aux;
bb4d2ac2 11910
ab273396
AM
11911 do
11912 {
11913 Elf_External_Vernaux evna;
bb4d2ac2 11914
dda8d76d 11915 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 11916 _("version need aux (3)")) == NULL)
bb4d2ac2 11917 {
ab273396
AM
11918 ivna.vna_next = 0;
11919 ivna.vna_other = 0;
11920 ivna.vna_name = 0;
bb4d2ac2 11921 }
bb4d2ac2 11922 else
bb4d2ac2 11923 {
ab273396
AM
11924 ivna.vna_other = BYTE_GET (evna.vna_other);
11925 ivna.vna_next = BYTE_GET (evna.vna_next);
11926 ivna.vna_name = BYTE_GET (evna.vna_name);
11927 }
bb4d2ac2 11928
ab273396
AM
11929 vna_off += ivna.vna_next;
11930 }
11931 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 11932
ab273396
AM
11933 if (ivna.vna_other == vers_data)
11934 break;
bb4d2ac2 11935
ab273396
AM
11936 offset += ivn.vn_next;
11937 }
11938 while (ivn.vn_next != 0);
bb4d2ac2 11939
ab273396
AM
11940 if (ivna.vna_other == vers_data)
11941 {
11942 *sym_info = symbol_undefined;
11943 *vna_other = ivna.vna_other;
11944 return (ivna.vna_name < strtab_size
11945 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 11946 }
7a815dd5
L
11947 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
11948 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
11949 return _("<corrupt>");
bb4d2ac2 11950 }
ab273396 11951 return NULL;
bb4d2ac2
L
11952}
11953
10ca4b04
L
11954static void
11955print_dynamic_symbol (Filedata *filedata, unsigned long si,
11956 Elf_Internal_Sym *symtab,
11957 Elf_Internal_Shdr *section,
11958 char *strtab, size_t strtab_size)
252b5132 11959{
10ca4b04
L
11960 const char *version_string;
11961 enum versioned_symbol_info sym_info;
11962 unsigned short vna_other;
11963 Elf_Internal_Sym *psym = symtab + si;
252b5132 11964
10ca4b04
L
11965 printf ("%6ld: ", si);
11966 print_vma (psym->st_value, LONG_HEX);
11967 putchar (' ');
11968 print_vma (psym->st_size, DEC_5);
11969 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11970 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
11971 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
11972 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11973 else
252b5132 11974 {
10ca4b04 11975 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 11976
10ca4b04
L
11977 printf (" %-7s", get_symbol_visibility (vis));
11978 /* Check to see if any other bits in the st_other field are set.
11979 Note - displaying this information disrupts the layout of the
11980 table being generated, but for the moment this case is very rare. */
11981 if (psym->st_other ^ vis)
11982 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 11983 }
10ca4b04
L
11984 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
11985 print_symbol (25, VALID_SYMBOL_NAME (strtab, strtab_size,
11986 psym->st_name)
11987 ? strtab + psym->st_name : _("<corrupt>"));
11988
11989 version_string
11990 = get_symbol_version_string (filedata,
11991 (section == NULL
11992 || section->sh_type == SHT_DYNSYM),
11993 strtab, strtab_size, si,
11994 psym, &sym_info, &vna_other);
11995 if (version_string)
11996 {
11997 if (sym_info == symbol_undefined)
11998 printf ("@%s (%d)", version_string, vna_other);
f7a99963 11999 else
10ca4b04
L
12000 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12001 version_string);
12002 }
6bd1a22c 12003
10ca4b04 12004 putchar ('\n');
6bd1a22c 12005
10ca4b04
L
12006 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12007 && section != NULL
12008 && si >= section->sh_info
12009 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12010 && filedata->file_header.e_machine != EM_MIPS
12011 /* Solaris binaries have been found to violate this requirement as
12012 well. Not sure if this is a bug or an ABI requirement. */
12013 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12014 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12015 si, printable_section_name (filedata, section), section->sh_info);
12016}
f16a9783 12017
10ca4b04
L
12018/* Dump the symbol table. */
12019static bfd_boolean
12020process_symbol_table (Filedata * filedata)
12021{
12022 Elf_Internal_Shdr * section;
f16a9783 12023
10ca4b04
L
12024 if (!do_syms && !do_dyn_syms && !do_histogram)
12025 return TRUE;
6bd1a22c
L
12026
12027 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
12028 && do_syms
12029 && do_using_dynamic
3102e897
NC
12030 && dynamic_strings != NULL
12031 && dynamic_symbols != NULL)
6bd1a22c 12032 {
10ca4b04 12033 unsigned long si;
6bd1a22c 12034
10ca4b04
L
12035 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12036 "\nSymbol table for image contains %lu entries:\n",
12037 num_dynamic_syms), num_dynamic_syms);
12038 if (is_32bit_elf)
12039 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12040 else
12041 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12042
10ca4b04
L
12043 for (si = 0; si < num_dynamic_syms; si++)
12044 print_dynamic_symbol (filedata, si, dynamic_symbols, NULL,
12045 dynamic_strings, dynamic_strings_length);
252b5132 12046 }
8b73c356 12047 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12048 && filedata->section_headers != NULL)
252b5132 12049 {
b34976b6 12050 unsigned int i;
252b5132 12051
dda8d76d
NC
12052 for (i = 0, section = filedata->section_headers;
12053 i < filedata->file_header.e_shnum;
252b5132
RH
12054 i++, section++)
12055 {
2cf0635d 12056 char * strtab = NULL;
c256ffe7 12057 unsigned long int strtab_size = 0;
2cf0635d 12058 Elf_Internal_Sym * symtab;
ef3df110 12059 unsigned long si, num_syms;
252b5132 12060
2c610e4b
L
12061 if ((section->sh_type != SHT_SYMTAB
12062 && section->sh_type != SHT_DYNSYM)
12063 || (!do_syms
12064 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12065 continue;
12066
dd24e3da
NC
12067 if (section->sh_entsize == 0)
12068 {
12069 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12070 printable_section_name (filedata, section));
dd24e3da
NC
12071 continue;
12072 }
12073
d3a49aa8
AM
12074 num_syms = section->sh_size / section->sh_entsize;
12075 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12076 "\nSymbol table '%s' contains %lu entries:\n",
12077 num_syms),
dda8d76d 12078 printable_section_name (filedata, section),
d3a49aa8 12079 num_syms);
dd24e3da 12080
f7a99963 12081 if (is_32bit_elf)
ca47b30c 12082 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12083 else
ca47b30c 12084 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12085
dda8d76d 12086 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12087 if (symtab == NULL)
12088 continue;
12089
dda8d76d 12090 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12091 {
dda8d76d
NC
12092 strtab = filedata->string_table;
12093 strtab_size = filedata->string_table_length;
c256ffe7 12094 }
dda8d76d 12095 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12096 {
2cf0635d 12097 Elf_Internal_Shdr * string_sec;
252b5132 12098
dda8d76d 12099 string_sec = filedata->section_headers + section->sh_link;
252b5132 12100
dda8d76d 12101 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12102 1, string_sec->sh_size,
12103 _("string table"));
c256ffe7 12104 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12105 }
12106
10ca4b04
L
12107 for (si = 0; si < num_syms; si++)
12108 print_dynamic_symbol (filedata, si, symtab, section,
12109 strtab, strtab_size);
252b5132
RH
12110
12111 free (symtab);
dda8d76d 12112 if (strtab != filedata->string_table)
252b5132
RH
12113 free (strtab);
12114 }
12115 }
12116 else if (do_syms)
12117 printf
12118 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12119
12120 if (do_histogram && buckets != NULL)
12121 {
2cf0635d
NC
12122 unsigned long * lengths;
12123 unsigned long * counts;
66543521
AM
12124 unsigned long hn;
12125 bfd_vma si;
12126 unsigned long maxlength = 0;
12127 unsigned long nzero_counts = 0;
12128 unsigned long nsyms = 0;
6bd6a03d 12129 char *visited;
252b5132 12130
d3a49aa8
AM
12131 printf (ngettext ("\nHistogram for bucket list length "
12132 "(total of %lu bucket):\n",
12133 "\nHistogram for bucket list length "
12134 "(total of %lu buckets):\n",
12135 (unsigned long) nbuckets),
66543521 12136 (unsigned long) nbuckets);
252b5132 12137
3f5e193b 12138 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
12139 if (lengths == NULL)
12140 {
8b73c356 12141 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12142 goto err_out;
252b5132 12143 }
6bd6a03d
AM
12144 visited = xcmalloc (nchains, 1);
12145 memset (visited, 0, nchains);
8b73c356
NC
12146
12147 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
12148 for (hn = 0; hn < nbuckets; ++hn)
12149 {
6bd6a03d 12150 for (si = buckets[hn]; si > 0; si = chains[si])
252b5132 12151 {
b34976b6 12152 ++nsyms;
252b5132 12153 if (maxlength < ++lengths[hn])
b34976b6 12154 ++maxlength;
6bd6a03d
AM
12155 if (si >= nchains || visited[si])
12156 {
12157 error (_("histogram chain is corrupt\n"));
12158 break;
12159 }
12160 visited[si] = 1;
252b5132
RH
12161 }
12162 }
6bd6a03d 12163 free (visited);
252b5132 12164
3f5e193b 12165 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12166 if (counts == NULL)
12167 {
b2e951ec 12168 free (lengths);
8b73c356 12169 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12170 goto err_out;
252b5132
RH
12171 }
12172
12173 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 12174 ++counts[lengths[hn]];
252b5132 12175
103f02d3 12176 if (nbuckets > 0)
252b5132 12177 {
66543521
AM
12178 unsigned long i;
12179 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 12180 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 12181 for (i = 1; i <= maxlength; ++i)
103f02d3 12182 {
66543521
AM
12183 nzero_counts += counts[i] * i;
12184 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
12185 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
12186 (nzero_counts * 100.0) / nsyms);
12187 }
252b5132
RH
12188 }
12189
12190 free (counts);
12191 free (lengths);
12192 }
12193
fd486f32
AM
12194 free (buckets);
12195 buckets = NULL;
a5e0be5c 12196 nbuckets = 0;
fd486f32
AM
12197 free (chains);
12198 chains = NULL;
252b5132 12199
d3a44ec6 12200 if (do_histogram && gnubuckets != NULL)
fdc90cb4 12201 {
2cf0635d
NC
12202 unsigned long * lengths;
12203 unsigned long * counts;
fdc90cb4
JJ
12204 unsigned long hn;
12205 unsigned long maxlength = 0;
12206 unsigned long nzero_counts = 0;
12207 unsigned long nsyms = 0;
fdc90cb4 12208
f16a9783 12209 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12210 "(total of %lu bucket):\n",
f16a9783 12211 "\nHistogram for `%s' bucket list length "
d3a49aa8
AM
12212 "(total of %lu buckets):\n",
12213 (unsigned long) ngnubuckets),
f16a9783 12214 GNU_HASH_SECTION_NAME,
8b73c356
NC
12215 (unsigned long) ngnubuckets);
12216
3f5e193b 12217 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
12218 if (lengths == NULL)
12219 {
8b73c356 12220 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12221 goto err_out;
fdc90cb4
JJ
12222 }
12223
fdc90cb4
JJ
12224 printf (_(" Length Number %% of total Coverage\n"));
12225
12226 for (hn = 0; hn < ngnubuckets; ++hn)
12227 if (gnubuckets[hn] != 0)
12228 {
12229 bfd_vma off, length = 1;
12230
6bd1a22c 12231 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
12232 /* PR 17531 file: 010-77222-0.004. */
12233 off < ngnuchains && (gnuchains[off] & 1) == 0;
12234 ++off)
fdc90cb4
JJ
12235 ++length;
12236 lengths[hn] = length;
12237 if (length > maxlength)
12238 maxlength = length;
12239 nsyms += length;
12240 }
12241
3f5e193b 12242 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12243 if (counts == NULL)
12244 {
b2e951ec 12245 free (lengths);
8b73c356 12246 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12247 goto err_out;
fdc90cb4
JJ
12248 }
12249
12250 for (hn = 0; hn < ngnubuckets; ++hn)
12251 ++counts[lengths[hn]];
12252
12253 if (ngnubuckets > 0)
12254 {
12255 unsigned long j;
12256 printf (" 0 %-10lu (%5.1f%%)\n",
12257 counts[0], (counts[0] * 100.0) / ngnubuckets);
12258 for (j = 1; j <= maxlength; ++j)
12259 {
12260 nzero_counts += counts[j] * j;
12261 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
12262 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
12263 (nzero_counts * 100.0) / nsyms);
12264 }
12265 }
12266
12267 free (counts);
12268 free (lengths);
fdc90cb4 12269 }
fd486f32 12270 free (gnubuckets);
b71d4fa7 12271 gnubuckets = NULL;
a5e0be5c 12272 ngnubuckets = 0;
fd486f32 12273 free (gnuchains);
b71d4fa7 12274 gnuchains = NULL;
a5e0be5c 12275 ngnuchains = 0;
fd486f32 12276 free (mipsxlat);
b71d4fa7 12277 mipsxlat = NULL;
32ec8896 12278 return TRUE;
fd486f32
AM
12279
12280 err_out:
12281 free (gnubuckets);
b71d4fa7 12282 gnubuckets = NULL;
a5e0be5c 12283 ngnubuckets = 0;
fd486f32 12284 free (gnuchains);
b71d4fa7 12285 gnuchains = NULL;
3052c068 12286 ngnuchains = 0;
fd486f32 12287 free (mipsxlat);
b71d4fa7 12288 mipsxlat = NULL;
fd486f32 12289 free (buckets);
b71d4fa7 12290 buckets = NULL;
a5e0be5c 12291 nbuckets = 0;
fd486f32 12292 free (chains);
b71d4fa7 12293 chains = NULL;
fd486f32 12294 return FALSE;
252b5132
RH
12295}
12296
32ec8896 12297static bfd_boolean
dda8d76d 12298process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12299{
b4c96d0d 12300 unsigned int i;
252b5132
RH
12301
12302 if (dynamic_syminfo == NULL
12303 || !do_dynamic)
12304 /* No syminfo, this is ok. */
32ec8896 12305 return TRUE;
252b5132
RH
12306
12307 /* There better should be a dynamic symbol section. */
12308 if (dynamic_symbols == NULL || dynamic_strings == NULL)
32ec8896 12309 return FALSE;
252b5132
RH
12310
12311 if (dynamic_addr)
d3a49aa8
AM
12312 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12313 "contains %d entry:\n",
12314 "\nDynamic info segment at offset 0x%lx "
12315 "contains %d entries:\n",
12316 dynamic_syminfo_nent),
252b5132
RH
12317 dynamic_syminfo_offset, dynamic_syminfo_nent);
12318
12319 printf (_(" Num: Name BoundTo Flags\n"));
12320 for (i = 0; i < dynamic_syminfo_nent; ++i)
12321 {
12322 unsigned short int flags = dynamic_syminfo[i].si_flags;
12323
31104126 12324 printf ("%4d: ", i);
4082ef84
NC
12325 if (i >= num_dynamic_syms)
12326 printf (_("<corrupt index>"));
12327 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
12328 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
12329 else
2b692964 12330 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 12331 putchar (' ');
252b5132
RH
12332
12333 switch (dynamic_syminfo[i].si_boundto)
12334 {
12335 case SYMINFO_BT_SELF:
12336 fputs ("SELF ", stdout);
12337 break;
12338 case SYMINFO_BT_PARENT:
12339 fputs ("PARENT ", stdout);
12340 break;
12341 default:
12342 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
12343 && dynamic_syminfo[i].si_boundto < dynamic_nent
12344 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12345 {
d79b3d50 12346 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12347 putchar (' ' );
12348 }
252b5132
RH
12349 else
12350 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
12351 break;
12352 }
12353
12354 if (flags & SYMINFO_FLG_DIRECT)
12355 printf (" DIRECT");
12356 if (flags & SYMINFO_FLG_PASSTHRU)
12357 printf (" PASSTHRU");
12358 if (flags & SYMINFO_FLG_COPY)
12359 printf (" COPY");
12360 if (flags & SYMINFO_FLG_LAZYLOAD)
12361 printf (" LAZYLOAD");
12362
12363 puts ("");
12364 }
12365
32ec8896 12366 return TRUE;
252b5132
RH
12367}
12368
75802ccb
CE
12369/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
12370 is contained by the region START .. END. The types of ADDR, START
12371 and END should all be the same. Note both ADDR + NELEM and END
12372 point to just beyond the end of the regions that are being tested. */
12373#define IN_RANGE(START,END,ADDR,NELEM) \
12374 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 12375
cf13d699
NC
12376/* Check to see if the given reloc needs to be handled in a target specific
12377 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12378 FALSE.
12379
12380 If called with reloc == NULL, then this is a signal that reloc processing
12381 for the current section has finished, and any saved state should be
12382 discarded. */
09c11c86 12383
cf13d699 12384static bfd_boolean
dda8d76d
NC
12385target_specific_reloc_handling (Filedata * filedata,
12386 Elf_Internal_Rela * reloc,
12387 unsigned char * start,
12388 unsigned char * end,
12389 Elf_Internal_Sym * symtab,
12390 unsigned long num_syms)
252b5132 12391{
f84ce13b
NC
12392 unsigned int reloc_type = 0;
12393 unsigned long sym_index = 0;
12394
12395 if (reloc)
12396 {
dda8d76d 12397 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12398 sym_index = get_reloc_symindex (reloc->r_info);
12399 }
252b5132 12400
dda8d76d 12401 switch (filedata->file_header.e_machine)
252b5132 12402 {
13761a11
NC
12403 case EM_MSP430:
12404 case EM_MSP430_OLD:
12405 {
12406 static Elf_Internal_Sym * saved_sym = NULL;
12407
f84ce13b
NC
12408 if (reloc == NULL)
12409 {
12410 saved_sym = NULL;
12411 return TRUE;
12412 }
12413
13761a11
NC
12414 switch (reloc_type)
12415 {
12416 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12417 if (uses_msp430x_relocs (filedata))
13761a11 12418 break;
1a0670f3 12419 /* Fall through. */
13761a11 12420 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12421 /* PR 21139. */
12422 if (sym_index >= num_syms)
12423 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12424 sym_index);
12425 else
12426 saved_sym = symtab + sym_index;
13761a11
NC
12427 return TRUE;
12428
12429 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12430 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12431 goto handle_sym_diff;
0b4362b0 12432
13761a11
NC
12433 case 5: /* R_MSP430_16_BYTE */
12434 case 9: /* R_MSP430_8 */
dda8d76d 12435 if (uses_msp430x_relocs (filedata))
13761a11
NC
12436 break;
12437 goto handle_sym_diff;
12438
12439 case 2: /* R_MSP430_ABS16 */
12440 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12441 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12442 break;
12443 goto handle_sym_diff;
0b4362b0 12444
13761a11
NC
12445 handle_sym_diff:
12446 if (saved_sym != NULL)
12447 {
03f7786e 12448 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12449 bfd_vma value;
12450
f84ce13b
NC
12451 if (sym_index >= num_syms)
12452 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12453 sym_index);
03f7786e 12454 else
f84ce13b
NC
12455 {
12456 value = reloc->r_addend + (symtab[sym_index].st_value
12457 - saved_sym->st_value);
12458
b32e566b 12459 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12460 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12461 else
12462 /* PR 21137 */
12463 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12464 (long) reloc->r_offset);
f84ce13b 12465 }
13761a11
NC
12466
12467 saved_sym = NULL;
12468 return TRUE;
12469 }
12470 break;
12471
12472 default:
12473 if (saved_sym != NULL)
071436c6 12474 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12475 break;
12476 }
12477 break;
12478 }
12479
cf13d699
NC
12480 case EM_MN10300:
12481 case EM_CYGNUS_MN10300:
12482 {
12483 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12484
f84ce13b
NC
12485 if (reloc == NULL)
12486 {
12487 saved_sym = NULL;
12488 return TRUE;
12489 }
12490
cf13d699
NC
12491 switch (reloc_type)
12492 {
12493 case 34: /* R_MN10300_ALIGN */
12494 return TRUE;
12495 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12496 if (sym_index >= num_syms)
12497 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12498 sym_index);
12499 else
12500 saved_sym = symtab + sym_index;
cf13d699 12501 return TRUE;
f84ce13b 12502
cf13d699
NC
12503 case 1: /* R_MN10300_32 */
12504 case 2: /* R_MN10300_16 */
12505 if (saved_sym != NULL)
12506 {
03f7786e 12507 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12508 bfd_vma value;
252b5132 12509
f84ce13b
NC
12510 if (sym_index >= num_syms)
12511 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12512 sym_index);
03f7786e 12513 else
f84ce13b
NC
12514 {
12515 value = reloc->r_addend + (symtab[sym_index].st_value
12516 - saved_sym->st_value);
12517
b32e566b 12518 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12519 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12520 else
12521 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12522 (long) reloc->r_offset);
f84ce13b 12523 }
252b5132 12524
cf13d699
NC
12525 saved_sym = NULL;
12526 return TRUE;
12527 }
12528 break;
12529 default:
12530 if (saved_sym != NULL)
071436c6 12531 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12532 break;
12533 }
12534 break;
12535 }
6ff71e76
NC
12536
12537 case EM_RL78:
12538 {
12539 static bfd_vma saved_sym1 = 0;
12540 static bfd_vma saved_sym2 = 0;
12541 static bfd_vma value;
12542
f84ce13b
NC
12543 if (reloc == NULL)
12544 {
12545 saved_sym1 = saved_sym2 = 0;
12546 return TRUE;
12547 }
12548
6ff71e76
NC
12549 switch (reloc_type)
12550 {
12551 case 0x80: /* R_RL78_SYM. */
12552 saved_sym1 = saved_sym2;
f84ce13b
NC
12553 if (sym_index >= num_syms)
12554 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12555 sym_index);
12556 else
12557 {
12558 saved_sym2 = symtab[sym_index].st_value;
12559 saved_sym2 += reloc->r_addend;
12560 }
6ff71e76
NC
12561 return TRUE;
12562
12563 case 0x83: /* R_RL78_OPsub. */
12564 value = saved_sym1 - saved_sym2;
12565 saved_sym2 = saved_sym1 = 0;
12566 return TRUE;
12567 break;
12568
12569 case 0x41: /* R_RL78_ABS32. */
b32e566b 12570 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12571 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12572 else
12573 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12574 (long) reloc->r_offset);
6ff71e76
NC
12575 value = 0;
12576 return TRUE;
12577
12578 case 0x43: /* R_RL78_ABS16. */
b32e566b 12579 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12580 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12581 else
12582 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12583 (long) reloc->r_offset);
6ff71e76
NC
12584 value = 0;
12585 return TRUE;
12586
12587 default:
12588 break;
12589 }
12590 break;
12591 }
252b5132
RH
12592 }
12593
cf13d699 12594 return FALSE;
252b5132
RH
12595}
12596
aca88567
NC
12597/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12598 DWARF debug sections. This is a target specific test. Note - we do not
12599 go through the whole including-target-headers-multiple-times route, (as
12600 we have already done with <elf/h8.h>) because this would become very
12601 messy and even then this function would have to contain target specific
12602 information (the names of the relocs instead of their numeric values).
12603 FIXME: This is not the correct way to solve this problem. The proper way
12604 is to have target specific reloc sizing and typing functions created by
12605 the reloc-macros.h header, in the same way that it already creates the
12606 reloc naming functions. */
12607
12608static bfd_boolean
dda8d76d 12609is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12610{
d347c9df 12611 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12612 switch (filedata->file_header.e_machine)
aca88567 12613 {
41e92641 12614 case EM_386:
22abe556 12615 case EM_IAMCU:
41e92641 12616 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12617 case EM_68K:
12618 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12619 case EM_860:
12620 return reloc_type == 1; /* R_860_32. */
12621 case EM_960:
12622 return reloc_type == 2; /* R_960_32. */
a06ea964 12623 case EM_AARCH64:
9282b95a
JW
12624 return (reloc_type == 258
12625 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
12626 case EM_BPF:
12627 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
12628 case EM_ADAPTEVA_EPIPHANY:
12629 return reloc_type == 3;
aca88567 12630 case EM_ALPHA:
137b6b5f 12631 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12632 case EM_ARC:
12633 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12634 case EM_ARC_COMPACT:
12635 case EM_ARC_COMPACT2:
12636 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12637 case EM_ARM:
12638 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12639 case EM_AVR_OLD:
aca88567
NC
12640 case EM_AVR:
12641 return reloc_type == 1;
12642 case EM_BLACKFIN:
12643 return reloc_type == 0x12; /* R_byte4_data. */
12644 case EM_CRIS:
12645 return reloc_type == 3; /* R_CRIS_32. */
12646 case EM_CR16:
12647 return reloc_type == 3; /* R_CR16_NUM32. */
12648 case EM_CRX:
12649 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
12650 case EM_CSKY:
12651 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
12652 case EM_CYGNUS_FRV:
12653 return reloc_type == 1;
41e92641
NC
12654 case EM_CYGNUS_D10V:
12655 case EM_D10V:
12656 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12657 case EM_CYGNUS_D30V:
12658 case EM_D30V:
12659 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12660 case EM_DLX:
12661 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12662 case EM_CYGNUS_FR30:
12663 case EM_FR30:
12664 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12665 case EM_FT32:
12666 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12667 case EM_H8S:
12668 case EM_H8_300:
12669 case EM_H8_300H:
12670 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12671 case EM_IA_64:
262cdac7
AM
12672 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12673 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12674 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12675 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12676 case EM_IP2K_OLD:
12677 case EM_IP2K:
12678 return reloc_type == 2; /* R_IP2K_32. */
12679 case EM_IQ2000:
12680 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12681 case EM_LATTICEMICO32:
12682 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12683 case EM_M32C_OLD:
aca88567
NC
12684 case EM_M32C:
12685 return reloc_type == 3; /* R_M32C_32. */
12686 case EM_M32R:
12687 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12688 case EM_68HC11:
12689 case EM_68HC12:
12690 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 12691 case EM_S12Z:
2849d19f
JD
12692 return reloc_type == 7 || /* R_S12Z_EXT32 */
12693 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
12694 case EM_MCORE:
12695 return reloc_type == 1; /* R_MCORE_ADDR32. */
12696 case EM_CYGNUS_MEP:
12697 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12698 case EM_METAG:
12699 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12700 case EM_MICROBLAZE:
12701 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12702 case EM_MIPS:
12703 return reloc_type == 2; /* R_MIPS_32. */
12704 case EM_MMIX:
12705 return reloc_type == 4; /* R_MMIX_32. */
12706 case EM_CYGNUS_MN10200:
12707 case EM_MN10200:
12708 return reloc_type == 1; /* R_MN10200_32. */
12709 case EM_CYGNUS_MN10300:
12710 case EM_MN10300:
12711 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12712 case EM_MOXIE:
12713 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12714 case EM_MSP430_OLD:
12715 case EM_MSP430:
13761a11 12716 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12717 case EM_MT:
12718 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12719 case EM_NDS32:
12720 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12721 case EM_ALTERA_NIOS2:
36591ba1 12722 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12723 case EM_NIOS32:
12724 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12725 case EM_OR1K:
12726 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12727 case EM_PARISC:
9abca702 12728 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 12729 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12730 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12731 case EM_PJ:
12732 case EM_PJ_OLD:
12733 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12734 case EM_PPC64:
12735 return reloc_type == 1; /* R_PPC64_ADDR32. */
12736 case EM_PPC:
12737 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12738 case EM_TI_PRU:
12739 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12740 case EM_RISCV:
12741 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12742 case EM_RL78:
12743 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12744 case EM_RX:
12745 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12746 case EM_S370:
12747 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12748 case EM_S390_OLD:
12749 case EM_S390:
12750 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12751 case EM_SCORE:
12752 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12753 case EM_SH:
12754 return reloc_type == 1; /* R_SH_DIR32. */
12755 case EM_SPARC32PLUS:
12756 case EM_SPARCV9:
12757 case EM_SPARC:
12758 return reloc_type == 3 /* R_SPARC_32. */
12759 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12760 case EM_SPU:
12761 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12762 case EM_TI_C6000:
12763 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12764 case EM_TILEGX:
12765 return reloc_type == 2; /* R_TILEGX_32. */
12766 case EM_TILEPRO:
12767 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12768 case EM_CYGNUS_V850:
12769 case EM_V850:
12770 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12771 case EM_V800:
12772 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12773 case EM_VAX:
12774 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12775 case EM_VISIUM:
12776 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12777 case EM_WEBASSEMBLY:
12778 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12779 case EM_X86_64:
8a9036a4 12780 case EM_L1OM:
7a9068fe 12781 case EM_K1OM:
aca88567 12782 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12783 case EM_XC16X:
12784 case EM_C166:
12785 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12786 case EM_XGATE:
12787 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12788 case EM_XSTORMY16:
12789 return reloc_type == 1; /* R_XSTROMY16_32. */
12790 case EM_XTENSA_OLD:
12791 case EM_XTENSA:
12792 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
12793 case EM_Z80:
12794 return reloc_type == 6; /* R_Z80_32. */
aca88567 12795 default:
bee0ee85
NC
12796 {
12797 static unsigned int prev_warn = 0;
12798
12799 /* Avoid repeating the same warning multiple times. */
dda8d76d 12800 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12801 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12802 filedata->file_header.e_machine);
12803 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12804 return FALSE;
12805 }
aca88567
NC
12806 }
12807}
12808
12809/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12810 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12811
12812static bfd_boolean
dda8d76d 12813is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12814{
dda8d76d 12815 switch (filedata->file_header.e_machine)
d347c9df 12816 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12817 {
41e92641 12818 case EM_386:
22abe556 12819 case EM_IAMCU:
3e0873ac 12820 return reloc_type == 2; /* R_386_PC32. */
aca88567 12821 case EM_68K:
3e0873ac 12822 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12823 case EM_AARCH64:
12824 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12825 case EM_ADAPTEVA_EPIPHANY:
12826 return reloc_type == 6;
aca88567
NC
12827 case EM_ALPHA:
12828 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12829 case EM_ARC_COMPACT:
12830 case EM_ARC_COMPACT2:
12831 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12832 case EM_ARM:
3e0873ac 12833 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12834 case EM_AVR_OLD:
12835 case EM_AVR:
12836 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12837 case EM_MICROBLAZE:
12838 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12839 case EM_OR1K:
12840 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 12841 case EM_PARISC:
85acf597 12842 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
12843 case EM_PPC:
12844 return reloc_type == 26; /* R_PPC_REL32. */
12845 case EM_PPC64:
3e0873ac 12846 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
12847 case EM_RISCV:
12848 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
12849 case EM_S390_OLD:
12850 case EM_S390:
3e0873ac 12851 return reloc_type == 5; /* R_390_PC32. */
aca88567 12852 case EM_SH:
3e0873ac 12853 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
12854 case EM_SPARC32PLUS:
12855 case EM_SPARCV9:
12856 case EM_SPARC:
3e0873ac 12857 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
12858 case EM_SPU:
12859 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
12860 case EM_TILEGX:
12861 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
12862 case EM_TILEPRO:
12863 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
12864 case EM_VISIUM:
12865 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 12866 case EM_X86_64:
8a9036a4 12867 case EM_L1OM:
7a9068fe 12868 case EM_K1OM:
3e0873ac 12869 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
12870 case EM_VAX:
12871 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
12872 case EM_XTENSA_OLD:
12873 case EM_XTENSA:
12874 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
12875 default:
12876 /* Do not abort or issue an error message here. Not all targets use
12877 pc-relative 32-bit relocs in their DWARF debug information and we
12878 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
12879 more helpful warning message will be generated by apply_relocations
12880 anyway, so just return. */
aca88567
NC
12881 return FALSE;
12882 }
12883}
12884
12885/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12886 a 64-bit absolute RELA relocation used in DWARF debug sections. */
12887
12888static bfd_boolean
dda8d76d 12889is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12890{
dda8d76d 12891 switch (filedata->file_header.e_machine)
aca88567 12892 {
a06ea964
NC
12893 case EM_AARCH64:
12894 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
12895 case EM_ALPHA:
12896 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 12897 case EM_IA_64:
262cdac7
AM
12898 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
12899 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
12900 case EM_PARISC:
12901 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
12902 case EM_PPC64:
12903 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
12904 case EM_RISCV:
12905 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
12906 case EM_SPARC32PLUS:
12907 case EM_SPARCV9:
12908 case EM_SPARC:
714da62f
NC
12909 return reloc_type == 32 /* R_SPARC_64. */
12910 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 12911 case EM_X86_64:
8a9036a4 12912 case EM_L1OM:
7a9068fe 12913 case EM_K1OM:
aca88567 12914 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
12915 case EM_S390_OLD:
12916 case EM_S390:
aa137e4d
NC
12917 return reloc_type == 22; /* R_S390_64. */
12918 case EM_TILEGX:
12919 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 12920 case EM_MIPS:
aa137e4d 12921 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
12922 default:
12923 return FALSE;
12924 }
12925}
12926
85acf597
RH
12927/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
12928 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
12929
12930static bfd_boolean
dda8d76d 12931is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 12932{
dda8d76d 12933 switch (filedata->file_header.e_machine)
85acf597 12934 {
a06ea964
NC
12935 case EM_AARCH64:
12936 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 12937 case EM_ALPHA:
aa137e4d 12938 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 12939 case EM_IA_64:
262cdac7
AM
12940 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
12941 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 12942 case EM_PARISC:
aa137e4d 12943 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 12944 case EM_PPC64:
aa137e4d 12945 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
12946 case EM_SPARC32PLUS:
12947 case EM_SPARCV9:
12948 case EM_SPARC:
aa137e4d 12949 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 12950 case EM_X86_64:
8a9036a4 12951 case EM_L1OM:
7a9068fe 12952 case EM_K1OM:
aa137e4d 12953 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
12954 case EM_S390_OLD:
12955 case EM_S390:
aa137e4d
NC
12956 return reloc_type == 23; /* R_S390_PC64. */
12957 case EM_TILEGX:
12958 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
12959 default:
12960 return FALSE;
12961 }
12962}
12963
4dc3c23d
AM
12964/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12965 a 24-bit absolute RELA relocation used in DWARF debug sections. */
12966
12967static bfd_boolean
dda8d76d 12968is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 12969{
dda8d76d 12970 switch (filedata->file_header.e_machine)
4dc3c23d
AM
12971 {
12972 case EM_CYGNUS_MN10200:
12973 case EM_MN10200:
12974 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
12975 case EM_FT32:
12976 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
12977 case EM_Z80:
12978 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
12979 default:
12980 return FALSE;
12981 }
12982}
12983
aca88567
NC
12984/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12985 a 16-bit absolute RELA relocation used in DWARF debug sections. */
12986
12987static bfd_boolean
dda8d76d 12988is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 12989{
d347c9df 12990 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12991 switch (filedata->file_header.e_machine)
4b78141a 12992 {
886a2506
NC
12993 case EM_ARC:
12994 case EM_ARC_COMPACT:
12995 case EM_ARC_COMPACT2:
12996 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
12997 case EM_ADAPTEVA_EPIPHANY:
12998 return reloc_type == 5;
aca88567
NC
12999 case EM_AVR_OLD:
13000 case EM_AVR:
13001 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13002 case EM_CYGNUS_D10V:
13003 case EM_D10V:
13004 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13005 case EM_FT32:
13006 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13007 case EM_H8S:
13008 case EM_H8_300:
13009 case EM_H8_300H:
aca88567
NC
13010 return reloc_type == R_H8_DIR16;
13011 case EM_IP2K_OLD:
13012 case EM_IP2K:
13013 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13014 case EM_M32C_OLD:
f4236fe4
DD
13015 case EM_M32C:
13016 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13017 case EM_CYGNUS_MN10200:
13018 case EM_MN10200:
13019 return reloc_type == 2; /* R_MN10200_16. */
13020 case EM_CYGNUS_MN10300:
13021 case EM_MN10300:
13022 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13023 case EM_MSP430:
dda8d76d 13024 if (uses_msp430x_relocs (filedata))
13761a11 13025 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13026 /* Fall through. */
78c8d46c 13027 case EM_MSP430_OLD:
aca88567 13028 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13029 case EM_NDS32:
13030 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13031 case EM_ALTERA_NIOS2:
36591ba1 13032 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13033 case EM_NIOS32:
13034 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13035 case EM_OR1K:
13036 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13037 case EM_RISCV:
13038 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13039 case EM_TI_PRU:
13040 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13041 case EM_TI_C6000:
13042 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13043 case EM_VISIUM:
13044 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13045 case EM_XC16X:
13046 case EM_C166:
13047 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13048 case EM_XGATE:
13049 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13050 case EM_Z80:
13051 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13052 default:
aca88567 13053 return FALSE;
4b78141a
NC
13054 }
13055}
13056
39e07931
AS
13057/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13058 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13059
13060static bfd_boolean
13061is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13062{
13063 switch (filedata->file_header.e_machine)
13064 {
13065 case EM_RISCV:
13066 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13067 case EM_Z80:
13068 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13069 default:
13070 return FALSE;
13071 }
13072}
13073
13074/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13075 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13076
13077static bfd_boolean
13078is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13079{
13080 switch (filedata->file_header.e_machine)
13081 {
13082 case EM_RISCV:
13083 return reloc_type == 53; /* R_RISCV_SET6. */
13084 default:
13085 return FALSE;
13086 }
13087}
13088
03336641
JW
13089/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13090 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13091
13092static bfd_boolean
13093is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13094{
13095 /* Please keep this table alpha-sorted for ease of visual lookup. */
13096 switch (filedata->file_header.e_machine)
13097 {
13098 case EM_RISCV:
13099 return reloc_type == 35; /* R_RISCV_ADD32. */
13100 default:
13101 return FALSE;
13102 }
13103}
13104
13105/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13106 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13107
13108static bfd_boolean
13109is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13110{
13111 /* Please keep this table alpha-sorted for ease of visual lookup. */
13112 switch (filedata->file_header.e_machine)
13113 {
13114 case EM_RISCV:
13115 return reloc_type == 39; /* R_RISCV_SUB32. */
13116 default:
13117 return FALSE;
13118 }
13119}
13120
13121/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13122 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13123
13124static bfd_boolean
13125is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13126{
13127 /* Please keep this table alpha-sorted for ease of visual lookup. */
13128 switch (filedata->file_header.e_machine)
13129 {
13130 case EM_RISCV:
13131 return reloc_type == 36; /* R_RISCV_ADD64. */
13132 default:
13133 return FALSE;
13134 }
13135}
13136
13137/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13138 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13139
13140static bfd_boolean
13141is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13142{
13143 /* Please keep this table alpha-sorted for ease of visual lookup. */
13144 switch (filedata->file_header.e_machine)
13145 {
13146 case EM_RISCV:
13147 return reloc_type == 40; /* R_RISCV_SUB64. */
13148 default:
13149 return FALSE;
13150 }
13151}
13152
13153/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13154 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13155
13156static bfd_boolean
13157is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13158{
13159 /* Please keep this table alpha-sorted for ease of visual lookup. */
13160 switch (filedata->file_header.e_machine)
13161 {
13162 case EM_RISCV:
13163 return reloc_type == 34; /* R_RISCV_ADD16. */
13164 default:
13165 return FALSE;
13166 }
13167}
13168
13169/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13170 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13171
13172static bfd_boolean
13173is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13174{
13175 /* Please keep this table alpha-sorted for ease of visual lookup. */
13176 switch (filedata->file_header.e_machine)
13177 {
13178 case EM_RISCV:
13179 return reloc_type == 38; /* R_RISCV_SUB16. */
13180 default:
13181 return FALSE;
13182 }
13183}
13184
13185/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13186 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13187
13188static bfd_boolean
13189is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13190{
13191 /* Please keep this table alpha-sorted for ease of visual lookup. */
13192 switch (filedata->file_header.e_machine)
13193 {
13194 case EM_RISCV:
13195 return reloc_type == 33; /* R_RISCV_ADD8. */
13196 default:
13197 return FALSE;
13198 }
13199}
13200
13201/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13202 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13203
13204static bfd_boolean
13205is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13206{
13207 /* Please keep this table alpha-sorted for ease of visual lookup. */
13208 switch (filedata->file_header.e_machine)
13209 {
13210 case EM_RISCV:
13211 return reloc_type == 37; /* R_RISCV_SUB8. */
13212 default:
13213 return FALSE;
13214 }
13215}
13216
39e07931
AS
13217/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13218 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13219
13220static bfd_boolean
13221is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13222{
13223 switch (filedata->file_header.e_machine)
13224 {
13225 case EM_RISCV:
13226 return reloc_type == 52; /* R_RISCV_SUB6. */
13227 default:
13228 return FALSE;
13229 }
13230}
13231
2a7b2e88
JK
13232/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13233 relocation entries (possibly formerly used for SHT_GROUP sections). */
13234
13235static bfd_boolean
dda8d76d 13236is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13237{
dda8d76d 13238 switch (filedata->file_header.e_machine)
2a7b2e88 13239 {
cb8f3167 13240 case EM_386: /* R_386_NONE. */
d347c9df 13241 case EM_68K: /* R_68K_NONE. */
cfb8c092 13242 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13243 case EM_ALPHA: /* R_ALPHA_NONE. */
13244 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13245 case EM_ARC: /* R_ARC_NONE. */
886a2506 13246 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13247 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13248 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13249 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13250 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13251 case EM_FT32: /* R_FT32_NONE. */
13252 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13253 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13254 case EM_L1OM: /* R_X86_64_NONE. */
13255 case EM_M32R: /* R_M32R_NONE. */
13256 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13257 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13258 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13259 case EM_NIOS32: /* R_NIOS_NONE. */
13260 case EM_OR1K: /* R_OR1K_NONE. */
13261 case EM_PARISC: /* R_PARISC_NONE. */
13262 case EM_PPC64: /* R_PPC64_NONE. */
13263 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13264 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13265 case EM_S390: /* R_390_NONE. */
13266 case EM_S390_OLD:
13267 case EM_SH: /* R_SH_NONE. */
13268 case EM_SPARC32PLUS:
13269 case EM_SPARC: /* R_SPARC_NONE. */
13270 case EM_SPARCV9:
aa137e4d
NC
13271 case EM_TILEGX: /* R_TILEGX_NONE. */
13272 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13273 case EM_TI_C6000:/* R_C6000_NONE. */
13274 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13275 case EM_XC16X:
6655dba2 13276 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 13277 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13278 return reloc_type == 0;
d347c9df 13279
a06ea964
NC
13280 case EM_AARCH64:
13281 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13282 case EM_AVR_OLD:
13283 case EM_AVR:
13284 return (reloc_type == 0 /* R_AVR_NONE. */
13285 || reloc_type == 30 /* R_AVR_DIFF8. */
13286 || reloc_type == 31 /* R_AVR_DIFF16. */
13287 || reloc_type == 32 /* R_AVR_DIFF32. */);
13288 case EM_METAG:
13289 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13290 case EM_NDS32:
13291 return (reloc_type == 0 /* R_XTENSA_NONE. */
13292 || reloc_type == 204 /* R_NDS32_DIFF8. */
13293 || reloc_type == 205 /* R_NDS32_DIFF16. */
13294 || reloc_type == 206 /* R_NDS32_DIFF32. */
13295 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13296 case EM_TI_PRU:
13297 return (reloc_type == 0 /* R_PRU_NONE. */
13298 || reloc_type == 65 /* R_PRU_DIFF8. */
13299 || reloc_type == 66 /* R_PRU_DIFF16. */
13300 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13301 case EM_XTENSA_OLD:
13302 case EM_XTENSA:
4dc3c23d
AM
13303 return (reloc_type == 0 /* R_XTENSA_NONE. */
13304 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13305 || reloc_type == 18 /* R_XTENSA_DIFF16. */
13306 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
13307 }
13308 return FALSE;
13309}
13310
d1c4b12b
NC
13311/* Returns TRUE if there is a relocation against
13312 section NAME at OFFSET bytes. */
13313
13314bfd_boolean
13315reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13316{
13317 Elf_Internal_Rela * relocs;
13318 Elf_Internal_Rela * rp;
13319
13320 if (dsec == NULL || dsec->reloc_info == NULL)
13321 return FALSE;
13322
13323 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13324
13325 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13326 if (rp->r_offset == offset)
13327 return TRUE;
13328
13329 return FALSE;
13330}
13331
cf13d699 13332/* Apply relocations to a section.
32ec8896
NC
13333 Returns TRUE upon success, FALSE otherwise.
13334 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13335 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13336 will be set to the number of relocs loaded.
13337
cf13d699 13338 Note: So far support has been added only for those relocations
32ec8896
NC
13339 which can be found in debug sections. FIXME: Add support for
13340 more relocations ? */
1b315056 13341
32ec8896 13342static bfd_boolean
dda8d76d 13343apply_relocations (Filedata * filedata,
d1c4b12b
NC
13344 const Elf_Internal_Shdr * section,
13345 unsigned char * start,
13346 bfd_size_type size,
1449284b 13347 void ** relocs_return,
d1c4b12b 13348 unsigned long * num_relocs_return)
1b315056 13349{
cf13d699 13350 Elf_Internal_Shdr * relsec;
0d2a7a93 13351 unsigned char * end = start + size;
cb8f3167 13352
d1c4b12b
NC
13353 if (relocs_return != NULL)
13354 {
13355 * (Elf_Internal_Rela **) relocs_return = NULL;
13356 * num_relocs_return = 0;
13357 }
13358
dda8d76d 13359 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13360 /* No relocs to apply. */
13361 return TRUE;
1b315056 13362
cf13d699 13363 /* Find the reloc section associated with the section. */
dda8d76d
NC
13364 for (relsec = filedata->section_headers;
13365 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13366 ++relsec)
252b5132 13367 {
41e92641
NC
13368 bfd_boolean is_rela;
13369 unsigned long num_relocs;
2cf0635d
NC
13370 Elf_Internal_Rela * relocs;
13371 Elf_Internal_Rela * rp;
13372 Elf_Internal_Shdr * symsec;
13373 Elf_Internal_Sym * symtab;
ba5cdace 13374 unsigned long num_syms;
2cf0635d 13375 Elf_Internal_Sym * sym;
252b5132 13376
41e92641 13377 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13378 || relsec->sh_info >= filedata->file_header.e_shnum
13379 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13380 || relsec->sh_size == 0
dda8d76d 13381 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13382 continue;
428409d5 13383
a788aedd
AM
13384 symsec = filedata->section_headers + relsec->sh_link;
13385 if (symsec->sh_type != SHT_SYMTAB
13386 && symsec->sh_type != SHT_DYNSYM)
13387 return FALSE;
13388
41e92641
NC
13389 is_rela = relsec->sh_type == SHT_RELA;
13390
13391 if (is_rela)
13392 {
dda8d76d 13393 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13394 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13395 return FALSE;
41e92641
NC
13396 }
13397 else
13398 {
dda8d76d 13399 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13400 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13401 return FALSE;
41e92641
NC
13402 }
13403
13404 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13405 if (filedata->file_header.e_machine == EM_SH)
41e92641 13406 is_rela = FALSE;
428409d5 13407
dda8d76d 13408 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13409
41e92641 13410 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13411 {
41e92641
NC
13412 bfd_vma addend;
13413 unsigned int reloc_type;
13414 unsigned int reloc_size;
03336641
JW
13415 bfd_boolean reloc_inplace = FALSE;
13416 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13417 unsigned char * rloc;
ba5cdace 13418 unsigned long sym_index;
4b78141a 13419
dda8d76d 13420 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13421
dda8d76d 13422 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13423 continue;
dda8d76d 13424 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13425 continue;
dda8d76d
NC
13426 else if (is_32bit_abs_reloc (filedata, reloc_type)
13427 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13428 reloc_size = 4;
dda8d76d
NC
13429 else if (is_64bit_abs_reloc (filedata, reloc_type)
13430 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13431 reloc_size = 8;
dda8d76d 13432 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13433 reloc_size = 3;
dda8d76d 13434 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13435 reloc_size = 2;
39e07931
AS
13436 else if (is_8bit_abs_reloc (filedata, reloc_type)
13437 || is_6bit_abs_reloc (filedata, reloc_type))
13438 reloc_size = 1;
03336641
JW
13439 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13440 reloc_type))
13441 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13442 {
13443 reloc_size = 4;
13444 reloc_inplace = TRUE;
13445 }
13446 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13447 reloc_type))
13448 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13449 {
13450 reloc_size = 8;
13451 reloc_inplace = TRUE;
13452 }
13453 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13454 reloc_type))
13455 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13456 {
13457 reloc_size = 2;
13458 reloc_inplace = TRUE;
13459 }
13460 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13461 reloc_type))
13462 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13463 {
13464 reloc_size = 1;
13465 reloc_inplace = TRUE;
13466 }
39e07931
AS
13467 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13468 reloc_type)))
13469 {
13470 reloc_size = 1;
13471 reloc_inplace = TRUE;
13472 }
aca88567 13473 else
4b78141a 13474 {
bee0ee85 13475 static unsigned int prev_reloc = 0;
dda8d76d 13476
bee0ee85
NC
13477 if (reloc_type != prev_reloc)
13478 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13479 reloc_type, printable_section_name (filedata, section));
bee0ee85 13480 prev_reloc = reloc_type;
4b78141a
NC
13481 continue;
13482 }
103f02d3 13483
91d6fa6a 13484 rloc = start + rp->r_offset;
75802ccb 13485 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
13486 {
13487 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13488 (unsigned long) rp->r_offset,
dda8d76d 13489 printable_section_name (filedata, section));
700dd8b7
L
13490 continue;
13491 }
103f02d3 13492
ba5cdace
NC
13493 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13494 if (sym_index >= num_syms)
13495 {
13496 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13497 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
13498 continue;
13499 }
13500 sym = symtab + sym_index;
41e92641
NC
13501
13502 /* If the reloc has a symbol associated with it,
55f25fc3
L
13503 make sure that it is of an appropriate type.
13504
13505 Relocations against symbols without type can happen.
13506 Gcc -feliminate-dwarf2-dups may generate symbols
13507 without type for debug info.
13508
13509 Icc generates relocations against function symbols
13510 instead of local labels.
13511
13512 Relocations against object symbols can happen, eg when
13513 referencing a global array. For an example of this see
13514 the _clz.o binary in libgcc.a. */
aca88567 13515 if (sym != symtab
b8871f35 13516 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13517 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13518 {
d3a49aa8 13519 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13520 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13521 printable_section_name (filedata, relsec),
d3a49aa8 13522 (long int)(rp - relocs));
aca88567 13523 continue;
5b18a4bc 13524 }
252b5132 13525
4dc3c23d
AM
13526 addend = 0;
13527 if (is_rela)
13528 addend += rp->r_addend;
c47320c3
AM
13529 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13530 partial_inplace. */
4dc3c23d 13531 if (!is_rela
dda8d76d 13532 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13533 && reloc_type == 1)
dda8d76d
NC
13534 || ((filedata->file_header.e_machine == EM_PJ
13535 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13536 && reloc_type == 1)
dda8d76d
NC
13537 || ((filedata->file_header.e_machine == EM_D30V
13538 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13539 && reloc_type == 12)
13540 || reloc_inplace)
39e07931
AS
13541 {
13542 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
13543 addend += byte_get (rloc, reloc_size) & 0x3f;
13544 else
13545 addend += byte_get (rloc, reloc_size);
13546 }
cb8f3167 13547
dda8d76d
NC
13548 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13549 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13550 {
13551 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13552 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13553 addend -= 8;
91d6fa6a 13554 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13555 reloc_size);
13556 }
39e07931
AS
13557 else if (is_6bit_abs_reloc (filedata, reloc_type)
13558 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
13559 {
13560 if (reloc_subtract)
13561 addend -= sym->st_value;
13562 else
13563 addend += sym->st_value;
13564 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
13565 byte_put (rloc, addend, reloc_size);
13566 }
03336641
JW
13567 else if (reloc_subtract)
13568 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13569 else
91d6fa6a 13570 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13571 }
252b5132 13572
5b18a4bc 13573 free (symtab);
f84ce13b
NC
13574 /* Let the target specific reloc processing code know that
13575 we have finished with these relocs. */
dda8d76d 13576 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13577
13578 if (relocs_return)
13579 {
13580 * (Elf_Internal_Rela **) relocs_return = relocs;
13581 * num_relocs_return = num_relocs;
13582 }
13583 else
13584 free (relocs);
13585
5b18a4bc
NC
13586 break;
13587 }
32ec8896 13588
dfc616fa 13589 return TRUE;
5b18a4bc 13590}
103f02d3 13591
cf13d699 13592#ifdef SUPPORT_DISASSEMBLY
32ec8896 13593static bfd_boolean
dda8d76d 13594disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13595{
dda8d76d 13596 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13597
74e1a04b 13598 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13599
32ec8896 13600 return TRUE;
cf13d699
NC
13601}
13602#endif
13603
13604/* Reads in the contents of SECTION from FILE, returning a pointer
13605 to a malloc'ed buffer or NULL if something went wrong. */
13606
13607static char *
dda8d76d 13608get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13609{
dda8d76d 13610 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13611
13612 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13613 {
c6b78c96 13614 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13615 printable_section_name (filedata, section));
cf13d699
NC
13616 return NULL;
13617 }
13618
dda8d76d 13619 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13620 _("section contents"));
cf13d699
NC
13621}
13622
0e602686
NC
13623/* Uncompresses a section that was compressed using zlib, in place. */
13624
13625static bfd_boolean
dda8d76d
NC
13626uncompress_section_contents (unsigned char ** buffer,
13627 dwarf_size_type uncompressed_size,
13628 dwarf_size_type * size)
0e602686
NC
13629{
13630 dwarf_size_type compressed_size = *size;
13631 unsigned char * compressed_buffer = *buffer;
13632 unsigned char * uncompressed_buffer;
13633 z_stream strm;
13634 int rc;
13635
13636 /* It is possible the section consists of several compressed
13637 buffers concatenated together, so we uncompress in a loop. */
13638 /* PR 18313: The state field in the z_stream structure is supposed
13639 to be invisible to the user (ie us), but some compilers will
13640 still complain about it being used without initialisation. So
13641 we first zero the entire z_stream structure and then set the fields
13642 that we need. */
13643 memset (& strm, 0, sizeof strm);
13644 strm.avail_in = compressed_size;
13645 strm.next_in = (Bytef *) compressed_buffer;
13646 strm.avail_out = uncompressed_size;
13647 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13648
13649 rc = inflateInit (& strm);
13650 while (strm.avail_in > 0)
13651 {
13652 if (rc != Z_OK)
13653 goto fail;
13654 strm.next_out = ((Bytef *) uncompressed_buffer
13655 + (uncompressed_size - strm.avail_out));
13656 rc = inflate (&strm, Z_FINISH);
13657 if (rc != Z_STREAM_END)
13658 goto fail;
13659 rc = inflateReset (& strm);
13660 }
13661 rc = inflateEnd (& strm);
13662 if (rc != Z_OK
13663 || strm.avail_out != 0)
13664 goto fail;
13665
13666 *buffer = uncompressed_buffer;
13667 *size = uncompressed_size;
13668 return TRUE;
13669
13670 fail:
13671 free (uncompressed_buffer);
13672 /* Indicate decompression failure. */
13673 *buffer = NULL;
13674 return FALSE;
13675}
dd24e3da 13676
32ec8896 13677static bfd_boolean
dda8d76d 13678dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13679{
0e602686
NC
13680 Elf_Internal_Shdr * relsec;
13681 bfd_size_type num_bytes;
fd8008d8
L
13682 unsigned char * data;
13683 unsigned char * end;
13684 unsigned char * real_start;
13685 unsigned char * start;
0e602686 13686 bfd_boolean some_strings_shown;
cf13d699 13687
dda8d76d 13688 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13689 if (start == NULL)
c6b78c96
NC
13690 /* PR 21820: Do not fail if the section was empty. */
13691 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13692
0e602686 13693 num_bytes = section->sh_size;
cf13d699 13694
dda8d76d 13695 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13696
0e602686
NC
13697 if (decompress_dumps)
13698 {
13699 dwarf_size_type new_size = num_bytes;
13700 dwarf_size_type uncompressed_size = 0;
13701
13702 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13703 {
13704 Elf_Internal_Chdr chdr;
13705 unsigned int compression_header_size
ebdf1ebf
NC
13706 = get_compression_header (& chdr, (unsigned char *) start,
13707 num_bytes);
5844b465
NC
13708 if (compression_header_size == 0)
13709 /* An error message will have already been generated
13710 by get_compression_header. */
13711 goto error_out;
0e602686 13712
813dabb9 13713 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13714 {
813dabb9 13715 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13716 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 13717 goto error_out;
813dabb9 13718 }
813dabb9
L
13719 uncompressed_size = chdr.ch_size;
13720 start += compression_header_size;
13721 new_size -= compression_header_size;
0e602686
NC
13722 }
13723 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13724 {
13725 /* Read the zlib header. In this case, it should be "ZLIB"
13726 followed by the uncompressed section size, 8 bytes in
13727 big-endian order. */
13728 uncompressed_size = start[4]; uncompressed_size <<= 8;
13729 uncompressed_size += start[5]; uncompressed_size <<= 8;
13730 uncompressed_size += start[6]; uncompressed_size <<= 8;
13731 uncompressed_size += start[7]; uncompressed_size <<= 8;
13732 uncompressed_size += start[8]; uncompressed_size <<= 8;
13733 uncompressed_size += start[9]; uncompressed_size <<= 8;
13734 uncompressed_size += start[10]; uncompressed_size <<= 8;
13735 uncompressed_size += start[11];
13736 start += 12;
13737 new_size -= 12;
13738 }
13739
1835f746
NC
13740 if (uncompressed_size)
13741 {
13742 if (uncompress_section_contents (& start,
13743 uncompressed_size, & new_size))
13744 num_bytes = new_size;
13745 else
13746 {
13747 error (_("Unable to decompress section %s\n"),
dda8d76d 13748 printable_section_name (filedata, section));
f761cb13 13749 goto error_out;
1835f746
NC
13750 }
13751 }
bc303e5d
NC
13752 else
13753 start = real_start;
0e602686 13754 }
fd8008d8 13755
cf13d699
NC
13756 /* If the section being dumped has relocations against it the user might
13757 be expecting these relocations to have been applied. Check for this
13758 case and issue a warning message in order to avoid confusion.
13759 FIXME: Maybe we ought to have an option that dumps a section with
13760 relocs applied ? */
dda8d76d
NC
13761 for (relsec = filedata->section_headers;
13762 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13763 ++relsec)
13764 {
13765 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13766 || relsec->sh_info >= filedata->file_header.e_shnum
13767 || filedata->section_headers + relsec->sh_info != section
cf13d699 13768 || relsec->sh_size == 0
dda8d76d 13769 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13770 continue;
13771
13772 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13773 break;
13774 }
13775
cf13d699
NC
13776 data = start;
13777 end = start + num_bytes;
13778 some_strings_shown = FALSE;
13779
ba3265d0
NC
13780#ifdef HAVE_MBSTATE_T
13781 mbstate_t state;
13782 /* Initialise the multibyte conversion state. */
13783 memset (& state, 0, sizeof (state));
13784#endif
13785
13786 bfd_boolean continuing = FALSE;
13787
cf13d699
NC
13788 while (data < end)
13789 {
13790 while (!ISPRINT (* data))
13791 if (++ data >= end)
13792 break;
13793
13794 if (data < end)
13795 {
071436c6
NC
13796 size_t maxlen = end - data;
13797
ba3265d0
NC
13798 if (continuing)
13799 {
13800 printf (" ");
13801 continuing = FALSE;
13802 }
13803 else
13804 {
cf13d699 13805#ifndef __MSVCRT__
ba3265d0
NC
13806 /* PR 11128: Use two separate invocations in order to work
13807 around bugs in the Solaris 8 implementation of printf. */
13808 printf (" [%6tx] ", data - start);
cf13d699 13809#else
ba3265d0 13810 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 13811#endif
ba3265d0
NC
13812 }
13813
4082ef84
NC
13814 if (maxlen > 0)
13815 {
ba3265d0
NC
13816 char c;
13817
13818 while (maxlen)
13819 {
13820 c = *data++;
13821
13822 if (c == 0)
13823 break;
13824
13825 /* PR 25543: Treat new-lines as string-ending characters. */
13826 if (c == '\n')
13827 {
13828 printf ("\\n\n");
13829 if (*data != 0)
13830 continuing = TRUE;
13831 break;
13832 }
13833
13834 /* Do not print control characters directly as they can affect terminal
13835 settings. Such characters usually appear in the names generated
13836 by the assembler for local labels. */
13837 if (ISCNTRL (c))
13838 {
13839 printf ("^%c", c + 0x40);
13840 }
13841 else if (ISPRINT (c))
13842 {
13843 putchar (c);
13844 }
13845 else
13846 {
13847 size_t n;
13848#ifdef HAVE_MBSTATE_T
13849 wchar_t w;
13850#endif
13851 /* Let printf do the hard work of displaying multibyte characters. */
13852 printf ("%.1s", data - 1);
13853#ifdef HAVE_MBSTATE_T
13854 /* Try to find out how many bytes made up the character that was
13855 just printed. Advance the symbol pointer past the bytes that
13856 were displayed. */
13857 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
13858#else
13859 n = 1;
13860#endif
13861 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
13862 data += (n - 1);
13863 }
13864 }
13865
13866 if (c != '\n')
13867 putchar ('\n');
4082ef84
NC
13868 }
13869 else
13870 {
13871 printf (_("<corrupt>\n"));
13872 data = end;
13873 }
cf13d699
NC
13874 some_strings_shown = TRUE;
13875 }
13876 }
13877
13878 if (! some_strings_shown)
13879 printf (_(" No strings found in this section."));
13880
0e602686 13881 free (real_start);
cf13d699
NC
13882
13883 putchar ('\n');
32ec8896 13884 return TRUE;
f761cb13
AM
13885
13886error_out:
13887 free (real_start);
13888 return FALSE;
cf13d699
NC
13889}
13890
32ec8896 13891static bfd_boolean
dda8d76d
NC
13892dump_section_as_bytes (Elf_Internal_Shdr * section,
13893 Filedata * filedata,
13894 bfd_boolean relocate)
cf13d699
NC
13895{
13896 Elf_Internal_Shdr * relsec;
0e602686
NC
13897 bfd_size_type bytes;
13898 bfd_size_type section_size;
13899 bfd_vma addr;
13900 unsigned char * data;
13901 unsigned char * real_start;
13902 unsigned char * start;
13903
dda8d76d 13904 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13905 if (start == NULL)
c6b78c96
NC
13906 /* PR 21820: Do not fail if the section was empty. */
13907 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 13908
0e602686 13909 section_size = section->sh_size;
cf13d699 13910
dda8d76d 13911 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13912
0e602686
NC
13913 if (decompress_dumps)
13914 {
13915 dwarf_size_type new_size = section_size;
13916 dwarf_size_type uncompressed_size = 0;
13917
13918 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13919 {
13920 Elf_Internal_Chdr chdr;
13921 unsigned int compression_header_size
ebdf1ebf 13922 = get_compression_header (& chdr, start, section_size);
0e602686 13923
5844b465
NC
13924 if (compression_header_size == 0)
13925 /* An error message will have already been generated
13926 by get_compression_header. */
13927 goto error_out;
13928
813dabb9 13929 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13930 {
813dabb9 13931 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13932 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 13933 goto error_out;
0e602686 13934 }
813dabb9
L
13935 uncompressed_size = chdr.ch_size;
13936 start += compression_header_size;
13937 new_size -= compression_header_size;
0e602686
NC
13938 }
13939 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13940 {
13941 /* Read the zlib header. In this case, it should be "ZLIB"
13942 followed by the uncompressed section size, 8 bytes in
13943 big-endian order. */
13944 uncompressed_size = start[4]; uncompressed_size <<= 8;
13945 uncompressed_size += start[5]; uncompressed_size <<= 8;
13946 uncompressed_size += start[6]; uncompressed_size <<= 8;
13947 uncompressed_size += start[7]; uncompressed_size <<= 8;
13948 uncompressed_size += start[8]; uncompressed_size <<= 8;
13949 uncompressed_size += start[9]; uncompressed_size <<= 8;
13950 uncompressed_size += start[10]; uncompressed_size <<= 8;
13951 uncompressed_size += start[11];
13952 start += 12;
13953 new_size -= 12;
13954 }
13955
f055032e
NC
13956 if (uncompressed_size)
13957 {
13958 if (uncompress_section_contents (& start, uncompressed_size,
13959 & new_size))
bc303e5d
NC
13960 {
13961 section_size = new_size;
13962 }
f055032e
NC
13963 else
13964 {
13965 error (_("Unable to decompress section %s\n"),
dda8d76d 13966 printable_section_name (filedata, section));
bc303e5d 13967 /* FIXME: Print the section anyway ? */
f761cb13 13968 goto error_out;
f055032e
NC
13969 }
13970 }
bc303e5d
NC
13971 else
13972 start = real_start;
0e602686 13973 }
14ae95f2 13974
cf13d699
NC
13975 if (relocate)
13976 {
dda8d76d 13977 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 13978 goto error_out;
cf13d699
NC
13979 }
13980 else
13981 {
13982 /* If the section being dumped has relocations against it the user might
13983 be expecting these relocations to have been applied. Check for this
13984 case and issue a warning message in order to avoid confusion.
13985 FIXME: Maybe we ought to have an option that dumps a section with
13986 relocs applied ? */
dda8d76d
NC
13987 for (relsec = filedata->section_headers;
13988 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13989 ++relsec)
13990 {
13991 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13992 || relsec->sh_info >= filedata->file_header.e_shnum
13993 || filedata->section_headers + relsec->sh_info != section
cf13d699 13994 || relsec->sh_size == 0
dda8d76d 13995 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13996 continue;
13997
13998 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13999 break;
14000 }
14001 }
14002
14003 addr = section->sh_addr;
0e602686 14004 bytes = section_size;
cf13d699
NC
14005 data = start;
14006
14007 while (bytes)
14008 {
14009 int j;
14010 int k;
14011 int lbytes;
14012
14013 lbytes = (bytes > 16 ? 16 : bytes);
14014
14015 printf (" 0x%8.8lx ", (unsigned long) addr);
14016
14017 for (j = 0; j < 16; j++)
14018 {
14019 if (j < lbytes)
14020 printf ("%2.2x", data[j]);
14021 else
14022 printf (" ");
14023
14024 if ((j & 3) == 3)
14025 printf (" ");
14026 }
14027
14028 for (j = 0; j < lbytes; j++)
14029 {
14030 k = data[j];
14031 if (k >= ' ' && k < 0x7f)
14032 printf ("%c", k);
14033 else
14034 printf (".");
14035 }
14036
14037 putchar ('\n');
14038
14039 data += lbytes;
14040 addr += lbytes;
14041 bytes -= lbytes;
14042 }
14043
0e602686 14044 free (real_start);
cf13d699
NC
14045
14046 putchar ('\n');
32ec8896 14047 return TRUE;
f761cb13
AM
14048
14049 error_out:
14050 free (real_start);
14051 return FALSE;
cf13d699
NC
14052}
14053
7d9813f1
NA
14054static ctf_sect_t *
14055shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14056{
90bd5423 14057 buf->cts_name = SECTION_NAME (shdr);
7d9813f1
NA
14058 buf->cts_size = shdr->sh_size;
14059 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14060
14061 return buf;
14062}
14063
14064/* Formatting callback function passed to ctf_dump. Returns either the pointer
14065 it is passed, or a pointer to newly-allocated storage, in which case
14066 dump_ctf() will free it when it no longer needs it. */
14067
14068static char *dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14069 char *s, void *arg)
14070{
3e50a591 14071 const char *blanks = arg;
7d9813f1
NA
14072 char *new_s;
14073
3e50a591 14074 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14075 return s;
14076 return new_s;
14077}
14078
14079static bfd_boolean
14080dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14081{
14082 Elf_Internal_Shdr * parent_sec = NULL;
14083 Elf_Internal_Shdr * symtab_sec = NULL;
14084 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14085 void * data = NULL;
14086 void * symdata = NULL;
14087 void * strdata = NULL;
14088 void * parentdata = NULL;
14089 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14090 ctf_sect_t * symsectp = NULL;
14091 ctf_sect_t * strsectp = NULL;
14092 ctf_file_t * ctf = NULL;
14093 ctf_file_t * parent = NULL;
7d9813f1 14094
9b32cba4
NA
14095 const char *things[] = {"Header", "Labels", "Data objects",
14096 "Function objects", "Variables", "Types", "Strings",
14097 ""};
7d9813f1
NA
14098 const char **thing;
14099 int err;
14100 bfd_boolean ret = FALSE;
14101 size_t i;
14102
14103 shdr_to_ctf_sect (&ctfsect, section, filedata);
14104 data = get_section_contents (section, filedata);
14105 ctfsect.cts_data = data;
14106
616febde
NA
14107 if (!dump_ctf_symtab_name)
14108 dump_ctf_symtab_name = strdup (".symtab");
14109
14110 if (!dump_ctf_strtab_name)
14111 dump_ctf_strtab_name = strdup (".strtab");
14112
14113 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14114 {
14115 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14116 {
14117 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14118 goto fail;
14119 }
14120 if ((symdata = (void *) get_data (NULL, filedata,
14121 symtab_sec->sh_offset, 1,
14122 symtab_sec->sh_size,
14123 _("symbols"))) == NULL)
14124 goto fail;
14125 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14126 symsect.cts_data = symdata;
14127 }
616febde 14128 if (dump_ctf_strtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14129 {
14130 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14131 {
14132 error (_("No string table section named %s\n"),
14133 dump_ctf_strtab_name);
14134 goto fail;
14135 }
14136 if ((strdata = (void *) get_data (NULL, filedata,
14137 strtab_sec->sh_offset, 1,
14138 strtab_sec->sh_size,
14139 _("strings"))) == NULL)
14140 goto fail;
14141 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14142 strsect.cts_data = strdata;
14143 }
14144 if (dump_ctf_parent_name)
14145 {
14146 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14147 {
14148 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14149 goto fail;
14150 }
14151 if ((parentdata = (void *) get_data (NULL, filedata,
14152 parent_sec->sh_offset, 1,
14153 parent_sec->sh_size,
14154 _("CTF parent"))) == NULL)
14155 goto fail;
14156 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14157 parentsect.cts_data = parentdata;
14158 }
14159
14160 /* Load the CTF file and dump it. */
14161
14162 if ((ctf = ctf_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
14163 {
14164 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14165 goto fail;
14166 }
14167
14168 if (parentdata)
14169 {
14170 if ((parent = ctf_bufopen (&parentsect, symsectp, strsectp, &err)) == NULL)
14171 {
14172 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14173 goto fail;
14174 }
14175
14176 ctf_import (ctf, parent);
14177 }
14178
14179 ret = TRUE;
14180
14181 printf (_("\nDump of CTF section '%s':\n"),
14182 printable_section_name (filedata, section));
14183
9b32cba4 14184 for (i = 0, thing = things; *thing[0]; thing++, i++)
7d9813f1
NA
14185 {
14186 ctf_dump_state_t *s = NULL;
14187 char *item;
14188
14189 printf ("\n %s:\n", *thing);
14190 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14191 (void *) " ")) != NULL)
14192 {
14193 printf ("%s\n", item);
14194 free (item);
14195 }
14196
14197 if (ctf_errno (ctf))
14198 {
14199 error (_("Iteration failed: %s, %s\n"), *thing,
14200 ctf_errmsg (ctf_errno (ctf)));
14201 ret = FALSE;
14202 }
14203 }
14204
14205 fail:
14206 ctf_file_close (ctf);
14207 ctf_file_close (parent);
14208 free (parentdata);
14209 free (data);
14210 free (symdata);
14211 free (strdata);
14212 return ret;
14213}
14214
32ec8896 14215static bfd_boolean
dda8d76d
NC
14216load_specific_debug_section (enum dwarf_section_display_enum debug,
14217 const Elf_Internal_Shdr * sec,
14218 void * data)
1007acb3 14219{
2cf0635d 14220 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 14221 char buf [64];
dda8d76d 14222 Filedata * filedata = (Filedata *) data;
9abca702 14223
19e6b90e 14224 if (section->start != NULL)
dda8d76d
NC
14225 {
14226 /* If it is already loaded, do nothing. */
14227 if (streq (section->filename, filedata->file_name))
14228 return TRUE;
14229 free (section->start);
14230 }
1007acb3 14231
19e6b90e
L
14232 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
14233 section->address = sec->sh_addr;
06614111 14234 section->user_data = NULL;
dda8d76d
NC
14235 section->filename = filedata->file_name;
14236 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
14237 sec->sh_offset, 1,
14238 sec->sh_size, buf);
59245841
NC
14239 if (section->start == NULL)
14240 section->size = 0;
14241 else
14242 {
77115a4a
L
14243 unsigned char *start = section->start;
14244 dwarf_size_type size = sec->sh_size;
dab394de 14245 dwarf_size_type uncompressed_size = 0;
77115a4a
L
14246
14247 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
14248 {
14249 Elf_Internal_Chdr chdr;
d8024a91
NC
14250 unsigned int compression_header_size;
14251
f53be977
L
14252 if (size < (is_32bit_elf
14253 ? sizeof (Elf32_External_Chdr)
14254 : sizeof (Elf64_External_Chdr)))
d8024a91 14255 {
55be8fd0 14256 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 14257 section->name);
32ec8896 14258 return FALSE;
d8024a91
NC
14259 }
14260
ebdf1ebf 14261 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
14262 if (compression_header_size == 0)
14263 /* An error message will have already been generated
14264 by get_compression_header. */
14265 return FALSE;
d8024a91 14266
813dabb9
L
14267 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
14268 {
14269 warn (_("section '%s' has unsupported compress type: %d\n"),
14270 section->name, chdr.ch_type);
32ec8896 14271 return FALSE;
813dabb9 14272 }
dab394de 14273 uncompressed_size = chdr.ch_size;
77115a4a
L
14274 start += compression_header_size;
14275 size -= compression_header_size;
14276 }
dab394de
L
14277 else if (size > 12 && streq ((char *) start, "ZLIB"))
14278 {
14279 /* Read the zlib header. In this case, it should be "ZLIB"
14280 followed by the uncompressed section size, 8 bytes in
14281 big-endian order. */
14282 uncompressed_size = start[4]; uncompressed_size <<= 8;
14283 uncompressed_size += start[5]; uncompressed_size <<= 8;
14284 uncompressed_size += start[6]; uncompressed_size <<= 8;
14285 uncompressed_size += start[7]; uncompressed_size <<= 8;
14286 uncompressed_size += start[8]; uncompressed_size <<= 8;
14287 uncompressed_size += start[9]; uncompressed_size <<= 8;
14288 uncompressed_size += start[10]; uncompressed_size <<= 8;
14289 uncompressed_size += start[11];
14290 start += 12;
14291 size -= 12;
14292 }
14293
1835f746 14294 if (uncompressed_size)
77115a4a 14295 {
1835f746
NC
14296 if (uncompress_section_contents (&start, uncompressed_size,
14297 &size))
14298 {
14299 /* Free the compressed buffer, update the section buffer
14300 and the section size if uncompress is successful. */
14301 free (section->start);
14302 section->start = start;
14303 }
14304 else
14305 {
14306 error (_("Unable to decompress section %s\n"),
dda8d76d 14307 printable_section_name (filedata, sec));
32ec8896 14308 return FALSE;
1835f746 14309 }
77115a4a 14310 }
bc303e5d 14311
77115a4a 14312 section->size = size;
59245841 14313 }
4a114e3e 14314
1b315056 14315 if (section->start == NULL)
32ec8896 14316 return FALSE;
1b315056 14317
19e6b90e 14318 if (debug_displays [debug].relocate)
32ec8896 14319 {
dda8d76d 14320 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
14321 & section->reloc_info, & section->num_relocs))
14322 return FALSE;
14323 }
d1c4b12b
NC
14324 else
14325 {
14326 section->reloc_info = NULL;
14327 section->num_relocs = 0;
14328 }
1007acb3 14329
32ec8896 14330 return TRUE;
1007acb3
L
14331}
14332
301a9420
AM
14333#if HAVE_LIBDEBUGINFOD
14334/* Return a hex string representation of the build-id. */
14335unsigned char *
14336get_build_id (void * data)
14337{
14338 Filedata * filedata = (Filedata *)data;
14339 Elf_Internal_Shdr * shdr;
14340 unsigned long i;
14341
55be8fd0
NC
14342 /* Iterate through notes to find note.gnu.build-id.
14343 FIXME: Only the first note in any note section is examined. */
301a9420
AM
14344 for (i = 0, shdr = filedata->section_headers;
14345 i < filedata->file_header.e_shnum && shdr != NULL;
14346 i++, shdr++)
14347 {
14348 if (shdr->sh_type != SHT_NOTE)
14349 continue;
14350
14351 char * next;
14352 char * end;
14353 size_t data_remaining;
14354 size_t min_notesz;
14355 Elf_External_Note * enote;
14356 Elf_Internal_Note inote;
14357
14358 bfd_vma offset = shdr->sh_offset;
14359 bfd_vma align = shdr->sh_addralign;
14360 bfd_vma length = shdr->sh_size;
14361
14362 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
14363 if (enote == NULL)
14364 continue;
14365
14366 if (align < 4)
14367 align = 4;
14368 else if (align != 4 && align != 8)
f761cb13
AM
14369 {
14370 free (enote);
14371 continue;
14372 }
301a9420
AM
14373
14374 end = (char *) enote + length;
14375 data_remaining = end - (char *) enote;
14376
14377 if (!is_ia64_vms (filedata))
14378 {
14379 min_notesz = offsetof (Elf_External_Note, name);
14380 if (data_remaining < min_notesz)
14381 {
55be8fd0
NC
14382 warn (_("\
14383malformed note encountered in section %s whilst scanning for build-id note\n"),
14384 printable_section_name (filedata, shdr));
f761cb13 14385 free (enote);
55be8fd0 14386 continue;
301a9420
AM
14387 }
14388 data_remaining -= min_notesz;
14389
14390 inote.type = BYTE_GET (enote->type);
14391 inote.namesz = BYTE_GET (enote->namesz);
14392 inote.namedata = enote->name;
14393 inote.descsz = BYTE_GET (enote->descsz);
14394 inote.descdata = ((char *) enote
14395 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
14396 inote.descpos = offset + (inote.descdata - (char *) enote);
14397 next = ((char *) enote
14398 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
14399 }
14400 else
14401 {
14402 Elf64_External_VMS_Note *vms_enote;
14403
14404 /* PR binutils/15191
14405 Make sure that there is enough data to read. */
14406 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14407 if (data_remaining < min_notesz)
14408 {
55be8fd0
NC
14409 warn (_("\
14410malformed note encountered in section %s whilst scanning for build-id note\n"),
14411 printable_section_name (filedata, shdr));
f761cb13 14412 free (enote);
55be8fd0 14413 continue;
301a9420
AM
14414 }
14415 data_remaining -= min_notesz;
14416
14417 vms_enote = (Elf64_External_VMS_Note *) enote;
14418 inote.type = BYTE_GET (vms_enote->type);
14419 inote.namesz = BYTE_GET (vms_enote->namesz);
14420 inote.namedata = vms_enote->name;
14421 inote.descsz = BYTE_GET (vms_enote->descsz);
14422 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14423 inote.descpos = offset + (inote.descdata - (char *) enote);
14424 next = inote.descdata + align_power (inote.descsz, 3);
14425 }
14426
14427 /* Skip malformed notes. */
14428 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
14429 || (size_t) (inote.descdata - inote.namedata) > data_remaining
14430 || (size_t) (next - inote.descdata) < inote.descsz
14431 || ((size_t) (next - inote.descdata)
14432 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
14433 {
55be8fd0
NC
14434 warn (_("\
14435malformed note encountered in section %s whilst scanning for build-id note\n"),
14436 printable_section_name (filedata, shdr));
f761cb13 14437 free (enote);
301a9420
AM
14438 continue;
14439 }
14440
14441 /* Check if this is the build-id note. If so then convert the build-id
14442 bytes to a hex string. */
14443 if (inote.namesz > 0
14444 && const_strneq (inote.namedata, "GNU")
14445 && inote.type == NT_GNU_BUILD_ID)
14446 {
14447 unsigned long j;
14448 char * build_id;
14449
14450 build_id = malloc (inote.descsz * 2 + 1);
14451 if (build_id == NULL)
f761cb13
AM
14452 {
14453 free (enote);
14454 return NULL;
14455 }
301a9420
AM
14456
14457 for (j = 0; j < inote.descsz; ++j)
14458 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
14459 build_id[inote.descsz * 2] = '\0';
f761cb13 14460 free (enote);
301a9420 14461
55be8fd0 14462 return (unsigned char *) build_id;
301a9420 14463 }
f761cb13 14464 free (enote);
301a9420
AM
14465 }
14466
14467 return NULL;
14468}
14469#endif /* HAVE_LIBDEBUGINFOD */
14470
657d0d47
CC
14471/* If this is not NULL, load_debug_section will only look for sections
14472 within the list of sections given here. */
32ec8896 14473static unsigned int * section_subset = NULL;
657d0d47 14474
32ec8896 14475bfd_boolean
dda8d76d 14476load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 14477{
2cf0635d
NC
14478 struct dwarf_section * section = &debug_displays [debug].section;
14479 Elf_Internal_Shdr * sec;
dda8d76d
NC
14480 Filedata * filedata = (Filedata *) data;
14481
f425ec66
NC
14482 /* Without section headers we cannot find any sections. */
14483 if (filedata->section_headers == NULL)
14484 return FALSE;
14485
9c1ce108
AM
14486 if (filedata->string_table == NULL
14487 && filedata->file_header.e_shstrndx != SHN_UNDEF
14488 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
14489 {
14490 Elf_Internal_Shdr * strs;
14491
14492 /* Read in the string table, so that we have section names to scan. */
14493 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
14494
4dff97b2 14495 if (strs != NULL && strs->sh_size != 0)
dda8d76d 14496 {
9c1ce108
AM
14497 filedata->string_table
14498 = (char *) get_data (NULL, filedata, strs->sh_offset,
14499 1, strs->sh_size, _("string table"));
dda8d76d 14500
9c1ce108
AM
14501 filedata->string_table_length
14502 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
14503 }
14504 }
d966045b
DJ
14505
14506 /* Locate the debug section. */
dda8d76d 14507 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
14508 if (sec != NULL)
14509 section->name = section->uncompressed_name;
14510 else
14511 {
dda8d76d 14512 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
14513 if (sec != NULL)
14514 section->name = section->compressed_name;
14515 }
14516 if (sec == NULL)
32ec8896 14517 return FALSE;
d966045b 14518
657d0d47
CC
14519 /* If we're loading from a subset of sections, and we've loaded
14520 a section matching this name before, it's likely that it's a
14521 different one. */
14522 if (section_subset != NULL)
14523 free_debug_section (debug);
14524
dda8d76d 14525 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
14526}
14527
19e6b90e
L
14528void
14529free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 14530{
2cf0635d 14531 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 14532
19e6b90e
L
14533 if (section->start == NULL)
14534 return;
1007acb3 14535
19e6b90e
L
14536 free ((char *) section->start);
14537 section->start = NULL;
14538 section->address = 0;
14539 section->size = 0;
a788aedd
AM
14540
14541 if (section->reloc_info != NULL)
14542 {
14543 free (section->reloc_info);
14544 section->reloc_info = NULL;
14545 section->num_relocs = 0;
14546 }
1007acb3
L
14547}
14548
32ec8896 14549static bfd_boolean
dda8d76d 14550display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 14551{
2cf0635d 14552 char * name = SECTION_NAME (section);
dda8d76d 14553 const char * print_name = printable_section_name (filedata, section);
19e6b90e 14554 bfd_size_type length;
32ec8896 14555 bfd_boolean result = TRUE;
3f5e193b 14556 int i;
1007acb3 14557
19e6b90e
L
14558 length = section->sh_size;
14559 if (length == 0)
1007acb3 14560 {
74e1a04b 14561 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 14562 return TRUE;
1007acb3 14563 }
5dff79d8
NC
14564 if (section->sh_type == SHT_NOBITS)
14565 {
14566 /* There is no point in dumping the contents of a debugging section
14567 which has the NOBITS type - the bits in the file will be random.
14568 This can happen when a file containing a .eh_frame section is
14569 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
14570 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
14571 print_name);
32ec8896 14572 return FALSE;
5dff79d8 14573 }
1007acb3 14574
0112cd26 14575 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 14576 name = ".debug_info";
1007acb3 14577
19e6b90e
L
14578 /* See if we know how to display the contents of this section. */
14579 for (i = 0; i < max; i++)
d85bf2ba
NC
14580 {
14581 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
14582 struct dwarf_section_display * display = debug_displays + i;
14583 struct dwarf_section * sec = & display->section;
d966045b 14584
d85bf2ba
NC
14585 if (streq (sec->uncompressed_name, name)
14586 || (id == line && const_strneq (name, ".debug_line."))
14587 || streq (sec->compressed_name, name))
14588 {
14589 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 14590
d85bf2ba
NC
14591 if (secondary)
14592 free_debug_section (id);
dda8d76d 14593
d85bf2ba
NC
14594 if (i == line && const_strneq (name, ".debug_line."))
14595 sec->name = name;
14596 else if (streq (sec->uncompressed_name, name))
14597 sec->name = sec->uncompressed_name;
14598 else
14599 sec->name = sec->compressed_name;
657d0d47 14600
d85bf2ba
NC
14601 if (load_specific_debug_section (id, section, filedata))
14602 {
14603 /* If this debug section is part of a CU/TU set in a .dwp file,
14604 restrict load_debug_section to the sections in that set. */
14605 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 14606
d85bf2ba 14607 result &= display->display (sec, filedata);
657d0d47 14608
d85bf2ba 14609 section_subset = NULL;
1007acb3 14610
d85bf2ba
NC
14611 if (secondary || (id != info && id != abbrev))
14612 free_debug_section (id);
14613 }
14614 break;
14615 }
14616 }
1007acb3 14617
19e6b90e 14618 if (i == max)
1007acb3 14619 {
74e1a04b 14620 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 14621 result = FALSE;
1007acb3
L
14622 }
14623
19e6b90e 14624 return result;
5b18a4bc 14625}
103f02d3 14626
aef1f6d0
DJ
14627/* Set DUMP_SECTS for all sections where dumps were requested
14628 based on section name. */
14629
14630static void
dda8d76d 14631initialise_dumps_byname (Filedata * filedata)
aef1f6d0 14632{
2cf0635d 14633 struct dump_list_entry * cur;
aef1f6d0
DJ
14634
14635 for (cur = dump_sects_byname; cur; cur = cur->next)
14636 {
14637 unsigned int i;
32ec8896 14638 bfd_boolean any = FALSE;
aef1f6d0 14639
dda8d76d
NC
14640 for (i = 0; i < filedata->file_header.e_shnum; i++)
14641 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 14642 {
6431e409 14643 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 14644 any = TRUE;
aef1f6d0
DJ
14645 }
14646
14647 if (!any)
14648 warn (_("Section '%s' was not dumped because it does not exist!\n"),
14649 cur->name);
14650 }
14651}
14652
32ec8896 14653static bfd_boolean
dda8d76d 14654process_section_contents (Filedata * filedata)
5b18a4bc 14655{
2cf0635d 14656 Elf_Internal_Shdr * section;
19e6b90e 14657 unsigned int i;
32ec8896 14658 bfd_boolean res = TRUE;
103f02d3 14659
19e6b90e 14660 if (! do_dump)
32ec8896 14661 return TRUE;
103f02d3 14662
dda8d76d 14663 initialise_dumps_byname (filedata);
aef1f6d0 14664
dda8d76d 14665 for (i = 0, section = filedata->section_headers;
6431e409 14666 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
14667 i++, section++)
14668 {
6431e409 14669 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 14670
19e6b90e 14671#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
14672 if (dump & DISASS_DUMP)
14673 {
14674 if (! disassemble_section (section, filedata))
14675 res = FALSE;
14676 }
19e6b90e 14677#endif
dda8d76d 14678 if (dump & HEX_DUMP)
32ec8896 14679 {
dda8d76d 14680 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
14681 res = FALSE;
14682 }
103f02d3 14683
dda8d76d 14684 if (dump & RELOC_DUMP)
32ec8896 14685 {
dda8d76d 14686 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
14687 res = FALSE;
14688 }
09c11c86 14689
dda8d76d 14690 if (dump & STRING_DUMP)
32ec8896 14691 {
dda8d76d 14692 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
14693 res = FALSE;
14694 }
cf13d699 14695
dda8d76d 14696 if (dump & DEBUG_DUMP)
32ec8896 14697 {
dda8d76d 14698 if (! display_debug_section (i, section, filedata))
32ec8896
NC
14699 res = FALSE;
14700 }
7d9813f1
NA
14701
14702 if (dump & CTF_DUMP)
14703 {
14704 if (! dump_section_as_ctf (section, filedata))
14705 res = FALSE;
14706 }
5b18a4bc 14707 }
103f02d3 14708
19e6b90e
L
14709 /* Check to see if the user requested a
14710 dump of a section that does not exist. */
6431e409 14711 while (i < filedata->dump.num_dump_sects)
0ee3043f 14712 {
6431e409 14713 if (filedata->dump.dump_sects[i])
32ec8896
NC
14714 {
14715 warn (_("Section %d was not dumped because it does not exist!\n"), i);
14716 res = FALSE;
14717 }
0ee3043f
NC
14718 i++;
14719 }
32ec8896
NC
14720
14721 return res;
5b18a4bc 14722}
103f02d3 14723
5b18a4bc 14724static void
19e6b90e 14725process_mips_fpe_exception (int mask)
5b18a4bc 14726{
19e6b90e
L
14727 if (mask)
14728 {
32ec8896
NC
14729 bfd_boolean first = TRUE;
14730
19e6b90e 14731 if (mask & OEX_FPU_INEX)
32ec8896 14732 fputs ("INEX", stdout), first = FALSE;
19e6b90e 14733 if (mask & OEX_FPU_UFLO)
32ec8896 14734 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14735 if (mask & OEX_FPU_OFLO)
32ec8896 14736 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14737 if (mask & OEX_FPU_DIV0)
32ec8896 14738 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
14739 if (mask & OEX_FPU_INVAL)
14740 printf ("%sINVAL", first ? "" : "|");
14741 }
5b18a4bc 14742 else
19e6b90e 14743 fputs ("0", stdout);
5b18a4bc 14744}
103f02d3 14745
f6f0e17b
NC
14746/* Display's the value of TAG at location P. If TAG is
14747 greater than 0 it is assumed to be an unknown tag, and
14748 a message is printed to this effect. Otherwise it is
14749 assumed that a message has already been printed.
14750
14751 If the bottom bit of TAG is set it assumed to have a
14752 string value, otherwise it is assumed to have an integer
14753 value.
14754
14755 Returns an updated P pointing to the first unread byte
14756 beyond the end of TAG's value.
14757
14758 Reads at or beyond END will not be made. */
14759
14760static unsigned char *
60abdbed 14761display_tag_value (signed int tag,
f6f0e17b
NC
14762 unsigned char * p,
14763 const unsigned char * const end)
14764{
14765 unsigned long val;
14766
14767 if (tag > 0)
14768 printf (" Tag_unknown_%d: ", tag);
14769
14770 if (p >= end)
14771 {
4082ef84 14772 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
14773 }
14774 else if (tag & 1)
14775 {
071436c6
NC
14776 /* PR 17531 file: 027-19978-0.004. */
14777 size_t maxlen = (end - p) - 1;
14778
14779 putchar ('"');
4082ef84
NC
14780 if (maxlen > 0)
14781 {
14782 print_symbol ((int) maxlen, (const char *) p);
14783 p += strnlen ((char *) p, maxlen) + 1;
14784 }
14785 else
14786 {
14787 printf (_("<corrupt string tag>"));
14788 p = (unsigned char *) end;
14789 }
071436c6 14790 printf ("\"\n");
f6f0e17b
NC
14791 }
14792 else
14793 {
cd30bcef 14794 READ_ULEB (val, p, end);
f6f0e17b
NC
14795 printf ("%ld (0x%lx)\n", val, val);
14796 }
14797
4082ef84 14798 assert (p <= end);
f6f0e17b
NC
14799 return p;
14800}
14801
53a346d8
CZ
14802/* ARC ABI attributes section. */
14803
14804static unsigned char *
14805display_arc_attribute (unsigned char * p,
14806 const unsigned char * const end)
14807{
14808 unsigned int tag;
53a346d8
CZ
14809 unsigned int val;
14810
cd30bcef 14811 READ_ULEB (tag, p, end);
53a346d8
CZ
14812
14813 switch (tag)
14814 {
14815 case Tag_ARC_PCS_config:
cd30bcef 14816 READ_ULEB (val, p, end);
53a346d8
CZ
14817 printf (" Tag_ARC_PCS_config: ");
14818 switch (val)
14819 {
14820 case 0:
14821 printf (_("Absent/Non standard\n"));
14822 break;
14823 case 1:
14824 printf (_("Bare metal/mwdt\n"));
14825 break;
14826 case 2:
14827 printf (_("Bare metal/newlib\n"));
14828 break;
14829 case 3:
14830 printf (_("Linux/uclibc\n"));
14831 break;
14832 case 4:
14833 printf (_("Linux/glibc\n"));
14834 break;
14835 default:
14836 printf (_("Unknown\n"));
14837 break;
14838 }
14839 break;
14840
14841 case Tag_ARC_CPU_base:
cd30bcef 14842 READ_ULEB (val, p, end);
53a346d8
CZ
14843 printf (" Tag_ARC_CPU_base: ");
14844 switch (val)
14845 {
14846 default:
14847 case TAG_CPU_NONE:
14848 printf (_("Absent\n"));
14849 break;
14850 case TAG_CPU_ARC6xx:
14851 printf ("ARC6xx\n");
14852 break;
14853 case TAG_CPU_ARC7xx:
14854 printf ("ARC7xx\n");
14855 break;
14856 case TAG_CPU_ARCEM:
14857 printf ("ARCEM\n");
14858 break;
14859 case TAG_CPU_ARCHS:
14860 printf ("ARCHS\n");
14861 break;
14862 }
14863 break;
14864
14865 case Tag_ARC_CPU_variation:
cd30bcef 14866 READ_ULEB (val, p, end);
53a346d8
CZ
14867 printf (" Tag_ARC_CPU_variation: ");
14868 switch (val)
14869 {
14870 default:
14871 if (val > 0 && val < 16)
53a346d8 14872 printf ("Core%d\n", val);
d8cbc93b
JL
14873 else
14874 printf ("Unknown\n");
14875 break;
14876
53a346d8
CZ
14877 case 0:
14878 printf (_("Absent\n"));
14879 break;
14880 }
14881 break;
14882
14883 case Tag_ARC_CPU_name:
14884 printf (" Tag_ARC_CPU_name: ");
14885 p = display_tag_value (-1, p, end);
14886 break;
14887
14888 case Tag_ARC_ABI_rf16:
cd30bcef 14889 READ_ULEB (val, p, end);
53a346d8
CZ
14890 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
14891 break;
14892
14893 case Tag_ARC_ABI_osver:
cd30bcef 14894 READ_ULEB (val, p, end);
53a346d8
CZ
14895 printf (" Tag_ARC_ABI_osver: v%d\n", val);
14896 break;
14897
14898 case Tag_ARC_ABI_pic:
14899 case Tag_ARC_ABI_sda:
cd30bcef 14900 READ_ULEB (val, p, end);
53a346d8
CZ
14901 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
14902 : " Tag_ARC_ABI_pic: ");
14903 switch (val)
14904 {
14905 case 0:
14906 printf (_("Absent\n"));
14907 break;
14908 case 1:
14909 printf ("MWDT\n");
14910 break;
14911 case 2:
14912 printf ("GNU\n");
14913 break;
14914 default:
14915 printf (_("Unknown\n"));
14916 break;
14917 }
14918 break;
14919
14920 case Tag_ARC_ABI_tls:
cd30bcef 14921 READ_ULEB (val, p, end);
53a346d8
CZ
14922 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
14923 break;
14924
14925 case Tag_ARC_ABI_enumsize:
cd30bcef 14926 READ_ULEB (val, p, end);
53a346d8
CZ
14927 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
14928 _("smallest"));
14929 break;
14930
14931 case Tag_ARC_ABI_exceptions:
cd30bcef 14932 READ_ULEB (val, p, end);
53a346d8
CZ
14933 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
14934 : _("default"));
14935 break;
14936
14937 case Tag_ARC_ABI_double_size:
cd30bcef 14938 READ_ULEB (val, p, end);
53a346d8
CZ
14939 printf (" Tag_ARC_ABI_double_size: %d\n", val);
14940 break;
14941
14942 case Tag_ARC_ISA_config:
14943 printf (" Tag_ARC_ISA_config: ");
14944 p = display_tag_value (-1, p, end);
14945 break;
14946
14947 case Tag_ARC_ISA_apex:
14948 printf (" Tag_ARC_ISA_apex: ");
14949 p = display_tag_value (-1, p, end);
14950 break;
14951
14952 case Tag_ARC_ISA_mpy_option:
cd30bcef 14953 READ_ULEB (val, p, end);
53a346d8
CZ
14954 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
14955 break;
14956
db1e1b45 14957 case Tag_ARC_ATR_version:
cd30bcef 14958 READ_ULEB (val, p, end);
db1e1b45 14959 printf (" Tag_ARC_ATR_version: %d\n", val);
14960 break;
14961
53a346d8
CZ
14962 default:
14963 return display_tag_value (tag & 1, p, end);
14964 }
14965
14966 return p;
14967}
14968
11c1ff18
PB
14969/* ARM EABI attributes section. */
14970typedef struct
14971{
70e99720 14972 unsigned int tag;
2cf0635d 14973 const char * name;
11c1ff18 14974 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 14975 unsigned int type;
2cf0635d 14976 const char ** table;
11c1ff18
PB
14977} arm_attr_public_tag;
14978
2cf0635d 14979static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 14980 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 14981 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 14982 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
2cf0635d
NC
14983static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
14984static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 14985 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 14986static const char * arm_attr_tag_FP_arch[] =
bca38921 14987 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 14988 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 14989static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 14990static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
14991 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
14992 "NEON for ARMv8.1"};
2cf0635d 14993static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
14994 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
14995 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 14996static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 14997 {"V6", "SB", "TLS", "Unused"};
2cf0635d 14998static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 14999 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 15000static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15001 {"Absolute", "PC-relative", "None"};
2cf0635d 15002static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15003 {"None", "direct", "GOT-indirect"};
2cf0635d 15004static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15005 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
15006static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15007static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15008 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
15009static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15010static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15011static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15012 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 15013static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 15014 {"Unused", "small", "int", "forced to int"};
2cf0635d 15015static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15016 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 15017static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 15018 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 15019static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15020 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 15021static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15022 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15023 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 15024static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15025 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15026 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 15027static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 15028static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 15029 {"Not Allowed", "Allowed"};
2cf0635d 15030static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15031 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
15032static const char * arm_attr_tag_DSP_extension[] =
15033 {"Follow architecture", "Allowed"};
dd24e3da 15034static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
15035 {"Not Allowed", "Allowed"};
15036static const char * arm_attr_tag_DIV_use[] =
dd24e3da 15037 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15038 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
15039static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15040static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 15041 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15042 "TrustZone and Virtualization Extensions"};
dd24e3da 15043static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15044 {"Not Allowed", "Allowed"};
11c1ff18 15045
a7ad558c
AV
15046static const char * arm_attr_tag_MVE_arch[] =
15047 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15048
11c1ff18
PB
15049#define LOOKUP(id, name) \
15050 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15051static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15052{
15053 {4, "CPU_raw_name", 1, NULL},
15054 {5, "CPU_name", 1, NULL},
15055 LOOKUP(6, CPU_arch),
15056 {7, "CPU_arch_profile", 0, NULL},
15057 LOOKUP(8, ARM_ISA_use),
15058 LOOKUP(9, THUMB_ISA_use),
75375b3e 15059 LOOKUP(10, FP_arch),
11c1ff18 15060 LOOKUP(11, WMMX_arch),
f5f53991
AS
15061 LOOKUP(12, Advanced_SIMD_arch),
15062 LOOKUP(13, PCS_config),
11c1ff18
PB
15063 LOOKUP(14, ABI_PCS_R9_use),
15064 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15065 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15066 LOOKUP(17, ABI_PCS_GOT_use),
15067 LOOKUP(18, ABI_PCS_wchar_t),
15068 LOOKUP(19, ABI_FP_rounding),
15069 LOOKUP(20, ABI_FP_denormal),
15070 LOOKUP(21, ABI_FP_exceptions),
15071 LOOKUP(22, ABI_FP_user_exceptions),
15072 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15073 {24, "ABI_align_needed", 0, NULL},
15074 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15075 LOOKUP(26, ABI_enum_size),
15076 LOOKUP(27, ABI_HardFP_use),
15077 LOOKUP(28, ABI_VFP_args),
15078 LOOKUP(29, ABI_WMMX_args),
15079 LOOKUP(30, ABI_optimization_goals),
15080 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15081 {32, "compatibility", 0, NULL},
f5f53991 15082 LOOKUP(34, CPU_unaligned_access),
75375b3e 15083 LOOKUP(36, FP_HP_extension),
8e79c3df 15084 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15085 LOOKUP(42, MPextension_use),
15086 LOOKUP(44, DIV_use),
15afaa63 15087 LOOKUP(46, DSP_extension),
a7ad558c 15088 LOOKUP(48, MVE_arch),
f5f53991
AS
15089 {64, "nodefaults", 0, NULL},
15090 {65, "also_compatible_with", 0, NULL},
15091 LOOKUP(66, T2EE_use),
15092 {67, "conformance", 1, NULL},
15093 LOOKUP(68, Virtualization_use),
cd21e546 15094 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15095};
15096#undef LOOKUP
15097
11c1ff18 15098static unsigned char *
f6f0e17b
NC
15099display_arm_attribute (unsigned char * p,
15100 const unsigned char * const end)
11c1ff18 15101{
70e99720 15102 unsigned int tag;
70e99720 15103 unsigned int val;
2cf0635d 15104 arm_attr_public_tag * attr;
11c1ff18 15105 unsigned i;
70e99720 15106 unsigned int type;
11c1ff18 15107
cd30bcef 15108 READ_ULEB (tag, p, end);
11c1ff18 15109 attr = NULL;
2cf0635d 15110 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15111 {
15112 if (arm_attr_public_tags[i].tag == tag)
15113 {
15114 attr = &arm_attr_public_tags[i];
15115 break;
15116 }
15117 }
15118
15119 if (attr)
15120 {
15121 printf (" Tag_%s: ", attr->name);
15122 switch (attr->type)
15123 {
15124 case 0:
15125 switch (tag)
15126 {
15127 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15128 READ_ULEB (val, p, end);
11c1ff18
PB
15129 switch (val)
15130 {
2b692964
NC
15131 case 0: printf (_("None\n")); break;
15132 case 'A': printf (_("Application\n")); break;
15133 case 'R': printf (_("Realtime\n")); break;
15134 case 'M': printf (_("Microcontroller\n")); break;
15135 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15136 default: printf ("??? (%d)\n", val); break;
15137 }
15138 break;
15139
75375b3e 15140 case 24: /* Tag_align_needed. */
cd30bcef 15141 READ_ULEB (val, p, end);
75375b3e
MGD
15142 switch (val)
15143 {
2b692964
NC
15144 case 0: printf (_("None\n")); break;
15145 case 1: printf (_("8-byte\n")); break;
15146 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15147 case 3: printf ("??? 3\n"); break;
15148 default:
15149 if (val <= 12)
dd24e3da 15150 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15151 1 << val);
15152 else
15153 printf ("??? (%d)\n", val);
15154 break;
15155 }
15156 break;
15157
15158 case 25: /* Tag_align_preserved. */
cd30bcef 15159 READ_ULEB (val, p, end);
75375b3e
MGD
15160 switch (val)
15161 {
2b692964
NC
15162 case 0: printf (_("None\n")); break;
15163 case 1: printf (_("8-byte, except leaf SP\n")); break;
15164 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
15165 case 3: printf ("??? 3\n"); break;
15166 default:
15167 if (val <= 12)
dd24e3da 15168 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15169 1 << val);
15170 else
15171 printf ("??? (%d)\n", val);
15172 break;
15173 }
15174 break;
15175
11c1ff18 15176 case 32: /* Tag_compatibility. */
071436c6 15177 {
cd30bcef 15178 READ_ULEB (val, p, end);
071436c6 15179 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15180 if (p < end - 1)
15181 {
15182 size_t maxlen = (end - p) - 1;
15183
15184 print_symbol ((int) maxlen, (const char *) p);
15185 p += strnlen ((char *) p, maxlen) + 1;
15186 }
15187 else
15188 {
15189 printf (_("<corrupt>"));
15190 p = (unsigned char *) end;
15191 }
071436c6 15192 putchar ('\n');
071436c6 15193 }
11c1ff18
PB
15194 break;
15195
f5f53991 15196 case 64: /* Tag_nodefaults. */
541a3cbd
NC
15197 /* PR 17531: file: 001-505008-0.01. */
15198 if (p < end)
15199 p++;
2b692964 15200 printf (_("True\n"));
f5f53991
AS
15201 break;
15202
15203 case 65: /* Tag_also_compatible_with. */
cd30bcef 15204 READ_ULEB (val, p, end);
f5f53991
AS
15205 if (val == 6 /* Tag_CPU_arch. */)
15206 {
cd30bcef 15207 READ_ULEB (val, p, end);
071436c6 15208 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
15209 printf ("??? (%d)\n", val);
15210 else
15211 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
15212 }
15213 else
15214 printf ("???\n");
071436c6
NC
15215 while (p < end && *(p++) != '\0' /* NUL terminator. */)
15216 ;
f5f53991
AS
15217 break;
15218
11c1ff18 15219 default:
bee0ee85
NC
15220 printf (_("<unknown: %d>\n"), tag);
15221 break;
11c1ff18
PB
15222 }
15223 return p;
15224
15225 case 1:
f6f0e17b 15226 return display_tag_value (-1, p, end);
11c1ff18 15227 case 2:
f6f0e17b 15228 return display_tag_value (0, p, end);
11c1ff18
PB
15229
15230 default:
15231 assert (attr->type & 0x80);
cd30bcef 15232 READ_ULEB (val, p, end);
11c1ff18
PB
15233 type = attr->type & 0x7f;
15234 if (val >= type)
15235 printf ("??? (%d)\n", val);
15236 else
15237 printf ("%s\n", attr->table[val]);
15238 return p;
15239 }
15240 }
11c1ff18 15241
f6f0e17b 15242 return display_tag_value (tag, p, end);
11c1ff18
PB
15243}
15244
104d59d1 15245static unsigned char *
60bca95a 15246display_gnu_attribute (unsigned char * p,
60abdbed 15247 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 15248 const unsigned char * const end)
104d59d1 15249{
cd30bcef 15250 unsigned int tag;
60abdbed 15251 unsigned int val;
104d59d1 15252
cd30bcef 15253 READ_ULEB (tag, p, end);
104d59d1
JM
15254
15255 /* Tag_compatibility is the only generic GNU attribute defined at
15256 present. */
15257 if (tag == 32)
15258 {
cd30bcef 15259 READ_ULEB (val, p, end);
071436c6
NC
15260
15261 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
15262 if (p == end)
15263 {
071436c6 15264 printf (_("<corrupt>\n"));
f6f0e17b
NC
15265 warn (_("corrupt vendor attribute\n"));
15266 }
15267 else
15268 {
4082ef84
NC
15269 if (p < end - 1)
15270 {
15271 size_t maxlen = (end - p) - 1;
071436c6 15272
4082ef84
NC
15273 print_symbol ((int) maxlen, (const char *) p);
15274 p += strnlen ((char *) p, maxlen) + 1;
15275 }
15276 else
15277 {
15278 printf (_("<corrupt>"));
15279 p = (unsigned char *) end;
15280 }
071436c6 15281 putchar ('\n');
f6f0e17b 15282 }
104d59d1
JM
15283 return p;
15284 }
15285
15286 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 15287 return display_proc_gnu_attribute (p, tag, end);
104d59d1 15288
f6f0e17b 15289 return display_tag_value (tag, p, end);
104d59d1
JM
15290}
15291
34c8bcba 15292static unsigned char *
f6f0e17b 15293display_power_gnu_attribute (unsigned char * p,
60abdbed 15294 unsigned int tag,
f6f0e17b 15295 const unsigned char * const end)
34c8bcba 15296{
005d79fd 15297 unsigned int val;
34c8bcba
JM
15298
15299 if (tag == Tag_GNU_Power_ABI_FP)
15300 {
34c8bcba 15301 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 15302 if (p == end)
005d79fd
AM
15303 {
15304 printf (_("<corrupt>\n"));
15305 return p;
15306 }
cd30bcef 15307 READ_ULEB (val, p, end);
60bca95a 15308
005d79fd
AM
15309 if (val > 15)
15310 printf ("(%#x), ", val);
15311
15312 switch (val & 3)
34c8bcba
JM
15313 {
15314 case 0:
005d79fd 15315 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
15316 break;
15317 case 1:
005d79fd 15318 printf (_("hard float, "));
34c8bcba
JM
15319 break;
15320 case 2:
005d79fd 15321 printf (_("soft float, "));
34c8bcba 15322 break;
3c7b9897 15323 case 3:
005d79fd 15324 printf (_("single-precision hard float, "));
3c7b9897 15325 break;
005d79fd
AM
15326 }
15327
15328 switch (val & 0xC)
15329 {
15330 case 0:
15331 printf (_("unspecified long double\n"));
15332 break;
15333 case 4:
15334 printf (_("128-bit IBM long double\n"));
15335 break;
15336 case 8:
15337 printf (_("64-bit long double\n"));
15338 break;
15339 case 12:
15340 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
15341 break;
15342 }
15343 return p;
005d79fd 15344 }
34c8bcba 15345
c6e65352
DJ
15346 if (tag == Tag_GNU_Power_ABI_Vector)
15347 {
c6e65352 15348 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 15349 if (p == end)
005d79fd
AM
15350 {
15351 printf (_("<corrupt>\n"));
15352 return p;
15353 }
cd30bcef 15354 READ_ULEB (val, p, end);
005d79fd
AM
15355
15356 if (val > 3)
15357 printf ("(%#x), ", val);
15358
15359 switch (val & 3)
c6e65352
DJ
15360 {
15361 case 0:
005d79fd 15362 printf (_("unspecified\n"));
c6e65352
DJ
15363 break;
15364 case 1:
005d79fd 15365 printf (_("generic\n"));
c6e65352
DJ
15366 break;
15367 case 2:
15368 printf ("AltiVec\n");
15369 break;
15370 case 3:
15371 printf ("SPE\n");
15372 break;
c6e65352
DJ
15373 }
15374 return p;
005d79fd 15375 }
c6e65352 15376
f82e0623
NF
15377 if (tag == Tag_GNU_Power_ABI_Struct_Return)
15378 {
005d79fd 15379 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 15380 if (p == end)
f6f0e17b 15381 {
005d79fd 15382 printf (_("<corrupt>\n"));
f6f0e17b
NC
15383 return p;
15384 }
cd30bcef 15385 READ_ULEB (val, p, end);
0b4362b0 15386
005d79fd
AM
15387 if (val > 2)
15388 printf ("(%#x), ", val);
15389
15390 switch (val & 3)
15391 {
15392 case 0:
15393 printf (_("unspecified\n"));
15394 break;
15395 case 1:
15396 printf ("r3/r4\n");
15397 break;
15398 case 2:
15399 printf (_("memory\n"));
15400 break;
15401 case 3:
15402 printf ("???\n");
15403 break;
15404 }
f82e0623
NF
15405 return p;
15406 }
15407
f6f0e17b 15408 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
15409}
15410
643f7afb
AK
15411static unsigned char *
15412display_s390_gnu_attribute (unsigned char * p,
60abdbed 15413 unsigned int tag,
643f7afb
AK
15414 const unsigned char * const end)
15415{
cd30bcef 15416 unsigned int val;
643f7afb
AK
15417
15418 if (tag == Tag_GNU_S390_ABI_Vector)
15419 {
643f7afb 15420 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 15421 READ_ULEB (val, p, end);
643f7afb
AK
15422
15423 switch (val)
15424 {
15425 case 0:
15426 printf (_("any\n"));
15427 break;
15428 case 1:
15429 printf (_("software\n"));
15430 break;
15431 case 2:
15432 printf (_("hardware\n"));
15433 break;
15434 default:
15435 printf ("??? (%d)\n", val);
15436 break;
15437 }
15438 return p;
15439 }
15440
15441 return display_tag_value (tag & 1, p, end);
15442}
15443
9e8c70f9 15444static void
60abdbed 15445display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
15446{
15447 if (mask)
15448 {
32ec8896 15449 bfd_boolean first = TRUE;
071436c6 15450
9e8c70f9 15451 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 15452 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 15453 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 15454 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 15455 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 15456 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 15457 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 15458 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 15459 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 15460 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 15461 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 15462 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 15463 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 15464 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 15465 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 15466 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 15467 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 15468 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 15469 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 15470 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 15471 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 15472 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 15473 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 15474 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 15475 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 15476 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 15477 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 15478 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 15479 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 15480 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 15481 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 15482 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
15483 }
15484 else
071436c6
NC
15485 fputc ('0', stdout);
15486 fputc ('\n', stdout);
9e8c70f9
DM
15487}
15488
3d68f91c 15489static void
60abdbed 15490display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
15491{
15492 if (mask)
15493 {
32ec8896 15494 bfd_boolean first = TRUE;
071436c6 15495
3d68f91c 15496 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 15497 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 15498 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 15499 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 15500 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 15501 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 15502 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 15503 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 15504 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 15505 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 15506 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 15507 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 15508 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 15509 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 15510 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 15511 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 15512 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 15513 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 15514 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 15515 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 15516 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 15517 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
15518 }
15519 else
071436c6
NC
15520 fputc ('0', stdout);
15521 fputc ('\n', stdout);
3d68f91c
JM
15522}
15523
9e8c70f9 15524static unsigned char *
f6f0e17b 15525display_sparc_gnu_attribute (unsigned char * p,
60abdbed 15526 unsigned int tag,
f6f0e17b 15527 const unsigned char * const end)
9e8c70f9 15528{
cd30bcef 15529 unsigned int val;
3d68f91c 15530
9e8c70f9
DM
15531 if (tag == Tag_GNU_Sparc_HWCAPS)
15532 {
cd30bcef 15533 READ_ULEB (val, p, end);
9e8c70f9 15534 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
15535 display_sparc_hwcaps (val);
15536 return p;
3d68f91c
JM
15537 }
15538 if (tag == Tag_GNU_Sparc_HWCAPS2)
15539 {
cd30bcef 15540 READ_ULEB (val, p, end);
3d68f91c
JM
15541 printf (" Tag_GNU_Sparc_HWCAPS2: ");
15542 display_sparc_hwcaps2 (val);
15543 return p;
15544 }
9e8c70f9 15545
f6f0e17b 15546 return display_tag_value (tag, p, end);
9e8c70f9
DM
15547}
15548
351cdf24 15549static void
32ec8896 15550print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
15551{
15552 switch (val)
15553 {
15554 case Val_GNU_MIPS_ABI_FP_ANY:
15555 printf (_("Hard or soft float\n"));
15556 break;
15557 case Val_GNU_MIPS_ABI_FP_DOUBLE:
15558 printf (_("Hard float (double precision)\n"));
15559 break;
15560 case Val_GNU_MIPS_ABI_FP_SINGLE:
15561 printf (_("Hard float (single precision)\n"));
15562 break;
15563 case Val_GNU_MIPS_ABI_FP_SOFT:
15564 printf (_("Soft float\n"));
15565 break;
15566 case Val_GNU_MIPS_ABI_FP_OLD_64:
15567 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
15568 break;
15569 case Val_GNU_MIPS_ABI_FP_XX:
15570 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
15571 break;
15572 case Val_GNU_MIPS_ABI_FP_64:
15573 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
15574 break;
15575 case Val_GNU_MIPS_ABI_FP_64A:
15576 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
15577 break;
3350cc01
CM
15578 case Val_GNU_MIPS_ABI_FP_NAN2008:
15579 printf (_("NaN 2008 compatibility\n"));
15580 break;
351cdf24
MF
15581 default:
15582 printf ("??? (%d)\n", val);
15583 break;
15584 }
15585}
15586
2cf19d5c 15587static unsigned char *
f6f0e17b 15588display_mips_gnu_attribute (unsigned char * p,
60abdbed 15589 unsigned int tag,
f6f0e17b 15590 const unsigned char * const end)
2cf19d5c 15591{
2cf19d5c
JM
15592 if (tag == Tag_GNU_MIPS_ABI_FP)
15593 {
32ec8896 15594 unsigned int val;
f6f0e17b 15595
2cf19d5c 15596 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 15597 READ_ULEB (val, p, end);
351cdf24 15598 print_mips_fp_abi_value (val);
2cf19d5c
JM
15599 return p;
15600 }
15601
a9f58168
CF
15602 if (tag == Tag_GNU_MIPS_ABI_MSA)
15603 {
32ec8896 15604 unsigned int val;
a9f58168 15605
a9f58168 15606 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 15607 READ_ULEB (val, p, end);
a9f58168
CF
15608
15609 switch (val)
15610 {
15611 case Val_GNU_MIPS_ABI_MSA_ANY:
15612 printf (_("Any MSA or not\n"));
15613 break;
15614 case Val_GNU_MIPS_ABI_MSA_128:
15615 printf (_("128-bit MSA\n"));
15616 break;
15617 default:
15618 printf ("??? (%d)\n", val);
15619 break;
15620 }
15621 return p;
15622 }
15623
f6f0e17b 15624 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
15625}
15626
59e6276b 15627static unsigned char *
f6f0e17b
NC
15628display_tic6x_attribute (unsigned char * p,
15629 const unsigned char * const end)
59e6276b 15630{
60abdbed 15631 unsigned int tag;
cd30bcef 15632 unsigned int val;
59e6276b 15633
cd30bcef 15634 READ_ULEB (tag, p, end);
59e6276b
JM
15635
15636 switch (tag)
15637 {
75fa6dc1 15638 case Tag_ISA:
75fa6dc1 15639 printf (" Tag_ISA: ");
cd30bcef 15640 READ_ULEB (val, p, end);
59e6276b
JM
15641
15642 switch (val)
15643 {
75fa6dc1 15644 case C6XABI_Tag_ISA_none:
59e6276b
JM
15645 printf (_("None\n"));
15646 break;
75fa6dc1 15647 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
15648 printf ("C62x\n");
15649 break;
75fa6dc1 15650 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
15651 printf ("C67x\n");
15652 break;
75fa6dc1 15653 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
15654 printf ("C67x+\n");
15655 break;
75fa6dc1 15656 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
15657 printf ("C64x\n");
15658 break;
75fa6dc1 15659 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
15660 printf ("C64x+\n");
15661 break;
75fa6dc1 15662 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
15663 printf ("C674x\n");
15664 break;
15665 default:
15666 printf ("??? (%d)\n", val);
15667 break;
15668 }
15669 return p;
15670
87779176 15671 case Tag_ABI_wchar_t:
87779176 15672 printf (" Tag_ABI_wchar_t: ");
cd30bcef 15673 READ_ULEB (val, p, end);
87779176
JM
15674 switch (val)
15675 {
15676 case 0:
15677 printf (_("Not used\n"));
15678 break;
15679 case 1:
15680 printf (_("2 bytes\n"));
15681 break;
15682 case 2:
15683 printf (_("4 bytes\n"));
15684 break;
15685 default:
15686 printf ("??? (%d)\n", val);
15687 break;
15688 }
15689 return p;
15690
15691 case Tag_ABI_stack_align_needed:
87779176 15692 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 15693 READ_ULEB (val, p, end);
87779176
JM
15694 switch (val)
15695 {
15696 case 0:
15697 printf (_("8-byte\n"));
15698 break;
15699 case 1:
15700 printf (_("16-byte\n"));
15701 break;
15702 default:
15703 printf ("??? (%d)\n", val);
15704 break;
15705 }
15706 return p;
15707
15708 case Tag_ABI_stack_align_preserved:
cd30bcef 15709 READ_ULEB (val, p, end);
87779176
JM
15710 printf (" Tag_ABI_stack_align_preserved: ");
15711 switch (val)
15712 {
15713 case 0:
15714 printf (_("8-byte\n"));
15715 break;
15716 case 1:
15717 printf (_("16-byte\n"));
15718 break;
15719 default:
15720 printf ("??? (%d)\n", val);
15721 break;
15722 }
15723 return p;
15724
b5593623 15725 case Tag_ABI_DSBT:
cd30bcef 15726 READ_ULEB (val, p, end);
b5593623
JM
15727 printf (" Tag_ABI_DSBT: ");
15728 switch (val)
15729 {
15730 case 0:
15731 printf (_("DSBT addressing not used\n"));
15732 break;
15733 case 1:
15734 printf (_("DSBT addressing used\n"));
15735 break;
15736 default:
15737 printf ("??? (%d)\n", val);
15738 break;
15739 }
15740 return p;
15741
87779176 15742 case Tag_ABI_PID:
cd30bcef 15743 READ_ULEB (val, p, end);
87779176
JM
15744 printf (" Tag_ABI_PID: ");
15745 switch (val)
15746 {
15747 case 0:
15748 printf (_("Data addressing position-dependent\n"));
15749 break;
15750 case 1:
15751 printf (_("Data addressing position-independent, GOT near DP\n"));
15752 break;
15753 case 2:
15754 printf (_("Data addressing position-independent, GOT far from DP\n"));
15755 break;
15756 default:
15757 printf ("??? (%d)\n", val);
15758 break;
15759 }
15760 return p;
15761
15762 case Tag_ABI_PIC:
cd30bcef 15763 READ_ULEB (val, p, end);
87779176
JM
15764 printf (" Tag_ABI_PIC: ");
15765 switch (val)
15766 {
15767 case 0:
15768 printf (_("Code addressing position-dependent\n"));
15769 break;
15770 case 1:
15771 printf (_("Code addressing position-independent\n"));
15772 break;
15773 default:
15774 printf ("??? (%d)\n", val);
15775 break;
15776 }
15777 return p;
15778
15779 case Tag_ABI_array_object_alignment:
cd30bcef 15780 READ_ULEB (val, p, end);
87779176
JM
15781 printf (" Tag_ABI_array_object_alignment: ");
15782 switch (val)
15783 {
15784 case 0:
15785 printf (_("8-byte\n"));
15786 break;
15787 case 1:
15788 printf (_("4-byte\n"));
15789 break;
15790 case 2:
15791 printf (_("16-byte\n"));
15792 break;
15793 default:
15794 printf ("??? (%d)\n", val);
15795 break;
15796 }
15797 return p;
15798
15799 case Tag_ABI_array_object_align_expected:
cd30bcef 15800 READ_ULEB (val, p, end);
87779176
JM
15801 printf (" Tag_ABI_array_object_align_expected: ");
15802 switch (val)
15803 {
15804 case 0:
15805 printf (_("8-byte\n"));
15806 break;
15807 case 1:
15808 printf (_("4-byte\n"));
15809 break;
15810 case 2:
15811 printf (_("16-byte\n"));
15812 break;
15813 default:
15814 printf ("??? (%d)\n", val);
15815 break;
15816 }
15817 return p;
15818
3cbd1c06 15819 case Tag_ABI_compatibility:
071436c6 15820 {
cd30bcef 15821 READ_ULEB (val, p, end);
071436c6 15822 printf (" Tag_ABI_compatibility: ");
071436c6 15823 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15824 if (p < end - 1)
15825 {
15826 size_t maxlen = (end - p) - 1;
15827
15828 print_symbol ((int) maxlen, (const char *) p);
15829 p += strnlen ((char *) p, maxlen) + 1;
15830 }
15831 else
15832 {
15833 printf (_("<corrupt>"));
15834 p = (unsigned char *) end;
15835 }
071436c6 15836 putchar ('\n');
071436c6
NC
15837 return p;
15838 }
87779176
JM
15839
15840 case Tag_ABI_conformance:
071436c6 15841 {
4082ef84
NC
15842 printf (" Tag_ABI_conformance: \"");
15843 if (p < end - 1)
15844 {
15845 size_t maxlen = (end - p) - 1;
071436c6 15846
4082ef84
NC
15847 print_symbol ((int) maxlen, (const char *) p);
15848 p += strnlen ((char *) p, maxlen) + 1;
15849 }
15850 else
15851 {
15852 printf (_("<corrupt>"));
15853 p = (unsigned char *) end;
15854 }
071436c6 15855 printf ("\"\n");
071436c6
NC
15856 return p;
15857 }
59e6276b
JM
15858 }
15859
f6f0e17b
NC
15860 return display_tag_value (tag, p, end);
15861}
59e6276b 15862
f6f0e17b 15863static void
60abdbed 15864display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
15865{
15866 unsigned long addr = 0;
15867 size_t bytes = end - p;
15868
feceaa59 15869 assert (end >= p);
f6f0e17b 15870 while (bytes)
87779176 15871 {
f6f0e17b
NC
15872 int j;
15873 int k;
15874 int lbytes = (bytes > 16 ? 16 : bytes);
15875
15876 printf (" 0x%8.8lx ", addr);
15877
15878 for (j = 0; j < 16; j++)
15879 {
15880 if (j < lbytes)
15881 printf ("%2.2x", p[j]);
15882 else
15883 printf (" ");
15884
15885 if ((j & 3) == 3)
15886 printf (" ");
15887 }
15888
15889 for (j = 0; j < lbytes; j++)
15890 {
15891 k = p[j];
15892 if (k >= ' ' && k < 0x7f)
15893 printf ("%c", k);
15894 else
15895 printf (".");
15896 }
15897
15898 putchar ('\n');
15899
15900 p += lbytes;
15901 bytes -= lbytes;
15902 addr += lbytes;
87779176 15903 }
59e6276b 15904
f6f0e17b 15905 putchar ('\n');
59e6276b
JM
15906}
15907
13761a11
NC
15908static unsigned char *
15909display_msp430x_attribute (unsigned char * p,
15910 const unsigned char * const end)
15911{
60abdbed
NC
15912 unsigned int val;
15913 unsigned int tag;
13761a11 15914
cd30bcef 15915 READ_ULEB (tag, p, end);
0b4362b0 15916
13761a11
NC
15917 switch (tag)
15918 {
15919 case OFBA_MSPABI_Tag_ISA:
13761a11 15920 printf (" Tag_ISA: ");
cd30bcef 15921 READ_ULEB (val, p, end);
13761a11
NC
15922 switch (val)
15923 {
15924 case 0: printf (_("None\n")); break;
15925 case 1: printf (_("MSP430\n")); break;
15926 case 2: printf (_("MSP430X\n")); break;
15927 default: printf ("??? (%d)\n", val); break;
15928 }
15929 break;
15930
15931 case OFBA_MSPABI_Tag_Code_Model:
13761a11 15932 printf (" Tag_Code_Model: ");
cd30bcef 15933 READ_ULEB (val, p, end);
13761a11
NC
15934 switch (val)
15935 {
15936 case 0: printf (_("None\n")); break;
15937 case 1: printf (_("Small\n")); break;
15938 case 2: printf (_("Large\n")); break;
15939 default: printf ("??? (%d)\n", val); break;
15940 }
15941 break;
15942
15943 case OFBA_MSPABI_Tag_Data_Model:
13761a11 15944 printf (" Tag_Data_Model: ");
cd30bcef 15945 READ_ULEB (val, p, end);
13761a11
NC
15946 switch (val)
15947 {
15948 case 0: printf (_("None\n")); break;
15949 case 1: printf (_("Small\n")); break;
15950 case 2: printf (_("Large\n")); break;
15951 case 3: printf (_("Restricted Large\n")); break;
15952 default: printf ("??? (%d)\n", val); break;
15953 }
15954 break;
15955
15956 default:
15957 printf (_(" <unknown tag %d>: "), tag);
15958
15959 if (tag & 1)
15960 {
071436c6 15961 putchar ('"');
4082ef84
NC
15962 if (p < end - 1)
15963 {
15964 size_t maxlen = (end - p) - 1;
15965
15966 print_symbol ((int) maxlen, (const char *) p);
15967 p += strnlen ((char *) p, maxlen) + 1;
15968 }
15969 else
15970 {
15971 printf (_("<corrupt>"));
15972 p = (unsigned char *) end;
15973 }
071436c6 15974 printf ("\"\n");
13761a11
NC
15975 }
15976 else
15977 {
cd30bcef 15978 READ_ULEB (val, p, end);
13761a11
NC
15979 printf ("%d (0x%x)\n", val, val);
15980 }
15981 break;
15982 }
15983
4082ef84 15984 assert (p <= end);
13761a11
NC
15985 return p;
15986}
15987
c0ea7c52
JL
15988static unsigned char *
15989display_msp430_gnu_attribute (unsigned char * p,
15990 unsigned int tag,
15991 const unsigned char * const end)
15992{
15993 if (tag == Tag_GNU_MSP430_Data_Region)
15994 {
cd30bcef 15995 unsigned int val;
c0ea7c52 15996
c0ea7c52 15997 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 15998 READ_ULEB (val, p, end);
c0ea7c52
JL
15999
16000 switch (val)
16001 {
16002 case Val_GNU_MSP430_Data_Region_Any:
16003 printf (_("Any Region\n"));
16004 break;
16005 case Val_GNU_MSP430_Data_Region_Lower:
16006 printf (_("Lower Region Only\n"));
16007 break;
16008 default:
cd30bcef 16009 printf ("??? (%u)\n", val);
c0ea7c52
JL
16010 }
16011 return p;
16012 }
16013 return display_tag_value (tag & 1, p, end);
16014}
16015
2dc8dd17
JW
16016struct riscv_attr_tag_t {
16017 const char *name;
cd30bcef 16018 unsigned int tag;
2dc8dd17
JW
16019};
16020
16021static struct riscv_attr_tag_t riscv_attr_tag[] =
16022{
16023#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16024 T(arch),
16025 T(priv_spec),
16026 T(priv_spec_minor),
16027 T(priv_spec_revision),
16028 T(unaligned_access),
16029 T(stack_align),
16030#undef T
16031};
16032
16033static unsigned char *
16034display_riscv_attribute (unsigned char *p,
16035 const unsigned char * const end)
16036{
cd30bcef
AM
16037 unsigned int val;
16038 unsigned int tag;
2dc8dd17
JW
16039 struct riscv_attr_tag_t *attr = NULL;
16040 unsigned i;
16041
cd30bcef 16042 READ_ULEB (tag, p, end);
2dc8dd17
JW
16043
16044 /* Find the name of attribute. */
16045 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16046 {
16047 if (riscv_attr_tag[i].tag == tag)
16048 {
16049 attr = &riscv_attr_tag[i];
16050 break;
16051 }
16052 }
16053
16054 if (attr)
16055 printf (" %s: ", attr->name);
16056 else
16057 return display_tag_value (tag, p, end);
16058
16059 switch (tag)
16060 {
16061 case Tag_RISCV_priv_spec:
16062 case Tag_RISCV_priv_spec_minor:
16063 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16064 READ_ULEB (val, p, end);
16065 printf (_("%u\n"), val);
2dc8dd17
JW
16066 break;
16067 case Tag_RISCV_unaligned_access:
cd30bcef 16068 READ_ULEB (val, p, end);
2dc8dd17
JW
16069 switch (val)
16070 {
16071 case 0:
16072 printf (_("No unaligned access\n"));
16073 break;
16074 case 1:
16075 printf (_("Unaligned access\n"));
16076 break;
16077 }
16078 break;
16079 case Tag_RISCV_stack_align:
cd30bcef
AM
16080 READ_ULEB (val, p, end);
16081 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16082 break;
16083 case Tag_RISCV_arch:
16084 p = display_tag_value (-1, p, end);
16085 break;
16086 default:
16087 return display_tag_value (tag, p, end);
16088 }
16089
16090 return p;
16091}
16092
32ec8896 16093static bfd_boolean
dda8d76d 16094process_attributes (Filedata * filedata,
60bca95a 16095 const char * public_name,
104d59d1 16096 unsigned int proc_type,
f6f0e17b 16097 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 16098 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 16099{
2cf0635d 16100 Elf_Internal_Shdr * sect;
11c1ff18 16101 unsigned i;
32ec8896 16102 bfd_boolean res = TRUE;
11c1ff18
PB
16103
16104 /* Find the section header so that we get the size. */
dda8d76d
NC
16105 for (i = 0, sect = filedata->section_headers;
16106 i < filedata->file_header.e_shnum;
11c1ff18
PB
16107 i++, sect++)
16108 {
071436c6
NC
16109 unsigned char * contents;
16110 unsigned char * p;
16111
104d59d1 16112 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
16113 continue;
16114
dda8d76d 16115 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 16116 sect->sh_size, _("attributes"));
60bca95a 16117 if (contents == NULL)
32ec8896
NC
16118 {
16119 res = FALSE;
16120 continue;
16121 }
60bca95a 16122
11c1ff18 16123 p = contents;
60abdbed
NC
16124 /* The first character is the version of the attributes.
16125 Currently only version 1, (aka 'A') is recognised here. */
16126 if (*p != 'A')
32ec8896
NC
16127 {
16128 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
16129 res = FALSE;
16130 }
60abdbed 16131 else
11c1ff18 16132 {
071436c6
NC
16133 bfd_vma section_len;
16134
16135 section_len = sect->sh_size - 1;
11c1ff18 16136 p++;
60bca95a 16137
071436c6 16138 while (section_len > 0)
11c1ff18 16139 {
071436c6 16140 bfd_vma attr_len;
e9847026 16141 unsigned int namelen;
11c1ff18 16142 bfd_boolean public_section;
104d59d1 16143 bfd_boolean gnu_section;
11c1ff18 16144
071436c6 16145 if (section_len <= 4)
e0a31db1
NC
16146 {
16147 error (_("Tag section ends prematurely\n"));
32ec8896 16148 res = FALSE;
e0a31db1
NC
16149 break;
16150 }
071436c6 16151 attr_len = byte_get (p, 4);
11c1ff18 16152 p += 4;
60bca95a 16153
071436c6 16154 if (attr_len > section_len)
11c1ff18 16155 {
071436c6
NC
16156 error (_("Bad attribute length (%u > %u)\n"),
16157 (unsigned) attr_len, (unsigned) section_len);
16158 attr_len = section_len;
32ec8896 16159 res = FALSE;
11c1ff18 16160 }
74e1a04b 16161 /* PR 17531: file: 001-101425-0.004 */
071436c6 16162 else if (attr_len < 5)
74e1a04b 16163 {
071436c6 16164 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 16165 res = FALSE;
74e1a04b
NC
16166 break;
16167 }
e9847026 16168
071436c6
NC
16169 section_len -= attr_len;
16170 attr_len -= 4;
16171
16172 namelen = strnlen ((char *) p, attr_len) + 1;
16173 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
16174 {
16175 error (_("Corrupt attribute section name\n"));
32ec8896 16176 res = FALSE;
e9847026
NC
16177 break;
16178 }
16179
071436c6
NC
16180 printf (_("Attribute Section: "));
16181 print_symbol (INT_MAX, (const char *) p);
16182 putchar ('\n');
60bca95a
NC
16183
16184 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
16185 public_section = TRUE;
16186 else
16187 public_section = FALSE;
60bca95a
NC
16188
16189 if (streq ((char *) p, "gnu"))
104d59d1
JM
16190 gnu_section = TRUE;
16191 else
16192 gnu_section = FALSE;
60bca95a 16193
11c1ff18 16194 p += namelen;
071436c6 16195 attr_len -= namelen;
e0a31db1 16196
071436c6 16197 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 16198 {
e0a31db1 16199 int tag;
cd30bcef 16200 unsigned int val;
11c1ff18 16201 bfd_vma size;
071436c6 16202 unsigned char * end;
60bca95a 16203
e0a31db1 16204 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 16205 if (attr_len < 6)
e0a31db1
NC
16206 {
16207 error (_("Unused bytes at end of section\n"));
32ec8896 16208 res = FALSE;
e0a31db1
NC
16209 section_len = 0;
16210 break;
16211 }
16212
16213 tag = *(p++);
11c1ff18 16214 size = byte_get (p, 4);
071436c6 16215 if (size > attr_len)
11c1ff18 16216 {
e9847026 16217 error (_("Bad subsection length (%u > %u)\n"),
071436c6 16218 (unsigned) size, (unsigned) attr_len);
32ec8896 16219 res = FALSE;
071436c6 16220 size = attr_len;
11c1ff18 16221 }
e0a31db1
NC
16222 /* PR binutils/17531: Safe handling of corrupt files. */
16223 if (size < 6)
16224 {
16225 error (_("Bad subsection length (%u < 6)\n"),
16226 (unsigned) size);
32ec8896 16227 res = FALSE;
e0a31db1
NC
16228 section_len = 0;
16229 break;
16230 }
60bca95a 16231
071436c6 16232 attr_len -= size;
11c1ff18 16233 end = p + size - 1;
071436c6 16234 assert (end <= contents + sect->sh_size);
11c1ff18 16235 p += 4;
60bca95a 16236
11c1ff18
PB
16237 switch (tag)
16238 {
16239 case 1:
2b692964 16240 printf (_("File Attributes\n"));
11c1ff18
PB
16241 break;
16242 case 2:
2b692964 16243 printf (_("Section Attributes:"));
11c1ff18
PB
16244 goto do_numlist;
16245 case 3:
2b692964 16246 printf (_("Symbol Attributes:"));
1a0670f3 16247 /* Fall through. */
11c1ff18
PB
16248 do_numlist:
16249 for (;;)
16250 {
cd30bcef 16251 READ_ULEB (val, p, end);
11c1ff18
PB
16252 if (val == 0)
16253 break;
16254 printf (" %d", val);
16255 }
16256 printf ("\n");
16257 break;
16258 default:
2b692964 16259 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
16260 public_section = FALSE;
16261 break;
16262 }
60bca95a 16263
071436c6 16264 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
16265 {
16266 while (p < end)
f6f0e17b 16267 p = display_pub_attribute (p, end);
60abdbed 16268 assert (p == end);
104d59d1 16269 }
071436c6 16270 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
16271 {
16272 while (p < end)
16273 p = display_gnu_attribute (p,
f6f0e17b
NC
16274 display_proc_gnu_attribute,
16275 end);
60abdbed 16276 assert (p == end);
11c1ff18 16277 }
071436c6 16278 else if (p < end)
11c1ff18 16279 {
071436c6 16280 printf (_(" Unknown attribute:\n"));
f6f0e17b 16281 display_raw_attribute (p, end);
11c1ff18
PB
16282 p = end;
16283 }
071436c6
NC
16284 else
16285 attr_len = 0;
11c1ff18
PB
16286 }
16287 }
16288 }
d70c5fc7 16289
60bca95a 16290 free (contents);
11c1ff18 16291 }
32ec8896
NC
16292
16293 return res;
11c1ff18
PB
16294}
16295
ccb4c951
RS
16296/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
16297 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
16298 and return the VMA of the next entry, or -1 if there was a problem.
16299 Does not read from DATA_END or beyond. */
ccb4c951
RS
16300
16301static bfd_vma
82b1b41b
NC
16302print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
16303 unsigned char * data_end)
ccb4c951
RS
16304{
16305 printf (" ");
16306 print_vma (addr, LONG_HEX);
16307 printf (" ");
16308 if (addr < pltgot + 0xfff0)
16309 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
16310 else
16311 printf ("%10s", "");
16312 printf (" ");
16313 if (data == NULL)
2b692964 16314 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
16315 else
16316 {
16317 bfd_vma entry;
82b1b41b 16318 unsigned char * from = data + addr - pltgot;
ccb4c951 16319
82b1b41b
NC
16320 if (from + (is_32bit_elf ? 4 : 8) > data_end)
16321 {
16322 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
16323 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
16324 return (bfd_vma) -1;
16325 }
16326 else
16327 {
16328 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16329 print_vma (entry, LONG_HEX);
16330 }
ccb4c951
RS
16331 }
16332 return addr + (is_32bit_elf ? 4 : 8);
16333}
16334
861fb55a
DJ
16335/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
16336 PLTGOT. Print the Address and Initial fields of an entry at VMA
16337 ADDR and return the VMA of the next entry. */
16338
16339static bfd_vma
2cf0635d 16340print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
16341{
16342 printf (" ");
16343 print_vma (addr, LONG_HEX);
16344 printf (" ");
16345 if (data == NULL)
2b692964 16346 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
16347 else
16348 {
16349 bfd_vma entry;
16350
16351 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16352 print_vma (entry, LONG_HEX);
16353 }
16354 return addr + (is_32bit_elf ? 4 : 8);
16355}
16356
351cdf24
MF
16357static void
16358print_mips_ases (unsigned int mask)
16359{
16360 if (mask & AFL_ASE_DSP)
16361 fputs ("\n\tDSP ASE", stdout);
16362 if (mask & AFL_ASE_DSPR2)
16363 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
16364 if (mask & AFL_ASE_DSPR3)
16365 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
16366 if (mask & AFL_ASE_EVA)
16367 fputs ("\n\tEnhanced VA Scheme", stdout);
16368 if (mask & AFL_ASE_MCU)
16369 fputs ("\n\tMCU (MicroController) ASE", stdout);
16370 if (mask & AFL_ASE_MDMX)
16371 fputs ("\n\tMDMX ASE", stdout);
16372 if (mask & AFL_ASE_MIPS3D)
16373 fputs ("\n\tMIPS-3D ASE", stdout);
16374 if (mask & AFL_ASE_MT)
16375 fputs ("\n\tMT ASE", stdout);
16376 if (mask & AFL_ASE_SMARTMIPS)
16377 fputs ("\n\tSmartMIPS ASE", stdout);
16378 if (mask & AFL_ASE_VIRT)
16379 fputs ("\n\tVZ ASE", stdout);
16380 if (mask & AFL_ASE_MSA)
16381 fputs ("\n\tMSA ASE", stdout);
16382 if (mask & AFL_ASE_MIPS16)
16383 fputs ("\n\tMIPS16 ASE", stdout);
16384 if (mask & AFL_ASE_MICROMIPS)
16385 fputs ("\n\tMICROMIPS ASE", stdout);
16386 if (mask & AFL_ASE_XPA)
16387 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
16388 if (mask & AFL_ASE_MIPS16E2)
16389 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
16390 if (mask & AFL_ASE_CRC)
16391 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
16392 if (mask & AFL_ASE_GINV)
16393 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
16394 if (mask & AFL_ASE_LOONGSON_MMI)
16395 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
16396 if (mask & AFL_ASE_LOONGSON_CAM)
16397 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
16398 if (mask & AFL_ASE_LOONGSON_EXT)
16399 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
16400 if (mask & AFL_ASE_LOONGSON_EXT2)
16401 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
16402 if (mask == 0)
16403 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
16404 else if ((mask & ~AFL_ASE_MASK) != 0)
16405 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
16406}
16407
16408static void
16409print_mips_isa_ext (unsigned int isa_ext)
16410{
16411 switch (isa_ext)
16412 {
16413 case 0:
16414 fputs (_("None"), stdout);
16415 break;
16416 case AFL_EXT_XLR:
16417 fputs ("RMI XLR", stdout);
16418 break;
2c629856
N
16419 case AFL_EXT_OCTEON3:
16420 fputs ("Cavium Networks Octeon3", stdout);
16421 break;
351cdf24
MF
16422 case AFL_EXT_OCTEON2:
16423 fputs ("Cavium Networks Octeon2", stdout);
16424 break;
16425 case AFL_EXT_OCTEONP:
16426 fputs ("Cavium Networks OcteonP", stdout);
16427 break;
351cdf24
MF
16428 case AFL_EXT_OCTEON:
16429 fputs ("Cavium Networks Octeon", stdout);
16430 break;
16431 case AFL_EXT_5900:
16432 fputs ("Toshiba R5900", stdout);
16433 break;
16434 case AFL_EXT_4650:
16435 fputs ("MIPS R4650", stdout);
16436 break;
16437 case AFL_EXT_4010:
16438 fputs ("LSI R4010", stdout);
16439 break;
16440 case AFL_EXT_4100:
16441 fputs ("NEC VR4100", stdout);
16442 break;
16443 case AFL_EXT_3900:
16444 fputs ("Toshiba R3900", stdout);
16445 break;
16446 case AFL_EXT_10000:
16447 fputs ("MIPS R10000", stdout);
16448 break;
16449 case AFL_EXT_SB1:
16450 fputs ("Broadcom SB-1", stdout);
16451 break;
16452 case AFL_EXT_4111:
16453 fputs ("NEC VR4111/VR4181", stdout);
16454 break;
16455 case AFL_EXT_4120:
16456 fputs ("NEC VR4120", stdout);
16457 break;
16458 case AFL_EXT_5400:
16459 fputs ("NEC VR5400", stdout);
16460 break;
16461 case AFL_EXT_5500:
16462 fputs ("NEC VR5500", stdout);
16463 break;
16464 case AFL_EXT_LOONGSON_2E:
16465 fputs ("ST Microelectronics Loongson 2E", stdout);
16466 break;
16467 case AFL_EXT_LOONGSON_2F:
16468 fputs ("ST Microelectronics Loongson 2F", stdout);
16469 break;
38bf472a
MR
16470 case AFL_EXT_INTERAPTIV_MR2:
16471 fputs ("Imagination interAptiv MR2", stdout);
16472 break;
351cdf24 16473 default:
00ac7aa0 16474 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
16475 }
16476}
16477
32ec8896 16478static signed int
351cdf24
MF
16479get_mips_reg_size (int reg_size)
16480{
16481 return (reg_size == AFL_REG_NONE) ? 0
16482 : (reg_size == AFL_REG_32) ? 32
16483 : (reg_size == AFL_REG_64) ? 64
16484 : (reg_size == AFL_REG_128) ? 128
16485 : -1;
16486}
16487
32ec8896 16488static bfd_boolean
dda8d76d 16489process_mips_specific (Filedata * filedata)
5b18a4bc 16490{
2cf0635d 16491 Elf_Internal_Dyn * entry;
351cdf24 16492 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
16493 size_t liblist_offset = 0;
16494 size_t liblistno = 0;
16495 size_t conflictsno = 0;
16496 size_t options_offset = 0;
16497 size_t conflicts_offset = 0;
861fb55a
DJ
16498 size_t pltrelsz = 0;
16499 size_t pltrel = 0;
ccb4c951 16500 bfd_vma pltgot = 0;
861fb55a
DJ
16501 bfd_vma mips_pltgot = 0;
16502 bfd_vma jmprel = 0;
ccb4c951
RS
16503 bfd_vma local_gotno = 0;
16504 bfd_vma gotsym = 0;
16505 bfd_vma symtabno = 0;
32ec8896 16506 bfd_boolean res = TRUE;
103f02d3 16507
dda8d76d 16508 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
16509 display_mips_gnu_attribute))
16510 res = FALSE;
2cf19d5c 16511
dda8d76d 16512 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
16513
16514 if (sect != NULL)
16515 {
16516 Elf_External_ABIFlags_v0 *abiflags_ext;
16517 Elf_Internal_ABIFlags_v0 abiflags_in;
16518
16519 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
16520 {
16521 error (_("Corrupt MIPS ABI Flags section.\n"));
16522 res = FALSE;
16523 }
351cdf24
MF
16524 else
16525 {
dda8d76d 16526 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
16527 sect->sh_size, _("MIPS ABI Flags section"));
16528 if (abiflags_ext)
16529 {
16530 abiflags_in.version = BYTE_GET (abiflags_ext->version);
16531 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
16532 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
16533 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
16534 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
16535 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
16536 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
16537 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
16538 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
16539 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
16540 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
16541
16542 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
16543 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
16544 if (abiflags_in.isa_rev > 1)
16545 printf ("r%d", abiflags_in.isa_rev);
16546 printf ("\nGPR size: %d",
16547 get_mips_reg_size (abiflags_in.gpr_size));
16548 printf ("\nCPR1 size: %d",
16549 get_mips_reg_size (abiflags_in.cpr1_size));
16550 printf ("\nCPR2 size: %d",
16551 get_mips_reg_size (abiflags_in.cpr2_size));
16552 fputs ("\nFP ABI: ", stdout);
16553 print_mips_fp_abi_value (abiflags_in.fp_abi);
16554 fputs ("ISA Extension: ", stdout);
16555 print_mips_isa_ext (abiflags_in.isa_ext);
16556 fputs ("\nASEs:", stdout);
16557 print_mips_ases (abiflags_in.ases);
16558 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
16559 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
16560 fputc ('\n', stdout);
16561 free (abiflags_ext);
16562 }
16563 }
16564 }
16565
19e6b90e
L
16566 /* We have a lot of special sections. Thanks SGI! */
16567 if (dynamic_section == NULL)
bbdd9a68
MR
16568 {
16569 /* No dynamic information available. See if there is static GOT. */
dda8d76d 16570 sect = find_section (filedata, ".got");
bbdd9a68
MR
16571 if (sect != NULL)
16572 {
16573 unsigned char *data_end;
16574 unsigned char *data;
16575 bfd_vma ent, end;
16576 int addr_size;
16577
16578 pltgot = sect->sh_addr;
16579
16580 ent = pltgot;
16581 addr_size = (is_32bit_elf ? 4 : 8);
16582 end = pltgot + sect->sh_size;
16583
dda8d76d 16584 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
16585 end - pltgot, 1,
16586 _("Global Offset Table data"));
16587 /* PR 12855: Null data is handled gracefully throughout. */
16588 data_end = data + (end - pltgot);
16589
16590 printf (_("\nStatic GOT:\n"));
16591 printf (_(" Canonical gp value: "));
16592 print_vma (ent + 0x7ff0, LONG_HEX);
16593 printf ("\n\n");
16594
16595 /* In a dynamic binary GOT[0] is reserved for the dynamic
16596 loader to store the lazy resolver pointer, however in
16597 a static binary it may well have been omitted and GOT
16598 reduced to a table of addresses.
16599 PR 21344: Check for the entry being fully available
16600 before fetching it. */
16601 if (data
16602 && data + ent - pltgot + addr_size <= data_end
16603 && byte_get (data + ent - pltgot, addr_size) == 0)
16604 {
16605 printf (_(" Reserved entries:\n"));
16606 printf (_(" %*s %10s %*s\n"),
16607 addr_size * 2, _("Address"), _("Access"),
16608 addr_size * 2, _("Value"));
16609 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16610 printf ("\n");
16611 if (ent == (bfd_vma) -1)
16612 goto sgot_print_fail;
16613
16614 /* Check for the MSB of GOT[1] being set, identifying a
16615 GNU object. This entry will be used by some runtime
16616 loaders, to store the module pointer. Otherwise this
16617 is an ordinary local entry.
16618 PR 21344: Check for the entry being fully available
16619 before fetching it. */
16620 if (data
16621 && data + ent - pltgot + addr_size <= data_end
16622 && (byte_get (data + ent - pltgot, addr_size)
16623 >> (addr_size * 8 - 1)) != 0)
16624 {
16625 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16626 printf ("\n");
16627 if (ent == (bfd_vma) -1)
16628 goto sgot_print_fail;
16629 }
16630 printf ("\n");
16631 }
16632
f17e9d8a 16633 if (data != NULL && ent < end)
bbdd9a68
MR
16634 {
16635 printf (_(" Local entries:\n"));
16636 printf (" %*s %10s %*s\n",
16637 addr_size * 2, _("Address"), _("Access"),
16638 addr_size * 2, _("Value"));
16639 while (ent < end)
16640 {
16641 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16642 printf ("\n");
16643 if (ent == (bfd_vma) -1)
16644 goto sgot_print_fail;
16645 }
16646 printf ("\n");
16647 }
16648
16649 sgot_print_fail:
16650 if (data)
16651 free (data);
16652 }
16653 return res;
16654 }
252b5132 16655
071436c6
NC
16656 for (entry = dynamic_section;
16657 /* PR 17531 file: 012-50589-0.004. */
16658 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
16659 ++entry)
252b5132
RH
16660 switch (entry->d_tag)
16661 {
16662 case DT_MIPS_LIBLIST:
d93f0186 16663 liblist_offset
dda8d76d 16664 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16665 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
16666 break;
16667 case DT_MIPS_LIBLISTNO:
16668 liblistno = entry->d_un.d_val;
16669 break;
16670 case DT_MIPS_OPTIONS:
dda8d76d 16671 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
16672 break;
16673 case DT_MIPS_CONFLICT:
d93f0186 16674 conflicts_offset
dda8d76d 16675 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16676 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
16677 break;
16678 case DT_MIPS_CONFLICTNO:
16679 conflictsno = entry->d_un.d_val;
16680 break;
ccb4c951 16681 case DT_PLTGOT:
861fb55a
DJ
16682 pltgot = entry->d_un.d_ptr;
16683 break;
ccb4c951
RS
16684 case DT_MIPS_LOCAL_GOTNO:
16685 local_gotno = entry->d_un.d_val;
16686 break;
16687 case DT_MIPS_GOTSYM:
16688 gotsym = entry->d_un.d_val;
16689 break;
16690 case DT_MIPS_SYMTABNO:
16691 symtabno = entry->d_un.d_val;
16692 break;
861fb55a
DJ
16693 case DT_MIPS_PLTGOT:
16694 mips_pltgot = entry->d_un.d_ptr;
16695 break;
16696 case DT_PLTREL:
16697 pltrel = entry->d_un.d_val;
16698 break;
16699 case DT_PLTRELSZ:
16700 pltrelsz = entry->d_un.d_val;
16701 break;
16702 case DT_JMPREL:
16703 jmprel = entry->d_un.d_ptr;
16704 break;
252b5132
RH
16705 default:
16706 break;
16707 }
16708
16709 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
16710 {
2cf0635d 16711 Elf32_External_Lib * elib;
252b5132
RH
16712 size_t cnt;
16713
dda8d76d 16714 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
16715 sizeof (Elf32_External_Lib),
16716 liblistno,
16717 _("liblist section data"));
a6e9f9df 16718 if (elib)
252b5132 16719 {
d3a49aa8
AM
16720 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
16721 "\nSection '.liblist' contains %lu entries:\n",
16722 (unsigned long) liblistno),
a6e9f9df 16723 (unsigned long) liblistno);
2b692964 16724 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
16725 stdout);
16726
16727 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 16728 {
a6e9f9df 16729 Elf32_Lib liblist;
91d6fa6a 16730 time_t atime;
d5b07ef4 16731 char timebuf[128];
2cf0635d 16732 struct tm * tmp;
a6e9f9df
AM
16733
16734 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16735 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
16736 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16737 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16738 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16739
91d6fa6a 16740 tmp = gmtime (&atime);
e9e44622
JJ
16741 snprintf (timebuf, sizeof (timebuf),
16742 "%04u-%02u-%02uT%02u:%02u:%02u",
16743 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16744 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 16745
31104126 16746 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
16747 if (VALID_DYNAMIC_NAME (liblist.l_name))
16748 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
16749 else
2b692964 16750 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
16751 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
16752 liblist.l_version);
a6e9f9df
AM
16753
16754 if (liblist.l_flags == 0)
2b692964 16755 puts (_(" NONE"));
a6e9f9df
AM
16756 else
16757 {
16758 static const struct
252b5132 16759 {
2cf0635d 16760 const char * name;
a6e9f9df 16761 int bit;
252b5132 16762 }
a6e9f9df
AM
16763 l_flags_vals[] =
16764 {
16765 { " EXACT_MATCH", LL_EXACT_MATCH },
16766 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
16767 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
16768 { " EXPORTS", LL_EXPORTS },
16769 { " DELAY_LOAD", LL_DELAY_LOAD },
16770 { " DELTA", LL_DELTA }
16771 };
16772 int flags = liblist.l_flags;
16773 size_t fcnt;
16774
60bca95a 16775 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
16776 if ((flags & l_flags_vals[fcnt].bit) != 0)
16777 {
16778 fputs (l_flags_vals[fcnt].name, stdout);
16779 flags ^= l_flags_vals[fcnt].bit;
16780 }
16781 if (flags != 0)
16782 printf (" %#x", (unsigned int) flags);
252b5132 16783
a6e9f9df
AM
16784 puts ("");
16785 }
252b5132 16786 }
252b5132 16787
a6e9f9df
AM
16788 free (elib);
16789 }
32ec8896
NC
16790 else
16791 res = FALSE;
252b5132
RH
16792 }
16793
16794 if (options_offset != 0)
16795 {
2cf0635d 16796 Elf_External_Options * eopt;
252b5132
RH
16797 size_t offset;
16798 int cnt;
dda8d76d 16799 sect = filedata->section_headers;
252b5132
RH
16800
16801 /* Find the section header so that we get the size. */
dda8d76d 16802 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 16803 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
16804 if (sect == NULL)
16805 {
16806 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 16807 return FALSE;
071436c6 16808 }
7fc0c668
NC
16809 /* PR 24243 */
16810 if (sect->sh_size < sizeof (* eopt))
16811 {
16812 error (_("The MIPS options section is too small.\n"));
16813 return FALSE;
16814 }
252b5132 16815
dda8d76d 16816 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 16817 sect->sh_size, _("options"));
a6e9f9df 16818 if (eopt)
252b5132 16819 {
2e6be59c
NC
16820 Elf_Internal_Options * iopt;
16821 Elf_Internal_Options * option;
16822 Elf_Internal_Options * iopt_end;
16823
3f5e193b
NC
16824 iopt = (Elf_Internal_Options *)
16825 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
16826 if (iopt == NULL)
16827 {
fb324ee9 16828 error (_("Out of memory allocating space for MIPS options\n"));
645f43a8 16829 free (eopt);
32ec8896 16830 return FALSE;
a6e9f9df 16831 }
76da6bbe 16832
a6e9f9df
AM
16833 offset = cnt = 0;
16834 option = iopt;
2e6be59c
NC
16835 iopt_end = iopt + (sect->sh_size / sizeof (eopt));
16836
82b1b41b 16837 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 16838 {
2cf0635d 16839 Elf_External_Options * eoption;
252b5132 16840
a6e9f9df 16841 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 16842
a6e9f9df
AM
16843 option->kind = BYTE_GET (eoption->kind);
16844 option->size = BYTE_GET (eoption->size);
16845 option->section = BYTE_GET (eoption->section);
16846 option->info = BYTE_GET (eoption->info);
76da6bbe 16847
82b1b41b
NC
16848 /* PR 17531: file: ffa0fa3b. */
16849 if (option->size < sizeof (* eopt)
16850 || offset + option->size > sect->sh_size)
16851 {
645f43a8
AM
16852 error (_("Invalid size (%u) for MIPS option\n"),
16853 option->size);
16854 free (iopt);
16855 free (eopt);
32ec8896 16856 return FALSE;
82b1b41b 16857 }
a6e9f9df 16858 offset += option->size;
14ae95f2 16859
a6e9f9df
AM
16860 ++option;
16861 ++cnt;
16862 }
252b5132 16863
d3a49aa8
AM
16864 printf (ngettext ("\nSection '%s' contains %d entry:\n",
16865 "\nSection '%s' contains %d entries:\n",
16866 cnt),
dda8d76d 16867 printable_section_name (filedata, sect), cnt);
76da6bbe 16868
a6e9f9df 16869 option = iopt;
82b1b41b 16870 offset = 0;
252b5132 16871
a6e9f9df 16872 while (cnt-- > 0)
252b5132 16873 {
a6e9f9df
AM
16874 size_t len;
16875
16876 switch (option->kind)
252b5132 16877 {
a6e9f9df
AM
16878 case ODK_NULL:
16879 /* This shouldn't happen. */
16880 printf (" NULL %d %lx", option->section, option->info);
16881 break;
2e6be59c 16882
a6e9f9df
AM
16883 case ODK_REGINFO:
16884 printf (" REGINFO ");
dda8d76d 16885 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 16886 {
2cf0635d 16887 Elf32_External_RegInfo * ereg;
b34976b6 16888 Elf32_RegInfo reginfo;
a6e9f9df 16889
2e6be59c
NC
16890 /* 32bit form. */
16891 if (option + 2 > iopt_end)
16892 {
16893 printf (_("<corrupt>\n"));
16894 error (_("Truncated MIPS REGINFO option\n"));
16895 cnt = 0;
16896 break;
16897 }
16898
a6e9f9df 16899 ereg = (Elf32_External_RegInfo *) (option + 1);
2e6be59c 16900
a6e9f9df
AM
16901 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
16902 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
16903 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16904 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16905 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
16906 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
16907
16908 printf ("GPR %08lx GP 0x%lx\n",
16909 reginfo.ri_gprmask,
16910 (unsigned long) reginfo.ri_gp_value);
16911 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
16912 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
16913 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
16914 }
16915 else
16916 {
16917 /* 64 bit form. */
2cf0635d 16918 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
16919 Elf64_Internal_RegInfo reginfo;
16920
2e6be59c
NC
16921 if (option + 2 > iopt_end)
16922 {
16923 printf (_("<corrupt>\n"));
16924 error (_("Truncated MIPS REGINFO option\n"));
16925 cnt = 0;
16926 break;
16927 }
16928
a6e9f9df
AM
16929 ereg = (Elf64_External_RegInfo *) (option + 1);
16930 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
16931 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
16932 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16933 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16934 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 16935 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
16936
16937 printf ("GPR %08lx GP 0x",
16938 reginfo.ri_gprmask);
16939 printf_vma (reginfo.ri_gp_value);
16940 printf ("\n");
16941
16942 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
16943 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
16944 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
16945 }
16946 ++option;
16947 continue;
2e6be59c 16948
a6e9f9df
AM
16949 case ODK_EXCEPTIONS:
16950 fputs (" EXCEPTIONS fpe_min(", stdout);
16951 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
16952 fputs (") fpe_max(", stdout);
16953 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
16954 fputs (")", stdout);
16955
16956 if (option->info & OEX_PAGE0)
16957 fputs (" PAGE0", stdout);
16958 if (option->info & OEX_SMM)
16959 fputs (" SMM", stdout);
16960 if (option->info & OEX_FPDBUG)
16961 fputs (" FPDBUG", stdout);
16962 if (option->info & OEX_DISMISS)
16963 fputs (" DISMISS", stdout);
16964 break;
2e6be59c 16965
a6e9f9df
AM
16966 case ODK_PAD:
16967 fputs (" PAD ", stdout);
16968 if (option->info & OPAD_PREFIX)
16969 fputs (" PREFIX", stdout);
16970 if (option->info & OPAD_POSTFIX)
16971 fputs (" POSTFIX", stdout);
16972 if (option->info & OPAD_SYMBOL)
16973 fputs (" SYMBOL", stdout);
16974 break;
2e6be59c 16975
a6e9f9df
AM
16976 case ODK_HWPATCH:
16977 fputs (" HWPATCH ", stdout);
16978 if (option->info & OHW_R4KEOP)
16979 fputs (" R4KEOP", stdout);
16980 if (option->info & OHW_R8KPFETCH)
16981 fputs (" R8KPFETCH", stdout);
16982 if (option->info & OHW_R5KEOP)
16983 fputs (" R5KEOP", stdout);
16984 if (option->info & OHW_R5KCVTL)
16985 fputs (" R5KCVTL", stdout);
16986 break;
2e6be59c 16987
a6e9f9df
AM
16988 case ODK_FILL:
16989 fputs (" FILL ", stdout);
16990 /* XXX Print content of info word? */
16991 break;
2e6be59c 16992
a6e9f9df
AM
16993 case ODK_TAGS:
16994 fputs (" TAGS ", stdout);
16995 /* XXX Print content of info word? */
16996 break;
2e6be59c 16997
a6e9f9df
AM
16998 case ODK_HWAND:
16999 fputs (" HWAND ", stdout);
17000 if (option->info & OHWA0_R4KEOP_CHECKED)
17001 fputs (" R4KEOP_CHECKED", stdout);
17002 if (option->info & OHWA0_R4KEOP_CLEAN)
17003 fputs (" R4KEOP_CLEAN", stdout);
17004 break;
2e6be59c 17005
a6e9f9df
AM
17006 case ODK_HWOR:
17007 fputs (" HWOR ", stdout);
17008 if (option->info & OHWA0_R4KEOP_CHECKED)
17009 fputs (" R4KEOP_CHECKED", stdout);
17010 if (option->info & OHWA0_R4KEOP_CLEAN)
17011 fputs (" R4KEOP_CLEAN", stdout);
17012 break;
2e6be59c 17013
a6e9f9df
AM
17014 case ODK_GP_GROUP:
17015 printf (" GP_GROUP %#06lx self-contained %#06lx",
17016 option->info & OGP_GROUP,
17017 (option->info & OGP_SELF) >> 16);
17018 break;
2e6be59c 17019
a6e9f9df
AM
17020 case ODK_IDENT:
17021 printf (" IDENT %#06lx self-contained %#06lx",
17022 option->info & OGP_GROUP,
17023 (option->info & OGP_SELF) >> 16);
17024 break;
2e6be59c 17025
a6e9f9df
AM
17026 default:
17027 /* This shouldn't happen. */
17028 printf (" %3d ??? %d %lx",
17029 option->kind, option->section, option->info);
17030 break;
252b5132 17031 }
a6e9f9df 17032
2cf0635d 17033 len = sizeof (* eopt);
a6e9f9df 17034 while (len < option->size)
82b1b41b 17035 {
7e27a9d5 17036 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 17037
82b1b41b
NC
17038 if (ISPRINT (datum))
17039 printf ("%c", datum);
17040 else
17041 printf ("\\%03o", datum);
17042 len ++;
17043 }
a6e9f9df 17044 fputs ("\n", stdout);
82b1b41b
NC
17045
17046 offset += option->size;
252b5132 17047 ++option;
252b5132 17048 }
645f43a8 17049 free (iopt);
a6e9f9df 17050 free (eopt);
252b5132 17051 }
32ec8896
NC
17052 else
17053 res = FALSE;
252b5132
RH
17054 }
17055
17056 if (conflicts_offset != 0 && conflictsno != 0)
17057 {
2cf0635d 17058 Elf32_Conflict * iconf;
252b5132
RH
17059 size_t cnt;
17060
17061 if (dynamic_symbols == NULL)
17062 {
591a748a 17063 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 17064 return FALSE;
252b5132
RH
17065 }
17066
7296a62a
NC
17067 /* PR 21345 - print a slightly more helpful error message
17068 if we are sure that the cmalloc will fail. */
645f43a8 17069 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
17070 {
17071 error (_("Overlarge number of conflicts detected: %lx\n"),
17072 (long) conflictsno);
17073 return FALSE;
17074 }
17075
3f5e193b 17076 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
17077 if (iconf == NULL)
17078 {
8b73c356 17079 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 17080 return FALSE;
252b5132
RH
17081 }
17082
9ea033b2 17083 if (is_32bit_elf)
252b5132 17084 {
2cf0635d 17085 Elf32_External_Conflict * econf32;
a6e9f9df 17086
3f5e193b 17087 econf32 = (Elf32_External_Conflict *)
95099889
AM
17088 get_data (NULL, filedata, conflicts_offset,
17089 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 17090 if (!econf32)
5a814d6d
AM
17091 {
17092 free (iconf);
17093 return FALSE;
17094 }
252b5132
RH
17095
17096 for (cnt = 0; cnt < conflictsno; ++cnt)
17097 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
17098
17099 free (econf32);
252b5132
RH
17100 }
17101 else
17102 {
2cf0635d 17103 Elf64_External_Conflict * econf64;
a6e9f9df 17104
3f5e193b 17105 econf64 = (Elf64_External_Conflict *)
95099889
AM
17106 get_data (NULL, filedata, conflicts_offset,
17107 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 17108 if (!econf64)
5a814d6d
AM
17109 {
17110 free (iconf);
17111 return FALSE;
17112 }
252b5132
RH
17113
17114 for (cnt = 0; cnt < conflictsno; ++cnt)
17115 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
17116
17117 free (econf64);
252b5132
RH
17118 }
17119
d3a49aa8
AM
17120 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
17121 "\nSection '.conflict' contains %lu entries:\n",
17122 (unsigned long) conflictsno),
c7e7ca54 17123 (unsigned long) conflictsno);
252b5132
RH
17124 puts (_(" Num: Index Value Name"));
17125
17126 for (cnt = 0; cnt < conflictsno; ++cnt)
17127 {
b34976b6 17128 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
17129
17130 if (iconf[cnt] >= num_dynamic_syms)
17131 printf (_("<corrupt symbol index>"));
d79b3d50 17132 else
e0a31db1
NC
17133 {
17134 Elf_Internal_Sym * psym;
17135
17136 psym = & dynamic_symbols[iconf[cnt]];
17137 print_vma (psym->st_value, FULL_HEX);
17138 putchar (' ');
17139 if (VALID_DYNAMIC_NAME (psym->st_name))
17140 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
17141 else
17142 printf (_("<corrupt: %14ld>"), psym->st_name);
17143 }
31104126 17144 putchar ('\n');
252b5132
RH
17145 }
17146
252b5132
RH
17147 free (iconf);
17148 }
17149
ccb4c951
RS
17150 if (pltgot != 0 && local_gotno != 0)
17151 {
91d6fa6a 17152 bfd_vma ent, local_end, global_end;
bbeee7ea 17153 size_t i, offset;
2cf0635d 17154 unsigned char * data;
82b1b41b 17155 unsigned char * data_end;
bbeee7ea 17156 int addr_size;
ccb4c951 17157
91d6fa6a 17158 ent = pltgot;
ccb4c951
RS
17159 addr_size = (is_32bit_elf ? 4 : 8);
17160 local_end = pltgot + local_gotno * addr_size;
ccb4c951 17161
74e1a04b
NC
17162 /* PR binutils/17533 file: 012-111227-0.004 */
17163 if (symtabno < gotsym)
17164 {
17165 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 17166 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 17167 return FALSE;
74e1a04b 17168 }
82b1b41b 17169
74e1a04b 17170 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
17171 /* PR 17531: file: 54c91a34. */
17172 if (global_end < local_end)
17173 {
17174 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 17175 return FALSE;
82b1b41b 17176 }
948f632f 17177
dda8d76d
NC
17178 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
17179 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
17180 global_end - pltgot, 1,
17181 _("Global Offset Table data"));
919383ac 17182 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 17183 data_end = data + (global_end - pltgot);
59245841 17184
ccb4c951
RS
17185 printf (_("\nPrimary GOT:\n"));
17186 printf (_(" Canonical gp value: "));
17187 print_vma (pltgot + 0x7ff0, LONG_HEX);
17188 printf ("\n\n");
17189
17190 printf (_(" Reserved entries:\n"));
17191 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
17192 addr_size * 2, _("Address"), _("Access"),
17193 addr_size * 2, _("Initial"));
82b1b41b 17194 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 17195 printf (_(" Lazy resolver\n"));
82b1b41b
NC
17196 if (ent == (bfd_vma) -1)
17197 goto got_print_fail;
75ec1fdb 17198
c4ab9505
MR
17199 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
17200 This entry will be used by some runtime loaders, to store the
17201 module pointer. Otherwise this is an ordinary local entry.
17202 PR 21344: Check for the entry being fully available before
17203 fetching it. */
17204 if (data
17205 && data + ent - pltgot + addr_size <= data_end
17206 && (byte_get (data + ent - pltgot, addr_size)
17207 >> (addr_size * 8 - 1)) != 0)
17208 {
17209 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17210 printf (_(" Module pointer (GNU extension)\n"));
17211 if (ent == (bfd_vma) -1)
17212 goto got_print_fail;
ccb4c951
RS
17213 }
17214 printf ("\n");
17215
f17e9d8a 17216 if (data != NULL && ent < local_end)
ccb4c951
RS
17217 {
17218 printf (_(" Local entries:\n"));
cc5914eb 17219 printf (" %*s %10s %*s\n",
2b692964
NC
17220 addr_size * 2, _("Address"), _("Access"),
17221 addr_size * 2, _("Initial"));
91d6fa6a 17222 while (ent < local_end)
ccb4c951 17223 {
82b1b41b 17224 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17225 printf ("\n");
82b1b41b
NC
17226 if (ent == (bfd_vma) -1)
17227 goto got_print_fail;
ccb4c951
RS
17228 }
17229 printf ("\n");
17230 }
17231
f17e9d8a 17232 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
17233 {
17234 int sym_width;
17235
17236 printf (_(" Global entries:\n"));
cc5914eb 17237 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
17238 addr_size * 2, _("Address"),
17239 _("Access"),
2b692964 17240 addr_size * 2, _("Initial"),
9cf03b7e
NC
17241 addr_size * 2, _("Sym.Val."),
17242 _("Type"),
17243 /* Note for translators: "Ndx" = abbreviated form of "Index". */
17244 _("Ndx"), _("Name"));
0b4362b0 17245
ccb4c951 17246 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 17247
ccb4c951
RS
17248 for (i = gotsym; i < symtabno; i++)
17249 {
82b1b41b 17250 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17251 printf (" ");
e0a31db1
NC
17252
17253 if (dynamic_symbols == NULL)
17254 printf (_("<no dynamic symbols>"));
17255 else if (i < num_dynamic_syms)
17256 {
17257 Elf_Internal_Sym * psym = dynamic_symbols + i;
17258
17259 print_vma (psym->st_value, LONG_HEX);
17260 printf (" %-7s %3s ",
dda8d76d
NC
17261 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17262 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
17263
17264 if (VALID_DYNAMIC_NAME (psym->st_name))
17265 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
17266 else
17267 printf (_("<corrupt: %14ld>"), psym->st_name);
17268 }
ccb4c951 17269 else
7fc5ac57
JBG
17270 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
17271 (unsigned long) i);
e0a31db1 17272
ccb4c951 17273 printf ("\n");
82b1b41b
NC
17274 if (ent == (bfd_vma) -1)
17275 break;
ccb4c951
RS
17276 }
17277 printf ("\n");
17278 }
17279
82b1b41b 17280 got_print_fail:
ccb4c951
RS
17281 if (data)
17282 free (data);
17283 }
17284
861fb55a
DJ
17285 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
17286 {
91d6fa6a 17287 bfd_vma ent, end;
861fb55a
DJ
17288 size_t offset, rel_offset;
17289 unsigned long count, i;
2cf0635d 17290 unsigned char * data;
861fb55a 17291 int addr_size, sym_width;
2cf0635d 17292 Elf_Internal_Rela * rels;
861fb55a 17293
dda8d76d 17294 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
17295 if (pltrel == DT_RELA)
17296 {
dda8d76d 17297 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17298 return FALSE;
861fb55a
DJ
17299 }
17300 else
17301 {
dda8d76d 17302 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17303 return FALSE;
861fb55a
DJ
17304 }
17305
91d6fa6a 17306 ent = mips_pltgot;
861fb55a
DJ
17307 addr_size = (is_32bit_elf ? 4 : 8);
17308 end = mips_pltgot + (2 + count) * addr_size;
17309
dda8d76d
NC
17310 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
17311 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 17312 1, _("Procedure Linkage Table data"));
59245841 17313 if (data == NULL)
32ec8896 17314 return FALSE;
59245841 17315
9cf03b7e 17316 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
17317 printf (_(" Reserved entries:\n"));
17318 printf (_(" %*s %*s Purpose\n"),
2b692964 17319 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 17320 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17321 printf (_(" PLT lazy resolver\n"));
91d6fa6a 17322 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17323 printf (_(" Module pointer\n"));
861fb55a
DJ
17324 printf ("\n");
17325
17326 printf (_(" Entries:\n"));
cc5914eb 17327 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
17328 addr_size * 2, _("Address"),
17329 addr_size * 2, _("Initial"),
17330 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
17331 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
17332 for (i = 0; i < count; i++)
17333 {
df97ab2a 17334 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 17335
91d6fa6a 17336 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 17337 printf (" ");
e0a31db1 17338
df97ab2a
MF
17339 if (idx >= num_dynamic_syms)
17340 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 17341 else
e0a31db1 17342 {
df97ab2a 17343 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
17344
17345 print_vma (psym->st_value, LONG_HEX);
17346 printf (" %-7s %3s ",
dda8d76d
NC
17347 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17348 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
17349 if (VALID_DYNAMIC_NAME (psym->st_name))
17350 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
17351 else
17352 printf (_("<corrupt: %14ld>"), psym->st_name);
17353 }
861fb55a
DJ
17354 printf ("\n");
17355 }
17356 printf ("\n");
17357
17358 if (data)
17359 free (data);
17360 free (rels);
17361 }
17362
32ec8896 17363 return res;
252b5132
RH
17364}
17365
32ec8896 17366static bfd_boolean
dda8d76d 17367process_nds32_specific (Filedata * filedata)
35c08157
KLC
17368{
17369 Elf_Internal_Shdr *sect = NULL;
17370
dda8d76d 17371 sect = find_section (filedata, ".nds32_e_flags");
35c08157
KLC
17372 if (sect != NULL)
17373 {
17374 unsigned int *flag;
17375
17376 printf ("\nNDS32 elf flags section:\n");
dda8d76d 17377 flag = get_data (NULL, filedata, sect->sh_offset, 1,
35c08157
KLC
17378 sect->sh_size, _("NDS32 elf flags section"));
17379
32ec8896
NC
17380 if (! flag)
17381 return FALSE;
17382
35c08157
KLC
17383 switch ((*flag) & 0x3)
17384 {
17385 case 0:
17386 printf ("(VEC_SIZE):\tNo entry.\n");
17387 break;
17388 case 1:
17389 printf ("(VEC_SIZE):\t4 bytes\n");
17390 break;
17391 case 2:
17392 printf ("(VEC_SIZE):\t16 bytes\n");
17393 break;
17394 case 3:
17395 printf ("(VEC_SIZE):\treserved\n");
17396 break;
17397 }
17398 }
17399
17400 return TRUE;
17401}
17402
32ec8896 17403static bfd_boolean
dda8d76d 17404process_gnu_liblist (Filedata * filedata)
047b2264 17405{
2cf0635d
NC
17406 Elf_Internal_Shdr * section;
17407 Elf_Internal_Shdr * string_sec;
17408 Elf32_External_Lib * elib;
17409 char * strtab;
c256ffe7 17410 size_t strtab_size;
047b2264 17411 size_t cnt;
d3a49aa8 17412 unsigned long num_liblist;
047b2264 17413 unsigned i;
32ec8896 17414 bfd_boolean res = TRUE;
047b2264
JJ
17415
17416 if (! do_arch)
32ec8896 17417 return TRUE;
047b2264 17418
dda8d76d
NC
17419 for (i = 0, section = filedata->section_headers;
17420 i < filedata->file_header.e_shnum;
b34976b6 17421 i++, section++)
047b2264
JJ
17422 {
17423 switch (section->sh_type)
17424 {
17425 case SHT_GNU_LIBLIST:
dda8d76d 17426 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
17427 break;
17428
3f5e193b 17429 elib = (Elf32_External_Lib *)
dda8d76d 17430 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 17431 _("liblist section data"));
047b2264
JJ
17432
17433 if (elib == NULL)
32ec8896
NC
17434 {
17435 res = FALSE;
17436 break;
17437 }
047b2264 17438
dda8d76d
NC
17439 string_sec = filedata->section_headers + section->sh_link;
17440 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
17441 string_sec->sh_size,
17442 _("liblist string table"));
047b2264
JJ
17443 if (strtab == NULL
17444 || section->sh_entsize != sizeof (Elf32_External_Lib))
17445 {
17446 free (elib);
2842702f 17447 free (strtab);
32ec8896 17448 res = FALSE;
047b2264
JJ
17449 break;
17450 }
59245841 17451 strtab_size = string_sec->sh_size;
047b2264 17452
d3a49aa8
AM
17453 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
17454 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
17455 "\nLibrary list section '%s' contains %lu entries:\n",
17456 num_liblist),
dda8d76d 17457 printable_section_name (filedata, section),
d3a49aa8 17458 num_liblist);
047b2264 17459
2b692964 17460 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
17461
17462 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
17463 ++cnt)
17464 {
17465 Elf32_Lib liblist;
91d6fa6a 17466 time_t atime;
d5b07ef4 17467 char timebuf[128];
2cf0635d 17468 struct tm * tmp;
047b2264
JJ
17469
17470 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17471 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
17472 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17473 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17474 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17475
91d6fa6a 17476 tmp = gmtime (&atime);
e9e44622
JJ
17477 snprintf (timebuf, sizeof (timebuf),
17478 "%04u-%02u-%02uT%02u:%02u:%02u",
17479 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17480 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
17481
17482 printf ("%3lu: ", (unsigned long) cnt);
17483 if (do_wide)
c256ffe7 17484 printf ("%-20s", liblist.l_name < strtab_size
2b692964 17485 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 17486 else
c256ffe7 17487 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 17488 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
17489 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
17490 liblist.l_version, liblist.l_flags);
17491 }
17492
17493 free (elib);
2842702f 17494 free (strtab);
047b2264
JJ
17495 }
17496 }
17497
32ec8896 17498 return res;
047b2264
JJ
17499}
17500
9437c45b 17501static const char *
dda8d76d 17502get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
17503{
17504 static char buff[64];
103f02d3 17505
dda8d76d 17506 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
17507 switch (e_type)
17508 {
57346661 17509 case NT_AUXV:
1ec5cd37 17510 return _("NT_AUXV (auxiliary vector)");
57346661 17511 case NT_PRSTATUS:
1ec5cd37 17512 return _("NT_PRSTATUS (prstatus structure)");
57346661 17513 case NT_FPREGSET:
1ec5cd37 17514 return _("NT_FPREGSET (floating point registers)");
57346661 17515 case NT_PRPSINFO:
1ec5cd37 17516 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 17517 case NT_TASKSTRUCT:
1ec5cd37 17518 return _("NT_TASKSTRUCT (task structure)");
57346661 17519 case NT_PRXFPREG:
1ec5cd37 17520 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
17521 case NT_PPC_VMX:
17522 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
17523 case NT_PPC_VSX:
17524 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
17525 case NT_PPC_TAR:
17526 return _("NT_PPC_TAR (ppc TAR register)");
17527 case NT_PPC_PPR:
17528 return _("NT_PPC_PPR (ppc PPR register)");
17529 case NT_PPC_DSCR:
17530 return _("NT_PPC_DSCR (ppc DSCR register)");
17531 case NT_PPC_EBB:
17532 return _("NT_PPC_EBB (ppc EBB registers)");
17533 case NT_PPC_PMU:
17534 return _("NT_PPC_PMU (ppc PMU registers)");
17535 case NT_PPC_TM_CGPR:
17536 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
17537 case NT_PPC_TM_CFPR:
17538 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
17539 case NT_PPC_TM_CVMX:
17540 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
17541 case NT_PPC_TM_CVSX:
3fd21718 17542 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
17543 case NT_PPC_TM_SPR:
17544 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
17545 case NT_PPC_TM_CTAR:
17546 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
17547 case NT_PPC_TM_CPPR:
17548 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
17549 case NT_PPC_TM_CDSCR:
17550 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
17551 case NT_386_TLS:
17552 return _("NT_386_TLS (x86 TLS information)");
17553 case NT_386_IOPERM:
17554 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
17555 case NT_X86_XSTATE:
17556 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
17557 case NT_S390_HIGH_GPRS:
17558 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
17559 case NT_S390_TIMER:
17560 return _("NT_S390_TIMER (s390 timer register)");
17561 case NT_S390_TODCMP:
17562 return _("NT_S390_TODCMP (s390 TOD comparator register)");
17563 case NT_S390_TODPREG:
17564 return _("NT_S390_TODPREG (s390 TOD programmable register)");
17565 case NT_S390_CTRS:
17566 return _("NT_S390_CTRS (s390 control registers)");
17567 case NT_S390_PREFIX:
17568 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
17569 case NT_S390_LAST_BREAK:
17570 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
17571 case NT_S390_SYSTEM_CALL:
17572 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
17573 case NT_S390_TDB:
17574 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
17575 case NT_S390_VXRS_LOW:
17576 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
17577 case NT_S390_VXRS_HIGH:
17578 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
17579 case NT_S390_GS_CB:
17580 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
17581 case NT_S390_GS_BC:
17582 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
17583 case NT_ARM_VFP:
17584 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
17585 case NT_ARM_TLS:
17586 return _("NT_ARM_TLS (AArch TLS registers)");
17587 case NT_ARM_HW_BREAK:
17588 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
17589 case NT_ARM_HW_WATCH:
17590 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 17591 case NT_PSTATUS:
1ec5cd37 17592 return _("NT_PSTATUS (pstatus structure)");
57346661 17593 case NT_FPREGS:
1ec5cd37 17594 return _("NT_FPREGS (floating point registers)");
57346661 17595 case NT_PSINFO:
1ec5cd37 17596 return _("NT_PSINFO (psinfo structure)");
57346661 17597 case NT_LWPSTATUS:
1ec5cd37 17598 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 17599 case NT_LWPSINFO:
1ec5cd37 17600 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 17601 case NT_WIN32PSTATUS:
1ec5cd37 17602 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
17603 case NT_SIGINFO:
17604 return _("NT_SIGINFO (siginfo_t data)");
17605 case NT_FILE:
17606 return _("NT_FILE (mapped files)");
1ec5cd37
NC
17607 default:
17608 break;
17609 }
17610 else
17611 switch (e_type)
17612 {
17613 case NT_VERSION:
17614 return _("NT_VERSION (version)");
17615 case NT_ARCH:
17616 return _("NT_ARCH (architecture)");
9ef920e9 17617 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 17618 return _("OPEN");
9ef920e9 17619 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 17620 return _("func");
1ec5cd37
NC
17621 default:
17622 break;
17623 }
17624
e9e44622 17625 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 17626 return buff;
779fe533
NC
17627}
17628
32ec8896 17629static bfd_boolean
9ece1fa9
TT
17630print_core_note (Elf_Internal_Note *pnote)
17631{
17632 unsigned int addr_size = is_32bit_elf ? 4 : 8;
17633 bfd_vma count, page_size;
17634 unsigned char *descdata, *filenames, *descend;
17635
17636 if (pnote->type != NT_FILE)
04ac15ab
AS
17637 {
17638 if (do_wide)
17639 printf ("\n");
17640 return TRUE;
17641 }
9ece1fa9
TT
17642
17643#ifndef BFD64
17644 if (!is_32bit_elf)
17645 {
17646 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
17647 /* Still "successful". */
32ec8896 17648 return TRUE;
9ece1fa9
TT
17649 }
17650#endif
17651
17652 if (pnote->descsz < 2 * addr_size)
17653 {
32ec8896
NC
17654 error (_(" Malformed note - too short for header\n"));
17655 return FALSE;
9ece1fa9
TT
17656 }
17657
17658 descdata = (unsigned char *) pnote->descdata;
17659 descend = descdata + pnote->descsz;
17660
17661 if (descdata[pnote->descsz - 1] != '\0')
17662 {
32ec8896
NC
17663 error (_(" Malformed note - does not end with \\0\n"));
17664 return FALSE;
9ece1fa9
TT
17665 }
17666
17667 count = byte_get (descdata, addr_size);
17668 descdata += addr_size;
17669
17670 page_size = byte_get (descdata, addr_size);
17671 descdata += addr_size;
17672
5396a86e
AM
17673 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
17674 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 17675 {
32ec8896
NC
17676 error (_(" Malformed note - too short for supplied file count\n"));
17677 return FALSE;
9ece1fa9
TT
17678 }
17679
17680 printf (_(" Page size: "));
17681 print_vma (page_size, DEC);
17682 printf ("\n");
17683
17684 printf (_(" %*s%*s%*s\n"),
17685 (int) (2 + 2 * addr_size), _("Start"),
17686 (int) (4 + 2 * addr_size), _("End"),
17687 (int) (4 + 2 * addr_size), _("Page Offset"));
17688 filenames = descdata + count * 3 * addr_size;
595712bb 17689 while (count-- > 0)
9ece1fa9
TT
17690 {
17691 bfd_vma start, end, file_ofs;
17692
17693 if (filenames == descend)
17694 {
32ec8896
NC
17695 error (_(" Malformed note - filenames end too early\n"));
17696 return FALSE;
9ece1fa9
TT
17697 }
17698
17699 start = byte_get (descdata, addr_size);
17700 descdata += addr_size;
17701 end = byte_get (descdata, addr_size);
17702 descdata += addr_size;
17703 file_ofs = byte_get (descdata, addr_size);
17704 descdata += addr_size;
17705
17706 printf (" ");
17707 print_vma (start, FULL_HEX);
17708 printf (" ");
17709 print_vma (end, FULL_HEX);
17710 printf (" ");
17711 print_vma (file_ofs, FULL_HEX);
17712 printf ("\n %s\n", filenames);
17713
17714 filenames += 1 + strlen ((char *) filenames);
17715 }
17716
32ec8896 17717 return TRUE;
9ece1fa9
TT
17718}
17719
1118d252
RM
17720static const char *
17721get_gnu_elf_note_type (unsigned e_type)
17722{
1449284b 17723 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
17724 switch (e_type)
17725 {
17726 case NT_GNU_ABI_TAG:
17727 return _("NT_GNU_ABI_TAG (ABI version tag)");
17728 case NT_GNU_HWCAP:
17729 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
17730 case NT_GNU_BUILD_ID:
17731 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
17732 case NT_GNU_GOLD_VERSION:
17733 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
17734 case NT_GNU_PROPERTY_TYPE_0:
17735 return _("NT_GNU_PROPERTY_TYPE_0");
17736 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
17737 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
17738 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
17739 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 17740 default:
1449284b
NC
17741 {
17742 static char buff[64];
1118d252 17743
1449284b
NC
17744 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17745 return buff;
17746 }
17747 }
1118d252
RM
17748}
17749
a9eafb08
L
17750static void
17751decode_x86_compat_isa (unsigned int bitmask)
17752{
17753 while (bitmask)
17754 {
17755 unsigned int bit = bitmask & (- bitmask);
17756
17757 bitmask &= ~ bit;
17758 switch (bit)
17759 {
17760 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
17761 printf ("i486");
17762 break;
17763 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
17764 printf ("586");
17765 break;
17766 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
17767 printf ("686");
17768 break;
17769 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
17770 printf ("SSE");
17771 break;
17772 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
17773 printf ("SSE2");
17774 break;
17775 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
17776 printf ("SSE3");
17777 break;
17778 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
17779 printf ("SSSE3");
17780 break;
17781 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
17782 printf ("SSE4_1");
17783 break;
17784 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
17785 printf ("SSE4_2");
17786 break;
17787 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
17788 printf ("AVX");
17789 break;
17790 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
17791 printf ("AVX2");
17792 break;
17793 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
17794 printf ("AVX512F");
17795 break;
17796 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
17797 printf ("AVX512CD");
17798 break;
17799 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
17800 printf ("AVX512ER");
17801 break;
17802 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
17803 printf ("AVX512PF");
17804 break;
17805 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
17806 printf ("AVX512VL");
17807 break;
17808 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
17809 printf ("AVX512DQ");
17810 break;
17811 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
17812 printf ("AVX512BW");
17813 break;
65b3d26e
L
17814 default:
17815 printf (_("<unknown: %x>"), bit);
17816 break;
a9eafb08
L
17817 }
17818 if (bitmask)
17819 printf (", ");
17820 }
17821}
17822
9ef920e9 17823static void
1fc87489 17824decode_x86_isa (unsigned int bitmask)
9ef920e9 17825{
0a59decb 17826 if (!bitmask)
90c745dc
L
17827 {
17828 printf (_("<None>"));
17829 return;
17830 }
90c745dc 17831
9ef920e9
NC
17832 while (bitmask)
17833 {
1fc87489 17834 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
17835
17836 bitmask &= ~ bit;
17837 switch (bit)
17838 {
a9eafb08
L
17839 case GNU_PROPERTY_X86_ISA_1_CMOV:
17840 printf ("CMOV");
17841 break;
17842 case GNU_PROPERTY_X86_ISA_1_SSE:
17843 printf ("SSE");
17844 break;
17845 case GNU_PROPERTY_X86_ISA_1_SSE2:
17846 printf ("SSE2");
17847 break;
17848 case GNU_PROPERTY_X86_ISA_1_SSE3:
17849 printf ("SSE3");
17850 break;
17851 case GNU_PROPERTY_X86_ISA_1_SSSE3:
17852 printf ("SSSE3");
17853 break;
17854 case GNU_PROPERTY_X86_ISA_1_SSE4_1:
17855 printf ("SSE4_1");
17856 break;
17857 case GNU_PROPERTY_X86_ISA_1_SSE4_2:
17858 printf ("SSE4_2");
17859 break;
17860 case GNU_PROPERTY_X86_ISA_1_AVX:
17861 printf ("AVX");
17862 break;
17863 case GNU_PROPERTY_X86_ISA_1_AVX2:
17864 printf ("AVX2");
17865 break;
17866 case GNU_PROPERTY_X86_ISA_1_FMA:
17867 printf ("FMA");
17868 break;
17869 case GNU_PROPERTY_X86_ISA_1_AVX512F:
17870 printf ("AVX512F");
17871 break;
17872 case GNU_PROPERTY_X86_ISA_1_AVX512CD:
17873 printf ("AVX512CD");
17874 break;
17875 case GNU_PROPERTY_X86_ISA_1_AVX512ER:
17876 printf ("AVX512ER");
17877 break;
17878 case GNU_PROPERTY_X86_ISA_1_AVX512PF:
17879 printf ("AVX512PF");
17880 break;
17881 case GNU_PROPERTY_X86_ISA_1_AVX512VL:
17882 printf ("AVX512VL");
17883 break;
17884 case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
17885 printf ("AVX512DQ");
17886 break;
17887 case GNU_PROPERTY_X86_ISA_1_AVX512BW:
17888 printf ("AVX512BW");
17889 break;
17890 case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
17891 printf ("AVX512_4FMAPS");
17892 break;
17893 case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
17894 printf ("AVX512_4VNNIW");
17895 break;
17896 case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
17897 printf ("AVX512_BITALG");
17898 break;
17899 case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
17900 printf ("AVX512_IFMA");
17901 break;
17902 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
17903 printf ("AVX512_VBMI");
17904 break;
17905 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
17906 printf ("AVX512_VBMI2");
17907 break;
17908 case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
17909 printf ("AVX512_VNNI");
17910 break;
462cac58
L
17911 case GNU_PROPERTY_X86_ISA_1_AVX512_BF16:
17912 printf ("AVX512_BF16");
17913 break;
65b3d26e
L
17914 default:
17915 printf (_("<unknown: %x>"), bit);
17916 break;
9ef920e9
NC
17917 }
17918 if (bitmask)
17919 printf (", ");
17920 }
17921}
17922
ee2fdd6f 17923static void
a9eafb08 17924decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 17925{
0a59decb 17926 if (!bitmask)
90c745dc
L
17927 {
17928 printf (_("<None>"));
17929 return;
17930 }
90c745dc 17931
ee2fdd6f
L
17932 while (bitmask)
17933 {
17934 unsigned int bit = bitmask & (- bitmask);
17935
17936 bitmask &= ~ bit;
17937 switch (bit)
17938 {
17939 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 17940 printf ("IBT");
ee2fdd6f 17941 break;
48580982 17942 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 17943 printf ("SHSTK");
48580982 17944 break;
ee2fdd6f
L
17945 default:
17946 printf (_("<unknown: %x>"), bit);
17947 break;
17948 }
17949 if (bitmask)
17950 printf (", ");
17951 }
17952}
17953
a9eafb08
L
17954static void
17955decode_x86_feature_2 (unsigned int bitmask)
17956{
0a59decb 17957 if (!bitmask)
90c745dc
L
17958 {
17959 printf (_("<None>"));
17960 return;
17961 }
90c745dc 17962
a9eafb08
L
17963 while (bitmask)
17964 {
17965 unsigned int bit = bitmask & (- bitmask);
17966
17967 bitmask &= ~ bit;
17968 switch (bit)
17969 {
17970 case GNU_PROPERTY_X86_FEATURE_2_X86:
17971 printf ("x86");
17972 break;
17973 case GNU_PROPERTY_X86_FEATURE_2_X87:
17974 printf ("x87");
17975 break;
17976 case GNU_PROPERTY_X86_FEATURE_2_MMX:
17977 printf ("MMX");
17978 break;
17979 case GNU_PROPERTY_X86_FEATURE_2_XMM:
17980 printf ("XMM");
17981 break;
17982 case GNU_PROPERTY_X86_FEATURE_2_YMM:
17983 printf ("YMM");
17984 break;
17985 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
17986 printf ("ZMM");
17987 break;
17988 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
17989 printf ("FXSR");
17990 break;
17991 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
17992 printf ("XSAVE");
17993 break;
17994 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
17995 printf ("XSAVEOPT");
17996 break;
17997 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
17998 printf ("XSAVEC");
17999 break;
65b3d26e
L
18000 default:
18001 printf (_("<unknown: %x>"), bit);
18002 break;
a9eafb08
L
18003 }
18004 if (bitmask)
18005 printf (", ");
18006 }
18007}
18008
cd702818
SD
18009static void
18010decode_aarch64_feature_1_and (unsigned int bitmask)
18011{
18012 while (bitmask)
18013 {
18014 unsigned int bit = bitmask & (- bitmask);
18015
18016 bitmask &= ~ bit;
18017 switch (bit)
18018 {
18019 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
18020 printf ("BTI");
18021 break;
18022
18023 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
18024 printf ("PAC");
18025 break;
18026
18027 default:
18028 printf (_("<unknown: %x>"), bit);
18029 break;
18030 }
18031 if (bitmask)
18032 printf (", ");
18033 }
18034}
18035
9ef920e9 18036static void
dda8d76d 18037print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
18038{
18039 unsigned char * ptr = (unsigned char *) pnote->descdata;
18040 unsigned char * ptr_end = ptr + pnote->descsz;
18041 unsigned int size = is_32bit_elf ? 4 : 8;
18042
18043 printf (_(" Properties: "));
18044
1fc87489 18045 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
18046 {
18047 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
18048 return;
18049 }
18050
6ab2c4ed 18051 while (ptr < ptr_end)
9ef920e9 18052 {
1fc87489 18053 unsigned int j;
6ab2c4ed
MC
18054 unsigned int type;
18055 unsigned int datasz;
18056
18057 if ((size_t) (ptr_end - ptr) < 8)
18058 {
18059 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
18060 break;
18061 }
18062
18063 type = byte_get (ptr, 4);
18064 datasz = byte_get (ptr + 4, 4);
9ef920e9 18065
1fc87489 18066 ptr += 8;
9ef920e9 18067
6ab2c4ed 18068 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 18069 {
1fc87489
L
18070 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
18071 type, datasz);
9ef920e9 18072 break;
1fc87489 18073 }
9ef920e9 18074
1fc87489
L
18075 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
18076 {
dda8d76d
NC
18077 if (filedata->file_header.e_machine == EM_X86_64
18078 || filedata->file_header.e_machine == EM_IAMCU
18079 || filedata->file_header.e_machine == EM_386)
1fc87489 18080 {
aa7bca9b
L
18081 unsigned int bitmask;
18082
18083 if (datasz == 4)
0a59decb 18084 bitmask = byte_get (ptr, 4);
aa7bca9b
L
18085 else
18086 bitmask = 0;
18087
1fc87489
L
18088 switch (type)
18089 {
18090 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 18091 if (datasz != 4)
aa7bca9b
L
18092 printf (_("x86 ISA used: <corrupt length: %#x> "),
18093 datasz);
1fc87489 18094 else
aa7bca9b
L
18095 {
18096 printf ("x86 ISA used: ");
18097 decode_x86_isa (bitmask);
18098 }
1fc87489 18099 goto next;
9ef920e9 18100
1fc87489 18101 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 18102 if (datasz != 4)
aa7bca9b
L
18103 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18104 datasz);
1fc87489 18105 else
aa7bca9b
L
18106 {
18107 printf ("x86 ISA needed: ");
18108 decode_x86_isa (bitmask);
18109 }
1fc87489 18110 goto next;
9ef920e9 18111
ee2fdd6f 18112 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 18113 if (datasz != 4)
aa7bca9b
L
18114 printf (_("x86 feature: <corrupt length: %#x> "),
18115 datasz);
ee2fdd6f 18116 else
aa7bca9b
L
18117 {
18118 printf ("x86 feature: ");
a9eafb08
L
18119 decode_x86_feature_1 (bitmask);
18120 }
18121 goto next;
18122
18123 case GNU_PROPERTY_X86_FEATURE_2_USED:
18124 if (datasz != 4)
18125 printf (_("x86 feature used: <corrupt length: %#x> "),
18126 datasz);
18127 else
18128 {
18129 printf ("x86 feature used: ");
18130 decode_x86_feature_2 (bitmask);
18131 }
18132 goto next;
18133
18134 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
18135 if (datasz != 4)
18136 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
18137 else
18138 {
18139 printf ("x86 feature needed: ");
18140 decode_x86_feature_2 (bitmask);
18141 }
18142 goto next;
18143
18144 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
18145 if (datasz != 4)
18146 printf (_("x86 ISA used: <corrupt length: %#x> "),
18147 datasz);
18148 else
18149 {
18150 printf ("x86 ISA used: ");
18151 decode_x86_compat_isa (bitmask);
18152 }
18153 goto next;
18154
18155 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
18156 if (datasz != 4)
18157 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18158 datasz);
18159 else
18160 {
18161 printf ("x86 ISA needed: ");
18162 decode_x86_compat_isa (bitmask);
aa7bca9b 18163 }
ee2fdd6f
L
18164 goto next;
18165
1fc87489
L
18166 default:
18167 break;
18168 }
18169 }
cd702818
SD
18170 else if (filedata->file_header.e_machine == EM_AARCH64)
18171 {
18172 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
18173 {
18174 printf ("AArch64 feature: ");
18175 if (datasz != 4)
18176 printf (_("<corrupt length: %#x> "), datasz);
18177 else
18178 decode_aarch64_feature_1_and (byte_get (ptr, 4));
18179 goto next;
18180 }
18181 }
1fc87489
L
18182 }
18183 else
18184 {
18185 switch (type)
9ef920e9 18186 {
1fc87489
L
18187 case GNU_PROPERTY_STACK_SIZE:
18188 printf (_("stack size: "));
18189 if (datasz != size)
18190 printf (_("<corrupt length: %#x> "), datasz);
18191 else
18192 printf ("%#lx", (unsigned long) byte_get (ptr, size));
18193 goto next;
18194
18195 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
18196 printf ("no copy on protected ");
18197 if (datasz)
18198 printf (_("<corrupt length: %#x> "), datasz);
18199 goto next;
18200
18201 default:
9ef920e9
NC
18202 break;
18203 }
9ef920e9
NC
18204 }
18205
1fc87489
L
18206 if (type < GNU_PROPERTY_LOPROC)
18207 printf (_("<unknown type %#x data: "), type);
18208 else if (type < GNU_PROPERTY_LOUSER)
18209 printf (_("<procesor-specific type %#x data: "), type);
18210 else
18211 printf (_("<application-specific type %#x data: "), type);
18212 for (j = 0; j < datasz; ++j)
18213 printf ("%02x ", ptr[j] & 0xff);
18214 printf (">");
18215
dc1e8a47 18216 next:
9ef920e9 18217 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
18218 if (ptr == ptr_end)
18219 break;
1fc87489 18220
6ab2c4ed
MC
18221 if (do_wide)
18222 printf (", ");
18223 else
18224 printf ("\n\t");
9ef920e9
NC
18225 }
18226
18227 printf ("\n");
18228}
18229
32ec8896 18230static bfd_boolean
dda8d76d 18231print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 18232{
1449284b 18233 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
18234 switch (pnote->type)
18235 {
18236 case NT_GNU_BUILD_ID:
18237 {
18238 unsigned long i;
18239
18240 printf (_(" Build ID: "));
18241 for (i = 0; i < pnote->descsz; ++i)
18242 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 18243 printf ("\n");
664f90a3
TT
18244 }
18245 break;
18246
18247 case NT_GNU_ABI_TAG:
18248 {
18249 unsigned long os, major, minor, subminor;
18250 const char *osname;
18251
3102e897
NC
18252 /* PR 17531: file: 030-599401-0.004. */
18253 if (pnote->descsz < 16)
18254 {
18255 printf (_(" <corrupt GNU_ABI_TAG>\n"));
18256 break;
18257 }
18258
664f90a3
TT
18259 os = byte_get ((unsigned char *) pnote->descdata, 4);
18260 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18261 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
18262 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
18263
18264 switch (os)
18265 {
18266 case GNU_ABI_TAG_LINUX:
18267 osname = "Linux";
18268 break;
18269 case GNU_ABI_TAG_HURD:
18270 osname = "Hurd";
18271 break;
18272 case GNU_ABI_TAG_SOLARIS:
18273 osname = "Solaris";
18274 break;
18275 case GNU_ABI_TAG_FREEBSD:
18276 osname = "FreeBSD";
18277 break;
18278 case GNU_ABI_TAG_NETBSD:
18279 osname = "NetBSD";
18280 break;
14ae95f2
RM
18281 case GNU_ABI_TAG_SYLLABLE:
18282 osname = "Syllable";
18283 break;
18284 case GNU_ABI_TAG_NACL:
18285 osname = "NaCl";
18286 break;
664f90a3
TT
18287 default:
18288 osname = "Unknown";
18289 break;
18290 }
18291
18292 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
18293 major, minor, subminor);
18294 }
18295 break;
926c5385
CC
18296
18297 case NT_GNU_GOLD_VERSION:
18298 {
18299 unsigned long i;
18300
18301 printf (_(" Version: "));
18302 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
18303 printf ("%c", pnote->descdata[i]);
18304 printf ("\n");
18305 }
18306 break;
1449284b
NC
18307
18308 case NT_GNU_HWCAP:
18309 {
18310 unsigned long num_entries, mask;
18311
18312 /* Hardware capabilities information. Word 0 is the number of entries.
18313 Word 1 is a bitmask of enabled entries. The rest of the descriptor
18314 is a series of entries, where each entry is a single byte followed
18315 by a nul terminated string. The byte gives the bit number to test
18316 if enabled in the bitmask. */
18317 printf (_(" Hardware Capabilities: "));
18318 if (pnote->descsz < 8)
18319 {
32ec8896
NC
18320 error (_("<corrupt GNU_HWCAP>\n"));
18321 return FALSE;
1449284b
NC
18322 }
18323 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
18324 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18325 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
18326 /* FIXME: Add code to display the entries... */
18327 }
18328 break;
18329
9ef920e9 18330 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 18331 print_gnu_property_note (filedata, pnote);
9ef920e9 18332 break;
9abca702 18333
1449284b
NC
18334 default:
18335 /* Handle unrecognised types. An error message should have already been
18336 created by get_gnu_elf_note_type(), so all that we need to do is to
18337 display the data. */
18338 {
18339 unsigned long i;
18340
18341 printf (_(" Description data: "));
18342 for (i = 0; i < pnote->descsz; ++i)
18343 printf ("%02x ", pnote->descdata[i] & 0xff);
18344 printf ("\n");
18345 }
18346 break;
664f90a3
TT
18347 }
18348
32ec8896 18349 return TRUE;
664f90a3
TT
18350}
18351
685080f2
NC
18352static const char *
18353get_v850_elf_note_type (enum v850_notes n_type)
18354{
18355 static char buff[64];
18356
18357 switch (n_type)
18358 {
18359 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
18360 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
18361 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
18362 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
18363 case V850_NOTE_CACHE_INFO: return _("Use of cache");
18364 case V850_NOTE_MMU_INFO: return _("Use of MMU");
18365 default:
18366 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
18367 return buff;
18368 }
18369}
18370
32ec8896 18371static bfd_boolean
685080f2
NC
18372print_v850_note (Elf_Internal_Note * pnote)
18373{
18374 unsigned int val;
18375
18376 if (pnote->descsz != 4)
32ec8896
NC
18377 return FALSE;
18378
685080f2
NC
18379 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
18380
18381 if (val == 0)
18382 {
18383 printf (_("not set\n"));
32ec8896 18384 return TRUE;
685080f2
NC
18385 }
18386
18387 switch (pnote->type)
18388 {
18389 case V850_NOTE_ALIGNMENT:
18390 switch (val)
18391 {
32ec8896
NC
18392 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
18393 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
18394 }
18395 break;
14ae95f2 18396
685080f2
NC
18397 case V850_NOTE_DATA_SIZE:
18398 switch (val)
18399 {
32ec8896
NC
18400 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
18401 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
18402 }
18403 break;
14ae95f2 18404
685080f2
NC
18405 case V850_NOTE_FPU_INFO:
18406 switch (val)
18407 {
32ec8896
NC
18408 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
18409 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
18410 }
18411 break;
14ae95f2 18412
685080f2
NC
18413 case V850_NOTE_MMU_INFO:
18414 case V850_NOTE_CACHE_INFO:
18415 case V850_NOTE_SIMD_INFO:
18416 if (val == EF_RH850_SIMD)
18417 {
18418 printf (_("yes\n"));
32ec8896 18419 return TRUE;
685080f2
NC
18420 }
18421 break;
18422
18423 default:
18424 /* An 'unknown note type' message will already have been displayed. */
18425 break;
18426 }
18427
18428 printf (_("unknown value: %x\n"), val);
32ec8896 18429 return FALSE;
685080f2
NC
18430}
18431
32ec8896 18432static bfd_boolean
c6056a74
SF
18433process_netbsd_elf_note (Elf_Internal_Note * pnote)
18434{
18435 unsigned int version;
18436
18437 switch (pnote->type)
18438 {
18439 case NT_NETBSD_IDENT:
b966f55f
AM
18440 if (pnote->descsz < 1)
18441 break;
c6056a74
SF
18442 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18443 if ((version / 10000) % 100)
b966f55f 18444 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
18445 version, version / 100000000, (version / 1000000) % 100,
18446 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 18447 'A' + (version / 10000) % 26);
c6056a74
SF
18448 else
18449 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 18450 version, version / 100000000, (version / 1000000) % 100,
15f205b1 18451 (version / 100) % 100);
32ec8896 18452 return TRUE;
c6056a74
SF
18453
18454 case NT_NETBSD_MARCH:
9abca702 18455 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 18456 pnote->descdata);
32ec8896 18457 return TRUE;
c6056a74 18458
9abca702
CZ
18459#ifdef NT_NETBSD_PAX
18460 case NT_NETBSD_PAX:
b966f55f
AM
18461 if (pnote->descsz < 1)
18462 break;
9abca702
CZ
18463 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18464 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
18465 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
18466 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
18467 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
18468 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
18469 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
18470 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
18471 return TRUE;
18472#endif
c6056a74 18473 }
b966f55f
AM
18474
18475 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
18476 pnote->descsz, pnote->type);
18477 return FALSE;
c6056a74
SF
18478}
18479
f4ddf30f 18480static const char *
dda8d76d 18481get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 18482{
f4ddf30f
JB
18483 switch (e_type)
18484 {
18485 case NT_FREEBSD_THRMISC:
18486 return _("NT_THRMISC (thrmisc structure)");
18487 case NT_FREEBSD_PROCSTAT_PROC:
18488 return _("NT_PROCSTAT_PROC (proc data)");
18489 case NT_FREEBSD_PROCSTAT_FILES:
18490 return _("NT_PROCSTAT_FILES (files data)");
18491 case NT_FREEBSD_PROCSTAT_VMMAP:
18492 return _("NT_PROCSTAT_VMMAP (vmmap data)");
18493 case NT_FREEBSD_PROCSTAT_GROUPS:
18494 return _("NT_PROCSTAT_GROUPS (groups data)");
18495 case NT_FREEBSD_PROCSTAT_UMASK:
18496 return _("NT_PROCSTAT_UMASK (umask data)");
18497 case NT_FREEBSD_PROCSTAT_RLIMIT:
18498 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
18499 case NT_FREEBSD_PROCSTAT_OSREL:
18500 return _("NT_PROCSTAT_OSREL (osreldate data)");
18501 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
18502 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
18503 case NT_FREEBSD_PROCSTAT_AUXV:
18504 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
18505 case NT_FREEBSD_PTLWPINFO:
18506 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 18507 }
dda8d76d 18508 return get_note_type (filedata, e_type);
f4ddf30f
JB
18509}
18510
9437c45b 18511static const char *
dda8d76d 18512get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
18513{
18514 static char buff[64];
18515
540e6170
CZ
18516 switch (e_type)
18517 {
18518 case NT_NETBSDCORE_PROCINFO:
18519 /* NetBSD core "procinfo" structure. */
18520 return _("NetBSD procinfo structure");
9437c45b 18521
540e6170
CZ
18522#ifdef NT_NETBSDCORE_AUXV
18523 case NT_NETBSDCORE_AUXV:
18524 return _("NetBSD ELF auxiliary vector data");
18525#endif
9437c45b 18526
06d949ec
KR
18527#ifdef NT_NETBSDCORE_LWPSTATUS
18528 case NT_NETBSDCORE_LWPSTATUS:
18529 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
18530#endif
18531
540e6170 18532 default:
06d949ec 18533 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
18534 defined for NetBSD core files. If the note type is less
18535 than the start of the machine-dependent note types, we don't
18536 understand it. */
18537
18538 if (e_type < NT_NETBSDCORE_FIRSTMACH)
18539 {
18540 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18541 return buff;
18542 }
18543 break;
9437c45b
JT
18544 }
18545
dda8d76d 18546 switch (filedata->file_header.e_machine)
9437c45b
JT
18547 {
18548 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
18549 and PT_GETFPREGS == mach+2. */
18550
18551 case EM_OLD_ALPHA:
18552 case EM_ALPHA:
18553 case EM_SPARC:
18554 case EM_SPARC32PLUS:
18555 case EM_SPARCV9:
18556 switch (e_type)
18557 {
2b692964 18558 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 18559 return _("PT_GETREGS (reg structure)");
2b692964 18560 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 18561 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18562 default:
18563 break;
18564 }
18565 break;
18566
c0d38b0e
CZ
18567 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
18568 There's also old PT___GETREGS40 == mach + 1 for old reg
18569 structure which lacks GBR. */
18570 case EM_SH:
18571 switch (e_type)
18572 {
18573 case NT_NETBSDCORE_FIRSTMACH + 1:
18574 return _("PT___GETREGS40 (old reg structure)");
18575 case NT_NETBSDCORE_FIRSTMACH + 3:
18576 return _("PT_GETREGS (reg structure)");
18577 case NT_NETBSDCORE_FIRSTMACH + 5:
18578 return _("PT_GETFPREGS (fpreg structure)");
18579 default:
18580 break;
18581 }
18582 break;
18583
9437c45b
JT
18584 /* On all other arch's, PT_GETREGS == mach+1 and
18585 PT_GETFPREGS == mach+3. */
18586 default:
18587 switch (e_type)
18588 {
2b692964 18589 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 18590 return _("PT_GETREGS (reg structure)");
2b692964 18591 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 18592 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18593 default:
18594 break;
18595 }
18596 }
18597
9cf03b7e 18598 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 18599 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
18600 return buff;
18601}
18602
70616151
TT
18603static const char *
18604get_stapsdt_note_type (unsigned e_type)
18605{
18606 static char buff[64];
18607
18608 switch (e_type)
18609 {
18610 case NT_STAPSDT:
18611 return _("NT_STAPSDT (SystemTap probe descriptors)");
18612
18613 default:
18614 break;
18615 }
18616
18617 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18618 return buff;
18619}
18620
32ec8896 18621static bfd_boolean
c6a9fc58
TT
18622print_stapsdt_note (Elf_Internal_Note *pnote)
18623{
3ca60c57
NC
18624 size_t len, maxlen;
18625 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
18626 char *data = pnote->descdata;
18627 char *data_end = pnote->descdata + pnote->descsz;
18628 bfd_vma pc, base_addr, semaphore;
18629 char *provider, *probe, *arg_fmt;
18630
3ca60c57
NC
18631 if (pnote->descsz < (addr_size * 3))
18632 goto stapdt_note_too_small;
18633
c6a9fc58
TT
18634 pc = byte_get ((unsigned char *) data, addr_size);
18635 data += addr_size;
3ca60c57 18636
c6a9fc58
TT
18637 base_addr = byte_get ((unsigned char *) data, addr_size);
18638 data += addr_size;
3ca60c57 18639
c6a9fc58
TT
18640 semaphore = byte_get ((unsigned char *) data, addr_size);
18641 data += addr_size;
18642
3ca60c57
NC
18643 if (data >= data_end)
18644 goto stapdt_note_too_small;
18645 maxlen = data_end - data;
18646 len = strnlen (data, maxlen);
18647 if (len < maxlen)
18648 {
18649 provider = data;
18650 data += len + 1;
18651 }
18652 else
18653 goto stapdt_note_too_small;
18654
18655 if (data >= data_end)
18656 goto stapdt_note_too_small;
18657 maxlen = data_end - data;
18658 len = strnlen (data, maxlen);
18659 if (len < maxlen)
18660 {
18661 probe = data;
18662 data += len + 1;
18663 }
18664 else
18665 goto stapdt_note_too_small;
9abca702 18666
3ca60c57
NC
18667 if (data >= data_end)
18668 goto stapdt_note_too_small;
18669 maxlen = data_end - data;
18670 len = strnlen (data, maxlen);
18671 if (len < maxlen)
18672 {
18673 arg_fmt = data;
18674 data += len + 1;
18675 }
18676 else
18677 goto stapdt_note_too_small;
c6a9fc58
TT
18678
18679 printf (_(" Provider: %s\n"), provider);
18680 printf (_(" Name: %s\n"), probe);
18681 printf (_(" Location: "));
18682 print_vma (pc, FULL_HEX);
18683 printf (_(", Base: "));
18684 print_vma (base_addr, FULL_HEX);
18685 printf (_(", Semaphore: "));
18686 print_vma (semaphore, FULL_HEX);
9cf03b7e 18687 printf ("\n");
c6a9fc58
TT
18688 printf (_(" Arguments: %s\n"), arg_fmt);
18689
18690 return data == data_end;
3ca60c57
NC
18691
18692 stapdt_note_too_small:
18693 printf (_(" <corrupt - note is too small>\n"));
18694 error (_("corrupt stapdt note - the data size is too small\n"));
18695 return FALSE;
c6a9fc58
TT
18696}
18697
00e98fc7
TG
18698static const char *
18699get_ia64_vms_note_type (unsigned e_type)
18700{
18701 static char buff[64];
18702
18703 switch (e_type)
18704 {
18705 case NT_VMS_MHD:
18706 return _("NT_VMS_MHD (module header)");
18707 case NT_VMS_LNM:
18708 return _("NT_VMS_LNM (language name)");
18709 case NT_VMS_SRC:
18710 return _("NT_VMS_SRC (source files)");
18711 case NT_VMS_TITLE:
9cf03b7e 18712 return "NT_VMS_TITLE";
00e98fc7
TG
18713 case NT_VMS_EIDC:
18714 return _("NT_VMS_EIDC (consistency check)");
18715 case NT_VMS_FPMODE:
18716 return _("NT_VMS_FPMODE (FP mode)");
18717 case NT_VMS_LINKTIME:
9cf03b7e 18718 return "NT_VMS_LINKTIME";
00e98fc7
TG
18719 case NT_VMS_IMGNAM:
18720 return _("NT_VMS_IMGNAM (image name)");
18721 case NT_VMS_IMGID:
18722 return _("NT_VMS_IMGID (image id)");
18723 case NT_VMS_LINKID:
18724 return _("NT_VMS_LINKID (link id)");
18725 case NT_VMS_IMGBID:
18726 return _("NT_VMS_IMGBID (build id)");
18727 case NT_VMS_GSTNAM:
18728 return _("NT_VMS_GSTNAM (sym table name)");
18729 case NT_VMS_ORIG_DYN:
9cf03b7e 18730 return "NT_VMS_ORIG_DYN";
00e98fc7 18731 case NT_VMS_PATCHTIME:
9cf03b7e 18732 return "NT_VMS_PATCHTIME";
00e98fc7
TG
18733 default:
18734 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18735 return buff;
18736 }
18737}
18738
32ec8896 18739static bfd_boolean
00e98fc7
TG
18740print_ia64_vms_note (Elf_Internal_Note * pnote)
18741{
8d18bf79
NC
18742 int maxlen = pnote->descsz;
18743
18744 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
18745 goto desc_size_fail;
18746
00e98fc7
TG
18747 switch (pnote->type)
18748 {
18749 case NT_VMS_MHD:
8d18bf79
NC
18750 if (maxlen <= 36)
18751 goto desc_size_fail;
18752
18753 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
18754
18755 printf (_(" Creation date : %.17s\n"), pnote->descdata);
18756 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
18757 if (l + 34 < maxlen)
18758 {
18759 printf (_(" Module name : %s\n"), pnote->descdata + 34);
18760 if (l + 35 < maxlen)
18761 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
18762 else
18763 printf (_(" Module version : <missing>\n"));
18764 }
00e98fc7 18765 else
8d18bf79
NC
18766 {
18767 printf (_(" Module name : <missing>\n"));
18768 printf (_(" Module version : <missing>\n"));
18769 }
00e98fc7 18770 break;
8d18bf79 18771
00e98fc7 18772 case NT_VMS_LNM:
8d18bf79 18773 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18774 break;
8d18bf79 18775
00e98fc7
TG
18776#ifdef BFD64
18777 case NT_VMS_FPMODE:
9cf03b7e 18778 printf (_(" Floating Point mode: "));
8d18bf79
NC
18779 if (maxlen < 8)
18780 goto desc_size_fail;
18781 /* FIXME: Generate an error if descsz > 8 ? */
18782
4a5cb34f 18783 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 18784 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 18785 break;
8d18bf79 18786
00e98fc7
TG
18787 case NT_VMS_LINKTIME:
18788 printf (_(" Link time: "));
8d18bf79
NC
18789 if (maxlen < 8)
18790 goto desc_size_fail;
18791 /* FIXME: Generate an error if descsz > 8 ? */
18792
00e98fc7 18793 print_vms_time
8d18bf79 18794 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
18795 printf ("\n");
18796 break;
8d18bf79 18797
00e98fc7
TG
18798 case NT_VMS_PATCHTIME:
18799 printf (_(" Patch time: "));
8d18bf79
NC
18800 if (maxlen < 8)
18801 goto desc_size_fail;
18802 /* FIXME: Generate an error if descsz > 8 ? */
18803
00e98fc7 18804 print_vms_time
8d18bf79 18805 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
18806 printf ("\n");
18807 break;
8d18bf79 18808
00e98fc7 18809 case NT_VMS_ORIG_DYN:
8d18bf79
NC
18810 if (maxlen < 34)
18811 goto desc_size_fail;
18812
00e98fc7
TG
18813 printf (_(" Major id: %u, minor id: %u\n"),
18814 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
18815 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 18816 printf (_(" Last modified : "));
00e98fc7
TG
18817 print_vms_time
18818 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 18819 printf (_("\n Link flags : "));
4a5cb34f 18820 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 18821 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 18822 printf (_(" Header flags: 0x%08x\n"),
948f632f 18823 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 18824 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
18825 break;
18826#endif
8d18bf79 18827
00e98fc7 18828 case NT_VMS_IMGNAM:
8d18bf79 18829 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18830 break;
8d18bf79 18831
00e98fc7 18832 case NT_VMS_GSTNAM:
8d18bf79 18833 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18834 break;
8d18bf79 18835
00e98fc7 18836 case NT_VMS_IMGID:
8d18bf79 18837 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18838 break;
8d18bf79 18839
00e98fc7 18840 case NT_VMS_LINKID:
8d18bf79 18841 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18842 break;
8d18bf79 18843
00e98fc7 18844 default:
32ec8896 18845 return FALSE;
00e98fc7 18846 }
8d18bf79 18847
32ec8896 18848 return TRUE;
8d18bf79
NC
18849
18850 desc_size_fail:
18851 printf (_(" <corrupt - data size is too small>\n"));
18852 error (_("corrupt IA64 note: data size is too small\n"));
18853 return FALSE;
00e98fc7
TG
18854}
18855
fd486f32
AM
18856struct build_attr_cache {
18857 Filedata *filedata;
18858 char *strtab;
18859 unsigned long strtablen;
18860 Elf_Internal_Sym *symtab;
18861 unsigned long nsyms;
18862} ba_cache;
18863
6f156d7a
NC
18864/* Find the symbol associated with a build attribute that is attached
18865 to address OFFSET. If PNAME is non-NULL then store the name of
18866 the symbol (if found) in the provided pointer, Returns NULL if a
18867 symbol could not be found. */
c799a79d 18868
6f156d7a
NC
18869static Elf_Internal_Sym *
18870get_symbol_for_build_attribute (Filedata * filedata,
18871 unsigned long offset,
18872 bfd_boolean is_open_attr,
18873 const char ** pname)
9ef920e9 18874{
fd486f32
AM
18875 Elf_Internal_Sym *saved_sym = NULL;
18876 Elf_Internal_Sym *sym;
9ef920e9 18877
dda8d76d 18878 if (filedata->section_headers != NULL
fd486f32 18879 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 18880 {
c799a79d 18881 Elf_Internal_Shdr * symsec;
9ef920e9 18882
fd486f32
AM
18883 free (ba_cache.strtab);
18884 ba_cache.strtab = NULL;
18885 free (ba_cache.symtab);
18886 ba_cache.symtab = NULL;
18887
c799a79d 18888 /* Load the symbol and string sections. */
dda8d76d
NC
18889 for (symsec = filedata->section_headers;
18890 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 18891 symsec ++)
9ef920e9 18892 {
28d13567
AM
18893 if (symsec->sh_type == SHT_SYMTAB
18894 && get_symtab (filedata, symsec,
18895 &ba_cache.symtab, &ba_cache.nsyms,
18896 &ba_cache.strtab, &ba_cache.strtablen))
18897 break;
9ef920e9 18898 }
fd486f32 18899 ba_cache.filedata = filedata;
9ef920e9
NC
18900 }
18901
fd486f32 18902 if (ba_cache.symtab == NULL)
6f156d7a 18903 return NULL;
9ef920e9 18904
c799a79d 18905 /* Find a symbol whose value matches offset. */
fd486f32 18906 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
18907 if (sym->st_value == offset)
18908 {
fd486f32 18909 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
18910 /* Huh ? This should not happen. */
18911 continue;
9ef920e9 18912
fd486f32 18913 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 18914 continue;
9ef920e9 18915
8fd75781
NC
18916 /* The AArch64 and ARM architectures define mapping symbols
18917 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
18918 if (ba_cache.strtab[sym->st_name] == '$'
18919 && ba_cache.strtab[sym->st_name + 1] != 0
18920 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
18921 continue;
18922
c799a79d
NC
18923 if (is_open_attr)
18924 {
18925 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
18926 and FILE or OBJECT symbols over NOTYPE symbols. We skip
18927 FUNC symbols entirely. */
18928 switch (ELF_ST_TYPE (sym->st_info))
18929 {
c799a79d 18930 case STT_OBJECT:
6f156d7a 18931 case STT_FILE:
c799a79d 18932 saved_sym = sym;
6f156d7a
NC
18933 if (sym->st_size)
18934 {
18935 /* If the symbol has a size associated
18936 with it then we can stop searching. */
fd486f32 18937 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 18938 }
c799a79d 18939 continue;
9ef920e9 18940
c799a79d
NC
18941 case STT_FUNC:
18942 /* Ignore function symbols. */
18943 continue;
18944
18945 default:
18946 break;
18947 }
18948
18949 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 18950 {
c799a79d
NC
18951 case STB_GLOBAL:
18952 if (saved_sym == NULL
18953 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
18954 saved_sym = sym;
18955 break;
c871dade 18956
c799a79d
NC
18957 case STB_LOCAL:
18958 if (saved_sym == NULL)
18959 saved_sym = sym;
18960 break;
18961
18962 default:
9ef920e9
NC
18963 break;
18964 }
18965 }
c799a79d
NC
18966 else
18967 {
18968 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
18969 continue;
18970
18971 saved_sym = sym;
18972 break;
18973 }
18974 }
18975
6f156d7a 18976 if (saved_sym && pname)
fd486f32 18977 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
18978
18979 return saved_sym;
c799a79d
NC
18980}
18981
d20e98ab
NC
18982/* Returns true iff addr1 and addr2 are in the same section. */
18983
18984static bfd_boolean
18985same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
18986{
18987 Elf_Internal_Shdr * a1;
18988 Elf_Internal_Shdr * a2;
18989
18990 a1 = find_section_by_address (filedata, addr1);
18991 a2 = find_section_by_address (filedata, addr2);
9abca702 18992
d20e98ab
NC
18993 return a1 == a2 && a1 != NULL;
18994}
18995
c799a79d 18996static bfd_boolean
dda8d76d
NC
18997print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
18998 Filedata * filedata)
c799a79d 18999{
6f156d7a
NC
19000 static unsigned long global_offset = 0;
19001 static unsigned long global_end = 0;
19002 static unsigned long func_offset = 0;
19003 static unsigned long func_end = 0;
c871dade 19004
6f156d7a
NC
19005 Elf_Internal_Sym * sym;
19006 const char * name;
19007 unsigned long start;
19008 unsigned long end;
19009 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
19010
19011 switch (pnote->descsz)
c799a79d 19012 {
6f156d7a
NC
19013 case 0:
19014 /* A zero-length description means that the range of
19015 the previous note of the same type should be used. */
c799a79d 19016 if (is_open_attr)
c871dade 19017 {
6f156d7a
NC
19018 if (global_end > global_offset)
19019 printf (_(" Applies to region from %#lx to %#lx\n"),
19020 global_offset, global_end);
19021 else
19022 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
19023 }
19024 else
19025 {
6f156d7a
NC
19026 if (func_end > func_offset)
19027 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
19028 else
19029 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 19030 }
6f156d7a 19031 return TRUE;
9ef920e9 19032
6f156d7a
NC
19033 case 4:
19034 start = byte_get ((unsigned char *) pnote->descdata, 4);
19035 end = 0;
19036 break;
19037
19038 case 8:
19039 if (is_32bit_elf)
19040 {
19041 /* FIXME: We should check that version 3+ notes are being used here... */
19042 start = byte_get ((unsigned char *) pnote->descdata, 4);
19043 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19044 }
19045 else
19046 {
19047 start = byte_get ((unsigned char *) pnote->descdata, 8);
19048 end = 0;
19049 }
19050 break;
19051
19052 case 16:
19053 start = byte_get ((unsigned char *) pnote->descdata, 8);
19054 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
19055 break;
9abca702 19056
6f156d7a 19057 default:
c799a79d
NC
19058 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
19059 printf (_(" <invalid descsz>"));
19060 return FALSE;
19061 }
19062
6f156d7a
NC
19063 name = NULL;
19064 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
19065 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
19066 in order to avoid them being confused with the start address of the
19067 first function in the file... */
19068 if (sym == NULL && is_open_attr)
19069 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
19070 & name);
6f156d7a
NC
19071
19072 if (end == 0 && sym != NULL && sym->st_size > 0)
19073 end = start + sym->st_size;
c799a79d
NC
19074
19075 if (is_open_attr)
19076 {
d20e98ab
NC
19077 /* FIXME: Need to properly allow for section alignment.
19078 16 is just the alignment used on x86_64. */
19079 if (global_end > 0
19080 && start > BFD_ALIGN (global_end, 16)
19081 /* Build notes are not guaranteed to be organised in order of
19082 increasing address, but we should find the all of the notes
19083 for one section in the same place. */
19084 && same_section (filedata, start, global_end))
6f156d7a
NC
19085 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
19086 global_end + 1, start - 1);
19087
19088 printf (_(" Applies to region from %#lx"), start);
19089 global_offset = start;
19090
19091 if (end)
19092 {
19093 printf (_(" to %#lx"), end);
19094 global_end = end;
19095 }
c799a79d
NC
19096 }
19097 else
19098 {
6f156d7a
NC
19099 printf (_(" Applies to region from %#lx"), start);
19100 func_offset = start;
19101
19102 if (end)
19103 {
19104 printf (_(" to %#lx"), end);
19105 func_end = end;
19106 }
c799a79d
NC
19107 }
19108
6f156d7a
NC
19109 if (sym && name)
19110 printf (_(" (%s)"), name);
19111
19112 printf ("\n");
19113 return TRUE;
9ef920e9
NC
19114}
19115
19116static bfd_boolean
19117print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
19118{
1d15e434
NC
19119 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
19120 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
19121 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
19122 char name_type;
19123 char name_attribute;
1d15e434 19124 const char * expected_types;
9ef920e9
NC
19125 const char * name = pnote->namedata;
19126 const char * text;
88305e1b 19127 signed int left;
9ef920e9
NC
19128
19129 if (name == NULL || pnote->namesz < 2)
19130 {
19131 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 19132 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
19133 return FALSE;
19134 }
19135
6f156d7a
NC
19136 if (do_wide)
19137 left = 28;
19138 else
19139 left = 20;
88305e1b
NC
19140
19141 /* Version 2 of the spec adds a "GA" prefix to the name field. */
19142 if (name[0] == 'G' && name[1] == 'A')
19143 {
6f156d7a
NC
19144 if (pnote->namesz < 4)
19145 {
19146 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
19147 print_symbol (-20, _(" <corrupt name>"));
19148 return FALSE;
19149 }
19150
88305e1b
NC
19151 printf ("GA");
19152 name += 2;
19153 left -= 2;
19154 }
19155
9ef920e9
NC
19156 switch ((name_type = * name))
19157 {
19158 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19159 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19160 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19161 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19162 printf ("%c", * name);
88305e1b 19163 left --;
9ef920e9
NC
19164 break;
19165 default:
19166 error (_("unrecognised attribute type in name field: %d\n"), name_type);
19167 print_symbol (-20, _("<unknown name type>"));
19168 return FALSE;
19169 }
19170
9ef920e9
NC
19171 ++ name;
19172 text = NULL;
19173
19174 switch ((name_attribute = * name))
19175 {
19176 case GNU_BUILD_ATTRIBUTE_VERSION:
19177 text = _("<version>");
1d15e434 19178 expected_types = string_expected;
9ef920e9
NC
19179 ++ name;
19180 break;
19181 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19182 text = _("<stack prot>");
75d7d298 19183 expected_types = "!+*";
9ef920e9
NC
19184 ++ name;
19185 break;
19186 case GNU_BUILD_ATTRIBUTE_RELRO:
19187 text = _("<relro>");
1d15e434 19188 expected_types = bool_expected;
9ef920e9
NC
19189 ++ name;
19190 break;
19191 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
19192 text = _("<stack size>");
1d15e434 19193 expected_types = number_expected;
9ef920e9
NC
19194 ++ name;
19195 break;
19196 case GNU_BUILD_ATTRIBUTE_TOOL:
19197 text = _("<tool>");
1d15e434 19198 expected_types = string_expected;
9ef920e9
NC
19199 ++ name;
19200 break;
19201 case GNU_BUILD_ATTRIBUTE_ABI:
19202 text = _("<ABI>");
19203 expected_types = "$*";
19204 ++ name;
19205 break;
19206 case GNU_BUILD_ATTRIBUTE_PIC:
19207 text = _("<PIC>");
1d15e434 19208 expected_types = number_expected;
9ef920e9
NC
19209 ++ name;
19210 break;
a8be5506
NC
19211 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
19212 text = _("<short enum>");
1d15e434 19213 expected_types = bool_expected;
a8be5506
NC
19214 ++ name;
19215 break;
9ef920e9
NC
19216 default:
19217 if (ISPRINT (* name))
19218 {
19219 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
19220
19221 if (len > left && ! do_wide)
19222 len = left;
75d7d298 19223 printf ("%.*s:", len, name);
9ef920e9 19224 left -= len;
0dd6ae21 19225 name += len;
9ef920e9
NC
19226 }
19227 else
19228 {
3e6b6445 19229 static char tmpbuf [128];
88305e1b 19230
3e6b6445
NC
19231 error (_("unrecognised byte in name field: %d\n"), * name);
19232 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
19233 text = tmpbuf;
19234 name ++;
9ef920e9
NC
19235 }
19236 expected_types = "*$!+";
19237 break;
19238 }
19239
19240 if (text)
88305e1b 19241 left -= printf ("%s", text);
9ef920e9
NC
19242
19243 if (strchr (expected_types, name_type) == NULL)
75d7d298 19244 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
19245
19246 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
19247 {
19248 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
19249 (unsigned long) pnote->namesz,
19250 (long) (name - pnote->namedata));
19251 return FALSE;
19252 }
19253
19254 if (left < 1 && ! do_wide)
19255 return TRUE;
19256
19257 switch (name_type)
19258 {
19259 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19260 {
b06b2c92 19261 unsigned int bytes;
ddef72cd
NC
19262 unsigned long long val = 0;
19263 unsigned int shift = 0;
19264 char * decoded = NULL;
19265
b06b2c92
NC
19266 bytes = pnote->namesz - (name - pnote->namedata);
19267 if (bytes > 0)
19268 /* The -1 is because the name field is always 0 terminated, and we
19269 want to be able to ensure that the shift in the while loop below
19270 will not overflow. */
19271 -- bytes;
19272
ddef72cd
NC
19273 if (bytes > sizeof (val))
19274 {
3e6b6445
NC
19275 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
19276 bytes);
19277 bytes = sizeof (val);
ddef72cd 19278 }
3e6b6445
NC
19279 /* We do not bother to warn if bytes == 0 as this can
19280 happen with some early versions of the gcc plugin. */
9ef920e9
NC
19281
19282 while (bytes --)
19283 {
79a964dc
NC
19284 unsigned long byte = (* name ++) & 0xff;
19285
19286 val |= byte << shift;
9ef920e9
NC
19287 shift += 8;
19288 }
19289
75d7d298 19290 switch (name_attribute)
9ef920e9 19291 {
75d7d298 19292 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
19293 switch (val)
19294 {
75d7d298
NC
19295 case 0: decoded = "static"; break;
19296 case 1: decoded = "pic"; break;
19297 case 2: decoded = "PIC"; break;
19298 case 3: decoded = "pie"; break;
19299 case 4: decoded = "PIE"; break;
19300 default: break;
9ef920e9 19301 }
75d7d298
NC
19302 break;
19303 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19304 switch (val)
9ef920e9 19305 {
75d7d298
NC
19306 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
19307 case 0: decoded = "off"; break;
19308 case 1: decoded = "on"; break;
19309 case 2: decoded = "all"; break;
19310 case 3: decoded = "strong"; break;
19311 case 4: decoded = "explicit"; break;
19312 default: break;
9ef920e9 19313 }
75d7d298
NC
19314 break;
19315 default:
19316 break;
9ef920e9
NC
19317 }
19318
75d7d298 19319 if (decoded != NULL)
3e6b6445
NC
19320 {
19321 print_symbol (-left, decoded);
19322 left = 0;
19323 }
19324 else if (val == 0)
19325 {
19326 printf ("0x0");
19327 left -= 3;
19328 }
9ef920e9 19329 else
75d7d298
NC
19330 {
19331 if (do_wide)
ddef72cd 19332 left -= printf ("0x%llx", val);
75d7d298 19333 else
ddef72cd 19334 left -= printf ("0x%-.*llx", left, val);
75d7d298 19335 }
9ef920e9
NC
19336 }
19337 break;
19338 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19339 left -= print_symbol (- left, name);
19340 break;
19341 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19342 left -= print_symbol (- left, "true");
19343 break;
19344 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19345 left -= print_symbol (- left, "false");
19346 break;
19347 }
19348
19349 if (do_wide && left > 0)
19350 printf ("%-*s", left, " ");
9abca702 19351
9ef920e9
NC
19352 return TRUE;
19353}
19354
6d118b09
NC
19355/* Note that by the ELF standard, the name field is already null byte
19356 terminated, and namesz includes the terminating null byte.
19357 I.E. the value of namesz for the name "FSF" is 4.
19358
e3c8793a 19359 If the value of namesz is zero, there is no name present. */
9ef920e9 19360
32ec8896 19361static bfd_boolean
9ef920e9 19362process_note (Elf_Internal_Note * pnote,
dda8d76d 19363 Filedata * filedata)
779fe533 19364{
2cf0635d
NC
19365 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
19366 const char * nt;
9437c45b
JT
19367
19368 if (pnote->namesz == 0)
1ec5cd37
NC
19369 /* If there is no note name, then use the default set of
19370 note type strings. */
dda8d76d 19371 nt = get_note_type (filedata, pnote->type);
1ec5cd37 19372
1118d252
RM
19373 else if (const_strneq (pnote->namedata, "GNU"))
19374 /* GNU-specific object file notes. */
19375 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
19376
19377 else if (const_strneq (pnote->namedata, "FreeBSD"))
19378 /* FreeBSD-specific core file notes. */
dda8d76d 19379 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 19380
0112cd26 19381 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 19382 /* NetBSD-specific core file notes. */
dda8d76d 19383 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 19384
c6056a74
SF
19385 else if (const_strneq (pnote->namedata, "NetBSD"))
19386 /* NetBSD-specific core file notes. */
19387 return process_netbsd_elf_note (pnote);
19388
9abca702
CZ
19389 else if (const_strneq (pnote->namedata, "PaX"))
19390 /* NetBSD-specific core file notes. */
19391 return process_netbsd_elf_note (pnote);
19392
b15fa79e
AM
19393 else if (strneq (pnote->namedata, "SPU/", 4))
19394 {
19395 /* SPU-specific core file notes. */
19396 nt = pnote->namedata + 4;
19397 name = "SPU";
19398 }
19399
00e98fc7
TG
19400 else if (const_strneq (pnote->namedata, "IPF/VMS"))
19401 /* VMS/ia64-specific file notes. */
19402 nt = get_ia64_vms_note_type (pnote->type);
19403
70616151
TT
19404 else if (const_strneq (pnote->namedata, "stapsdt"))
19405 nt = get_stapsdt_note_type (pnote->type);
19406
9437c45b 19407 else
1ec5cd37
NC
19408 /* Don't recognize this note name; just use the default set of
19409 note type strings. */
dda8d76d 19410 nt = get_note_type (filedata, pnote->type);
9437c45b 19411
1449284b 19412 printf (" ");
9ef920e9 19413
483767a3
AM
19414 if (((const_strneq (pnote->namedata, "GA")
19415 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19416 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19417 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19418 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
19419 print_gnu_build_attribute_name (pnote);
19420 else
19421 print_symbol (-20, name);
19422
19423 if (do_wide)
19424 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
19425 else
19426 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
19427
19428 if (const_strneq (pnote->namedata, "IPF/VMS"))
19429 return print_ia64_vms_note (pnote);
664f90a3 19430 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 19431 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
19432 else if (const_strneq (pnote->namedata, "stapsdt"))
19433 return print_stapsdt_note (pnote);
9ece1fa9
TT
19434 else if (const_strneq (pnote->namedata, "CORE"))
19435 return print_core_note (pnote);
483767a3
AM
19436 else if (((const_strneq (pnote->namedata, "GA")
19437 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19438 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19439 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19440 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 19441 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 19442
9ef920e9 19443 if (pnote->descsz)
1449284b
NC
19444 {
19445 unsigned long i;
19446
19447 printf (_(" description data: "));
19448 for (i = 0; i < pnote->descsz; i++)
178d8719 19449 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
19450 if (!do_wide)
19451 printf ("\n");
1449284b
NC
19452 }
19453
9ef920e9
NC
19454 if (do_wide)
19455 printf ("\n");
19456
32ec8896 19457 return TRUE;
1449284b 19458}
6d118b09 19459
32ec8896 19460static bfd_boolean
dda8d76d
NC
19461process_notes_at (Filedata * filedata,
19462 Elf_Internal_Shdr * section,
19463 bfd_vma offset,
82ed9683
L
19464 bfd_vma length,
19465 bfd_vma align)
779fe533 19466{
2cf0635d
NC
19467 Elf_External_Note * pnotes;
19468 Elf_External_Note * external;
4dff97b2
NC
19469 char * end;
19470 bfd_boolean res = TRUE;
103f02d3 19471
779fe533 19472 if (length <= 0)
32ec8896 19473 return FALSE;
103f02d3 19474
1449284b
NC
19475 if (section)
19476 {
dda8d76d 19477 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 19478 if (pnotes)
32ec8896 19479 {
dda8d76d 19480 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
19481 {
19482 free (pnotes);
19483 return FALSE;
19484 }
32ec8896 19485 }
1449284b
NC
19486 }
19487 else
82ed9683 19488 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 19489 _("notes"));
4dff97b2 19490
dd24e3da 19491 if (pnotes == NULL)
32ec8896 19492 return FALSE;
779fe533 19493
103f02d3 19494 external = pnotes;
103f02d3 19495
1449284b 19496 if (section)
dda8d76d 19497 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
19498 else
19499 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
19500 (unsigned long) offset, (unsigned long) length);
19501
82ed9683
L
19502 /* NB: Some note sections may have alignment value of 0 or 1. gABI
19503 specifies that notes should be aligned to 4 bytes in 32-bit
19504 objects and to 8 bytes in 64-bit objects. As a Linux extension,
19505 we also support 4 byte alignment in 64-bit objects. If section
19506 alignment is less than 4, we treate alignment as 4 bytes. */
19507 if (align < 4)
19508 align = 4;
19509 else if (align != 4 && align != 8)
19510 {
19511 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
19512 (long) align);
a788aedd 19513 free (pnotes);
82ed9683
L
19514 return FALSE;
19515 }
19516
dbe15e4e 19517 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 19518
c8071705
NC
19519 end = (char *) pnotes + length;
19520 while ((char *) external < end)
779fe533 19521 {
b34976b6 19522 Elf_Internal_Note inote;
15b42fb0 19523 size_t min_notesz;
4dff97b2 19524 char * next;
2cf0635d 19525 char * temp = NULL;
c8071705 19526 size_t data_remaining = end - (char *) external;
6d118b09 19527
dda8d76d 19528 if (!is_ia64_vms (filedata))
15b42fb0 19529 {
9dd3a467
NC
19530 /* PR binutils/15191
19531 Make sure that there is enough data to read. */
15b42fb0
AM
19532 min_notesz = offsetof (Elf_External_Note, name);
19533 if (data_remaining < min_notesz)
9dd3a467 19534 {
d3a49aa8
AM
19535 warn (ngettext ("Corrupt note: only %ld byte remains, "
19536 "not enough for a full note\n",
19537 "Corrupt note: only %ld bytes remain, "
19538 "not enough for a full note\n",
19539 data_remaining),
19540 (long) data_remaining);
9dd3a467
NC
19541 break;
19542 }
5396a86e
AM
19543 data_remaining -= min_notesz;
19544
15b42fb0
AM
19545 inote.type = BYTE_GET (external->type);
19546 inote.namesz = BYTE_GET (external->namesz);
19547 inote.namedata = external->name;
19548 inote.descsz = BYTE_GET (external->descsz);
276da9b3 19549 inote.descdata = ((char *) external
4dff97b2 19550 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 19551 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 19552 next = ((char *) external
4dff97b2 19553 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 19554 }
00e98fc7 19555 else
15b42fb0
AM
19556 {
19557 Elf64_External_VMS_Note *vms_external;
00e98fc7 19558
9dd3a467
NC
19559 /* PR binutils/15191
19560 Make sure that there is enough data to read. */
15b42fb0
AM
19561 min_notesz = offsetof (Elf64_External_VMS_Note, name);
19562 if (data_remaining < min_notesz)
9dd3a467 19563 {
d3a49aa8
AM
19564 warn (ngettext ("Corrupt note: only %ld byte remains, "
19565 "not enough for a full note\n",
19566 "Corrupt note: only %ld bytes remain, "
19567 "not enough for a full note\n",
19568 data_remaining),
19569 (long) data_remaining);
9dd3a467
NC
19570 break;
19571 }
5396a86e 19572 data_remaining -= min_notesz;
3e55a963 19573
15b42fb0
AM
19574 vms_external = (Elf64_External_VMS_Note *) external;
19575 inote.type = BYTE_GET (vms_external->type);
19576 inote.namesz = BYTE_GET (vms_external->namesz);
19577 inote.namedata = vms_external->name;
19578 inote.descsz = BYTE_GET (vms_external->descsz);
19579 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
19580 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19581 next = inote.descdata + align_power (inote.descsz, 3);
19582 }
19583
5396a86e
AM
19584 /* PR 17531: file: 3443835e. */
19585 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
19586 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
19587 || (size_t) (inote.descdata - inote.namedata) > data_remaining
19588 || (size_t) (next - inote.descdata) < inote.descsz
19589 || ((size_t) (next - inote.descdata)
19590 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 19591 {
15b42fb0 19592 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 19593 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
19594 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
19595 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
19596 break;
19597 }
19598
15b42fb0 19599 external = (Elf_External_Note *) next;
dd24e3da 19600
6d118b09
NC
19601 /* Verify that name is null terminated. It appears that at least
19602 one version of Linux (RedHat 6.0) generates corefiles that don't
19603 comply with the ELF spec by failing to include the null byte in
19604 namesz. */
18344509 19605 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 19606 {
5396a86e 19607 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 19608 {
5396a86e
AM
19609 temp = (char *) malloc (inote.namesz + 1);
19610 if (temp == NULL)
19611 {
19612 error (_("Out of memory allocating space for inote name\n"));
19613 res = FALSE;
19614 break;
19615 }
76da6bbe 19616
5396a86e
AM
19617 memcpy (temp, inote.namedata, inote.namesz);
19618 inote.namedata = temp;
19619 }
19620 inote.namedata[inote.namesz] = 0;
6d118b09
NC
19621 }
19622
dda8d76d 19623 if (! process_note (& inote, filedata))
6b4bf3bc 19624 res = FALSE;
103f02d3 19625
6d118b09
NC
19626 if (temp != NULL)
19627 {
19628 free (temp);
19629 temp = NULL;
19630 }
779fe533
NC
19631 }
19632
19633 free (pnotes);
103f02d3 19634
779fe533
NC
19635 return res;
19636}
19637
32ec8896 19638static bfd_boolean
dda8d76d 19639process_corefile_note_segments (Filedata * filedata)
779fe533 19640{
2cf0635d 19641 Elf_Internal_Phdr * segment;
b34976b6 19642 unsigned int i;
32ec8896 19643 bfd_boolean res = TRUE;
103f02d3 19644
dda8d76d 19645 if (! get_program_headers (filedata))
6b4bf3bc 19646 return TRUE;
103f02d3 19647
dda8d76d
NC
19648 for (i = 0, segment = filedata->program_headers;
19649 i < filedata->file_header.e_phnum;
b34976b6 19650 i++, segment++)
779fe533
NC
19651 {
19652 if (segment->p_type == PT_NOTE)
dda8d76d 19653 if (! process_notes_at (filedata, NULL,
32ec8896 19654 (bfd_vma) segment->p_offset,
82ed9683
L
19655 (bfd_vma) segment->p_filesz,
19656 (bfd_vma) segment->p_align))
32ec8896 19657 res = FALSE;
779fe533 19658 }
103f02d3 19659
779fe533
NC
19660 return res;
19661}
19662
32ec8896 19663static bfd_boolean
dda8d76d 19664process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
19665{
19666 Elf_External_Note * pnotes;
19667 Elf_External_Note * external;
c8071705 19668 char * end;
32ec8896 19669 bfd_boolean res = TRUE;
685080f2
NC
19670
19671 if (length <= 0)
32ec8896 19672 return FALSE;
685080f2 19673
dda8d76d 19674 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
19675 _("v850 notes"));
19676 if (pnotes == NULL)
32ec8896 19677 return FALSE;
685080f2
NC
19678
19679 external = pnotes;
c8071705 19680 end = (char*) pnotes + length;
685080f2
NC
19681
19682 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
19683 (unsigned long) offset, (unsigned long) length);
19684
c8071705 19685 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
19686 {
19687 Elf_External_Note * next;
19688 Elf_Internal_Note inote;
19689
19690 inote.type = BYTE_GET (external->type);
19691 inote.namesz = BYTE_GET (external->namesz);
19692 inote.namedata = external->name;
19693 inote.descsz = BYTE_GET (external->descsz);
19694 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
19695 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19696
c8071705
NC
19697 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
19698 {
19699 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
19700 inote.descdata = inote.namedata;
19701 inote.namesz = 0;
19702 }
19703
685080f2
NC
19704 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
19705
c8071705 19706 if ( ((char *) next > end)
685080f2
NC
19707 || ((char *) next < (char *) pnotes))
19708 {
19709 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
19710 (unsigned long) ((char *) external - (char *) pnotes));
19711 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19712 inote.type, inote.namesz, inote.descsz);
19713 break;
19714 }
19715
19716 external = next;
19717
19718 /* Prevent out-of-bounds indexing. */
c8071705 19719 if ( inote.namedata + inote.namesz > end
685080f2
NC
19720 || inote.namedata + inote.namesz < inote.namedata)
19721 {
19722 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
19723 (unsigned long) ((char *) external - (char *) pnotes));
19724 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19725 inote.type, inote.namesz, inote.descsz);
19726 break;
19727 }
19728
19729 printf (" %s: ", get_v850_elf_note_type (inote.type));
19730
19731 if (! print_v850_note (& inote))
19732 {
32ec8896 19733 res = FALSE;
685080f2
NC
19734 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
19735 inote.namesz, inote.descsz);
19736 }
19737 }
19738
19739 free (pnotes);
19740
19741 return res;
19742}
19743
32ec8896 19744static bfd_boolean
dda8d76d 19745process_note_sections (Filedata * filedata)
1ec5cd37 19746{
2cf0635d 19747 Elf_Internal_Shdr * section;
1ec5cd37 19748 unsigned long i;
32ec8896
NC
19749 unsigned int n = 0;
19750 bfd_boolean res = TRUE;
1ec5cd37 19751
dda8d76d
NC
19752 for (i = 0, section = filedata->section_headers;
19753 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 19754 i++, section++)
685080f2
NC
19755 {
19756 if (section->sh_type == SHT_NOTE)
19757 {
dda8d76d 19758 if (! process_notes_at (filedata, section,
32ec8896 19759 (bfd_vma) section->sh_offset,
82ed9683
L
19760 (bfd_vma) section->sh_size,
19761 (bfd_vma) section->sh_addralign))
32ec8896 19762 res = FALSE;
685080f2
NC
19763 n++;
19764 }
19765
dda8d76d
NC
19766 if (( filedata->file_header.e_machine == EM_V800
19767 || filedata->file_header.e_machine == EM_V850
19768 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
19769 && section->sh_type == SHT_RENESAS_INFO)
19770 {
dda8d76d 19771 if (! process_v850_notes (filedata,
32ec8896
NC
19772 (bfd_vma) section->sh_offset,
19773 (bfd_vma) section->sh_size))
19774 res = FALSE;
685080f2
NC
19775 n++;
19776 }
19777 }
df565f32
NC
19778
19779 if (n == 0)
19780 /* Try processing NOTE segments instead. */
dda8d76d 19781 return process_corefile_note_segments (filedata);
1ec5cd37
NC
19782
19783 return res;
19784}
19785
32ec8896 19786static bfd_boolean
dda8d76d 19787process_notes (Filedata * filedata)
779fe533
NC
19788{
19789 /* If we have not been asked to display the notes then do nothing. */
19790 if (! do_notes)
32ec8896 19791 return TRUE;
103f02d3 19792
dda8d76d
NC
19793 if (filedata->file_header.e_type != ET_CORE)
19794 return process_note_sections (filedata);
103f02d3 19795
779fe533 19796 /* No program headers means no NOTE segment. */
dda8d76d
NC
19797 if (filedata->file_header.e_phnum > 0)
19798 return process_corefile_note_segments (filedata);
779fe533 19799
1ec5cd37 19800 printf (_("No note segments present in the core file.\n"));
32ec8896 19801 return TRUE;
779fe533
NC
19802}
19803
60abdbed
NC
19804static unsigned char *
19805display_public_gnu_attributes (unsigned char * start,
19806 const unsigned char * const end)
19807{
19808 printf (_(" Unknown GNU attribute: %s\n"), start);
19809
19810 start += strnlen ((char *) start, end - start);
19811 display_raw_attribute (start, end);
19812
19813 return (unsigned char *) end;
19814}
19815
19816static unsigned char *
19817display_generic_attribute (unsigned char * start,
19818 unsigned int tag,
19819 const unsigned char * const end)
19820{
19821 if (tag == 0)
19822 return (unsigned char *) end;
19823
19824 return display_tag_value (tag, start, end);
19825}
19826
32ec8896 19827static bfd_boolean
dda8d76d 19828process_arch_specific (Filedata * filedata)
252b5132 19829{
a952a375 19830 if (! do_arch)
32ec8896 19831 return TRUE;
a952a375 19832
dda8d76d 19833 switch (filedata->file_header.e_machine)
252b5132 19834 {
53a346d8
CZ
19835 case EM_ARC:
19836 case EM_ARC_COMPACT:
19837 case EM_ARC_COMPACT2:
dda8d76d 19838 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
19839 display_arc_attribute,
19840 display_generic_attribute);
11c1ff18 19841 case EM_ARM:
dda8d76d 19842 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
19843 display_arm_attribute,
19844 display_generic_attribute);
19845
252b5132 19846 case EM_MIPS:
4fe85591 19847 case EM_MIPS_RS3_LE:
dda8d76d 19848 return process_mips_specific (filedata);
60abdbed
NC
19849
19850 case EM_MSP430:
dda8d76d
NC
19851 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
19852 display_msp430x_attribute,
c0ea7c52 19853 display_msp430_gnu_attribute);
60abdbed 19854
2dc8dd17
JW
19855 case EM_RISCV:
19856 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
19857 display_riscv_attribute,
19858 display_generic_attribute);
19859
35c08157 19860 case EM_NDS32:
dda8d76d 19861 return process_nds32_specific (filedata);
60abdbed 19862
34c8bcba 19863 case EM_PPC:
b82317dd 19864 case EM_PPC64:
dda8d76d 19865 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19866 display_power_gnu_attribute);
19867
643f7afb
AK
19868 case EM_S390:
19869 case EM_S390_OLD:
dda8d76d 19870 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19871 display_s390_gnu_attribute);
19872
9e8c70f9
DM
19873 case EM_SPARC:
19874 case EM_SPARC32PLUS:
19875 case EM_SPARCV9:
dda8d76d 19876 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19877 display_sparc_gnu_attribute);
19878
59e6276b 19879 case EM_TI_C6000:
dda8d76d 19880 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
19881 display_tic6x_attribute,
19882 display_generic_attribute);
19883
252b5132 19884 default:
dda8d76d 19885 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
19886 display_public_gnu_attributes,
19887 display_generic_attribute);
252b5132 19888 }
252b5132
RH
19889}
19890
32ec8896 19891static bfd_boolean
dda8d76d 19892get_file_header (Filedata * filedata)
252b5132 19893{
9ea033b2 19894 /* Read in the identity array. */
dda8d76d 19895 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 19896 return FALSE;
252b5132 19897
9ea033b2 19898 /* Determine how to read the rest of the header. */
dda8d76d 19899 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 19900 {
1a0670f3
AM
19901 default:
19902 case ELFDATANONE:
adab8cdc
AO
19903 case ELFDATA2LSB:
19904 byte_get = byte_get_little_endian;
19905 byte_put = byte_put_little_endian;
19906 break;
19907 case ELFDATA2MSB:
19908 byte_get = byte_get_big_endian;
19909 byte_put = byte_put_big_endian;
19910 break;
9ea033b2
NC
19911 }
19912
19913 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 19914 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
19915
19916 /* Read in the rest of the header. */
19917 if (is_32bit_elf)
19918 {
19919 Elf32_External_Ehdr ehdr32;
252b5132 19920
dda8d76d 19921 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 19922 return FALSE;
103f02d3 19923
dda8d76d
NC
19924 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
19925 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
19926 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
19927 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
19928 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
19929 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
19930 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
19931 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
19932 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
19933 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
19934 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
19935 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
19936 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 19937 }
252b5132 19938 else
9ea033b2
NC
19939 {
19940 Elf64_External_Ehdr ehdr64;
a952a375
NC
19941
19942 /* If we have been compiled with sizeof (bfd_vma) == 4, then
19943 we will not be able to cope with the 64bit data found in
19944 64 ELF files. Detect this now and abort before we start
50c2245b 19945 overwriting things. */
a952a375
NC
19946 if (sizeof (bfd_vma) < 8)
19947 {
e3c8793a
NC
19948 error (_("This instance of readelf has been built without support for a\n\
1994964 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 19950 return FALSE;
a952a375 19951 }
103f02d3 19952
dda8d76d 19953 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 19954 return FALSE;
103f02d3 19955
dda8d76d
NC
19956 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
19957 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
19958 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
19959 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
19960 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
19961 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
19962 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
19963 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
19964 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
19965 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
19966 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
19967 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
19968 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 19969 }
252b5132 19970
dda8d76d 19971 if (filedata->file_header.e_shoff)
7ece0d85
JJ
19972 {
19973 /* There may be some extensions in the first section header. Don't
19974 bomb if we can't read it. */
19975 if (is_32bit_elf)
dda8d76d 19976 get_32bit_section_headers (filedata, TRUE);
7ece0d85 19977 else
dda8d76d 19978 get_64bit_section_headers (filedata, TRUE);
7ece0d85 19979 }
560f3c1c 19980
32ec8896 19981 return TRUE;
252b5132
RH
19982}
19983
dda8d76d
NC
19984static void
19985close_file (Filedata * filedata)
19986{
19987 if (filedata)
19988 {
19989 if (filedata->handle)
19990 fclose (filedata->handle);
19991 free (filedata);
19992 }
19993}
19994
19995void
19996close_debug_file (void * data)
19997{
19998 close_file ((Filedata *) data);
19999}
20000
20001static Filedata *
20002open_file (const char * pathname)
20003{
20004 struct stat statbuf;
20005 Filedata * filedata = NULL;
20006
20007 if (stat (pathname, & statbuf) < 0
20008 || ! S_ISREG (statbuf.st_mode))
20009 goto fail;
20010
20011 filedata = calloc (1, sizeof * filedata);
20012 if (filedata == NULL)
20013 goto fail;
20014
20015 filedata->handle = fopen (pathname, "rb");
20016 if (filedata->handle == NULL)
20017 goto fail;
20018
20019 filedata->file_size = (bfd_size_type) statbuf.st_size;
20020 filedata->file_name = pathname;
20021
20022 if (! get_file_header (filedata))
20023 goto fail;
20024
20025 if (filedata->file_header.e_shoff)
20026 {
20027 bfd_boolean res;
20028
20029 /* Read the section headers again, this time for real. */
20030 if (is_32bit_elf)
20031 res = get_32bit_section_headers (filedata, FALSE);
20032 else
20033 res = get_64bit_section_headers (filedata, FALSE);
20034
20035 if (!res)
20036 goto fail;
20037 }
20038
20039 return filedata;
20040
20041 fail:
20042 if (filedata)
20043 {
20044 if (filedata->handle)
20045 fclose (filedata->handle);
20046 free (filedata);
20047 }
20048 return NULL;
20049}
20050
20051void *
20052open_debug_file (const char * pathname)
20053{
20054 return open_file (pathname);
20055}
20056
fb52b2f4
NC
20057/* Process one ELF object file according to the command line options.
20058 This file may actually be stored in an archive. The file is
32ec8896
NC
20059 positioned at the start of the ELF object. Returns TRUE if no
20060 problems were encountered, FALSE otherwise. */
fb52b2f4 20061
32ec8896 20062static bfd_boolean
dda8d76d 20063process_object (Filedata * filedata)
252b5132 20064{
24841daa 20065 bfd_boolean have_separate_files;
252b5132 20066 unsigned int i;
32ec8896 20067 bfd_boolean res = TRUE;
252b5132 20068
dda8d76d 20069 if (! get_file_header (filedata))
252b5132 20070 {
dda8d76d 20071 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 20072 return FALSE;
252b5132
RH
20073 }
20074
20075 /* Initialise per file variables. */
60bca95a 20076 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
20077 version_info[i] = 0;
20078
60bca95a 20079 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 20080 dynamic_info[i] = 0;
5115b233 20081 dynamic_info_DT_GNU_HASH = 0;
f16a9783 20082 dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
20083
20084 /* Process the file. */
20085 if (show_name)
dda8d76d 20086 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 20087
18bd398b
NC
20088 /* Initialise the dump_sects array from the cmdline_dump_sects array.
20089 Note we do this even if cmdline_dump_sects is empty because we
20090 must make sure that the dump_sets array is zeroed out before each
20091 object file is processed. */
6431e409
AM
20092 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
20093 memset (filedata->dump.dump_sects, 0,
20094 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20095
dda8d76d 20096 if (cmdline.num_dump_sects > 0)
18bd398b 20097 {
6431e409 20098 if (filedata->dump.num_dump_sects == 0)
18bd398b 20099 /* A sneaky way of allocating the dump_sects array. */
6431e409 20100 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 20101
6431e409
AM
20102 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
20103 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
20104 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20105 }
d70c5fc7 20106
dda8d76d 20107 if (! process_file_header (filedata))
32ec8896 20108 return FALSE;
252b5132 20109
dda8d76d 20110 if (! process_section_headers (filedata))
2f62977e 20111 {
32ec8896
NC
20112 /* Without loaded section headers we cannot process lots of things. */
20113 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 20114
2f62977e 20115 if (! do_using_dynamic)
32ec8896 20116 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 20117 }
252b5132 20118
dda8d76d 20119 if (! process_section_groups (filedata))
32ec8896
NC
20120 /* Without loaded section groups we cannot process unwind. */
20121 do_unwind = FALSE;
d1f5c6e3 20122
dda8d76d
NC
20123 if (process_program_headers (filedata))
20124 process_dynamic_section (filedata);
32ec8896
NC
20125 else
20126 res = FALSE;
252b5132 20127
dda8d76d 20128 if (! process_relocs (filedata))
32ec8896 20129 res = FALSE;
252b5132 20130
dda8d76d 20131 if (! process_unwind (filedata))
32ec8896 20132 res = FALSE;
4d6ed7c8 20133
dda8d76d 20134 if (! process_symbol_table (filedata))
32ec8896 20135 res = FALSE;
252b5132 20136
dda8d76d 20137 if (! process_syminfo (filedata))
32ec8896 20138 res = FALSE;
252b5132 20139
dda8d76d 20140 if (! process_version_sections (filedata))
32ec8896 20141 res = FALSE;
252b5132 20142
82ed9683 20143 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 20144 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 20145 else
24841daa 20146 have_separate_files = FALSE;
dda8d76d
NC
20147
20148 if (! process_section_contents (filedata))
32ec8896 20149 res = FALSE;
f5842774 20150
24841daa 20151 if (have_separate_files)
dda8d76d 20152 {
24841daa
NC
20153 separate_info * d;
20154
20155 for (d = first_separate_info; d != NULL; d = d->next)
20156 {
20157 if (! process_section_headers (d->handle))
20158 res = FALSE;
20159 else if (! process_section_contents (d->handle))
20160 res = FALSE;
20161 }
20162
20163 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
20164 }
20165
20166 if (! process_notes (filedata))
32ec8896 20167 res = FALSE;
103f02d3 20168
dda8d76d 20169 if (! process_gnu_liblist (filedata))
32ec8896 20170 res = FALSE;
047b2264 20171
dda8d76d 20172 if (! process_arch_specific (filedata))
32ec8896 20173 res = FALSE;
252b5132 20174
dda8d76d
NC
20175 free (filedata->program_headers);
20176 filedata->program_headers = NULL;
d93f0186 20177
dda8d76d
NC
20178 free (filedata->section_headers);
20179 filedata->section_headers = NULL;
252b5132 20180
dda8d76d
NC
20181 free (filedata->string_table);
20182 filedata->string_table = NULL;
20183 filedata->string_table_length = 0;
252b5132 20184
6431e409 20185 if (filedata->dump.dump_sects != NULL)
a788aedd 20186 {
6431e409
AM
20187 free (filedata->dump.dump_sects);
20188 filedata->dump.dump_sects = NULL;
20189 filedata->dump.num_dump_sects = 0;
a788aedd
AM
20190 }
20191
252b5132
RH
20192 if (dynamic_strings)
20193 {
20194 free (dynamic_strings);
20195 dynamic_strings = NULL;
d79b3d50 20196 dynamic_strings_length = 0;
252b5132
RH
20197 }
20198
20199 if (dynamic_symbols)
20200 {
20201 free (dynamic_symbols);
20202 dynamic_symbols = NULL;
19936277 20203 num_dynamic_syms = 0;
252b5132
RH
20204 }
20205
20206 if (dynamic_syminfo)
20207 {
20208 free (dynamic_syminfo);
20209 dynamic_syminfo = NULL;
20210 }
ff78d6d6 20211
293c573e
MR
20212 if (dynamic_section)
20213 {
20214 free (dynamic_section);
20215 dynamic_section = NULL;
20216 }
20217
8fb879cd
AM
20218 while (symtab_shndx_list != NULL)
20219 {
20220 elf_section_list *next = symtab_shndx_list->next;
20221 free (symtab_shndx_list);
20222 symtab_shndx_list = next;
20223 }
20224
e4b17d5c
L
20225 if (section_headers_groups)
20226 {
20227 free (section_headers_groups);
20228 section_headers_groups = NULL;
20229 }
20230
20231 if (section_groups)
20232 {
2cf0635d
NC
20233 struct group_list * g;
20234 struct group_list * next;
e4b17d5c
L
20235
20236 for (i = 0; i < group_count; i++)
20237 {
20238 for (g = section_groups [i].root; g != NULL; g = next)
20239 {
20240 next = g->next;
20241 free (g);
20242 }
20243 }
20244
20245 free (section_groups);
20246 section_groups = NULL;
20247 }
20248
19e6b90e 20249 free_debug_memory ();
18bd398b 20250
32ec8896 20251 return res;
252b5132
RH
20252}
20253
2cf0635d 20254/* Process an ELF archive.
32ec8896
NC
20255 On entry the file is positioned just after the ARMAG string.
20256 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 20257
32ec8896 20258static bfd_boolean
dda8d76d 20259process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
20260{
20261 struct archive_info arch;
20262 struct archive_info nested_arch;
20263 size_t got;
32ec8896 20264 bfd_boolean ret = TRUE;
2cf0635d 20265
32ec8896 20266 show_name = TRUE;
2cf0635d
NC
20267
20268 /* The ARCH structure is used to hold information about this archive. */
20269 arch.file_name = NULL;
20270 arch.file = NULL;
20271 arch.index_array = NULL;
20272 arch.sym_table = NULL;
20273 arch.longnames = NULL;
20274
20275 /* The NESTED_ARCH structure is used as a single-item cache of information
20276 about a nested archive (when members of a thin archive reside within
20277 another regular archive file). */
20278 nested_arch.file_name = NULL;
20279 nested_arch.file = NULL;
20280 nested_arch.index_array = NULL;
20281 nested_arch.sym_table = NULL;
20282 nested_arch.longnames = NULL;
20283
dda8d76d 20284 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
20285 filedata->file_size, is_thin_archive,
20286 do_archive_index) != 0)
2cf0635d 20287 {
32ec8896 20288 ret = FALSE;
2cf0635d 20289 goto out;
4145f1d5 20290 }
fb52b2f4 20291
4145f1d5
NC
20292 if (do_archive_index)
20293 {
2cf0635d 20294 if (arch.sym_table == NULL)
1cb7d8b1
AM
20295 error (_("%s: unable to dump the index as none was found\n"),
20296 filedata->file_name);
4145f1d5
NC
20297 else
20298 {
591f7597 20299 unsigned long i, l;
4145f1d5
NC
20300 unsigned long current_pos;
20301
1cb7d8b1
AM
20302 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
20303 "in the symbol table)\n"),
20304 filedata->file_name, (unsigned long) arch.index_num,
20305 arch.sym_size);
dda8d76d
NC
20306
20307 current_pos = ftell (filedata->handle);
4145f1d5 20308
2cf0635d 20309 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 20310 {
1cb7d8b1
AM
20311 if (i == 0
20312 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
20313 {
20314 char * member_name
20315 = get_archive_member_name_at (&arch, arch.index_array[i],
20316 &nested_arch);
2cf0635d 20317
1cb7d8b1
AM
20318 if (member_name != NULL)
20319 {
20320 char * qualified_name
20321 = make_qualified_name (&arch, &nested_arch,
20322 member_name);
2cf0635d 20323
1cb7d8b1
AM
20324 if (qualified_name != NULL)
20325 {
20326 printf (_("Contents of binary %s at offset "),
20327 qualified_name);
c2a7d3f5
NC
20328 (void) print_vma (arch.index_array[i], PREFIX_HEX);
20329 putchar ('\n');
1cb7d8b1
AM
20330 free (qualified_name);
20331 }
fd486f32 20332 free (member_name);
4145f1d5
NC
20333 }
20334 }
2cf0635d
NC
20335
20336 if (l >= arch.sym_size)
4145f1d5 20337 {
1cb7d8b1
AM
20338 error (_("%s: end of the symbol table reached "
20339 "before the end of the index\n"),
dda8d76d 20340 filedata->file_name);
32ec8896 20341 ret = FALSE;
cb8f3167 20342 break;
4145f1d5 20343 }
591f7597 20344 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
20345 printf ("\t%.*s\n",
20346 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 20347 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
20348 }
20349
67ce483b 20350 if (arch.uses_64bit_indices)
c2a7d3f5
NC
20351 l = (l + 7) & ~ 7;
20352 else
20353 l += l & 1;
20354
2cf0635d 20355 if (l < arch.sym_size)
32ec8896 20356 {
d3a49aa8
AM
20357 error (ngettext ("%s: %ld byte remains in the symbol table, "
20358 "but without corresponding entries in "
20359 "the index table\n",
20360 "%s: %ld bytes remain in the symbol table, "
20361 "but without corresponding entries in "
20362 "the index table\n",
20363 arch.sym_size - l),
dda8d76d 20364 filedata->file_name, arch.sym_size - l);
32ec8896
NC
20365 ret = FALSE;
20366 }
4145f1d5 20367
dda8d76d 20368 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 20369 {
1cb7d8b1
AM
20370 error (_("%s: failed to seek back to start of object files "
20371 "in the archive\n"),
dda8d76d 20372 filedata->file_name);
32ec8896 20373 ret = FALSE;
2cf0635d 20374 goto out;
4145f1d5 20375 }
fb52b2f4 20376 }
4145f1d5
NC
20377
20378 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
20379 && !do_segments && !do_header && !do_dump && !do_version
20380 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 20381 && !do_section_groups && !do_dyn_syms)
2cf0635d 20382 {
32ec8896 20383 ret = TRUE; /* Archive index only. */
2cf0635d
NC
20384 goto out;
20385 }
fb52b2f4
NC
20386 }
20387
fb52b2f4
NC
20388 while (1)
20389 {
2cf0635d
NC
20390 char * name;
20391 size_t namelen;
20392 char * qualified_name;
20393
20394 /* Read the next archive header. */
dda8d76d 20395 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
20396 {
20397 error (_("%s: failed to seek to next archive header\n"),
20398 arch.file_name);
20399 ret = FALSE;
20400 break;
20401 }
dda8d76d 20402 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 20403 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
20404 {
20405 if (got == 0)
2cf0635d 20406 break;
28e817cc
NC
20407 /* PR 24049 - we cannot use filedata->file_name as this will
20408 have already been freed. */
20409 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 20410
1cb7d8b1
AM
20411 ret = FALSE;
20412 break;
20413 }
2cf0635d 20414 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
20415 {
20416 error (_("%s: did not find a valid archive header\n"),
20417 arch.file_name);
20418 ret = FALSE;
20419 break;
20420 }
2cf0635d
NC
20421
20422 arch.next_arhdr_offset += sizeof arch.arhdr;
20423
20424 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
20425 if (archive_file_size & 01)
1cb7d8b1 20426 ++archive_file_size;
2cf0635d
NC
20427
20428 name = get_archive_member_name (&arch, &nested_arch);
20429 if (name == NULL)
fb52b2f4 20430 {
28e817cc 20431 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 20432 ret = FALSE;
d989285c 20433 break;
fb52b2f4 20434 }
2cf0635d 20435 namelen = strlen (name);
fb52b2f4 20436
2cf0635d
NC
20437 qualified_name = make_qualified_name (&arch, &nested_arch, name);
20438 if (qualified_name == NULL)
fb52b2f4 20439 {
28e817cc 20440 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 20441 free (name);
32ec8896 20442 ret = FALSE;
d989285c 20443 break;
fb52b2f4
NC
20444 }
20445
2cf0635d 20446 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
20447 {
20448 /* This is a proxy for an external member of a thin archive. */
20449 Filedata * member_filedata;
20450 char * member_file_name = adjust_relative_path
dda8d76d 20451 (filedata->file_name, name, namelen);
32ec8896 20452
fd486f32 20453 free (name);
1cb7d8b1
AM
20454 if (member_file_name == NULL)
20455 {
fd486f32 20456 free (qualified_name);
1cb7d8b1
AM
20457 ret = FALSE;
20458 break;
20459 }
2cf0635d 20460
1cb7d8b1
AM
20461 member_filedata = open_file (member_file_name);
20462 if (member_filedata == NULL)
20463 {
20464 error (_("Input file '%s' is not readable.\n"), member_file_name);
20465 free (member_file_name);
fd486f32 20466 free (qualified_name);
1cb7d8b1
AM
20467 ret = FALSE;
20468 break;
20469 }
2cf0635d 20470
1cb7d8b1 20471 archive_file_offset = arch.nested_member_origin;
dda8d76d 20472 member_filedata->file_name = qualified_name;
2cf0635d 20473
1cb7d8b1 20474 if (! process_object (member_filedata))
32ec8896 20475 ret = FALSE;
2cf0635d 20476
1cb7d8b1
AM
20477 close_file (member_filedata);
20478 free (member_file_name);
1cb7d8b1 20479 }
2cf0635d 20480 else if (is_thin_archive)
1cb7d8b1
AM
20481 {
20482 Filedata thin_filedata;
eb02c04d 20483
1cb7d8b1 20484 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 20485
a043396b
NC
20486 /* PR 15140: Allow for corrupt thin archives. */
20487 if (nested_arch.file == NULL)
20488 {
20489 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 20490 qualified_name, name);
fd486f32
AM
20491 free (qualified_name);
20492 free (name);
32ec8896 20493 ret = FALSE;
a043396b
NC
20494 break;
20495 }
fd486f32 20496 free (name);
a043396b 20497
1cb7d8b1
AM
20498 /* This is a proxy for a member of a nested archive. */
20499 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 20500
1cb7d8b1
AM
20501 /* The nested archive file will have been opened and setup by
20502 get_archive_member_name. */
20503 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
20504 {
20505 error (_("%s: failed to seek to archive member.\n"),
20506 nested_arch.file_name);
fd486f32 20507 free (qualified_name);
1cb7d8b1
AM
20508 ret = FALSE;
20509 break;
20510 }
2cf0635d 20511
dda8d76d
NC
20512 thin_filedata.handle = nested_arch.file;
20513 thin_filedata.file_name = qualified_name;
9abca702 20514
1cb7d8b1 20515 if (! process_object (& thin_filedata))
32ec8896 20516 ret = FALSE;
1cb7d8b1 20517 }
2cf0635d 20518 else
1cb7d8b1 20519 {
fd486f32 20520 free (name);
1cb7d8b1 20521 archive_file_offset = arch.next_arhdr_offset;
6a6196fc 20522 filedata->file_name = qualified_name;
1cb7d8b1 20523 if (! process_object (filedata))
32ec8896 20524 ret = FALSE;
4c836627
AM
20525 arch.next_arhdr_offset += archive_file_size;
20526 /* Stop looping with "negative" archive_file_size. */
20527 if (arch.next_arhdr_offset < archive_file_size)
80e2a3b6 20528 arch.next_arhdr_offset = -1ul;
1cb7d8b1 20529 }
fb52b2f4 20530
2cf0635d 20531 free (qualified_name);
fb52b2f4
NC
20532 }
20533
4145f1d5 20534 out:
2cf0635d
NC
20535 if (nested_arch.file != NULL)
20536 fclose (nested_arch.file);
20537 release_archive (&nested_arch);
20538 release_archive (&arch);
fb52b2f4 20539
d989285c 20540 return ret;
fb52b2f4
NC
20541}
20542
32ec8896 20543static bfd_boolean
2cf0635d 20544process_file (char * file_name)
fb52b2f4 20545{
dda8d76d 20546 Filedata * filedata = NULL;
fb52b2f4
NC
20547 struct stat statbuf;
20548 char armag[SARMAG];
32ec8896 20549 bfd_boolean ret = TRUE;
fb52b2f4
NC
20550
20551 if (stat (file_name, &statbuf) < 0)
20552 {
f24ddbdd
NC
20553 if (errno == ENOENT)
20554 error (_("'%s': No such file\n"), file_name);
20555 else
20556 error (_("Could not locate '%s'. System error message: %s\n"),
20557 file_name, strerror (errno));
32ec8896 20558 return FALSE;
f24ddbdd
NC
20559 }
20560
20561 if (! S_ISREG (statbuf.st_mode))
20562 {
20563 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 20564 return FALSE;
fb52b2f4
NC
20565 }
20566
dda8d76d
NC
20567 filedata = calloc (1, sizeof * filedata);
20568 if (filedata == NULL)
20569 {
20570 error (_("Out of memory allocating file data structure\n"));
20571 return FALSE;
20572 }
20573
20574 filedata->file_name = file_name;
20575 filedata->handle = fopen (file_name, "rb");
20576 if (filedata->handle == NULL)
fb52b2f4 20577 {
f24ddbdd 20578 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 20579 free (filedata);
32ec8896 20580 return FALSE;
fb52b2f4
NC
20581 }
20582
dda8d76d 20583 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 20584 {
4145f1d5 20585 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
20586 fclose (filedata->handle);
20587 free (filedata);
32ec8896 20588 return FALSE;
fb52b2f4
NC
20589 }
20590
dda8d76d 20591 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 20592
fb52b2f4 20593 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 20594 {
dda8d76d 20595 if (! process_archive (filedata, FALSE))
32ec8896
NC
20596 ret = FALSE;
20597 }
2cf0635d 20598 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 20599 {
dda8d76d 20600 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
20601 ret = FALSE;
20602 }
fb52b2f4
NC
20603 else
20604 {
4145f1d5
NC
20605 if (do_archive_index)
20606 error (_("File %s is not an archive so its index cannot be displayed.\n"),
20607 file_name);
20608
dda8d76d 20609 rewind (filedata->handle);
fb52b2f4 20610 archive_file_size = archive_file_offset = 0;
32ec8896 20611
dda8d76d 20612 if (! process_object (filedata))
32ec8896 20613 ret = FALSE;
fb52b2f4
NC
20614 }
20615
dda8d76d 20616 fclose (filedata->handle);
8fb879cd
AM
20617 free (filedata->section_headers);
20618 free (filedata->program_headers);
20619 free (filedata->string_table);
6431e409 20620 free (filedata->dump.dump_sects);
dda8d76d 20621 free (filedata);
32ec8896 20622
fd486f32 20623 free (ba_cache.strtab);
1bd6175a 20624 ba_cache.strtab = NULL;
fd486f32 20625 free (ba_cache.symtab);
1bd6175a 20626 ba_cache.symtab = NULL;
fd486f32
AM
20627 ba_cache.filedata = NULL;
20628
fb52b2f4
NC
20629 return ret;
20630}
20631
252b5132
RH
20632#ifdef SUPPORT_DISASSEMBLY
20633/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 20634 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 20635 symbols. */
252b5132
RH
20636
20637void
2cf0635d 20638print_address (unsigned int addr, FILE * outfile)
252b5132
RH
20639{
20640 fprintf (outfile,"0x%8.8x", addr);
20641}
20642
e3c8793a 20643/* Needed by the i386 disassembler. */
dda8d76d 20644
252b5132
RH
20645void
20646db_task_printsym (unsigned int addr)
20647{
20648 print_address (addr, stderr);
20649}
20650#endif
20651
20652int
2cf0635d 20653main (int argc, char ** argv)
252b5132 20654{
ff78d6d6
L
20655 int err;
20656
252b5132
RH
20657#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
20658 setlocale (LC_MESSAGES, "");
3882b010
L
20659#endif
20660#if defined (HAVE_SETLOCALE)
20661 setlocale (LC_CTYPE, "");
252b5132
RH
20662#endif
20663 bindtextdomain (PACKAGE, LOCALEDIR);
20664 textdomain (PACKAGE);
20665
869b9d07
MM
20666 expandargv (&argc, &argv);
20667
dda8d76d 20668 parse_args (& cmdline, argc, argv);
59f14fc0 20669
18bd398b 20670 if (optind < (argc - 1))
32ec8896 20671 show_name = TRUE;
5656ba2c
L
20672 else if (optind >= argc)
20673 {
20674 warn (_("Nothing to do.\n"));
20675 usage (stderr);
20676 }
18bd398b 20677
32ec8896 20678 err = FALSE;
252b5132 20679 while (optind < argc)
32ec8896
NC
20680 if (! process_file (argv[optind++]))
20681 err = TRUE;
252b5132 20682
dda8d76d
NC
20683 if (cmdline.dump_sects != NULL)
20684 free (cmdline.dump_sects);
252b5132 20685
7d9813f1
NA
20686 free (dump_ctf_symtab_name);
20687 free (dump_ctf_strtab_name);
20688 free (dump_ctf_parent_name);
20689
32ec8896 20690 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 20691}