]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
ld/emultempl/msp430.em: Remove unused variable
[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"
79bc120c 64#include "demangle.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
b8891f8d 103#include "elf/csky.h"
252b5132
RH
104#include "elf/d10v.h"
105#include "elf/d30v.h"
d172d4ba 106#include "elf/dlx.h"
aca4efc7 107#include "elf/bpf.h"
cfb8c092 108#include "elf/epiphany.h"
252b5132 109#include "elf/fr30.h"
5c70f934 110#include "elf/frv.h"
3f8107ab 111#include "elf/ft32.h"
3b16e843
NC
112#include "elf/h8.h"
113#include "elf/hppa.h"
114#include "elf/i386.h"
f954747f
AM
115#include "elf/i370.h"
116#include "elf/i860.h"
117#include "elf/i960.h"
3b16e843 118#include "elf/ia64.h"
1e4cf259 119#include "elf/ip2k.h"
84e94c90 120#include "elf/lm32.h"
1c0d3aa6 121#include "elf/iq2000.h"
49f58d10 122#include "elf/m32c.h"
3b16e843
NC
123#include "elf/m32r.h"
124#include "elf/m68k.h"
75751cd9 125#include "elf/m68hc11.h"
7b4ae824 126#include "elf/s12z.h"
252b5132 127#include "elf/mcore.h"
15ab5209 128#include "elf/mep.h"
a3c62988 129#include "elf/metag.h"
7ba29e2a 130#include "elf/microblaze.h"
3b16e843 131#include "elf/mips.h"
3c3bdf30 132#include "elf/mmix.h"
3b16e843
NC
133#include "elf/mn10200.h"
134#include "elf/mn10300.h"
5506d11a 135#include "elf/moxie.h"
4970f871 136#include "elf/mt.h"
2469cfa2 137#include "elf/msp430.h"
35c08157 138#include "elf/nds32.h"
fe944acf 139#include "elf/nfp.h"
13761a11 140#include "elf/nios2.h"
73589c9d 141#include "elf/or1k.h"
7d466069 142#include "elf/pj.h"
3b16e843 143#include "elf/ppc.h"
c833c019 144#include "elf/ppc64.h"
2b100bb5 145#include "elf/pru.h"
03336641 146#include "elf/riscv.h"
99c513f6 147#include "elf/rl78.h"
c7927a3c 148#include "elf/rx.h"
a85d7ed0 149#include "elf/s390.h"
1c0d3aa6 150#include "elf/score.h"
3b16e843
NC
151#include "elf/sh.h"
152#include "elf/sparc.h"
e9f53129 153#include "elf/spu.h"
40b36596 154#include "elf/tic6x.h"
aa137e4d
NC
155#include "elf/tilegx.h"
156#include "elf/tilepro.h"
3b16e843 157#include "elf/v850.h"
179d3252 158#include "elf/vax.h"
619ed720 159#include "elf/visium.h"
f96bd6c2 160#include "elf/wasm32.h"
3b16e843 161#include "elf/x86-64.h"
c29aca4a 162#include "elf/xc16x.h"
f6c1a2d5 163#include "elf/xgate.h"
93fbbb04 164#include "elf/xstormy16.h"
88da6820 165#include "elf/xtensa.h"
6655dba2 166#include "elf/z80.h"
252b5132 167
252b5132 168#include "getopt.h"
566b0d53 169#include "libiberty.h"
09c11c86 170#include "safe-ctype.h"
2cf0635d 171#include "filenames.h"
252b5132 172
15b42fb0
AM
173#ifndef offsetof
174#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
175#endif
176
6a40cf0c
NC
177typedef struct elf_section_list
178{
dda8d76d
NC
179 Elf_Internal_Shdr * hdr;
180 struct elf_section_list * next;
6a40cf0c
NC
181} elf_section_list;
182
dda8d76d
NC
183/* Flag bits indicating particular types of dump. */
184#define HEX_DUMP (1 << 0) /* The -x command line switch. */
185#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
186#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
187#define STRING_DUMP (1 << 3) /* The -p command line switch. */
188#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 189#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
190
191typedef unsigned char dump_type;
192
193/* A linked list of the section names for which dumps were requested. */
194struct dump_list_entry
195{
196 char * name;
197 dump_type type;
198 struct dump_list_entry * next;
199};
200
6431e409
AM
201/* A dynamic array of flags indicating for which sections a dump
202 has been requested via command line switches. */
1b513401
NC
203struct dump_data
204{
6431e409
AM
205 dump_type * dump_sects;
206 unsigned int num_dump_sects;
207};
208
209static struct dump_data cmdline;
210
211static struct dump_list_entry * dump_sects_byname;
212
2cf0635d 213char * program_name = "readelf";
dda8d76d 214
32ec8896
NC
215static bfd_boolean show_name = FALSE;
216static bfd_boolean do_dynamic = FALSE;
217static bfd_boolean do_syms = FALSE;
218static bfd_boolean do_dyn_syms = FALSE;
219static bfd_boolean do_reloc = FALSE;
220static bfd_boolean do_sections = FALSE;
221static bfd_boolean do_section_groups = FALSE;
222static bfd_boolean do_section_details = FALSE;
223static bfd_boolean do_segments = FALSE;
224static bfd_boolean do_unwind = FALSE;
225static bfd_boolean do_using_dynamic = FALSE;
226static bfd_boolean do_header = FALSE;
227static bfd_boolean do_dump = FALSE;
228static bfd_boolean do_version = FALSE;
229static bfd_boolean do_histogram = FALSE;
230static bfd_boolean do_debugging = FALSE;
7d9813f1 231static bfd_boolean do_ctf = FALSE;
32ec8896
NC
232static bfd_boolean do_arch = FALSE;
233static bfd_boolean do_notes = FALSE;
234static bfd_boolean do_archive_index = FALSE;
1b513401 235static bfd_boolean check_all = FALSE;
32ec8896
NC
236static bfd_boolean is_32bit_elf = FALSE;
237static bfd_boolean decompress_dumps = FALSE;
0942c7ab 238static bfd_boolean do_not_show_symbol_truncation = FALSE;
79bc120c
NC
239static bfd_boolean do_demangle = FALSE; /* Pretty print C++ symbol names. */
240static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
252b5132 241
7d9813f1
NA
242static char *dump_ctf_parent_name;
243static char *dump_ctf_symtab_name;
244static char *dump_ctf_strtab_name;
245
e4b17d5c
L
246struct group_list
247{
dda8d76d
NC
248 struct group_list * next;
249 unsigned int section_index;
e4b17d5c
L
250};
251
252struct group
253{
dda8d76d
NC
254 struct group_list * root;
255 unsigned int group_index;
e4b17d5c
L
256};
257
978c4450
AM
258typedef struct filedata
259{
260 const char * file_name;
261 FILE * handle;
262 bfd_size_type file_size;
263 Elf_Internal_Ehdr file_header;
264 Elf_Internal_Shdr * section_headers;
265 Elf_Internal_Phdr * program_headers;
266 char * string_table;
267 unsigned long string_table_length;
268 unsigned long archive_file_offset;
269 unsigned long archive_file_size;
270 unsigned long dynamic_addr;
271 bfd_size_type dynamic_size;
272 size_t dynamic_nent;
273 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 274 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
275 char * dynamic_strings;
276 unsigned long dynamic_strings_length;
8ac10c5b 277 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
278 unsigned long num_dynamic_syms;
279 Elf_Internal_Sym * dynamic_symbols;
280 bfd_vma version_info[16];
281 unsigned int dynamic_syminfo_nent;
282 Elf_Internal_Syminfo * dynamic_syminfo;
283 unsigned long dynamic_syminfo_offset;
284 bfd_size_type nbuckets;
285 bfd_size_type nchains;
286 bfd_vma * buckets;
287 bfd_vma * chains;
288 bfd_size_type ngnubuckets;
289 bfd_size_type ngnuchains;
290 bfd_vma * gnubuckets;
291 bfd_vma * gnuchains;
292 bfd_vma * mipsxlat;
293 bfd_vma gnusymidx;
294 char program_interpreter[PATH_MAX];
295 bfd_vma dynamic_info[DT_ENCODING];
296 bfd_vma dynamic_info_DT_GNU_HASH;
297 bfd_vma dynamic_info_DT_MIPS_XHASH;
298 elf_section_list * symtab_shndx_list;
299 size_t group_count;
300 struct group * section_groups;
301 struct group ** section_headers_groups;
302 /* A dynamic array of flags indicating for which sections a dump of
303 some kind has been requested. It is reset on a per-object file
304 basis and then initialised from the cmdline_dump_sects array,
305 the results of interpreting the -w switch, and the
306 dump_sects_byname list. */
307 struct dump_data dump;
308} Filedata;
aef1f6d0 309
c256ffe7 310/* How to print a vma value. */
843dd992
NC
311typedef enum print_mode
312{
313 HEX,
314 DEC,
315 DEC_5,
316 UNSIGNED,
317 PREFIX_HEX,
318 FULL_HEX,
319 LONG_HEX
320}
321print_mode;
322
bb4d2ac2
L
323/* Versioned symbol info. */
324enum versioned_symbol_info
325{
326 symbol_undefined,
327 symbol_hidden,
328 symbol_public
329};
330
32ec8896 331static const char * get_symbol_version_string
dda8d76d 332 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 333 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 334
9c19a809
NC
335#define UNKNOWN -1
336
2b692964
NC
337#define SECTION_NAME(X) \
338 ((X) == NULL ? _("<none>") \
dda8d76d
NC
339 : filedata->string_table == NULL ? _("<no-strings>") \
340 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
341 : filedata->string_table + (X)->sh_name))
252b5132 342
ee42cf8c 343#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 344
ba5cdace
NC
345#define GET_ELF_SYMBOLS(file, section, sym_count) \
346 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
347 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 348
10ca4b04
L
349#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
350 (strtab != NULL && offset < strtab_size)
978c4450
AM
351#define VALID_DYNAMIC_NAME(filedata, offset) \
352 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
353 filedata->dynamic_strings_length, offset)
d79b3d50
NC
354/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
355 already been called and verified that the string exists. */
978c4450
AM
356#define GET_DYNAMIC_NAME(filedata, offset) \
357 (filedata->dynamic_strings + offset)
18bd398b 358
61865e30
NC
359#define REMOVE_ARCH_BITS(ADDR) \
360 do \
361 { \
dda8d76d 362 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
363 (ADDR) &= ~1; \
364 } \
365 while (0)
f16a9783
MS
366
367/* Get the correct GNU hash section name. */
978c4450
AM
368#define GNU_HASH_SECTION_NAME(filedata) \
369 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 370\f
66cfc0fd
AM
371/* Print a BFD_VMA to an internal buffer, for use in error messages.
372 BFD_FMA_FMT can't be used in translated strings. */
373
374static const char *
375bfd_vmatoa (char *fmtch, bfd_vma value)
376{
377 /* bfd_vmatoa is used more then once in a printf call for output.
378 Cycle through an array of buffers. */
379 static int buf_pos = 0;
380 static struct bfd_vmatoa_buf
381 {
382 char place[64];
383 } buf[4];
384 char *ret;
385 char fmt[32];
386
387 ret = buf[buf_pos++].place;
388 buf_pos %= ARRAY_SIZE (buf);
389
390 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
391 snprintf (ret, sizeof (buf[0].place), fmt, value);
392 return ret;
393}
394
dda8d76d
NC
395/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
396 OFFSET + the offset of the current archive member, if we are examining an
397 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
398 allocate a buffer using malloc and fill that. In either case return the
399 pointer to the start of the retrieved data or NULL if something went wrong.
400 If something does go wrong and REASON is not NULL then emit an error
401 message using REASON as part of the context. */
59245841 402
c256ffe7 403static void *
dda8d76d
NC
404get_data (void * var,
405 Filedata * filedata,
406 unsigned long offset,
407 bfd_size_type size,
408 bfd_size_type nmemb,
409 const char * reason)
a6e9f9df 410{
2cf0635d 411 void * mvar;
57028622 412 bfd_size_type amt = size * nmemb;
a6e9f9df 413
c256ffe7 414 if (size == 0 || nmemb == 0)
a6e9f9df
AM
415 return NULL;
416
57028622
NC
417 /* If the size_t type is smaller than the bfd_size_type, eg because
418 you are building a 32-bit tool on a 64-bit host, then make sure
419 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
420 if ((size_t) size != size
421 || (size_t) nmemb != nmemb
422 || (size_t) amt != amt)
57028622
NC
423 {
424 if (reason)
66cfc0fd
AM
425 error (_("Size truncation prevents reading %s"
426 " elements of size %s for %s\n"),
427 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
428 return NULL;
429 }
430
431 /* Check for size overflow. */
7c1c1904 432 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
433 {
434 if (reason)
66cfc0fd
AM
435 error (_("Size overflow prevents reading %s"
436 " elements of size %s for %s\n"),
437 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
438 return NULL;
439 }
440
c22b42ce 441 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 442 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
443 if (filedata->archive_file_offset > filedata->file_size
444 || offset > filedata->file_size - filedata->archive_file_offset
445 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 446 {
049b0c3a 447 if (reason)
66cfc0fd
AM
448 error (_("Reading %s bytes extends past end of file for %s\n"),
449 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
450 return NULL;
451 }
452
978c4450
AM
453 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
454 SEEK_SET))
071436c6
NC
455 {
456 if (reason)
c9c1d674 457 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 458 filedata->archive_file_offset + offset, reason);
071436c6
NC
459 return NULL;
460 }
461
a6e9f9df
AM
462 mvar = var;
463 if (mvar == NULL)
464 {
7c1c1904
AM
465 /* + 1 so that we can '\0' terminate invalid string table sections. */
466 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
467
468 if (mvar == NULL)
469 {
049b0c3a 470 if (reason)
66cfc0fd
AM
471 error (_("Out of memory allocating %s bytes for %s\n"),
472 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
473 return NULL;
474 }
c256ffe7 475
c9c1d674 476 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
477 }
478
dda8d76d 479 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 480 {
049b0c3a 481 if (reason)
66cfc0fd
AM
482 error (_("Unable to read in %s bytes of %s\n"),
483 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
484 if (mvar != var)
485 free (mvar);
486 return NULL;
487 }
488
489 return mvar;
490}
491
32ec8896
NC
492/* Print a VMA value in the MODE specified.
493 Returns the number of characters displayed. */
cb8f3167 494
32ec8896 495static unsigned int
14a91970 496print_vma (bfd_vma vma, print_mode mode)
66543521 497{
32ec8896 498 unsigned int nc = 0;
66543521 499
14a91970 500 switch (mode)
66543521 501 {
14a91970
AM
502 case FULL_HEX:
503 nc = printf ("0x");
1a0670f3 504 /* Fall through. */
14a91970 505 case LONG_HEX:
f7a99963 506#ifdef BFD64
14a91970 507 if (is_32bit_elf)
437c2fb7 508 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 509#endif
14a91970
AM
510 printf_vma (vma);
511 return nc + 16;
b19aac67 512
14a91970
AM
513 case DEC_5:
514 if (vma <= 99999)
515 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 516 /* Fall through. */
14a91970
AM
517 case PREFIX_HEX:
518 nc = printf ("0x");
1a0670f3 519 /* Fall through. */
14a91970
AM
520 case HEX:
521 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 522
14a91970
AM
523 case DEC:
524 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 525
14a91970
AM
526 case UNSIGNED:
527 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
528
529 default:
530 /* FIXME: Report unrecognised mode ? */
531 return 0;
f7a99963 532 }
f7a99963
NC
533}
534
7bfd842d 535/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 536 multibye characters (assuming the host environment supports them).
31104126 537
7bfd842d
NC
538 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
539
0942c7ab
NC
540 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
541 abs(WIDTH) - 5 characters followed by "[...]".
542
7bfd842d
NC
543 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
544 padding as necessary.
171191ba
NC
545
546 Returns the number of emitted characters. */
547
548static unsigned int
0942c7ab 549print_symbol (signed int width, const char * symbol)
31104126 550{
171191ba 551 bfd_boolean extra_padding = FALSE;
0942c7ab 552 bfd_boolean do_dots = FALSE;
32ec8896 553 signed int num_printed = 0;
3bfcb652 554#ifdef HAVE_MBSTATE_T
7bfd842d 555 mbstate_t state;
3bfcb652 556#endif
32ec8896 557 unsigned int width_remaining;
79bc120c 558 const void * alloced_symbol = NULL;
961c521f 559
7bfd842d 560 if (width < 0)
961c521f 561 {
88305e1b 562 /* Keep the width positive. This helps the code below. */
961c521f 563 width = - width;
171191ba 564 extra_padding = TRUE;
0b4362b0 565 }
56d8f8a9
NC
566 else if (width == 0)
567 return 0;
961c521f 568
7bfd842d
NC
569 if (do_wide)
570 /* Set the remaining width to a very large value.
571 This simplifies the code below. */
572 width_remaining = INT_MAX;
573 else
0942c7ab
NC
574 {
575 width_remaining = width;
576 if (! do_not_show_symbol_truncation
577 && (int) strlen (symbol) > width)
578 {
579 width_remaining -= 5;
580 if ((int) width_remaining < 0)
581 width_remaining = 0;
582 do_dots = TRUE;
583 }
584 }
cb8f3167 585
3bfcb652 586#ifdef HAVE_MBSTATE_T
7bfd842d
NC
587 /* Initialise the multibyte conversion state. */
588 memset (& state, 0, sizeof (state));
3bfcb652 589#endif
961c521f 590
79bc120c
NC
591 if (do_demangle && *symbol)
592 {
593 const char * res = cplus_demangle (symbol, demangle_flags);
594
595 if (res != NULL)
596 alloced_symbol = symbol = res;
597 }
598
7bfd842d
NC
599 while (width_remaining)
600 {
601 size_t n;
7bfd842d 602 const char c = *symbol++;
961c521f 603
7bfd842d 604 if (c == 0)
961c521f
NC
605 break;
606
7bfd842d
NC
607 /* Do not print control characters directly as they can affect terminal
608 settings. Such characters usually appear in the names generated
609 by the assembler for local labels. */
610 if (ISCNTRL (c))
961c521f 611 {
7bfd842d 612 if (width_remaining < 2)
961c521f
NC
613 break;
614
7bfd842d
NC
615 printf ("^%c", c + 0x40);
616 width_remaining -= 2;
171191ba 617 num_printed += 2;
961c521f 618 }
7bfd842d
NC
619 else if (ISPRINT (c))
620 {
621 putchar (c);
622 width_remaining --;
623 num_printed ++;
624 }
961c521f
NC
625 else
626 {
3bfcb652
NC
627#ifdef HAVE_MBSTATE_T
628 wchar_t w;
629#endif
7bfd842d
NC
630 /* Let printf do the hard work of displaying multibyte characters. */
631 printf ("%.1s", symbol - 1);
632 width_remaining --;
633 num_printed ++;
634
3bfcb652 635#ifdef HAVE_MBSTATE_T
7bfd842d
NC
636 /* Try to find out how many bytes made up the character that was
637 just printed. Advance the symbol pointer past the bytes that
638 were displayed. */
639 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
640#else
641 n = 1;
642#endif
7bfd842d
NC
643 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
644 symbol += (n - 1);
961c521f 645 }
961c521f 646 }
171191ba 647
0942c7ab
NC
648 if (do_dots)
649 num_printed += printf ("[...]");
650
7bfd842d 651 if (extra_padding && num_printed < width)
171191ba
NC
652 {
653 /* Fill in the remaining spaces. */
7bfd842d
NC
654 printf ("%-*s", width - num_printed, " ");
655 num_printed = width;
171191ba
NC
656 }
657
79bc120c 658 free ((void *) alloced_symbol);
171191ba 659 return num_printed;
31104126
NC
660}
661
1449284b 662/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
663 the given section's name. Like print_symbol, except that it does not try
664 to print multibyte characters, it just interprets them as hex values. */
665
666static const char *
dda8d76d 667printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
668{
669#define MAX_PRINT_SEC_NAME_LEN 128
670 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
671 const char * name = SECTION_NAME (sec);
672 char * buf = sec_name_buf;
673 char c;
674 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
675
676 while ((c = * name ++) != 0)
677 {
678 if (ISCNTRL (c))
679 {
680 if (remaining < 2)
681 break;
948f632f 682
74e1a04b
NC
683 * buf ++ = '^';
684 * buf ++ = c + 0x40;
685 remaining -= 2;
686 }
687 else if (ISPRINT (c))
688 {
689 * buf ++ = c;
690 remaining -= 1;
691 }
692 else
693 {
694 static char hex[17] = "0123456789ABCDEF";
695
696 if (remaining < 4)
697 break;
698 * buf ++ = '<';
699 * buf ++ = hex[(c & 0xf0) >> 4];
700 * buf ++ = hex[c & 0x0f];
701 * buf ++ = '>';
702 remaining -= 4;
703 }
704
705 if (remaining == 0)
706 break;
707 }
708
709 * buf = 0;
710 return sec_name_buf;
711}
712
713static const char *
dda8d76d 714printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 715{
dda8d76d 716 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
717 return _("<corrupt>");
718
dda8d76d 719 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
720}
721
89fac5e3
RS
722/* Return a pointer to section NAME, or NULL if no such section exists. */
723
724static Elf_Internal_Shdr *
dda8d76d 725find_section (Filedata * filedata, const char * name)
89fac5e3
RS
726{
727 unsigned int i;
728
68807c3c
NC
729 if (filedata->section_headers == NULL)
730 return NULL;
dda8d76d
NC
731
732 for (i = 0; i < filedata->file_header.e_shnum; i++)
733 if (streq (SECTION_NAME (filedata->section_headers + i), name))
734 return filedata->section_headers + i;
89fac5e3
RS
735
736 return NULL;
737}
738
0b6ae522
DJ
739/* Return a pointer to a section containing ADDR, or NULL if no such
740 section exists. */
741
742static Elf_Internal_Shdr *
dda8d76d 743find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
744{
745 unsigned int i;
746
68807c3c
NC
747 if (filedata->section_headers == NULL)
748 return NULL;
749
dda8d76d 750 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 751 {
dda8d76d
NC
752 Elf_Internal_Shdr *sec = filedata->section_headers + i;
753
0b6ae522
DJ
754 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
755 return sec;
756 }
757
758 return NULL;
759}
760
071436c6 761static Elf_Internal_Shdr *
dda8d76d 762find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
763{
764 unsigned int i;
765
68807c3c
NC
766 if (filedata->section_headers == NULL)
767 return NULL;
768
dda8d76d 769 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 770 {
dda8d76d
NC
771 Elf_Internal_Shdr *sec = filedata->section_headers + i;
772
071436c6
NC
773 if (sec->sh_type == type)
774 return sec;
775 }
776
777 return NULL;
778}
779
657d0d47
CC
780/* Return a pointer to section NAME, or NULL if no such section exists,
781 restricted to the list of sections given in SET. */
782
783static Elf_Internal_Shdr *
dda8d76d 784find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
785{
786 unsigned int i;
787
68807c3c
NC
788 if (filedata->section_headers == NULL)
789 return NULL;
790
657d0d47
CC
791 if (set != NULL)
792 {
793 while ((i = *set++) > 0)
b814a36d
NC
794 {
795 /* See PR 21156 for a reproducer. */
dda8d76d 796 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
797 continue; /* FIXME: Should we issue an error message ? */
798
dda8d76d
NC
799 if (streq (SECTION_NAME (filedata->section_headers + i), name))
800 return filedata->section_headers + i;
b814a36d 801 }
657d0d47
CC
802 }
803
dda8d76d 804 return find_section (filedata, name);
657d0d47
CC
805}
806
32ec8896 807/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
808 This OS has so many departures from the ELF standard that we test it at
809 many places. */
810
32ec8896 811static inline bfd_boolean
dda8d76d 812is_ia64_vms (Filedata * filedata)
28f997cf 813{
dda8d76d
NC
814 return filedata->file_header.e_machine == EM_IA_64
815 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
816}
817
bcedfee6 818/* Guess the relocation size commonly used by the specific machines. */
252b5132 819
32ec8896 820static bfd_boolean
2dc4cec1 821guess_is_rela (unsigned int e_machine)
252b5132 822{
9c19a809 823 switch (e_machine)
252b5132
RH
824 {
825 /* Targets that use REL relocations. */
252b5132 826 case EM_386:
22abe556 827 case EM_IAMCU:
f954747f 828 case EM_960:
e9f53129 829 case EM_ARM:
2b0337b0 830 case EM_D10V:
252b5132 831 case EM_CYGNUS_D10V:
e9f53129 832 case EM_DLX:
252b5132 833 case EM_MIPS:
4fe85591 834 case EM_MIPS_RS3_LE:
e9f53129 835 case EM_CYGNUS_M32R:
1c0d3aa6 836 case EM_SCORE:
f6c1a2d5 837 case EM_XGATE:
fe944acf 838 case EM_NFP:
aca4efc7 839 case EM_BPF:
9c19a809 840 return FALSE;
103f02d3 841
252b5132
RH
842 /* Targets that use RELA relocations. */
843 case EM_68K:
f954747f 844 case EM_860:
a06ea964 845 case EM_AARCH64:
cfb8c092 846 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
847 case EM_ALPHA:
848 case EM_ALTERA_NIOS2:
886a2506
NC
849 case EM_ARC:
850 case EM_ARC_COMPACT:
851 case EM_ARC_COMPACT2:
e9f53129
AM
852 case EM_AVR:
853 case EM_AVR_OLD:
854 case EM_BLACKFIN:
60bca95a 855 case EM_CR16:
e9f53129
AM
856 case EM_CRIS:
857 case EM_CRX:
b8891f8d 858 case EM_CSKY:
2b0337b0 859 case EM_D30V:
252b5132 860 case EM_CYGNUS_D30V:
2b0337b0 861 case EM_FR30:
3f8107ab 862 case EM_FT32:
252b5132 863 case EM_CYGNUS_FR30:
5c70f934 864 case EM_CYGNUS_FRV:
e9f53129
AM
865 case EM_H8S:
866 case EM_H8_300:
867 case EM_H8_300H:
800eeca4 868 case EM_IA_64:
1e4cf259
NC
869 case EM_IP2K:
870 case EM_IP2K_OLD:
3b36097d 871 case EM_IQ2000:
84e94c90 872 case EM_LATTICEMICO32:
ff7eeb89 873 case EM_M32C_OLD:
49f58d10 874 case EM_M32C:
e9f53129
AM
875 case EM_M32R:
876 case EM_MCORE:
15ab5209 877 case EM_CYGNUS_MEP:
a3c62988 878 case EM_METAG:
e9f53129
AM
879 case EM_MMIX:
880 case EM_MN10200:
881 case EM_CYGNUS_MN10200:
882 case EM_MN10300:
883 case EM_CYGNUS_MN10300:
5506d11a 884 case EM_MOXIE:
e9f53129
AM
885 case EM_MSP430:
886 case EM_MSP430_OLD:
d031aafb 887 case EM_MT:
35c08157 888 case EM_NDS32:
64fd6348 889 case EM_NIOS32:
73589c9d 890 case EM_OR1K:
e9f53129
AM
891 case EM_PPC64:
892 case EM_PPC:
2b100bb5 893 case EM_TI_PRU:
e23eba97 894 case EM_RISCV:
99c513f6 895 case EM_RL78:
c7927a3c 896 case EM_RX:
e9f53129
AM
897 case EM_S390:
898 case EM_S390_OLD:
899 case EM_SH:
900 case EM_SPARC:
901 case EM_SPARC32PLUS:
902 case EM_SPARCV9:
903 case EM_SPU:
40b36596 904 case EM_TI_C6000:
aa137e4d
NC
905 case EM_TILEGX:
906 case EM_TILEPRO:
708e2187 907 case EM_V800:
e9f53129
AM
908 case EM_V850:
909 case EM_CYGNUS_V850:
910 case EM_VAX:
619ed720 911 case EM_VISIUM:
e9f53129 912 case EM_X86_64:
8a9036a4 913 case EM_L1OM:
7a9068fe 914 case EM_K1OM:
e9f53129
AM
915 case EM_XSTORMY16:
916 case EM_XTENSA:
917 case EM_XTENSA_OLD:
7ba29e2a
NC
918 case EM_MICROBLAZE:
919 case EM_MICROBLAZE_OLD:
f96bd6c2 920 case EM_WEBASSEMBLY:
9c19a809 921 return TRUE;
103f02d3 922
e9f53129
AM
923 case EM_68HC05:
924 case EM_68HC08:
925 case EM_68HC11:
926 case EM_68HC16:
927 case EM_FX66:
928 case EM_ME16:
d1133906 929 case EM_MMA:
d1133906
NC
930 case EM_NCPU:
931 case EM_NDR1:
e9f53129 932 case EM_PCP:
d1133906 933 case EM_ST100:
e9f53129 934 case EM_ST19:
d1133906 935 case EM_ST7:
e9f53129
AM
936 case EM_ST9PLUS:
937 case EM_STARCORE:
d1133906 938 case EM_SVX:
e9f53129 939 case EM_TINYJ:
9c19a809
NC
940 default:
941 warn (_("Don't know about relocations on this machine architecture\n"));
942 return FALSE;
943 }
944}
252b5132 945
dda8d76d 946/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
947 Returns TRUE upon success, FALSE otherwise. If successful then a
948 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
949 and the number of relocs loaded is placed in *NRELASP. It is the caller's
950 responsibility to free the allocated buffer. */
951
952static bfd_boolean
dda8d76d
NC
953slurp_rela_relocs (Filedata * filedata,
954 unsigned long rel_offset,
955 unsigned long rel_size,
956 Elf_Internal_Rela ** relasp,
957 unsigned long * nrelasp)
9c19a809 958{
2cf0635d 959 Elf_Internal_Rela * relas;
8b73c356 960 size_t nrelas;
4d6ed7c8 961 unsigned int i;
252b5132 962
4d6ed7c8
NC
963 if (is_32bit_elf)
964 {
2cf0635d 965 Elf32_External_Rela * erelas;
103f02d3 966
dda8d76d 967 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 968 rel_size, _("32-bit relocation data"));
a6e9f9df 969 if (!erelas)
32ec8896 970 return FALSE;
252b5132 971
4d6ed7c8 972 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 973
3f5e193b
NC
974 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
975 sizeof (Elf_Internal_Rela));
103f02d3 976
4d6ed7c8
NC
977 if (relas == NULL)
978 {
c256ffe7 979 free (erelas);
591a748a 980 error (_("out of memory parsing relocs\n"));
32ec8896 981 return FALSE;
4d6ed7c8 982 }
103f02d3 983
4d6ed7c8
NC
984 for (i = 0; i < nrelas; i++)
985 {
986 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
987 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 988 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 989 }
103f02d3 990
4d6ed7c8
NC
991 free (erelas);
992 }
993 else
994 {
2cf0635d 995 Elf64_External_Rela * erelas;
103f02d3 996
dda8d76d 997 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 998 rel_size, _("64-bit relocation data"));
a6e9f9df 999 if (!erelas)
32ec8896 1000 return FALSE;
4d6ed7c8
NC
1001
1002 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1003
3f5e193b
NC
1004 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1005 sizeof (Elf_Internal_Rela));
103f02d3 1006
4d6ed7c8
NC
1007 if (relas == NULL)
1008 {
c256ffe7 1009 free (erelas);
591a748a 1010 error (_("out of memory parsing relocs\n"));
32ec8896 1011 return FALSE;
9c19a809 1012 }
4d6ed7c8
NC
1013
1014 for (i = 0; i < nrelas; i++)
9c19a809 1015 {
66543521
AM
1016 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1017 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1018 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1019
1020 /* The #ifdef BFD64 below is to prevent a compile time
1021 warning. We know that if we do not have a 64 bit data
1022 type that we will never execute this code anyway. */
1023#ifdef BFD64
dda8d76d
NC
1024 if (filedata->file_header.e_machine == EM_MIPS
1025 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1026 {
1027 /* In little-endian objects, r_info isn't really a
1028 64-bit little-endian value: it has a 32-bit
1029 little-endian symbol index followed by four
1030 individual byte fields. Reorder INFO
1031 accordingly. */
91d6fa6a
NC
1032 bfd_vma inf = relas[i].r_info;
1033 inf = (((inf & 0xffffffff) << 32)
1034 | ((inf >> 56) & 0xff)
1035 | ((inf >> 40) & 0xff00)
1036 | ((inf >> 24) & 0xff0000)
1037 | ((inf >> 8) & 0xff000000));
1038 relas[i].r_info = inf;
861fb55a
DJ
1039 }
1040#endif /* BFD64 */
4d6ed7c8 1041 }
103f02d3 1042
4d6ed7c8
NC
1043 free (erelas);
1044 }
32ec8896 1045
4d6ed7c8
NC
1046 *relasp = relas;
1047 *nrelasp = nrelas;
32ec8896 1048 return TRUE;
4d6ed7c8 1049}
103f02d3 1050
dda8d76d 1051/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1052 Returns TRUE upon success, FALSE otherwise. If successful then a
1053 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1054 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1055 responsibility to free the allocated buffer. */
1056
1057static bfd_boolean
dda8d76d
NC
1058slurp_rel_relocs (Filedata * filedata,
1059 unsigned long rel_offset,
1060 unsigned long rel_size,
1061 Elf_Internal_Rela ** relsp,
1062 unsigned long * nrelsp)
4d6ed7c8 1063{
2cf0635d 1064 Elf_Internal_Rela * rels;
8b73c356 1065 size_t nrels;
4d6ed7c8 1066 unsigned int i;
103f02d3 1067
4d6ed7c8
NC
1068 if (is_32bit_elf)
1069 {
2cf0635d 1070 Elf32_External_Rel * erels;
103f02d3 1071
dda8d76d 1072 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1073 rel_size, _("32-bit relocation data"));
a6e9f9df 1074 if (!erels)
32ec8896 1075 return FALSE;
103f02d3 1076
4d6ed7c8 1077 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1078
3f5e193b 1079 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1080
4d6ed7c8
NC
1081 if (rels == NULL)
1082 {
c256ffe7 1083 free (erels);
591a748a 1084 error (_("out of memory parsing relocs\n"));
32ec8896 1085 return FALSE;
4d6ed7c8
NC
1086 }
1087
1088 for (i = 0; i < nrels; i++)
1089 {
1090 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1091 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1092 rels[i].r_addend = 0;
9ea033b2 1093 }
4d6ed7c8
NC
1094
1095 free (erels);
9c19a809
NC
1096 }
1097 else
1098 {
2cf0635d 1099 Elf64_External_Rel * erels;
9ea033b2 1100
dda8d76d 1101 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1102 rel_size, _("64-bit relocation data"));
a6e9f9df 1103 if (!erels)
32ec8896 1104 return FALSE;
103f02d3 1105
4d6ed7c8 1106 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1107
3f5e193b 1108 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1109
4d6ed7c8 1110 if (rels == NULL)
9c19a809 1111 {
c256ffe7 1112 free (erels);
591a748a 1113 error (_("out of memory parsing relocs\n"));
32ec8896 1114 return FALSE;
4d6ed7c8 1115 }
103f02d3 1116
4d6ed7c8
NC
1117 for (i = 0; i < nrels; i++)
1118 {
66543521
AM
1119 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1120 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1121 rels[i].r_addend = 0;
861fb55a
DJ
1122
1123 /* The #ifdef BFD64 below is to prevent a compile time
1124 warning. We know that if we do not have a 64 bit data
1125 type that we will never execute this code anyway. */
1126#ifdef BFD64
dda8d76d
NC
1127 if (filedata->file_header.e_machine == EM_MIPS
1128 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1129 {
1130 /* In little-endian objects, r_info isn't really a
1131 64-bit little-endian value: it has a 32-bit
1132 little-endian symbol index followed by four
1133 individual byte fields. Reorder INFO
1134 accordingly. */
91d6fa6a
NC
1135 bfd_vma inf = rels[i].r_info;
1136 inf = (((inf & 0xffffffff) << 32)
1137 | ((inf >> 56) & 0xff)
1138 | ((inf >> 40) & 0xff00)
1139 | ((inf >> 24) & 0xff0000)
1140 | ((inf >> 8) & 0xff000000));
1141 rels[i].r_info = inf;
861fb55a
DJ
1142 }
1143#endif /* BFD64 */
4d6ed7c8 1144 }
103f02d3 1145
4d6ed7c8
NC
1146 free (erels);
1147 }
32ec8896 1148
4d6ed7c8
NC
1149 *relsp = rels;
1150 *nrelsp = nrels;
32ec8896 1151 return TRUE;
4d6ed7c8 1152}
103f02d3 1153
aca88567
NC
1154/* Returns the reloc type extracted from the reloc info field. */
1155
1156static unsigned int
dda8d76d 1157get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1158{
1159 if (is_32bit_elf)
1160 return ELF32_R_TYPE (reloc_info);
1161
dda8d76d 1162 switch (filedata->file_header.e_machine)
aca88567
NC
1163 {
1164 case EM_MIPS:
1165 /* Note: We assume that reloc_info has already been adjusted for us. */
1166 return ELF64_MIPS_R_TYPE (reloc_info);
1167
1168 case EM_SPARCV9:
1169 return ELF64_R_TYPE_ID (reloc_info);
1170
1171 default:
1172 return ELF64_R_TYPE (reloc_info);
1173 }
1174}
1175
1176/* Return the symbol index extracted from the reloc info field. */
1177
1178static bfd_vma
1179get_reloc_symindex (bfd_vma reloc_info)
1180{
1181 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1182}
1183
13761a11 1184static inline bfd_boolean
dda8d76d 1185uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1186{
1187 return
dda8d76d 1188 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1189 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1190 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1191 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1192 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1193}
1194
d3ba0551
AM
1195/* Display the contents of the relocation data found at the specified
1196 offset. */
ee42cf8c 1197
32ec8896 1198static bfd_boolean
dda8d76d
NC
1199dump_relocations (Filedata * filedata,
1200 unsigned long rel_offset,
1201 unsigned long rel_size,
1202 Elf_Internal_Sym * symtab,
1203 unsigned long nsyms,
1204 char * strtab,
1205 unsigned long strtablen,
1206 int is_rela,
1207 bfd_boolean is_dynsym)
4d6ed7c8 1208{
32ec8896 1209 unsigned long i;
2cf0635d 1210 Elf_Internal_Rela * rels;
32ec8896 1211 bfd_boolean res = TRUE;
103f02d3 1212
4d6ed7c8 1213 if (is_rela == UNKNOWN)
dda8d76d 1214 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1215
4d6ed7c8
NC
1216 if (is_rela)
1217 {
dda8d76d 1218 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1219 return FALSE;
4d6ed7c8
NC
1220 }
1221 else
1222 {
dda8d76d 1223 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1224 return FALSE;
252b5132
RH
1225 }
1226
410f7a12
L
1227 if (is_32bit_elf)
1228 {
1229 if (is_rela)
2c71103e
NC
1230 {
1231 if (do_wide)
1232 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1233 else
1234 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1235 }
410f7a12 1236 else
2c71103e
NC
1237 {
1238 if (do_wide)
1239 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1240 else
1241 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1242 }
410f7a12 1243 }
252b5132 1244 else
410f7a12
L
1245 {
1246 if (is_rela)
2c71103e
NC
1247 {
1248 if (do_wide)
8beeaeb7 1249 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1250 else
1251 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1252 }
410f7a12 1253 else
2c71103e
NC
1254 {
1255 if (do_wide)
8beeaeb7 1256 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1257 else
1258 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1259 }
410f7a12 1260 }
252b5132
RH
1261
1262 for (i = 0; i < rel_size; i++)
1263 {
2cf0635d 1264 const char * rtype;
b34976b6 1265 bfd_vma offset;
91d6fa6a 1266 bfd_vma inf;
b34976b6
AM
1267 bfd_vma symtab_index;
1268 bfd_vma type;
103f02d3 1269
b34976b6 1270 offset = rels[i].r_offset;
91d6fa6a 1271 inf = rels[i].r_info;
103f02d3 1272
dda8d76d 1273 type = get_reloc_type (filedata, inf);
91d6fa6a 1274 symtab_index = get_reloc_symindex (inf);
252b5132 1275
410f7a12
L
1276 if (is_32bit_elf)
1277 {
39dbeff8
AM
1278 printf ("%8.8lx %8.8lx ",
1279 (unsigned long) offset & 0xffffffff,
91d6fa6a 1280 (unsigned long) inf & 0xffffffff);
410f7a12
L
1281 }
1282 else
1283 {
39dbeff8 1284 printf (do_wide
d1ce973e
AM
1285 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1286 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1287 offset, inf);
410f7a12 1288 }
103f02d3 1289
dda8d76d 1290 switch (filedata->file_header.e_machine)
252b5132
RH
1291 {
1292 default:
1293 rtype = NULL;
1294 break;
1295
a06ea964
NC
1296 case EM_AARCH64:
1297 rtype = elf_aarch64_reloc_type (type);
1298 break;
1299
2b0337b0 1300 case EM_M32R:
252b5132 1301 case EM_CYGNUS_M32R:
9ea033b2 1302 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1303 break;
1304
1305 case EM_386:
22abe556 1306 case EM_IAMCU:
9ea033b2 1307 rtype = elf_i386_reloc_type (type);
252b5132
RH
1308 break;
1309
ba2685cc
AM
1310 case EM_68HC11:
1311 case EM_68HC12:
1312 rtype = elf_m68hc11_reloc_type (type);
1313 break;
75751cd9 1314
7b4ae824
JD
1315 case EM_S12Z:
1316 rtype = elf_s12z_reloc_type (type);
1317 break;
1318
252b5132 1319 case EM_68K:
9ea033b2 1320 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1321 break;
1322
f954747f
AM
1323 case EM_960:
1324 rtype = elf_i960_reloc_type (type);
1325 break;
1326
adde6300 1327 case EM_AVR:
2b0337b0 1328 case EM_AVR_OLD:
adde6300
AM
1329 rtype = elf_avr_reloc_type (type);
1330 break;
1331
9ea033b2
NC
1332 case EM_OLD_SPARCV9:
1333 case EM_SPARC32PLUS:
1334 case EM_SPARCV9:
252b5132 1335 case EM_SPARC:
9ea033b2 1336 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1337 break;
1338
e9f53129
AM
1339 case EM_SPU:
1340 rtype = elf_spu_reloc_type (type);
1341 break;
1342
708e2187
NC
1343 case EM_V800:
1344 rtype = v800_reloc_type (type);
1345 break;
2b0337b0 1346 case EM_V850:
252b5132 1347 case EM_CYGNUS_V850:
9ea033b2 1348 rtype = v850_reloc_type (type);
252b5132
RH
1349 break;
1350
2b0337b0 1351 case EM_D10V:
252b5132 1352 case EM_CYGNUS_D10V:
9ea033b2 1353 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1354 break;
1355
2b0337b0 1356 case EM_D30V:
252b5132 1357 case EM_CYGNUS_D30V:
9ea033b2 1358 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1359 break;
1360
d172d4ba
NC
1361 case EM_DLX:
1362 rtype = elf_dlx_reloc_type (type);
1363 break;
1364
252b5132 1365 case EM_SH:
9ea033b2 1366 rtype = elf_sh_reloc_type (type);
252b5132
RH
1367 break;
1368
2b0337b0 1369 case EM_MN10300:
252b5132 1370 case EM_CYGNUS_MN10300:
9ea033b2 1371 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1372 break;
1373
2b0337b0 1374 case EM_MN10200:
252b5132 1375 case EM_CYGNUS_MN10200:
9ea033b2 1376 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1377 break;
1378
2b0337b0 1379 case EM_FR30:
252b5132 1380 case EM_CYGNUS_FR30:
9ea033b2 1381 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1382 break;
1383
ba2685cc
AM
1384 case EM_CYGNUS_FRV:
1385 rtype = elf_frv_reloc_type (type);
1386 break;
5c70f934 1387
b8891f8d
AJ
1388 case EM_CSKY:
1389 rtype = elf_csky_reloc_type (type);
1390 break;
1391
3f8107ab
AM
1392 case EM_FT32:
1393 rtype = elf_ft32_reloc_type (type);
1394 break;
1395
252b5132 1396 case EM_MCORE:
9ea033b2 1397 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1398 break;
1399
3c3bdf30
NC
1400 case EM_MMIX:
1401 rtype = elf_mmix_reloc_type (type);
1402 break;
1403
5506d11a
AM
1404 case EM_MOXIE:
1405 rtype = elf_moxie_reloc_type (type);
1406 break;
1407
2469cfa2 1408 case EM_MSP430:
dda8d76d 1409 if (uses_msp430x_relocs (filedata))
13761a11
NC
1410 {
1411 rtype = elf_msp430x_reloc_type (type);
1412 break;
1413 }
1a0670f3 1414 /* Fall through. */
2469cfa2
NC
1415 case EM_MSP430_OLD:
1416 rtype = elf_msp430_reloc_type (type);
1417 break;
1418
35c08157
KLC
1419 case EM_NDS32:
1420 rtype = elf_nds32_reloc_type (type);
1421 break;
1422
252b5132 1423 case EM_PPC:
9ea033b2 1424 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1425 break;
1426
c833c019
AM
1427 case EM_PPC64:
1428 rtype = elf_ppc64_reloc_type (type);
1429 break;
1430
252b5132 1431 case EM_MIPS:
4fe85591 1432 case EM_MIPS_RS3_LE:
9ea033b2 1433 rtype = elf_mips_reloc_type (type);
252b5132
RH
1434 break;
1435
e23eba97
NC
1436 case EM_RISCV:
1437 rtype = elf_riscv_reloc_type (type);
1438 break;
1439
252b5132 1440 case EM_ALPHA:
9ea033b2 1441 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1442 break;
1443
1444 case EM_ARM:
9ea033b2 1445 rtype = elf_arm_reloc_type (type);
252b5132
RH
1446 break;
1447
584da044 1448 case EM_ARC:
886a2506
NC
1449 case EM_ARC_COMPACT:
1450 case EM_ARC_COMPACT2:
9ea033b2 1451 rtype = elf_arc_reloc_type (type);
252b5132
RH
1452 break;
1453
1454 case EM_PARISC:
69e617ca 1455 rtype = elf_hppa_reloc_type (type);
252b5132 1456 break;
7d466069 1457
b8720f9d
JL
1458 case EM_H8_300:
1459 case EM_H8_300H:
1460 case EM_H8S:
1461 rtype = elf_h8_reloc_type (type);
1462 break;
1463
73589c9d
CS
1464 case EM_OR1K:
1465 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1466 break;
1467
7d466069 1468 case EM_PJ:
2b0337b0 1469 case EM_PJ_OLD:
7d466069
ILT
1470 rtype = elf_pj_reloc_type (type);
1471 break;
800eeca4
JW
1472 case EM_IA_64:
1473 rtype = elf_ia64_reloc_type (type);
1474 break;
1b61cf92
HPN
1475
1476 case EM_CRIS:
1477 rtype = elf_cris_reloc_type (type);
1478 break;
535c37ff 1479
f954747f
AM
1480 case EM_860:
1481 rtype = elf_i860_reloc_type (type);
1482 break;
1483
bcedfee6 1484 case EM_X86_64:
8a9036a4 1485 case EM_L1OM:
7a9068fe 1486 case EM_K1OM:
bcedfee6
NC
1487 rtype = elf_x86_64_reloc_type (type);
1488 break;
a85d7ed0 1489
f954747f
AM
1490 case EM_S370:
1491 rtype = i370_reloc_type (type);
1492 break;
1493
53c7db4b
KH
1494 case EM_S390_OLD:
1495 case EM_S390:
1496 rtype = elf_s390_reloc_type (type);
1497 break;
93fbbb04 1498
1c0d3aa6
NC
1499 case EM_SCORE:
1500 rtype = elf_score_reloc_type (type);
1501 break;
1502
93fbbb04
GK
1503 case EM_XSTORMY16:
1504 rtype = elf_xstormy16_reloc_type (type);
1505 break;
179d3252 1506
1fe1f39c
NC
1507 case EM_CRX:
1508 rtype = elf_crx_reloc_type (type);
1509 break;
1510
179d3252
JT
1511 case EM_VAX:
1512 rtype = elf_vax_reloc_type (type);
1513 break;
1e4cf259 1514
619ed720
EB
1515 case EM_VISIUM:
1516 rtype = elf_visium_reloc_type (type);
1517 break;
1518
aca4efc7
JM
1519 case EM_BPF:
1520 rtype = elf_bpf_reloc_type (type);
1521 break;
1522
cfb8c092
NC
1523 case EM_ADAPTEVA_EPIPHANY:
1524 rtype = elf_epiphany_reloc_type (type);
1525 break;
1526
1e4cf259
NC
1527 case EM_IP2K:
1528 case EM_IP2K_OLD:
1529 rtype = elf_ip2k_reloc_type (type);
1530 break;
3b36097d
SC
1531
1532 case EM_IQ2000:
1533 rtype = elf_iq2000_reloc_type (type);
1534 break;
88da6820
NC
1535
1536 case EM_XTENSA_OLD:
1537 case EM_XTENSA:
1538 rtype = elf_xtensa_reloc_type (type);
1539 break;
a34e3ecb 1540
84e94c90
NC
1541 case EM_LATTICEMICO32:
1542 rtype = elf_lm32_reloc_type (type);
1543 break;
1544
ff7eeb89 1545 case EM_M32C_OLD:
49f58d10
JB
1546 case EM_M32C:
1547 rtype = elf_m32c_reloc_type (type);
1548 break;
1549
d031aafb
NS
1550 case EM_MT:
1551 rtype = elf_mt_reloc_type (type);
a34e3ecb 1552 break;
1d65ded4
CM
1553
1554 case EM_BLACKFIN:
1555 rtype = elf_bfin_reloc_type (type);
1556 break;
15ab5209
DB
1557
1558 case EM_CYGNUS_MEP:
1559 rtype = elf_mep_reloc_type (type);
1560 break;
60bca95a
NC
1561
1562 case EM_CR16:
1563 rtype = elf_cr16_reloc_type (type);
1564 break;
dd24e3da 1565
7ba29e2a
NC
1566 case EM_MICROBLAZE:
1567 case EM_MICROBLAZE_OLD:
1568 rtype = elf_microblaze_reloc_type (type);
1569 break;
c7927a3c 1570
99c513f6
DD
1571 case EM_RL78:
1572 rtype = elf_rl78_reloc_type (type);
1573 break;
1574
c7927a3c
NC
1575 case EM_RX:
1576 rtype = elf_rx_reloc_type (type);
1577 break;
c29aca4a 1578
a3c62988
NC
1579 case EM_METAG:
1580 rtype = elf_metag_reloc_type (type);
1581 break;
1582
c29aca4a
NC
1583 case EM_XC16X:
1584 case EM_C166:
1585 rtype = elf_xc16x_reloc_type (type);
1586 break;
40b36596
JM
1587
1588 case EM_TI_C6000:
1589 rtype = elf_tic6x_reloc_type (type);
1590 break;
aa137e4d
NC
1591
1592 case EM_TILEGX:
1593 rtype = elf_tilegx_reloc_type (type);
1594 break;
1595
1596 case EM_TILEPRO:
1597 rtype = elf_tilepro_reloc_type (type);
1598 break;
f6c1a2d5 1599
f96bd6c2
PC
1600 case EM_WEBASSEMBLY:
1601 rtype = elf_wasm32_reloc_type (type);
1602 break;
1603
f6c1a2d5
NC
1604 case EM_XGATE:
1605 rtype = elf_xgate_reloc_type (type);
1606 break;
36591ba1
SL
1607
1608 case EM_ALTERA_NIOS2:
1609 rtype = elf_nios2_reloc_type (type);
1610 break;
2b100bb5
DD
1611
1612 case EM_TI_PRU:
1613 rtype = elf_pru_reloc_type (type);
1614 break;
fe944acf
FT
1615
1616 case EM_NFP:
1617 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1618 rtype = elf_nfp3200_reloc_type (type);
1619 else
1620 rtype = elf_nfp_reloc_type (type);
1621 break;
6655dba2
SB
1622
1623 case EM_Z80:
1624 rtype = elf_z80_reloc_type (type);
1625 break;
252b5132
RH
1626 }
1627
1628 if (rtype == NULL)
39dbeff8 1629 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1630 else
5c144731 1631 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1632
dda8d76d 1633 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1634 && rtype != NULL
7ace3541
RH
1635 && streq (rtype, "R_ALPHA_LITUSE")
1636 && is_rela)
1637 {
1638 switch (rels[i].r_addend)
1639 {
1640 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1641 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1642 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1643 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1644 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1645 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1646 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1647 default: rtype = NULL;
1648 }
32ec8896 1649
7ace3541
RH
1650 if (rtype)
1651 printf (" (%s)", rtype);
1652 else
1653 {
1654 putchar (' ');
1655 printf (_("<unknown addend: %lx>"),
1656 (unsigned long) rels[i].r_addend);
32ec8896 1657 res = FALSE;
7ace3541
RH
1658 }
1659 }
1660 else if (symtab_index)
252b5132 1661 {
af3fc3bc 1662 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1663 {
27a45f42
AS
1664 error (_(" bad symbol index: %08lx in reloc\n"),
1665 (unsigned long) symtab_index);
32ec8896
NC
1666 res = FALSE;
1667 }
af3fc3bc 1668 else
19936277 1669 {
2cf0635d 1670 Elf_Internal_Sym * psym;
bb4d2ac2
L
1671 const char * version_string;
1672 enum versioned_symbol_info sym_info;
1673 unsigned short vna_other;
19936277 1674
af3fc3bc 1675 psym = symtab + symtab_index;
103f02d3 1676
bb4d2ac2 1677 version_string
dda8d76d 1678 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1679 strtab, strtablen,
1680 symtab_index,
1681 psym,
1682 &sym_info,
1683 &vna_other);
1684
af3fc3bc 1685 printf (" ");
171191ba 1686
d8045f23
NC
1687 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1688 {
1689 const char * name;
1690 unsigned int len;
1691 unsigned int width = is_32bit_elf ? 8 : 14;
1692
1693 /* Relocations against GNU_IFUNC symbols do not use the value
1694 of the symbol as the address to relocate against. Instead
1695 they invoke the function named by the symbol and use its
1696 result as the address for relocation.
1697
1698 To indicate this to the user, do not display the value of
1699 the symbol in the "Symbols's Value" field. Instead show
1700 its name followed by () as a hint that the symbol is
1701 invoked. */
1702
1703 if (strtab == NULL
1704 || psym->st_name == 0
1705 || psym->st_name >= strtablen)
1706 name = "??";
1707 else
1708 name = strtab + psym->st_name;
1709
1710 len = print_symbol (width, name);
bb4d2ac2
L
1711 if (version_string)
1712 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1713 version_string);
d8045f23
NC
1714 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1715 }
1716 else
1717 {
1718 print_vma (psym->st_value, LONG_HEX);
171191ba 1719
d8045f23
NC
1720 printf (is_32bit_elf ? " " : " ");
1721 }
103f02d3 1722
af3fc3bc 1723 if (psym->st_name == 0)
f1ef08cb 1724 {
2cf0635d 1725 const char * sec_name = "<null>";
f1ef08cb
AM
1726 char name_buf[40];
1727
1728 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1729 {
dda8d76d
NC
1730 if (psym->st_shndx < filedata->file_header.e_shnum)
1731 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1732 else if (psym->st_shndx == SHN_ABS)
1733 sec_name = "ABS";
1734 else if (psym->st_shndx == SHN_COMMON)
1735 sec_name = "COMMON";
dda8d76d 1736 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1737 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1738 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1739 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1740 sec_name = "SCOMMON";
dda8d76d 1741 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1742 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1743 sec_name = "SUNDEF";
dda8d76d
NC
1744 else if ((filedata->file_header.e_machine == EM_X86_64
1745 || filedata->file_header.e_machine == EM_L1OM
1746 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1747 && psym->st_shndx == SHN_X86_64_LCOMMON)
1748 sec_name = "LARGE_COMMON";
dda8d76d
NC
1749 else if (filedata->file_header.e_machine == EM_IA_64
1750 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1751 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1752 sec_name = "ANSI_COM";
dda8d76d 1753 else if (is_ia64_vms (filedata)
148b93f2
NC
1754 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1755 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1756 else
1757 {
1758 sprintf (name_buf, "<section 0x%x>",
1759 (unsigned int) psym->st_shndx);
1760 sec_name = name_buf;
1761 }
1762 }
1763 print_symbol (22, sec_name);
1764 }
af3fc3bc 1765 else if (strtab == NULL)
d79b3d50 1766 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1767 else if (psym->st_name >= strtablen)
32ec8896 1768 {
27a45f42
AS
1769 error (_("<corrupt string table index: %3ld>\n"),
1770 psym->st_name);
32ec8896
NC
1771 res = FALSE;
1772 }
af3fc3bc 1773 else
bb4d2ac2
L
1774 {
1775 print_symbol (22, strtab + psym->st_name);
1776 if (version_string)
1777 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1778 version_string);
1779 }
103f02d3 1780
af3fc3bc 1781 if (is_rela)
171191ba 1782 {
7360e63f 1783 bfd_vma off = rels[i].r_addend;
171191ba 1784
7360e63f 1785 if ((bfd_signed_vma) off < 0)
598aaa76 1786 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1787 else
598aaa76 1788 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1789 }
19936277 1790 }
252b5132 1791 }
1b228002 1792 else if (is_rela)
f7a99963 1793 {
7360e63f 1794 bfd_vma off = rels[i].r_addend;
e04d7088
L
1795
1796 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1797 if ((bfd_signed_vma) off < 0)
e04d7088
L
1798 printf ("-%" BFD_VMA_FMT "x", - off);
1799 else
1800 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1801 }
252b5132 1802
dda8d76d 1803 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1804 && rtype != NULL
1805 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1806 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1807
252b5132 1808 putchar ('\n');
2c71103e 1809
aca88567 1810#ifdef BFD64
dda8d76d 1811 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1812 {
91d6fa6a
NC
1813 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1814 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1815 const char * rtype2 = elf_mips_reloc_type (type2);
1816 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1817
2c71103e
NC
1818 printf (" Type2: ");
1819
1820 if (rtype2 == NULL)
39dbeff8
AM
1821 printf (_("unrecognized: %-7lx"),
1822 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1823 else
1824 printf ("%-17.17s", rtype2);
1825
18bd398b 1826 printf ("\n Type3: ");
2c71103e
NC
1827
1828 if (rtype3 == NULL)
39dbeff8
AM
1829 printf (_("unrecognized: %-7lx"),
1830 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1831 else
1832 printf ("%-17.17s", rtype3);
1833
53c7db4b 1834 putchar ('\n');
2c71103e 1835 }
aca88567 1836#endif /* BFD64 */
252b5132
RH
1837 }
1838
c8286bd1 1839 free (rels);
32ec8896
NC
1840
1841 return res;
252b5132
RH
1842}
1843
37c18eed
SD
1844static const char *
1845get_aarch64_dynamic_type (unsigned long type)
1846{
1847 switch (type)
1848 {
1849 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1850 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1851 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1852 default:
1853 return NULL;
1854 }
1855}
1856
252b5132 1857static const char *
d3ba0551 1858get_mips_dynamic_type (unsigned long type)
252b5132
RH
1859{
1860 switch (type)
1861 {
1862 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1863 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1864 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1865 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1866 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1867 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1868 case DT_MIPS_MSYM: return "MIPS_MSYM";
1869 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1870 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1871 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1872 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1873 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1874 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1875 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1876 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1877 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1878 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1879 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1880 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1881 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1882 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1883 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1884 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1885 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1886 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1887 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1888 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1889 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1890 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1891 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1892 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1893 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1894 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1895 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1896 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1897 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1898 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1899 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1900 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1901 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1902 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1903 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1904 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1905 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1906 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1907 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1908 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1909 default:
1910 return NULL;
1911 }
1912}
1913
9a097730 1914static const char *
d3ba0551 1915get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1916{
1917 switch (type)
1918 {
1919 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1920 default:
1921 return NULL;
1922 }
103f02d3
UD
1923}
1924
7490d522
AM
1925static const char *
1926get_ppc_dynamic_type (unsigned long type)
1927{
1928 switch (type)
1929 {
a7f2871e 1930 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1931 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1932 default:
1933 return NULL;
1934 }
1935}
1936
f1cb7e17 1937static const char *
d3ba0551 1938get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1939{
1940 switch (type)
1941 {
a7f2871e
AM
1942 case DT_PPC64_GLINK: return "PPC64_GLINK";
1943 case DT_PPC64_OPD: return "PPC64_OPD";
1944 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1945 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1946 default:
1947 return NULL;
1948 }
1949}
1950
103f02d3 1951static const char *
d3ba0551 1952get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1953{
1954 switch (type)
1955 {
1956 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1957 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1958 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1959 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1960 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1961 case DT_HP_PREINIT: return "HP_PREINIT";
1962 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1963 case DT_HP_NEEDED: return "HP_NEEDED";
1964 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1965 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1966 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1967 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1968 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1969 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1970 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1971 case DT_HP_FILTERED: return "HP_FILTERED";
1972 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1973 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1974 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1975 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1976 case DT_PLT: return "PLT";
1977 case DT_PLT_SIZE: return "PLT_SIZE";
1978 case DT_DLT: return "DLT";
1979 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1980 default:
1981 return NULL;
1982 }
1983}
9a097730 1984
ecc51f48 1985static const char *
d3ba0551 1986get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1987{
1988 switch (type)
1989 {
148b93f2
NC
1990 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1991 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1992 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1993 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1994 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1995 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1996 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1997 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1998 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1999 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2000 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2001 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2002 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2003 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2004 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2005 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2006 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2007 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2008 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2009 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2010 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2011 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2012 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2013 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2014 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2015 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2016 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2017 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2018 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2019 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2020 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2021 default:
2022 return NULL;
2023 }
2024}
2025
fd85a6a1
NC
2026static const char *
2027get_solaris_section_type (unsigned long type)
2028{
2029 switch (type)
2030 {
2031 case 0x6fffffee: return "SUNW_ancillary";
2032 case 0x6fffffef: return "SUNW_capchain";
2033 case 0x6ffffff0: return "SUNW_capinfo";
2034 case 0x6ffffff1: return "SUNW_symsort";
2035 case 0x6ffffff2: return "SUNW_tlssort";
2036 case 0x6ffffff3: return "SUNW_LDYNSYM";
2037 case 0x6ffffff4: return "SUNW_dof";
2038 case 0x6ffffff5: return "SUNW_cap";
2039 case 0x6ffffff6: return "SUNW_SIGNATURE";
2040 case 0x6ffffff7: return "SUNW_ANNOTATE";
2041 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2042 case 0x6ffffff9: return "SUNW_DEBUG";
2043 case 0x6ffffffa: return "SUNW_move";
2044 case 0x6ffffffb: return "SUNW_COMDAT";
2045 case 0x6ffffffc: return "SUNW_syminfo";
2046 case 0x6ffffffd: return "SUNW_verdef";
2047 case 0x6ffffffe: return "SUNW_verneed";
2048 case 0x6fffffff: return "SUNW_versym";
2049 case 0x70000000: return "SPARC_GOTDATA";
2050 default: return NULL;
2051 }
2052}
2053
fabcb361
RH
2054static const char *
2055get_alpha_dynamic_type (unsigned long type)
2056{
2057 switch (type)
2058 {
2059 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2060 default: return NULL;
fabcb361
RH
2061 }
2062}
2063
1c0d3aa6
NC
2064static const char *
2065get_score_dynamic_type (unsigned long type)
2066{
2067 switch (type)
2068 {
2069 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2070 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2071 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2072 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2073 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2074 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2075 default: return NULL;
1c0d3aa6
NC
2076 }
2077}
2078
40b36596
JM
2079static const char *
2080get_tic6x_dynamic_type (unsigned long type)
2081{
2082 switch (type)
2083 {
2084 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2085 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2086 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2087 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2088 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2089 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2090 default: return NULL;
40b36596
JM
2091 }
2092}
1c0d3aa6 2093
36591ba1
SL
2094static const char *
2095get_nios2_dynamic_type (unsigned long type)
2096{
2097 switch (type)
2098 {
2099 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2100 default: return NULL;
36591ba1
SL
2101 }
2102}
2103
fd85a6a1
NC
2104static const char *
2105get_solaris_dynamic_type (unsigned long type)
2106{
2107 switch (type)
2108 {
2109 case 0x6000000d: return "SUNW_AUXILIARY";
2110 case 0x6000000e: return "SUNW_RTLDINF";
2111 case 0x6000000f: return "SUNW_FILTER";
2112 case 0x60000010: return "SUNW_CAP";
2113 case 0x60000011: return "SUNW_SYMTAB";
2114 case 0x60000012: return "SUNW_SYMSZ";
2115 case 0x60000013: return "SUNW_SORTENT";
2116 case 0x60000014: return "SUNW_SYMSORT";
2117 case 0x60000015: return "SUNW_SYMSORTSZ";
2118 case 0x60000016: return "SUNW_TLSSORT";
2119 case 0x60000017: return "SUNW_TLSSORTSZ";
2120 case 0x60000018: return "SUNW_CAPINFO";
2121 case 0x60000019: return "SUNW_STRPAD";
2122 case 0x6000001a: return "SUNW_CAPCHAIN";
2123 case 0x6000001b: return "SUNW_LDMACH";
2124 case 0x6000001d: return "SUNW_CAPCHAINENT";
2125 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2126 case 0x60000021: return "SUNW_PARENT";
2127 case 0x60000023: return "SUNW_ASLR";
2128 case 0x60000025: return "SUNW_RELAX";
2129 case 0x60000029: return "SUNW_NXHEAP";
2130 case 0x6000002b: return "SUNW_NXSTACK";
2131
2132 case 0x70000001: return "SPARC_REGISTER";
2133 case 0x7ffffffd: return "AUXILIARY";
2134 case 0x7ffffffe: return "USED";
2135 case 0x7fffffff: return "FILTER";
2136
15f205b1 2137 default: return NULL;
fd85a6a1
NC
2138 }
2139}
2140
252b5132 2141static const char *
dda8d76d 2142get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2143{
e9e44622 2144 static char buff[64];
252b5132
RH
2145
2146 switch (type)
2147 {
2148 case DT_NULL: return "NULL";
2149 case DT_NEEDED: return "NEEDED";
2150 case DT_PLTRELSZ: return "PLTRELSZ";
2151 case DT_PLTGOT: return "PLTGOT";
2152 case DT_HASH: return "HASH";
2153 case DT_STRTAB: return "STRTAB";
2154 case DT_SYMTAB: return "SYMTAB";
2155 case DT_RELA: return "RELA";
2156 case DT_RELASZ: return "RELASZ";
2157 case DT_RELAENT: return "RELAENT";
2158 case DT_STRSZ: return "STRSZ";
2159 case DT_SYMENT: return "SYMENT";
2160 case DT_INIT: return "INIT";
2161 case DT_FINI: return "FINI";
2162 case DT_SONAME: return "SONAME";
2163 case DT_RPATH: return "RPATH";
2164 case DT_SYMBOLIC: return "SYMBOLIC";
2165 case DT_REL: return "REL";
2166 case DT_RELSZ: return "RELSZ";
2167 case DT_RELENT: return "RELENT";
2168 case DT_PLTREL: return "PLTREL";
2169 case DT_DEBUG: return "DEBUG";
2170 case DT_TEXTREL: return "TEXTREL";
2171 case DT_JMPREL: return "JMPREL";
2172 case DT_BIND_NOW: return "BIND_NOW";
2173 case DT_INIT_ARRAY: return "INIT_ARRAY";
2174 case DT_FINI_ARRAY: return "FINI_ARRAY";
2175 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2176 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2177 case DT_RUNPATH: return "RUNPATH";
2178 case DT_FLAGS: return "FLAGS";
2d0e6f43 2179
d1133906
NC
2180 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2181 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2182 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2183
05107a46 2184 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2185 case DT_PLTPADSZ: return "PLTPADSZ";
2186 case DT_MOVEENT: return "MOVEENT";
2187 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2188 case DT_FEATURE: return "FEATURE";
252b5132
RH
2189 case DT_POSFLAG_1: return "POSFLAG_1";
2190 case DT_SYMINSZ: return "SYMINSZ";
2191 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2192
252b5132 2193 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2194 case DT_CONFIG: return "CONFIG";
2195 case DT_DEPAUDIT: return "DEPAUDIT";
2196 case DT_AUDIT: return "AUDIT";
2197 case DT_PLTPAD: return "PLTPAD";
2198 case DT_MOVETAB: return "MOVETAB";
252b5132 2199 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2200
252b5132 2201 case DT_VERSYM: return "VERSYM";
103f02d3 2202
67a4f2b7
AO
2203 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2204 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2205 case DT_RELACOUNT: return "RELACOUNT";
2206 case DT_RELCOUNT: return "RELCOUNT";
2207 case DT_FLAGS_1: return "FLAGS_1";
2208 case DT_VERDEF: return "VERDEF";
2209 case DT_VERDEFNUM: return "VERDEFNUM";
2210 case DT_VERNEED: return "VERNEED";
2211 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2212
019148e4 2213 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2214 case DT_USED: return "USED";
2215 case DT_FILTER: return "FILTER";
103f02d3 2216
047b2264
JJ
2217 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2218 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2219 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2220 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2221 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2222 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2223
252b5132
RH
2224 default:
2225 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2226 {
2cf0635d 2227 const char * result;
103f02d3 2228
dda8d76d 2229 switch (filedata->file_header.e_machine)
252b5132 2230 {
37c18eed
SD
2231 case EM_AARCH64:
2232 result = get_aarch64_dynamic_type (type);
2233 break;
252b5132 2234 case EM_MIPS:
4fe85591 2235 case EM_MIPS_RS3_LE:
252b5132
RH
2236 result = get_mips_dynamic_type (type);
2237 break;
9a097730
RH
2238 case EM_SPARCV9:
2239 result = get_sparc64_dynamic_type (type);
2240 break;
7490d522
AM
2241 case EM_PPC:
2242 result = get_ppc_dynamic_type (type);
2243 break;
f1cb7e17
AM
2244 case EM_PPC64:
2245 result = get_ppc64_dynamic_type (type);
2246 break;
ecc51f48
NC
2247 case EM_IA_64:
2248 result = get_ia64_dynamic_type (type);
2249 break;
fabcb361
RH
2250 case EM_ALPHA:
2251 result = get_alpha_dynamic_type (type);
2252 break;
1c0d3aa6
NC
2253 case EM_SCORE:
2254 result = get_score_dynamic_type (type);
2255 break;
40b36596
JM
2256 case EM_TI_C6000:
2257 result = get_tic6x_dynamic_type (type);
2258 break;
36591ba1
SL
2259 case EM_ALTERA_NIOS2:
2260 result = get_nios2_dynamic_type (type);
2261 break;
252b5132 2262 default:
dda8d76d 2263 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2264 result = get_solaris_dynamic_type (type);
2265 else
2266 result = NULL;
252b5132
RH
2267 break;
2268 }
2269
2270 if (result != NULL)
2271 return result;
2272
e9e44622 2273 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2274 }
eec8f817 2275 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2276 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2277 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2278 {
2cf0635d 2279 const char * result;
103f02d3 2280
dda8d76d 2281 switch (filedata->file_header.e_machine)
103f02d3
UD
2282 {
2283 case EM_PARISC:
2284 result = get_parisc_dynamic_type (type);
2285 break;
148b93f2
NC
2286 case EM_IA_64:
2287 result = get_ia64_dynamic_type (type);
2288 break;
103f02d3 2289 default:
dda8d76d 2290 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2291 result = get_solaris_dynamic_type (type);
2292 else
2293 result = NULL;
103f02d3
UD
2294 break;
2295 }
2296
2297 if (result != NULL)
2298 return result;
2299
e9e44622
JJ
2300 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2301 type);
103f02d3 2302 }
252b5132 2303 else
e9e44622 2304 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2305
252b5132
RH
2306 return buff;
2307 }
2308}
2309
2310static char *
d3ba0551 2311get_file_type (unsigned e_type)
252b5132 2312{
89246a0e 2313 static char buff[64];
252b5132
RH
2314
2315 switch (e_type)
2316 {
32ec8896
NC
2317 case ET_NONE: return _("NONE (None)");
2318 case ET_REL: return _("REL (Relocatable file)");
2319 case ET_EXEC: return _("EXEC (Executable file)");
2320 case ET_DYN: return _("DYN (Shared object file)");
2321 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2322
2323 default:
2324 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2325 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2326 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2327 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2328 else
e9e44622 2329 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2330 return buff;
2331 }
2332}
2333
2334static char *
d3ba0551 2335get_machine_name (unsigned e_machine)
252b5132 2336{
b34976b6 2337 static char buff[64]; /* XXX */
252b5132
RH
2338
2339 switch (e_machine)
2340 {
55e22ca8
NC
2341 /* Please keep this switch table sorted by increasing EM_ value. */
2342 /* 0 */
c45021f2
NC
2343 case EM_NONE: return _("None");
2344 case EM_M32: return "WE32100";
2345 case EM_SPARC: return "Sparc";
2346 case EM_386: return "Intel 80386";
2347 case EM_68K: return "MC68000";
2348 case EM_88K: return "MC88000";
22abe556 2349 case EM_IAMCU: return "Intel MCU";
fb70ec17 2350 case EM_860: return "Intel 80860";
c45021f2
NC
2351 case EM_MIPS: return "MIPS R3000";
2352 case EM_S370: return "IBM System/370";
55e22ca8 2353 /* 10 */
7036c0e1 2354 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2355 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2356 case EM_PARISC: return "HPPA";
55e22ca8 2357 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2358 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2359 case EM_960: return "Intel 80960";
c45021f2 2360 case EM_PPC: return "PowerPC";
55e22ca8 2361 /* 20 */
285d1771 2362 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2363 case EM_S390_OLD:
2364 case EM_S390: return "IBM S/390";
2365 case EM_SPU: return "SPU";
2366 /* 30 */
2367 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2368 case EM_FR20: return "Fujitsu FR20";
2369 case EM_RH32: return "TRW RH32";
b34976b6 2370 case EM_MCORE: return "MCORE";
55e22ca8 2371 /* 40 */
7036c0e1
AJ
2372 case EM_ARM: return "ARM";
2373 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2374 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2375 case EM_SPARCV9: return "Sparc v9";
2376 case EM_TRICORE: return "Siemens Tricore";
584da044 2377 case EM_ARC: return "ARC";
c2dcd04e
NC
2378 case EM_H8_300: return "Renesas H8/300";
2379 case EM_H8_300H: return "Renesas H8/300H";
2380 case EM_H8S: return "Renesas H8S";
2381 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2382 /* 50 */
30800947 2383 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2384 case EM_MIPS_X: return "Stanford MIPS-X";
2385 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2386 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2387 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2388 case EM_PCP: return "Siemens PCP";
2389 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2390 case EM_NDR1: return "Denso NDR1 microprocesspr";
2391 case EM_STARCORE: return "Motorola Star*Core processor";
2392 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2393 /* 60 */
7036c0e1
AJ
2394 case EM_ST100: return "STMicroelectronics ST100 processor";
2395 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2396 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2397 case EM_PDSP: return "Sony DSP processor";
2398 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2399 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2400 case EM_FX66: return "Siemens FX66 microcontroller";
2401 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2402 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2403 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2404 /* 70 */
7036c0e1
AJ
2405 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2406 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2407 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2408 case EM_SVX: return "Silicon Graphics SVx";
2409 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2410 case EM_VAX: return "Digital VAX";
1b61cf92 2411 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2412 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2413 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2414 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2415 /* 80 */
b34976b6 2416 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2417 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2418 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2419 case EM_AVR_OLD:
2420 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2421 case EM_CYGNUS_FR30:
2422 case EM_FR30: return "Fujitsu FR30";
2423 case EM_CYGNUS_D10V:
2424 case EM_D10V: return "d10v";
2425 case EM_CYGNUS_D30V:
2426 case EM_D30V: return "d30v";
2427 case EM_CYGNUS_V850:
2428 case EM_V850: return "Renesas V850";
2429 case EM_CYGNUS_M32R:
2430 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2431 case EM_CYGNUS_MN10300:
2432 case EM_MN10300: return "mn10300";
2433 /* 90 */
2434 case EM_CYGNUS_MN10200:
2435 case EM_MN10200: return "mn10200";
2436 case EM_PJ: return "picoJava";
73589c9d 2437 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2438 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2439 case EM_XTENSA_OLD:
2440 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2441 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2442 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2443 case EM_NS32K: return "National Semiconductor 32000 series";
2444 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2445 case EM_SNP1K: return "Trebia SNP 1000 processor";
2446 /* 100 */
9abca702 2447 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2448 case EM_IP2K_OLD:
2449 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2450 case EM_MAX: return "MAX Processor";
2451 case EM_CR: return "National Semiconductor CompactRISC";
2452 case EM_F2MC16: return "Fujitsu F2MC16";
2453 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2454 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2455 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2456 case EM_SEP: return "Sharp embedded microprocessor";
2457 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2458 /* 110 */
11636f9e
JM
2459 case EM_UNICORE: return "Unicore";
2460 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2461 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2462 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2463 case EM_CRX: return "National Semiconductor CRX microprocessor";
2464 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2465 case EM_C166:
d70c5fc7 2466 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2467 case EM_M16C: return "Renesas M16C series microprocessors";
2468 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2469 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2470 /* 120 */
2471 case EM_M32C: return "Renesas M32c";
2472 /* 130 */
11636f9e
JM
2473 case EM_TSK3000: return "Altium TSK3000 core";
2474 case EM_RS08: return "Freescale RS08 embedded processor";
2475 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2476 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2477 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2478 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2479 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2480 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2481 /* 140 */
11636f9e
JM
2482 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2483 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2484 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2485 case EM_TI_PRU: return "TI PRU I/O processor";
2486 /* 160 */
11636f9e
JM
2487 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2488 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2489 case EM_R32C: return "Renesas R32C series microprocessors";
2490 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2491 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2492 case EM_8051: return "Intel 8051 and variants";
2493 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2494 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2495 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2496 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2497 /* 170 */
11636f9e
JM
2498 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2499 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2500 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2501 case EM_RX: return "Renesas RX";
a3c62988 2502 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2503 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2504 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2505 case EM_CR16:
2506 case EM_MICROBLAZE:
2507 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2508 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2509 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2510 /* 180 */
2511 case EM_L1OM: return "Intel L1OM";
2512 case EM_K1OM: return "Intel K1OM";
2513 case EM_INTEL182: return "Intel (reserved)";
2514 case EM_AARCH64: return "AArch64";
2515 case EM_ARM184: return "ARM (reserved)";
2516 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2517 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2518 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2519 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2520 /* 190 */
11636f9e 2521 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2522 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2523 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2524 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2525 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2526 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2527 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2528 case EM_RL78: return "Renesas RL78";
6d913794 2529 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2530 case EM_78K0R: return "Renesas 78K0R";
2531 /* 200 */
6d913794 2532 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2533 case EM_BA1: return "Beyond BA1 CPU architecture";
2534 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2535 case EM_XCORE: return "XMOS xCORE processor family";
2536 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2537 /* 210 */
6d913794
NC
2538 case EM_KM32: return "KM211 KM32 32-bit processor";
2539 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2540 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2541 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2542 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2543 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2544 case EM_COGE: return "Cognitive Smart Memory Processor";
2545 case EM_COOL: return "Bluechip Systems CoolEngine";
2546 case EM_NORC: return "Nanoradio Optimized RISC";
2547 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2548 /* 220 */
15f205b1 2549 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2550 case EM_VISIUM: return "CDS VISIUMcore processor";
2551 case EM_FT32: return "FTDI Chip FT32";
2552 case EM_MOXIE: return "Moxie";
2553 case EM_AMDGPU: return "AMD GPU";
2554 case EM_RISCV: return "RISC-V";
2555 case EM_LANAI: return "Lanai 32-bit processor";
2556 case EM_BPF: return "Linux BPF";
fe944acf 2557 case EM_NFP: return "Netronome Flow Processor";
55e22ca8
NC
2558
2559 /* Large numbers... */
2560 case EM_MT: return "Morpho Techologies MT processor";
2561 case EM_ALPHA: return "Alpha";
2562 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2563 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2564 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2565 case EM_IQ2000: return "Vitesse IQ2000";
2566 case EM_M32C_OLD:
2567 case EM_NIOS32: return "Altera Nios";
2568 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2569 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2570 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2571 case EM_S12Z: return "Freescale S12Z";
b8891f8d 2572 case EM_CSKY: return "C-SKY";
55e22ca8 2573
252b5132 2574 default:
35d9dd2f 2575 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2576 return buff;
2577 }
2578}
2579
a9522a21
AB
2580static void
2581decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2582{
2583 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2584 other compilers don't a specific architecture type in the e_flags, and
2585 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2586 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2587 architectures.
2588
2589 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2590 but also sets a specific architecture type in the e_flags field.
2591
2592 However, when decoding the flags we don't worry if we see an
2593 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2594 ARCEM architecture type. */
2595
2596 switch (e_flags & EF_ARC_MACH_MSK)
2597 {
2598 /* We only expect these to occur for EM_ARC_COMPACT2. */
2599 case EF_ARC_CPU_ARCV2EM:
2600 strcat (buf, ", ARC EM");
2601 break;
2602 case EF_ARC_CPU_ARCV2HS:
2603 strcat (buf, ", ARC HS");
2604 break;
2605
2606 /* We only expect these to occur for EM_ARC_COMPACT. */
2607 case E_ARC_MACH_ARC600:
2608 strcat (buf, ", ARC600");
2609 break;
2610 case E_ARC_MACH_ARC601:
2611 strcat (buf, ", ARC601");
2612 break;
2613 case E_ARC_MACH_ARC700:
2614 strcat (buf, ", ARC700");
2615 break;
2616
2617 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2618 new ELF with new architecture being read by an old version of
2619 readelf, or (c) An ELF built with non-GNU compiler that does not
2620 set the architecture in the e_flags. */
2621 default:
2622 if (e_machine == EM_ARC_COMPACT)
2623 strcat (buf, ", Unknown ARCompact");
2624 else
2625 strcat (buf, ", Unknown ARC");
2626 break;
2627 }
2628
2629 switch (e_flags & EF_ARC_OSABI_MSK)
2630 {
2631 case E_ARC_OSABI_ORIG:
2632 strcat (buf, ", (ABI:legacy)");
2633 break;
2634 case E_ARC_OSABI_V2:
2635 strcat (buf, ", (ABI:v2)");
2636 break;
2637 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2638 case E_ARC_OSABI_V3:
2639 strcat (buf, ", v3 no-legacy-syscalls ABI");
2640 break;
53a346d8
CZ
2641 case E_ARC_OSABI_V4:
2642 strcat (buf, ", v4 ABI");
2643 break;
a9522a21
AB
2644 default:
2645 strcat (buf, ", unrecognised ARC OSABI flag");
2646 break;
2647 }
2648}
2649
f3485b74 2650static void
d3ba0551 2651decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2652{
2653 unsigned eabi;
32ec8896 2654 bfd_boolean unknown = FALSE;
f3485b74
NC
2655
2656 eabi = EF_ARM_EABI_VERSION (e_flags);
2657 e_flags &= ~ EF_ARM_EABIMASK;
2658
2659 /* Handle "generic" ARM flags. */
2660 if (e_flags & EF_ARM_RELEXEC)
2661 {
2662 strcat (buf, ", relocatable executable");
2663 e_flags &= ~ EF_ARM_RELEXEC;
2664 }
76da6bbe 2665
18a20338
CL
2666 if (e_flags & EF_ARM_PIC)
2667 {
2668 strcat (buf, ", position independent");
2669 e_flags &= ~ EF_ARM_PIC;
2670 }
2671
f3485b74
NC
2672 /* Now handle EABI specific flags. */
2673 switch (eabi)
2674 {
2675 default:
2c71103e 2676 strcat (buf, ", <unrecognized EABI>");
f3485b74 2677 if (e_flags)
32ec8896 2678 unknown = TRUE;
f3485b74
NC
2679 break;
2680
2681 case EF_ARM_EABI_VER1:
a5bcd848 2682 strcat (buf, ", Version1 EABI");
f3485b74
NC
2683 while (e_flags)
2684 {
2685 unsigned flag;
76da6bbe 2686
f3485b74
NC
2687 /* Process flags one bit at a time. */
2688 flag = e_flags & - e_flags;
2689 e_flags &= ~ flag;
76da6bbe 2690
f3485b74
NC
2691 switch (flag)
2692 {
a5bcd848 2693 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2694 strcat (buf, ", sorted symbol tables");
2695 break;
76da6bbe 2696
f3485b74 2697 default:
32ec8896 2698 unknown = TRUE;
f3485b74
NC
2699 break;
2700 }
2701 }
2702 break;
76da6bbe 2703
a5bcd848
PB
2704 case EF_ARM_EABI_VER2:
2705 strcat (buf, ", Version2 EABI");
2706 while (e_flags)
2707 {
2708 unsigned flag;
2709
2710 /* Process flags one bit at a time. */
2711 flag = e_flags & - e_flags;
2712 e_flags &= ~ flag;
2713
2714 switch (flag)
2715 {
2716 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2717 strcat (buf, ", sorted symbol tables");
2718 break;
2719
2720 case EF_ARM_DYNSYMSUSESEGIDX:
2721 strcat (buf, ", dynamic symbols use segment index");
2722 break;
2723
2724 case EF_ARM_MAPSYMSFIRST:
2725 strcat (buf, ", mapping symbols precede others");
2726 break;
2727
2728 default:
32ec8896 2729 unknown = TRUE;
a5bcd848
PB
2730 break;
2731 }
2732 }
2733 break;
2734
d507cf36
PB
2735 case EF_ARM_EABI_VER3:
2736 strcat (buf, ", Version3 EABI");
8cb51566
PB
2737 break;
2738
2739 case EF_ARM_EABI_VER4:
2740 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2741 while (e_flags)
2742 {
2743 unsigned flag;
2744
2745 /* Process flags one bit at a time. */
2746 flag = e_flags & - e_flags;
2747 e_flags &= ~ flag;
2748
2749 switch (flag)
2750 {
2751 case EF_ARM_BE8:
2752 strcat (buf, ", BE8");
2753 break;
2754
2755 case EF_ARM_LE8:
2756 strcat (buf, ", LE8");
2757 break;
2758
2759 default:
32ec8896 2760 unknown = TRUE;
3bfcb652
NC
2761 break;
2762 }
3bfcb652
NC
2763 }
2764 break;
3a4a14e9
PB
2765
2766 case EF_ARM_EABI_VER5:
2767 strcat (buf, ", Version5 EABI");
d507cf36
PB
2768 while (e_flags)
2769 {
2770 unsigned flag;
2771
2772 /* Process flags one bit at a time. */
2773 flag = e_flags & - e_flags;
2774 e_flags &= ~ flag;
2775
2776 switch (flag)
2777 {
2778 case EF_ARM_BE8:
2779 strcat (buf, ", BE8");
2780 break;
2781
2782 case EF_ARM_LE8:
2783 strcat (buf, ", LE8");
2784 break;
2785
3bfcb652
NC
2786 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2787 strcat (buf, ", soft-float ABI");
2788 break;
2789
2790 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2791 strcat (buf, ", hard-float ABI");
2792 break;
2793
d507cf36 2794 default:
32ec8896 2795 unknown = TRUE;
d507cf36
PB
2796 break;
2797 }
2798 }
2799 break;
2800
f3485b74 2801 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2802 strcat (buf, ", GNU EABI");
f3485b74
NC
2803 while (e_flags)
2804 {
2805 unsigned flag;
76da6bbe 2806
f3485b74
NC
2807 /* Process flags one bit at a time. */
2808 flag = e_flags & - e_flags;
2809 e_flags &= ~ flag;
76da6bbe 2810
f3485b74
NC
2811 switch (flag)
2812 {
a5bcd848 2813 case EF_ARM_INTERWORK:
f3485b74
NC
2814 strcat (buf, ", interworking enabled");
2815 break;
76da6bbe 2816
a5bcd848 2817 case EF_ARM_APCS_26:
f3485b74
NC
2818 strcat (buf, ", uses APCS/26");
2819 break;
76da6bbe 2820
a5bcd848 2821 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2822 strcat (buf, ", uses APCS/float");
2823 break;
76da6bbe 2824
a5bcd848 2825 case EF_ARM_PIC:
f3485b74
NC
2826 strcat (buf, ", position independent");
2827 break;
76da6bbe 2828
a5bcd848 2829 case EF_ARM_ALIGN8:
f3485b74
NC
2830 strcat (buf, ", 8 bit structure alignment");
2831 break;
76da6bbe 2832
a5bcd848 2833 case EF_ARM_NEW_ABI:
f3485b74
NC
2834 strcat (buf, ", uses new ABI");
2835 break;
76da6bbe 2836
a5bcd848 2837 case EF_ARM_OLD_ABI:
f3485b74
NC
2838 strcat (buf, ", uses old ABI");
2839 break;
76da6bbe 2840
a5bcd848 2841 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2842 strcat (buf, ", software FP");
2843 break;
76da6bbe 2844
90e01f86
ILT
2845 case EF_ARM_VFP_FLOAT:
2846 strcat (buf, ", VFP");
2847 break;
2848
fde78edd
NC
2849 case EF_ARM_MAVERICK_FLOAT:
2850 strcat (buf, ", Maverick FP");
2851 break;
2852
f3485b74 2853 default:
32ec8896 2854 unknown = TRUE;
f3485b74
NC
2855 break;
2856 }
2857 }
2858 }
f3485b74
NC
2859
2860 if (unknown)
2b692964 2861 strcat (buf,_(", <unknown>"));
f3485b74
NC
2862}
2863
343433df
AB
2864static void
2865decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2866{
2867 --size; /* Leave space for null terminator. */
2868
2869 switch (e_flags & EF_AVR_MACH)
2870 {
2871 case E_AVR_MACH_AVR1:
2872 strncat (buf, ", avr:1", size);
2873 break;
2874 case E_AVR_MACH_AVR2:
2875 strncat (buf, ", avr:2", size);
2876 break;
2877 case E_AVR_MACH_AVR25:
2878 strncat (buf, ", avr:25", size);
2879 break;
2880 case E_AVR_MACH_AVR3:
2881 strncat (buf, ", avr:3", size);
2882 break;
2883 case E_AVR_MACH_AVR31:
2884 strncat (buf, ", avr:31", size);
2885 break;
2886 case E_AVR_MACH_AVR35:
2887 strncat (buf, ", avr:35", size);
2888 break;
2889 case E_AVR_MACH_AVR4:
2890 strncat (buf, ", avr:4", size);
2891 break;
2892 case E_AVR_MACH_AVR5:
2893 strncat (buf, ", avr:5", size);
2894 break;
2895 case E_AVR_MACH_AVR51:
2896 strncat (buf, ", avr:51", size);
2897 break;
2898 case E_AVR_MACH_AVR6:
2899 strncat (buf, ", avr:6", size);
2900 break;
2901 case E_AVR_MACH_AVRTINY:
2902 strncat (buf, ", avr:100", size);
2903 break;
2904 case E_AVR_MACH_XMEGA1:
2905 strncat (buf, ", avr:101", size);
2906 break;
2907 case E_AVR_MACH_XMEGA2:
2908 strncat (buf, ", avr:102", size);
2909 break;
2910 case E_AVR_MACH_XMEGA3:
2911 strncat (buf, ", avr:103", size);
2912 break;
2913 case E_AVR_MACH_XMEGA4:
2914 strncat (buf, ", avr:104", size);
2915 break;
2916 case E_AVR_MACH_XMEGA5:
2917 strncat (buf, ", avr:105", size);
2918 break;
2919 case E_AVR_MACH_XMEGA6:
2920 strncat (buf, ", avr:106", size);
2921 break;
2922 case E_AVR_MACH_XMEGA7:
2923 strncat (buf, ", avr:107", size);
2924 break;
2925 default:
2926 strncat (buf, ", avr:<unknown>", size);
2927 break;
2928 }
2929
2930 size -= strlen (buf);
2931 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2932 strncat (buf, ", link-relax", size);
2933}
2934
35c08157
KLC
2935static void
2936decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2937{
2938 unsigned abi;
2939 unsigned arch;
2940 unsigned config;
2941 unsigned version;
32ec8896
NC
2942 bfd_boolean has_fpu = FALSE;
2943 unsigned int r = 0;
35c08157
KLC
2944
2945 static const char *ABI_STRINGS[] =
2946 {
2947 "ABI v0", /* use r5 as return register; only used in N1213HC */
2948 "ABI v1", /* use r0 as return register */
2949 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2950 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2951 "AABI",
2952 "ABI2 FP+"
35c08157
KLC
2953 };
2954 static const char *VER_STRINGS[] =
2955 {
2956 "Andes ELF V1.3 or older",
2957 "Andes ELF V1.3.1",
2958 "Andes ELF V1.4"
2959 };
2960 static const char *ARCH_STRINGS[] =
2961 {
2962 "",
2963 "Andes Star v1.0",
2964 "Andes Star v2.0",
2965 "Andes Star v3.0",
2966 "Andes Star v3.0m"
2967 };
2968
2969 abi = EF_NDS_ABI & e_flags;
2970 arch = EF_NDS_ARCH & e_flags;
2971 config = EF_NDS_INST & e_flags;
2972 version = EF_NDS32_ELF_VERSION & e_flags;
2973
2974 memset (buf, 0, size);
2975
2976 switch (abi)
2977 {
2978 case E_NDS_ABI_V0:
2979 case E_NDS_ABI_V1:
2980 case E_NDS_ABI_V2:
2981 case E_NDS_ABI_V2FP:
2982 case E_NDS_ABI_AABI:
40c7a7cb 2983 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2984 /* In case there are holes in the array. */
2985 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2986 break;
2987
2988 default:
2989 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2990 break;
2991 }
2992
2993 switch (version)
2994 {
2995 case E_NDS32_ELF_VER_1_2:
2996 case E_NDS32_ELF_VER_1_3:
2997 case E_NDS32_ELF_VER_1_4:
2998 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2999 break;
3000
3001 default:
3002 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3003 break;
3004 }
3005
3006 if (E_NDS_ABI_V0 == abi)
3007 {
3008 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3009 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3010 if (arch == E_NDS_ARCH_STAR_V1_0)
3011 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3012 return;
3013 }
3014
3015 switch (arch)
3016 {
3017 case E_NDS_ARCH_STAR_V1_0:
3018 case E_NDS_ARCH_STAR_V2_0:
3019 case E_NDS_ARCH_STAR_V3_0:
3020 case E_NDS_ARCH_STAR_V3_M:
3021 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3022 break;
3023
3024 default:
3025 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3026 /* ARCH version determines how the e_flags are interpreted.
3027 If it is unknown, we cannot proceed. */
3028 return;
3029 }
3030
3031 /* Newer ABI; Now handle architecture specific flags. */
3032 if (arch == E_NDS_ARCH_STAR_V1_0)
3033 {
3034 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3035 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3036
3037 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3038 r += snprintf (buf + r, size -r, ", MAC");
3039
3040 if (config & E_NDS32_HAS_DIV_INST)
3041 r += snprintf (buf + r, size -r, ", DIV");
3042
3043 if (config & E_NDS32_HAS_16BIT_INST)
3044 r += snprintf (buf + r, size -r, ", 16b");
3045 }
3046 else
3047 {
3048 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3049 {
3050 if (version <= E_NDS32_ELF_VER_1_3)
3051 r += snprintf (buf + r, size -r, ", [B8]");
3052 else
3053 r += snprintf (buf + r, size -r, ", EX9");
3054 }
3055
3056 if (config & E_NDS32_HAS_MAC_DX_INST)
3057 r += snprintf (buf + r, size -r, ", MAC_DX");
3058
3059 if (config & E_NDS32_HAS_DIV_DX_INST)
3060 r += snprintf (buf + r, size -r, ", DIV_DX");
3061
3062 if (config & E_NDS32_HAS_16BIT_INST)
3063 {
3064 if (version <= E_NDS32_ELF_VER_1_3)
3065 r += snprintf (buf + r, size -r, ", 16b");
3066 else
3067 r += snprintf (buf + r, size -r, ", IFC");
3068 }
3069 }
3070
3071 if (config & E_NDS32_HAS_EXT_INST)
3072 r += snprintf (buf + r, size -r, ", PERF1");
3073
3074 if (config & E_NDS32_HAS_EXT2_INST)
3075 r += snprintf (buf + r, size -r, ", PERF2");
3076
3077 if (config & E_NDS32_HAS_FPU_INST)
3078 {
32ec8896 3079 has_fpu = TRUE;
35c08157
KLC
3080 r += snprintf (buf + r, size -r, ", FPU_SP");
3081 }
3082
3083 if (config & E_NDS32_HAS_FPU_DP_INST)
3084 {
32ec8896 3085 has_fpu = TRUE;
35c08157
KLC
3086 r += snprintf (buf + r, size -r, ", FPU_DP");
3087 }
3088
3089 if (config & E_NDS32_HAS_FPU_MAC_INST)
3090 {
32ec8896 3091 has_fpu = TRUE;
35c08157
KLC
3092 r += snprintf (buf + r, size -r, ", FPU_MAC");
3093 }
3094
3095 if (has_fpu)
3096 {
3097 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3098 {
3099 case E_NDS32_FPU_REG_8SP_4DP:
3100 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3101 break;
3102 case E_NDS32_FPU_REG_16SP_8DP:
3103 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3104 break;
3105 case E_NDS32_FPU_REG_32SP_16DP:
3106 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3107 break;
3108 case E_NDS32_FPU_REG_32SP_32DP:
3109 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3110 break;
3111 }
3112 }
3113
3114 if (config & E_NDS32_HAS_AUDIO_INST)
3115 r += snprintf (buf + r, size -r, ", AUDIO");
3116
3117 if (config & E_NDS32_HAS_STRING_INST)
3118 r += snprintf (buf + r, size -r, ", STR");
3119
3120 if (config & E_NDS32_HAS_REDUCED_REGS)
3121 r += snprintf (buf + r, size -r, ", 16REG");
3122
3123 if (config & E_NDS32_HAS_VIDEO_INST)
3124 {
3125 if (version <= E_NDS32_ELF_VER_1_3)
3126 r += snprintf (buf + r, size -r, ", VIDEO");
3127 else
3128 r += snprintf (buf + r, size -r, ", SATURATION");
3129 }
3130
3131 if (config & E_NDS32_HAS_ENCRIPT_INST)
3132 r += snprintf (buf + r, size -r, ", ENCRP");
3133
3134 if (config & E_NDS32_HAS_L2C_INST)
3135 r += snprintf (buf + r, size -r, ", L2C");
3136}
3137
252b5132 3138static char *
dda8d76d 3139get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3140{
b34976b6 3141 static char buf[1024];
252b5132
RH
3142
3143 buf[0] = '\0';
76da6bbe 3144
252b5132
RH
3145 if (e_flags)
3146 {
3147 switch (e_machine)
3148 {
3149 default:
3150 break;
3151
886a2506 3152 case EM_ARC_COMPACT2:
886a2506 3153 case EM_ARC_COMPACT:
a9522a21
AB
3154 decode_ARC_machine_flags (e_flags, e_machine, buf);
3155 break;
886a2506 3156
f3485b74
NC
3157 case EM_ARM:
3158 decode_ARM_machine_flags (e_flags, buf);
3159 break;
76da6bbe 3160
343433df
AB
3161 case EM_AVR:
3162 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3163 break;
3164
781303ce
MF
3165 case EM_BLACKFIN:
3166 if (e_flags & EF_BFIN_PIC)
3167 strcat (buf, ", PIC");
3168
3169 if (e_flags & EF_BFIN_FDPIC)
3170 strcat (buf, ", FDPIC");
3171
3172 if (e_flags & EF_BFIN_CODE_IN_L1)
3173 strcat (buf, ", code in L1");
3174
3175 if (e_flags & EF_BFIN_DATA_IN_L1)
3176 strcat (buf, ", data in L1");
3177
3178 break;
3179
ec2dfb42
AO
3180 case EM_CYGNUS_FRV:
3181 switch (e_flags & EF_FRV_CPU_MASK)
3182 {
3183 case EF_FRV_CPU_GENERIC:
3184 break;
3185
3186 default:
3187 strcat (buf, ", fr???");
3188 break;
57346661 3189
ec2dfb42
AO
3190 case EF_FRV_CPU_FR300:
3191 strcat (buf, ", fr300");
3192 break;
3193
3194 case EF_FRV_CPU_FR400:
3195 strcat (buf, ", fr400");
3196 break;
3197 case EF_FRV_CPU_FR405:
3198 strcat (buf, ", fr405");
3199 break;
3200
3201 case EF_FRV_CPU_FR450:
3202 strcat (buf, ", fr450");
3203 break;
3204
3205 case EF_FRV_CPU_FR500:
3206 strcat (buf, ", fr500");
3207 break;
3208 case EF_FRV_CPU_FR550:
3209 strcat (buf, ", fr550");
3210 break;
3211
3212 case EF_FRV_CPU_SIMPLE:
3213 strcat (buf, ", simple");
3214 break;
3215 case EF_FRV_CPU_TOMCAT:
3216 strcat (buf, ", tomcat");
3217 break;
3218 }
1c877e87 3219 break;
ec2dfb42 3220
53c7db4b 3221 case EM_68K:
425c6cb0 3222 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3223 strcat (buf, ", m68000");
425c6cb0 3224 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3225 strcat (buf, ", cpu32");
3226 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3227 strcat (buf, ", fido_a");
425c6cb0 3228 else
266abb8f 3229 {
2cf0635d
NC
3230 char const * isa = _("unknown");
3231 char const * mac = _("unknown mac");
3232 char const * additional = NULL;
0112cd26 3233
c694fd50 3234 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3235 {
c694fd50 3236 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3237 isa = "A";
3238 additional = ", nodiv";
3239 break;
c694fd50 3240 case EF_M68K_CF_ISA_A:
266abb8f
NS
3241 isa = "A";
3242 break;
c694fd50 3243 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3244 isa = "A+";
3245 break;
c694fd50 3246 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3247 isa = "B";
3248 additional = ", nousp";
3249 break;
c694fd50 3250 case EF_M68K_CF_ISA_B:
266abb8f
NS
3251 isa = "B";
3252 break;
f608cd77
NS
3253 case EF_M68K_CF_ISA_C:
3254 isa = "C";
3255 break;
3256 case EF_M68K_CF_ISA_C_NODIV:
3257 isa = "C";
3258 additional = ", nodiv";
3259 break;
266abb8f
NS
3260 }
3261 strcat (buf, ", cf, isa ");
3262 strcat (buf, isa);
0b2e31dc
NS
3263 if (additional)
3264 strcat (buf, additional);
c694fd50 3265 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3266 strcat (buf, ", float");
c694fd50 3267 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3268 {
3269 case 0:
3270 mac = NULL;
3271 break;
c694fd50 3272 case EF_M68K_CF_MAC:
266abb8f
NS
3273 mac = "mac";
3274 break;
c694fd50 3275 case EF_M68K_CF_EMAC:
266abb8f
NS
3276 mac = "emac";
3277 break;
f608cd77
NS
3278 case EF_M68K_CF_EMAC_B:
3279 mac = "emac_b";
3280 break;
266abb8f
NS
3281 }
3282 if (mac)
3283 {
3284 strcat (buf, ", ");
3285 strcat (buf, mac);
3286 }
266abb8f 3287 }
53c7db4b 3288 break;
33c63f9d 3289
153a2776
NC
3290 case EM_CYGNUS_MEP:
3291 switch (e_flags & EF_MEP_CPU_MASK)
3292 {
3293 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3294 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3295 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3296 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3297 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3298 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3299 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3300 }
3301
3302 switch (e_flags & EF_MEP_COP_MASK)
3303 {
3304 case EF_MEP_COP_NONE: break;
3305 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3306 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3307 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3308 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3309 default: strcat (buf, _("<unknown MeP copro type>")); break;
3310 }
3311
3312 if (e_flags & EF_MEP_LIBRARY)
3313 strcat (buf, ", Built for Library");
3314
3315 if (e_flags & EF_MEP_INDEX_MASK)
3316 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3317 e_flags & EF_MEP_INDEX_MASK);
3318
3319 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3320 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3321 e_flags & ~ EF_MEP_ALL_FLAGS);
3322 break;
3323
252b5132
RH
3324 case EM_PPC:
3325 if (e_flags & EF_PPC_EMB)
3326 strcat (buf, ", emb");
3327
3328 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3329 strcat (buf, _(", relocatable"));
252b5132
RH
3330
3331 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3332 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3333 break;
3334
ee67d69a
AM
3335 case EM_PPC64:
3336 if (e_flags & EF_PPC64_ABI)
3337 {
3338 char abi[] = ", abiv0";
3339
3340 abi[6] += e_flags & EF_PPC64_ABI;
3341 strcat (buf, abi);
3342 }
3343 break;
3344
708e2187
NC
3345 case EM_V800:
3346 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3347 strcat (buf, ", RH850 ABI");
0b4362b0 3348
708e2187
NC
3349 if (e_flags & EF_V800_850E3)
3350 strcat (buf, ", V3 architecture");
3351
3352 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3353 strcat (buf, ", FPU not used");
3354
3355 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3356 strcat (buf, ", regmode: COMMON");
3357
3358 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3359 strcat (buf, ", r4 not used");
3360
3361 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3362 strcat (buf, ", r30 not used");
3363
3364 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3365 strcat (buf, ", r5 not used");
3366
3367 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3368 strcat (buf, ", r2 not used");
3369
3370 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3371 {
3372 switch (e_flags & - e_flags)
3373 {
3374 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3375 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3376 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3377 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3378 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3379 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3380 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3381 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3382 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3383 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3384 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3385 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3386 default: break;
3387 }
3388 }
3389 break;
3390
2b0337b0 3391 case EM_V850:
252b5132
RH
3392 case EM_CYGNUS_V850:
3393 switch (e_flags & EF_V850_ARCH)
3394 {
78c8d46c
NC
3395 case E_V850E3V5_ARCH:
3396 strcat (buf, ", v850e3v5");
3397 break;
1cd986c5
NC
3398 case E_V850E2V3_ARCH:
3399 strcat (buf, ", v850e2v3");
3400 break;
3401 case E_V850E2_ARCH:
3402 strcat (buf, ", v850e2");
3403 break;
3404 case E_V850E1_ARCH:
3405 strcat (buf, ", v850e1");
8ad30312 3406 break;
252b5132
RH
3407 case E_V850E_ARCH:
3408 strcat (buf, ", v850e");
3409 break;
252b5132
RH
3410 case E_V850_ARCH:
3411 strcat (buf, ", v850");
3412 break;
3413 default:
2b692964 3414 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3415 break;
3416 }
3417 break;
3418
2b0337b0 3419 case EM_M32R:
252b5132
RH
3420 case EM_CYGNUS_M32R:
3421 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3422 strcat (buf, ", m32r");
252b5132
RH
3423 break;
3424
3425 case EM_MIPS:
4fe85591 3426 case EM_MIPS_RS3_LE:
252b5132
RH
3427 if (e_flags & EF_MIPS_NOREORDER)
3428 strcat (buf, ", noreorder");
3429
3430 if (e_flags & EF_MIPS_PIC)
3431 strcat (buf, ", pic");
3432
3433 if (e_flags & EF_MIPS_CPIC)
3434 strcat (buf, ", cpic");
3435
d1bdd336
TS
3436 if (e_flags & EF_MIPS_UCODE)
3437 strcat (buf, ", ugen_reserved");
3438
252b5132
RH
3439 if (e_flags & EF_MIPS_ABI2)
3440 strcat (buf, ", abi2");
3441
43521d43
TS
3442 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3443 strcat (buf, ", odk first");
3444
a5d22d2a
TS
3445 if (e_flags & EF_MIPS_32BITMODE)
3446 strcat (buf, ", 32bitmode");
3447
ba92f887
MR
3448 if (e_flags & EF_MIPS_NAN2008)
3449 strcat (buf, ", nan2008");
3450
fef1b0b3
SE
3451 if (e_flags & EF_MIPS_FP64)
3452 strcat (buf, ", fp64");
3453
156c2f8b
NC
3454 switch ((e_flags & EF_MIPS_MACH))
3455 {
3456 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3457 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3458 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3459 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3460 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3461 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3462 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3463 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3464 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3465 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3466 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3467 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3468 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3469 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3470 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3471 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3472 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3473 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3474 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3475 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3476 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3477 case 0:
3478 /* We simply ignore the field in this case to avoid confusion:
3479 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3480 extension. */
3481 break;
2b692964 3482 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3483 }
43521d43
TS
3484
3485 switch ((e_flags & EF_MIPS_ABI))
3486 {
3487 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3488 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3489 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3490 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3491 case 0:
3492 /* We simply ignore the field in this case to avoid confusion:
3493 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3494 This means it is likely to be an o32 file, but not for
3495 sure. */
3496 break;
2b692964 3497 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3498 }
3499
3500 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3501 strcat (buf, ", mdmx");
3502
3503 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3504 strcat (buf, ", mips16");
3505
df58fc94
RS
3506 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3507 strcat (buf, ", micromips");
3508
43521d43
TS
3509 switch ((e_flags & EF_MIPS_ARCH))
3510 {
3511 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3512 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3513 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3514 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3515 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3516 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3517 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3518 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3519 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3520 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3521 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3522 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3523 }
252b5132 3524 break;
351b4b40 3525
35c08157
KLC
3526 case EM_NDS32:
3527 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3528 break;
3529
fe944acf
FT
3530 case EM_NFP:
3531 switch (EF_NFP_MACH (e_flags))
3532 {
3533 case E_NFP_MACH_3200:
3534 strcat (buf, ", NFP-32xx");
3535 break;
3536 case E_NFP_MACH_6000:
3537 strcat (buf, ", NFP-6xxx");
3538 break;
3539 }
3540 break;
3541
e23eba97
NC
3542 case EM_RISCV:
3543 if (e_flags & EF_RISCV_RVC)
3544 strcat (buf, ", RVC");
2922d21d 3545
7f999549
JW
3546 if (e_flags & EF_RISCV_RVE)
3547 strcat (buf, ", RVE");
3548
2922d21d
AW
3549 switch (e_flags & EF_RISCV_FLOAT_ABI)
3550 {
3551 case EF_RISCV_FLOAT_ABI_SOFT:
3552 strcat (buf, ", soft-float ABI");
3553 break;
3554
3555 case EF_RISCV_FLOAT_ABI_SINGLE:
3556 strcat (buf, ", single-float ABI");
3557 break;
3558
3559 case EF_RISCV_FLOAT_ABI_DOUBLE:
3560 strcat (buf, ", double-float ABI");
3561 break;
3562
3563 case EF_RISCV_FLOAT_ABI_QUAD:
3564 strcat (buf, ", quad-float ABI");
3565 break;
3566 }
e23eba97
NC
3567 break;
3568
ccde1100
AO
3569 case EM_SH:
3570 switch ((e_flags & EF_SH_MACH_MASK))
3571 {
3572 case EF_SH1: strcat (buf, ", sh1"); break;
3573 case EF_SH2: strcat (buf, ", sh2"); break;
3574 case EF_SH3: strcat (buf, ", sh3"); break;
3575 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3576 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3577 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3578 case EF_SH3E: strcat (buf, ", sh3e"); break;
3579 case EF_SH4: strcat (buf, ", sh4"); break;
3580 case EF_SH5: strcat (buf, ", sh5"); break;
3581 case EF_SH2E: strcat (buf, ", sh2e"); break;
3582 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3583 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3584 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3585 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3586 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3587 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3588 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3589 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3590 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3591 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3592 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3593 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3594 }
3595
cec6a5b8
MR
3596 if (e_flags & EF_SH_PIC)
3597 strcat (buf, ", pic");
3598
3599 if (e_flags & EF_SH_FDPIC)
3600 strcat (buf, ", fdpic");
ccde1100 3601 break;
948f632f 3602
73589c9d
CS
3603 case EM_OR1K:
3604 if (e_flags & EF_OR1K_NODELAY)
3605 strcat (buf, ", no delay");
3606 break;
57346661 3607
351b4b40
RH
3608 case EM_SPARCV9:
3609 if (e_flags & EF_SPARC_32PLUS)
3610 strcat (buf, ", v8+");
3611
3612 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3613 strcat (buf, ", ultrasparcI");
3614
3615 if (e_flags & EF_SPARC_SUN_US3)
3616 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3617
3618 if (e_flags & EF_SPARC_HAL_R1)
3619 strcat (buf, ", halr1");
3620
3621 if (e_flags & EF_SPARC_LEDATA)
3622 strcat (buf, ", ledata");
3623
3624 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3625 strcat (buf, ", tso");
3626
3627 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3628 strcat (buf, ", pso");
3629
3630 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3631 strcat (buf, ", rmo");
3632 break;
7d466069 3633
103f02d3
UD
3634 case EM_PARISC:
3635 switch (e_flags & EF_PARISC_ARCH)
3636 {
3637 case EFA_PARISC_1_0:
3638 strcpy (buf, ", PA-RISC 1.0");
3639 break;
3640 case EFA_PARISC_1_1:
3641 strcpy (buf, ", PA-RISC 1.1");
3642 break;
3643 case EFA_PARISC_2_0:
3644 strcpy (buf, ", PA-RISC 2.0");
3645 break;
3646 default:
3647 break;
3648 }
3649 if (e_flags & EF_PARISC_TRAPNIL)
3650 strcat (buf, ", trapnil");
3651 if (e_flags & EF_PARISC_EXT)
3652 strcat (buf, ", ext");
3653 if (e_flags & EF_PARISC_LSB)
3654 strcat (buf, ", lsb");
3655 if (e_flags & EF_PARISC_WIDE)
3656 strcat (buf, ", wide");
3657 if (e_flags & EF_PARISC_NO_KABP)
3658 strcat (buf, ", no kabp");
3659 if (e_flags & EF_PARISC_LAZYSWAP)
3660 strcat (buf, ", lazyswap");
30800947 3661 break;
76da6bbe 3662
7d466069 3663 case EM_PJ:
2b0337b0 3664 case EM_PJ_OLD:
7d466069
ILT
3665 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3666 strcat (buf, ", new calling convention");
3667
3668 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3669 strcat (buf, ", gnu calling convention");
3670 break;
4d6ed7c8
NC
3671
3672 case EM_IA_64:
3673 if ((e_flags & EF_IA_64_ABI64))
3674 strcat (buf, ", 64-bit");
3675 else
3676 strcat (buf, ", 32-bit");
3677 if ((e_flags & EF_IA_64_REDUCEDFP))
3678 strcat (buf, ", reduced fp model");
3679 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3680 strcat (buf, ", no function descriptors, constant gp");
3681 else if ((e_flags & EF_IA_64_CONS_GP))
3682 strcat (buf, ", constant gp");
3683 if ((e_flags & EF_IA_64_ABSOLUTE))
3684 strcat (buf, ", absolute");
dda8d76d 3685 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3686 {
3687 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3688 strcat (buf, ", vms_linkages");
3689 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3690 {
3691 case EF_IA_64_VMS_COMCOD_SUCCESS:
3692 break;
3693 case EF_IA_64_VMS_COMCOD_WARNING:
3694 strcat (buf, ", warning");
3695 break;
3696 case EF_IA_64_VMS_COMCOD_ERROR:
3697 strcat (buf, ", error");
3698 break;
3699 case EF_IA_64_VMS_COMCOD_ABORT:
3700 strcat (buf, ", abort");
3701 break;
3702 default:
bee0ee85
NC
3703 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3704 e_flags & EF_IA_64_VMS_COMCOD);
3705 strcat (buf, ", <unknown>");
28f997cf
TG
3706 }
3707 }
4d6ed7c8 3708 break;
179d3252
JT
3709
3710 case EM_VAX:
3711 if ((e_flags & EF_VAX_NONPIC))
3712 strcat (buf, ", non-PIC");
3713 if ((e_flags & EF_VAX_DFLOAT))
3714 strcat (buf, ", D-Float");
3715 if ((e_flags & EF_VAX_GFLOAT))
3716 strcat (buf, ", G-Float");
3717 break;
c7927a3c 3718
619ed720
EB
3719 case EM_VISIUM:
3720 if (e_flags & EF_VISIUM_ARCH_MCM)
3721 strcat (buf, ", mcm");
3722 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3723 strcat (buf, ", mcm24");
3724 if (e_flags & EF_VISIUM_ARCH_GR6)
3725 strcat (buf, ", gr6");
3726 break;
3727
4046d87a 3728 case EM_RL78:
1740ba0c
NC
3729 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3730 {
3731 case E_FLAG_RL78_ANY_CPU: break;
3732 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3733 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3734 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3735 }
856ea05c
KP
3736 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3737 strcat (buf, ", 64-bit doubles");
4046d87a 3738 break;
0b4362b0 3739
c7927a3c
NC
3740 case EM_RX:
3741 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3742 strcat (buf, ", 64-bit doubles");
3743 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3744 strcat (buf, ", dsp");
d4cb0ea0 3745 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3746 strcat (buf, ", pid");
708e2187
NC
3747 if (e_flags & E_FLAG_RX_ABI)
3748 strcat (buf, ", RX ABI");
3525236c
NC
3749 if (e_flags & E_FLAG_RX_SINSNS_SET)
3750 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3751 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3752 if (e_flags & E_FLAG_RX_V2)
3753 strcat (buf, ", V2");
f87673e0
YS
3754 if (e_flags & E_FLAG_RX_V3)
3755 strcat (buf, ", V3");
d4cb0ea0 3756 break;
55786da2
AK
3757
3758 case EM_S390:
3759 if (e_flags & EF_S390_HIGH_GPRS)
3760 strcat (buf, ", highgprs");
d4cb0ea0 3761 break;
40b36596
JM
3762
3763 case EM_TI_C6000:
3764 if ((e_flags & EF_C6000_REL))
3765 strcat (buf, ", relocatable module");
d4cb0ea0 3766 break;
13761a11
NC
3767
3768 case EM_MSP430:
3769 strcat (buf, _(": architecture variant: "));
3770 switch (e_flags & EF_MSP430_MACH)
3771 {
3772 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3773 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3774 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3775 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3776 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3777 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3778 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3779 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3780 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3781 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3782 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3783 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3784 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3785 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3786 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3787 default:
3788 strcat (buf, _(": unknown")); break;
3789 }
3790
3791 if (e_flags & ~ EF_MSP430_MACH)
3792 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3793 break;
3794
3795 case EM_Z80:
3796 switch (e_flags & EF_Z80_MACH_MSK)
3797 {
3798 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3799 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3800 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3801 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3802 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3803 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3804 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3805 default:
3806 strcat (buf, _(", unknown")); break;
3807 }
3808 break;
252b5132
RH
3809 }
3810 }
3811
3812 return buf;
3813}
3814
252b5132 3815static const char *
dda8d76d 3816get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3817{
3818 static char buff[32];
3819
3820 switch (osabi)
3821 {
3822 case ELFOSABI_NONE: return "UNIX - System V";
3823 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3824 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3825 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3826 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3827 case ELFOSABI_AIX: return "UNIX - AIX";
3828 case ELFOSABI_IRIX: return "UNIX - IRIX";
3829 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3830 case ELFOSABI_TRU64: return "UNIX - TRU64";
3831 case ELFOSABI_MODESTO: return "Novell - Modesto";
3832 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3833 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3834 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3835 case ELFOSABI_AROS: return "AROS";
11636f9e 3836 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3837 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3838 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3839 default:
40b36596 3840 if (osabi >= 64)
dda8d76d 3841 switch (filedata->file_header.e_machine)
40b36596
JM
3842 {
3843 case EM_ARM:
3844 switch (osabi)
3845 {
3846 case ELFOSABI_ARM: return "ARM";
18a20338 3847 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3848 default:
3849 break;
3850 }
3851 break;
3852
3853 case EM_MSP430:
3854 case EM_MSP430_OLD:
619ed720 3855 case EM_VISIUM:
40b36596
JM
3856 switch (osabi)
3857 {
3858 case ELFOSABI_STANDALONE: return _("Standalone App");
3859 default:
3860 break;
3861 }
3862 break;
3863
3864 case EM_TI_C6000:
3865 switch (osabi)
3866 {
3867 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3868 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3869 default:
3870 break;
3871 }
3872 break;
3873
3874 default:
3875 break;
3876 }
e9e44622 3877 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3878 return buff;
3879 }
3880}
3881
a06ea964
NC
3882static const char *
3883get_aarch64_segment_type (unsigned long type)
3884{
3885 switch (type)
3886 {
32ec8896
NC
3887 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3888 default: return NULL;
a06ea964 3889 }
a06ea964
NC
3890}
3891
b294bdf8
MM
3892static const char *
3893get_arm_segment_type (unsigned long type)
3894{
3895 switch (type)
3896 {
32ec8896
NC
3897 case PT_ARM_EXIDX: return "EXIDX";
3898 default: return NULL;
b294bdf8 3899 }
b294bdf8
MM
3900}
3901
b4cbbe8f
AK
3902static const char *
3903get_s390_segment_type (unsigned long type)
3904{
3905 switch (type)
3906 {
3907 case PT_S390_PGSTE: return "S390_PGSTE";
3908 default: return NULL;
3909 }
3910}
3911
d3ba0551
AM
3912static const char *
3913get_mips_segment_type (unsigned long type)
252b5132
RH
3914{
3915 switch (type)
3916 {
32ec8896
NC
3917 case PT_MIPS_REGINFO: return "REGINFO";
3918 case PT_MIPS_RTPROC: return "RTPROC";
3919 case PT_MIPS_OPTIONS: return "OPTIONS";
3920 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3921 default: return NULL;
252b5132 3922 }
252b5132
RH
3923}
3924
103f02d3 3925static const char *
d3ba0551 3926get_parisc_segment_type (unsigned long type)
103f02d3
UD
3927{
3928 switch (type)
3929 {
103f02d3
UD
3930 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3931 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3932 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3933 default: return NULL;
103f02d3 3934 }
103f02d3
UD
3935}
3936
4d6ed7c8 3937static const char *
d3ba0551 3938get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3939{
3940 switch (type)
3941 {
3942 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3943 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3944 default: return NULL;
4d6ed7c8 3945 }
4d6ed7c8
NC
3946}
3947
40b36596
JM
3948static const char *
3949get_tic6x_segment_type (unsigned long type)
3950{
3951 switch (type)
3952 {
32ec8896
NC
3953 case PT_C6000_PHATTR: return "C6000_PHATTR";
3954 default: return NULL;
40b36596 3955 }
40b36596
JM
3956}
3957
df3a023b
AM
3958static const char *
3959get_hpux_segment_type (unsigned long type, unsigned e_machine)
3960{
3961 if (e_machine == EM_PARISC)
3962 switch (type)
3963 {
3964 case PT_HP_TLS: return "HP_TLS";
3965 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3966 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3967 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3968 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3969 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3970 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3971 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3972 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3973 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3974 case PT_HP_PARALLEL: return "HP_PARALLEL";
3975 case PT_HP_FASTBIND: return "HP_FASTBIND";
3976 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3977 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3978 case PT_HP_STACK: return "HP_STACK";
3979 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
3980 default: return NULL;
3981 }
3982
3983 if (e_machine == EM_IA_64)
3984 switch (type)
3985 {
3986 case PT_HP_TLS: return "HP_TLS";
3987 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3988 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3989 case PT_IA_64_HP_STACK: return "HP_STACK";
3990 default: return NULL;
3991 }
3992
3993 return NULL;
3994}
3995
5522f910
NC
3996static const char *
3997get_solaris_segment_type (unsigned long type)
3998{
3999 switch (type)
4000 {
4001 case 0x6464e550: return "PT_SUNW_UNWIND";
4002 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4003 case 0x6ffffff7: return "PT_LOSUNW";
4004 case 0x6ffffffa: return "PT_SUNWBSS";
4005 case 0x6ffffffb: return "PT_SUNWSTACK";
4006 case 0x6ffffffc: return "PT_SUNWDTRACE";
4007 case 0x6ffffffd: return "PT_SUNWCAP";
4008 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4009 default: return NULL;
5522f910
NC
4010 }
4011}
4012
252b5132 4013static const char *
dda8d76d 4014get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4015{
b34976b6 4016 static char buff[32];
252b5132
RH
4017
4018 switch (p_type)
4019 {
b34976b6
AM
4020 case PT_NULL: return "NULL";
4021 case PT_LOAD: return "LOAD";
252b5132 4022 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4023 case PT_INTERP: return "INTERP";
4024 case PT_NOTE: return "NOTE";
4025 case PT_SHLIB: return "SHLIB";
4026 case PT_PHDR: return "PHDR";
13ae64f3 4027 case PT_TLS: return "TLS";
32ec8896 4028 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4029 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4030 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4031 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4032
3eba3ef3
NC
4033 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4034 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4035 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
4036
252b5132 4037 default:
df3a023b 4038 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4039 {
2cf0635d 4040 const char * result;
103f02d3 4041
dda8d76d 4042 switch (filedata->file_header.e_machine)
252b5132 4043 {
a06ea964
NC
4044 case EM_AARCH64:
4045 result = get_aarch64_segment_type (p_type);
4046 break;
b294bdf8
MM
4047 case EM_ARM:
4048 result = get_arm_segment_type (p_type);
4049 break;
252b5132 4050 case EM_MIPS:
4fe85591 4051 case EM_MIPS_RS3_LE:
252b5132
RH
4052 result = get_mips_segment_type (p_type);
4053 break;
103f02d3
UD
4054 case EM_PARISC:
4055 result = get_parisc_segment_type (p_type);
4056 break;
4d6ed7c8
NC
4057 case EM_IA_64:
4058 result = get_ia64_segment_type (p_type);
4059 break;
40b36596
JM
4060 case EM_TI_C6000:
4061 result = get_tic6x_segment_type (p_type);
4062 break;
b4cbbe8f
AK
4063 case EM_S390:
4064 case EM_S390_OLD:
4065 result = get_s390_segment_type (p_type);
4066 break;
252b5132
RH
4067 default:
4068 result = NULL;
4069 break;
4070 }
103f02d3 4071
252b5132
RH
4072 if (result != NULL)
4073 return result;
103f02d3 4074
1a9ccd70 4075 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4076 }
4077 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4078 {
df3a023b 4079 const char * result = NULL;
103f02d3 4080
df3a023b 4081 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4082 {
df3a023b
AM
4083 case ELFOSABI_GNU:
4084 case ELFOSABI_FREEBSD:
4085 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4086 {
4087 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4088 result = buff;
4089 }
103f02d3 4090 break;
df3a023b
AM
4091 case ELFOSABI_HPUX:
4092 result = get_hpux_segment_type (p_type,
4093 filedata->file_header.e_machine);
4094 break;
4095 case ELFOSABI_SOLARIS:
4096 result = get_solaris_segment_type (p_type);
00428cca 4097 break;
103f02d3 4098 default:
103f02d3
UD
4099 break;
4100 }
103f02d3
UD
4101 if (result != NULL)
4102 return result;
4103
1a9ccd70 4104 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4105 }
252b5132 4106 else
e9e44622 4107 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4108
4109 return buff;
4110 }
4111}
4112
53a346d8
CZ
4113static const char *
4114get_arc_section_type_name (unsigned int sh_type)
4115{
4116 switch (sh_type)
4117 {
4118 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4119 default:
4120 break;
4121 }
4122 return NULL;
4123}
4124
252b5132 4125static const char *
d3ba0551 4126get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4127{
4128 switch (sh_type)
4129 {
b34976b6
AM
4130 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4131 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4132 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4133 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4134 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4135 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4136 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4137 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4138 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4139 case SHT_MIPS_RELD: return "MIPS_RELD";
4140 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4141 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4142 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4143 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4144 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4145 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4146 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4147 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4148 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4149 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4150 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4151 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4152 case SHT_MIPS_LINE: return "MIPS_LINE";
4153 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4154 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4155 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4156 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4157 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4158 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4159 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4160 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4161 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4162 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4163 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4164 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4165 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4166 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4167 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4168 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4169 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4170 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4171 default:
4172 break;
4173 }
4174 return NULL;
4175}
4176
103f02d3 4177static const char *
d3ba0551 4178get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4179{
4180 switch (sh_type)
4181 {
4182 case SHT_PARISC_EXT: return "PARISC_EXT";
4183 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4184 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4185 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4186 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4187 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4188 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4189 default: return NULL;
103f02d3 4190 }
103f02d3
UD
4191}
4192
4d6ed7c8 4193static const char *
dda8d76d 4194get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4195{
18bd398b 4196 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4197 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4198 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4199
4d6ed7c8
NC
4200 switch (sh_type)
4201 {
148b93f2
NC
4202 case SHT_IA_64_EXT: return "IA_64_EXT";
4203 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4204 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4205 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4206 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4207 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4208 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4209 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4210 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4211 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4212 default:
4213 break;
4214 }
4215 return NULL;
4216}
4217
d2b2c203
DJ
4218static const char *
4219get_x86_64_section_type_name (unsigned int sh_type)
4220{
4221 switch (sh_type)
4222 {
4223 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4224 default: return NULL;
d2b2c203 4225 }
d2b2c203
DJ
4226}
4227
a06ea964
NC
4228static const char *
4229get_aarch64_section_type_name (unsigned int sh_type)
4230{
4231 switch (sh_type)
4232 {
32ec8896
NC
4233 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4234 default: return NULL;
a06ea964 4235 }
a06ea964
NC
4236}
4237
40a18ebd
NC
4238static const char *
4239get_arm_section_type_name (unsigned int sh_type)
4240{
4241 switch (sh_type)
4242 {
7f6fed87
NC
4243 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4244 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4245 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4246 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4247 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4248 default: return NULL;
40a18ebd 4249 }
40a18ebd
NC
4250}
4251
40b36596
JM
4252static const char *
4253get_tic6x_section_type_name (unsigned int sh_type)
4254{
4255 switch (sh_type)
4256 {
32ec8896
NC
4257 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4258 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4259 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4260 case SHT_TI_ICODE: return "TI_ICODE";
4261 case SHT_TI_XREF: return "TI_XREF";
4262 case SHT_TI_HANDLER: return "TI_HANDLER";
4263 case SHT_TI_INITINFO: return "TI_INITINFO";
4264 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4265 default: return NULL;
40b36596 4266 }
40b36596
JM
4267}
4268
13761a11
NC
4269static const char *
4270get_msp430x_section_type_name (unsigned int sh_type)
4271{
4272 switch (sh_type)
4273 {
32ec8896
NC
4274 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4275 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4276 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4277 default: return NULL;
13761a11
NC
4278 }
4279}
4280
fe944acf
FT
4281static const char *
4282get_nfp_section_type_name (unsigned int sh_type)
4283{
4284 switch (sh_type)
4285 {
4286 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4287 case SHT_NFP_INITREG: return "NFP_INITREG";
4288 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4289 default: return NULL;
4290 }
4291}
4292
685080f2
NC
4293static const char *
4294get_v850_section_type_name (unsigned int sh_type)
4295{
4296 switch (sh_type)
4297 {
32ec8896
NC
4298 case SHT_V850_SCOMMON: return "V850 Small Common";
4299 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4300 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4301 case SHT_RENESAS_IOP: return "RENESAS IOP";
4302 case SHT_RENESAS_INFO: return "RENESAS INFO";
4303 default: return NULL;
685080f2
NC
4304 }
4305}
4306
2dc8dd17
JW
4307static const char *
4308get_riscv_section_type_name (unsigned int sh_type)
4309{
4310 switch (sh_type)
4311 {
4312 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4313 default: return NULL;
4314 }
4315}
4316
252b5132 4317static const char *
dda8d76d 4318get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4319{
b34976b6 4320 static char buff[32];
9fb71ee4 4321 const char * result;
252b5132
RH
4322
4323 switch (sh_type)
4324 {
4325 case SHT_NULL: return "NULL";
4326 case SHT_PROGBITS: return "PROGBITS";
4327 case SHT_SYMTAB: return "SYMTAB";
4328 case SHT_STRTAB: return "STRTAB";
4329 case SHT_RELA: return "RELA";
4330 case SHT_HASH: return "HASH";
4331 case SHT_DYNAMIC: return "DYNAMIC";
4332 case SHT_NOTE: return "NOTE";
4333 case SHT_NOBITS: return "NOBITS";
4334 case SHT_REL: return "REL";
4335 case SHT_SHLIB: return "SHLIB";
4336 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4337 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4338 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4339 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4340 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4341 case SHT_GROUP: return "GROUP";
67ce483b 4342 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4343 case SHT_GNU_verdef: return "VERDEF";
4344 case SHT_GNU_verneed: return "VERNEED";
4345 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4346 case 0x6ffffff0: return "VERSYM";
4347 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4348 case 0x7ffffffd: return "AUXILIARY";
4349 case 0x7fffffff: return "FILTER";
047b2264 4350 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4351
4352 default:
4353 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4354 {
dda8d76d 4355 switch (filedata->file_header.e_machine)
252b5132 4356 {
53a346d8
CZ
4357 case EM_ARC:
4358 case EM_ARC_COMPACT:
4359 case EM_ARC_COMPACT2:
4360 result = get_arc_section_type_name (sh_type);
4361 break;
252b5132 4362 case EM_MIPS:
4fe85591 4363 case EM_MIPS_RS3_LE:
252b5132
RH
4364 result = get_mips_section_type_name (sh_type);
4365 break;
103f02d3
UD
4366 case EM_PARISC:
4367 result = get_parisc_section_type_name (sh_type);
4368 break;
4d6ed7c8 4369 case EM_IA_64:
dda8d76d 4370 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4371 break;
d2b2c203 4372 case EM_X86_64:
8a9036a4 4373 case EM_L1OM:
7a9068fe 4374 case EM_K1OM:
d2b2c203
DJ
4375 result = get_x86_64_section_type_name (sh_type);
4376 break;
a06ea964
NC
4377 case EM_AARCH64:
4378 result = get_aarch64_section_type_name (sh_type);
4379 break;
40a18ebd
NC
4380 case EM_ARM:
4381 result = get_arm_section_type_name (sh_type);
4382 break;
40b36596
JM
4383 case EM_TI_C6000:
4384 result = get_tic6x_section_type_name (sh_type);
4385 break;
13761a11
NC
4386 case EM_MSP430:
4387 result = get_msp430x_section_type_name (sh_type);
4388 break;
fe944acf
FT
4389 case EM_NFP:
4390 result = get_nfp_section_type_name (sh_type);
4391 break;
685080f2
NC
4392 case EM_V800:
4393 case EM_V850:
4394 case EM_CYGNUS_V850:
4395 result = get_v850_section_type_name (sh_type);
4396 break;
2dc8dd17
JW
4397 case EM_RISCV:
4398 result = get_riscv_section_type_name (sh_type);
4399 break;
252b5132
RH
4400 default:
4401 result = NULL;
4402 break;
4403 }
4404
4405 if (result != NULL)
4406 return result;
4407
9fb71ee4 4408 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4409 }
4410 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4411 {
dda8d76d 4412 switch (filedata->file_header.e_machine)
148b93f2
NC
4413 {
4414 case EM_IA_64:
dda8d76d 4415 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4416 break;
4417 default:
dda8d76d 4418 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4419 result = get_solaris_section_type (sh_type);
4420 else
1b4b80bf
NC
4421 {
4422 switch (sh_type)
4423 {
4424 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4425 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4426 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4427 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4428 default:
4429 result = NULL;
4430 break;
4431 }
4432 }
148b93f2
NC
4433 break;
4434 }
4435
4436 if (result != NULL)
4437 return result;
4438
9fb71ee4 4439 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4440 }
252b5132 4441 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4442 {
dda8d76d 4443 switch (filedata->file_header.e_machine)
685080f2
NC
4444 {
4445 case EM_V800:
4446 case EM_V850:
4447 case EM_CYGNUS_V850:
9fb71ee4 4448 result = get_v850_section_type_name (sh_type);
a9fb83be 4449 break;
685080f2 4450 default:
9fb71ee4 4451 result = NULL;
685080f2
NC
4452 break;
4453 }
4454
9fb71ee4
NC
4455 if (result != NULL)
4456 return result;
4457
4458 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4459 }
252b5132 4460 else
a7dbfd1c
NC
4461 /* This message is probably going to be displayed in a 15
4462 character wide field, so put the hex value first. */
4463 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4464
252b5132
RH
4465 return buff;
4466 }
4467}
4468
79bc120c
NC
4469enum long_option_values
4470{
4471 OPTION_DEBUG_DUMP = 512,
4472 OPTION_DYN_SYMS,
4473 OPTION_DWARF_DEPTH,
4474 OPTION_DWARF_START,
4475 OPTION_DWARF_CHECK,
4476 OPTION_CTF_DUMP,
4477 OPTION_CTF_PARENT,
4478 OPTION_CTF_SYMBOLS,
4479 OPTION_CTF_STRINGS,
4480 OPTION_WITH_SYMBOL_VERSIONS,
4481 OPTION_RECURSE_LIMIT,
4482 OPTION_NO_RECURSE_LIMIT,
4483 OPTION_NO_DEMANGLING
4484};
2979dc34 4485
85b1c36d 4486static struct option options[] =
252b5132 4487{
79bc120c
NC
4488 /* Note - This table is alpha-sorted on the 'val'
4489 field in order to make adding new options easier. */
4490 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4491 {"all", no_argument, 0, 'a'},
79bc120c
NC
4492 {"demangle", optional_argument, 0, 'C'},
4493 {"archive-index", no_argument, 0, 'c'},
4494 {"use-dynamic", no_argument, 0, 'D'},
4495 {"dynamic", no_argument, 0, 'd'},
b34976b6 4496 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4497 {"section-groups", no_argument, 0, 'g'},
4498 {"help", no_argument, 0, 'H'},
4499 {"file-header", no_argument, 0, 'h'},
b34976b6 4500 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4501 {"lint", no_argument, 0, 'L'},
4502 {"enable-checks", no_argument, 0, 'L'},
4503 {"program-headers", no_argument, 0, 'l'},
b34976b6 4504 {"segments", no_argument, 0, 'l'},
595cf52e 4505 {"full-section-name",no_argument, 0, 'N'},
79bc120c
NC
4506 {"notes", no_argument, 0, 'n'},
4507 {"string-dump", required_argument, 0, 'p'},
4508 {"relocated-dump", required_argument, 0, 'R'},
4509 {"relocs", no_argument, 0, 'r'},
4510 {"section-headers", no_argument, 0, 'S'},
4511 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4512 {"symbols", no_argument, 0, 's'},
4513 {"syms", no_argument, 0, 's'},
79bc120c
NC
4514 {"silent-truncation",no_argument, 0, 'T'},
4515 {"section-details", no_argument, 0, 't'},
09c11c86 4516 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4517 {"version-info", no_argument, 0, 'V'},
4518 {"version", no_argument, 0, 'v'},
4519 {"wide", no_argument, 0, 'W'},
b34976b6 4520 {"hex-dump", required_argument, 0, 'x'},
0e602686 4521 {"decompress", no_argument, 0, 'z'},
252b5132 4522
79bc120c
NC
4523 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4524 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4525 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4526 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4527 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
4528 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4529 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4530 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4531 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4532#ifdef ENABLE_LIBCTF
d344b407 4533 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4534 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4535 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4536 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4537#endif
7d9813f1 4538
b34976b6 4539 {0, no_argument, 0, 0}
252b5132
RH
4540};
4541
4542static void
2cf0635d 4543usage (FILE * stream)
252b5132 4544{
92f01d61
JM
4545 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4546 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4547 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4548 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4549 -h --file-header Display the ELF file header\n\
4550 -l --program-headers Display the program headers\n\
4551 --segments An alias for --program-headers\n\
4552 -S --section-headers Display the sections' header\n\
4553 --sections An alias for --section-headers\n\
f5842774 4554 -g --section-groups Display the section groups\n\
5477e8a0 4555 -t --section-details Display the section details\n\
8b53311e
NC
4556 -e --headers Equivalent to: -h -l -S\n\
4557 -s --syms Display the symbol table\n\
3f08eb35 4558 --symbols An alias for --syms\n\
1b513401 4559 --dyn-syms Display the dynamic symbol table\n\
79bc120c
NC
4560 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4561 The STYLE, if specified, can be `auto' (the default),\n\
4562 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
4563 or `gnat'\n\
4564 --no-demangle Do not demangle low-level symbol names. (This is the default)\n\
4565 --recurse-limit Enable a demangling recursion limit. (This is the default)\n\
4566 --no-recurse-limit Disable a demangling recursion limit\n\
8b53311e
NC
4567 -n --notes Display the core notes (if present)\n\
4568 -r --relocs Display the relocations (if present)\n\
4569 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4570 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4571 -V --version-info Display the version sections (if present)\n\
1b31d05e 4572 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4573 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4574 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4575 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4576 -x --hex-dump=<number|name>\n\
4577 Dump the contents of section <number|name> as bytes\n\
4578 -p --string-dump=<number|name>\n\
4579 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4580 -R --relocated-dump=<number|name>\n\
4581 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4582 -z --decompress Decompress section before dumping it\n\
e4b7104b 4583 -w[lLiaprmfFsoORtUuTgAckK] or\n\
1ed06042 4584 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
e4b7104b 4585 =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
657d0d47 4586 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4587 =addr,=cu_index,=links,=follow-links]\n\
4588 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4589 fprintf (stream, _("\
4590 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4591 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4592 or deeper\n"));
094e34f2 4593#ifdef ENABLE_LIBCTF
7d9813f1
NA
4594 fprintf (stream, _("\
4595 --ctf=<number|name> Display CTF info from section <number|name>\n\
4596 --ctf-parent=<number|name>\n\
4597 Use section <number|name> as the CTF parent\n\n\
4598 --ctf-symbols=<number|name>\n\
4599 Use section <number|name> as the CTF external symtab\n\n\
4600 --ctf-strings=<number|name>\n\
4601 Use section <number|name> as the CTF external strtab\n\n"));
094e34f2 4602#endif
7d9813f1 4603
252b5132 4604#ifdef SUPPORT_DISASSEMBLY
92f01d61 4605 fprintf (stream, _("\
09c11c86
NC
4606 -i --instruction-dump=<number|name>\n\
4607 Disassemble the contents of section <number|name>\n"));
252b5132 4608#endif
92f01d61 4609 fprintf (stream, _("\
8b53311e
NC
4610 -I --histogram Display histogram of bucket list lengths\n\
4611 -W --wide Allow output width to exceed 80 characters\n\
0942c7ab 4612 -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
07012eee 4613 @<file> Read options from <file>\n\
8b53311e
NC
4614 -H --help Display this information\n\
4615 -v --version Display the version number of readelf\n"));
1118d252 4616
92f01d61
JM
4617 if (REPORT_BUGS_TO[0] && stream == stdout)
4618 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4619
92f01d61 4620 exit (stream == stdout ? 0 : 1);
252b5132
RH
4621}
4622
18bd398b
NC
4623/* Record the fact that the user wants the contents of section number
4624 SECTION to be displayed using the method(s) encoded as flags bits
4625 in TYPE. Note, TYPE can be zero if we are creating the array for
4626 the first time. */
4627
252b5132 4628static void
6431e409
AM
4629request_dump_bynumber (struct dump_data *dumpdata,
4630 unsigned int section, dump_type type)
252b5132 4631{
6431e409 4632 if (section >= dumpdata->num_dump_sects)
252b5132 4633 {
2cf0635d 4634 dump_type * new_dump_sects;
252b5132 4635
3f5e193b 4636 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4637 sizeof (* new_dump_sects));
252b5132
RH
4638
4639 if (new_dump_sects == NULL)
591a748a 4640 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4641 else
4642 {
6431e409 4643 if (dumpdata->dump_sects)
21b65bac
NC
4644 {
4645 /* Copy current flag settings. */
6431e409
AM
4646 memcpy (new_dump_sects, dumpdata->dump_sects,
4647 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4648
6431e409 4649 free (dumpdata->dump_sects);
21b65bac 4650 }
252b5132 4651
6431e409
AM
4652 dumpdata->dump_sects = new_dump_sects;
4653 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4654 }
4655 }
4656
6431e409
AM
4657 if (dumpdata->dump_sects)
4658 dumpdata->dump_sects[section] |= type;
252b5132
RH
4659}
4660
aef1f6d0
DJ
4661/* Request a dump by section name. */
4662
4663static void
2cf0635d 4664request_dump_byname (const char * section, dump_type type)
aef1f6d0 4665{
2cf0635d 4666 struct dump_list_entry * new_request;
aef1f6d0 4667
3f5e193b
NC
4668 new_request = (struct dump_list_entry *)
4669 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4670 if (!new_request)
591a748a 4671 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4672
4673 new_request->name = strdup (section);
4674 if (!new_request->name)
591a748a 4675 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4676
4677 new_request->type = type;
4678
4679 new_request->next = dump_sects_byname;
4680 dump_sects_byname = new_request;
4681}
4682
cf13d699 4683static inline void
6431e409 4684request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4685{
4686 int section;
4687 char * cp;
4688
4689 do_dump++;
4690 section = strtoul (optarg, & cp, 0);
4691
4692 if (! *cp && section >= 0)
6431e409 4693 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4694 else
4695 request_dump_byname (optarg, type);
4696}
4697
252b5132 4698static void
6431e409 4699parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4700{
4701 int c;
4702
4703 if (argc < 2)
92f01d61 4704 usage (stderr);
252b5132
RH
4705
4706 while ((c = getopt_long
79bc120c 4707 (argc, argv, "ACDHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4708 {
252b5132
RH
4709 switch (c)
4710 {
4711 case 0:
4712 /* Long options. */
4713 break;
4714 case 'H':
92f01d61 4715 usage (stdout);
252b5132
RH
4716 break;
4717
4718 case 'a':
32ec8896
NC
4719 do_syms = TRUE;
4720 do_reloc = TRUE;
4721 do_unwind = TRUE;
4722 do_dynamic = TRUE;
4723 do_header = TRUE;
4724 do_sections = TRUE;
4725 do_section_groups = TRUE;
4726 do_segments = TRUE;
4727 do_version = TRUE;
4728 do_histogram = TRUE;
4729 do_arch = TRUE;
4730 do_notes = TRUE;
252b5132 4731 break;
79bc120c 4732
f5842774 4733 case 'g':
32ec8896 4734 do_section_groups = TRUE;
f5842774 4735 break;
5477e8a0 4736 case 't':
595cf52e 4737 case 'N':
32ec8896
NC
4738 do_sections = TRUE;
4739 do_section_details = TRUE;
595cf52e 4740 break;
252b5132 4741 case 'e':
32ec8896
NC
4742 do_header = TRUE;
4743 do_sections = TRUE;
4744 do_segments = TRUE;
252b5132 4745 break;
a952a375 4746 case 'A':
32ec8896 4747 do_arch = TRUE;
a952a375 4748 break;
252b5132 4749 case 'D':
32ec8896 4750 do_using_dynamic = TRUE;
252b5132
RH
4751 break;
4752 case 'r':
32ec8896 4753 do_reloc = TRUE;
252b5132 4754 break;
4d6ed7c8 4755 case 'u':
32ec8896 4756 do_unwind = TRUE;
4d6ed7c8 4757 break;
252b5132 4758 case 'h':
32ec8896 4759 do_header = TRUE;
252b5132
RH
4760 break;
4761 case 'l':
32ec8896 4762 do_segments = TRUE;
252b5132
RH
4763 break;
4764 case 's':
32ec8896 4765 do_syms = TRUE;
252b5132
RH
4766 break;
4767 case 'S':
32ec8896 4768 do_sections = TRUE;
252b5132
RH
4769 break;
4770 case 'd':
32ec8896 4771 do_dynamic = TRUE;
252b5132 4772 break;
a952a375 4773 case 'I':
32ec8896 4774 do_histogram = TRUE;
a952a375 4775 break;
779fe533 4776 case 'n':
32ec8896 4777 do_notes = TRUE;
779fe533 4778 break;
4145f1d5 4779 case 'c':
32ec8896 4780 do_archive_index = TRUE;
4145f1d5 4781 break;
1b513401
NC
4782 case 'L':
4783 do_checks = TRUE;
4784 break;
252b5132 4785 case 'x':
6431e409 4786 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4787 break;
09c11c86 4788 case 'p':
6431e409 4789 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4790 break;
4791 case 'R':
6431e409 4792 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4793 break;
0e602686 4794 case 'z':
32ec8896 4795 decompress_dumps = TRUE;
0e602686 4796 break;
252b5132 4797 case 'w':
32ec8896 4798 do_dump = TRUE;
252b5132 4799 if (optarg == 0)
613ff48b 4800 {
32ec8896 4801 do_debugging = TRUE;
613ff48b
CC
4802 dwarf_select_sections_all ();
4803 }
252b5132
RH
4804 else
4805 {
32ec8896 4806 do_debugging = FALSE;
4cb93e3b 4807 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4808 }
4809 break;
2979dc34 4810 case OPTION_DEBUG_DUMP:
32ec8896 4811 do_dump = TRUE;
2979dc34 4812 if (optarg == 0)
32ec8896 4813 do_debugging = TRUE;
2979dc34
JJ
4814 else
4815 {
32ec8896 4816 do_debugging = FALSE;
4cb93e3b 4817 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4818 }
4819 break;
fd2f0033
TT
4820 case OPTION_DWARF_DEPTH:
4821 {
4822 char *cp;
4823
4824 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4825 }
4826 break;
4827 case OPTION_DWARF_START:
4828 {
4829 char *cp;
4830
4831 dwarf_start_die = strtoul (optarg, & cp, 0);
4832 }
4833 break;
4723351a 4834 case OPTION_DWARF_CHECK:
32ec8896 4835 dwarf_check = TRUE;
4723351a 4836 break;
7d9813f1
NA
4837 case OPTION_CTF_DUMP:
4838 do_ctf = TRUE;
6431e409 4839 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4840 break;
4841 case OPTION_CTF_SYMBOLS:
df16e041 4842 free (dump_ctf_symtab_name);
7d9813f1
NA
4843 dump_ctf_symtab_name = strdup (optarg);
4844 break;
4845 case OPTION_CTF_STRINGS:
df16e041 4846 free (dump_ctf_strtab_name);
7d9813f1
NA
4847 dump_ctf_strtab_name = strdup (optarg);
4848 break;
4849 case OPTION_CTF_PARENT:
df16e041 4850 free (dump_ctf_parent_name);
7d9813f1
NA
4851 dump_ctf_parent_name = strdup (optarg);
4852 break;
2c610e4b 4853 case OPTION_DYN_SYMS:
32ec8896 4854 do_dyn_syms = TRUE;
2c610e4b 4855 break;
252b5132
RH
4856#ifdef SUPPORT_DISASSEMBLY
4857 case 'i':
6431e409 4858 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4859 break;
252b5132
RH
4860#endif
4861 case 'v':
4862 print_version (program_name);
4863 break;
4864 case 'V':
32ec8896 4865 do_version = TRUE;
252b5132 4866 break;
d974e256 4867 case 'W':
32ec8896 4868 do_wide = TRUE;
d974e256 4869 break;
0942c7ab
NC
4870 case 'T':
4871 do_not_show_symbol_truncation = TRUE;
4872 break;
79bc120c
NC
4873 case 'C':
4874 do_demangle = TRUE;
4875 if (optarg != NULL)
4876 {
4877 enum demangling_styles style;
4878
4879 style = cplus_demangle_name_to_style (optarg);
4880 if (style == unknown_demangling)
4881 error (_("unknown demangling style `%s'"), optarg);
4882
4883 cplus_demangle_set_style (style);
4884 }
4885 break;
4886 case OPTION_NO_DEMANGLING:
4887 do_demangle = FALSE;
4888 break;
4889 case OPTION_RECURSE_LIMIT:
4890 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
4891 break;
4892 case OPTION_NO_RECURSE_LIMIT:
4893 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
4894 break;
4895 case OPTION_WITH_SYMBOL_VERSIONS:
4896 /* Ignored for backward compatibility. */
4897 break;
4898
252b5132 4899 default:
252b5132
RH
4900 /* xgettext:c-format */
4901 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4902 /* Fall through. */
252b5132 4903 case '?':
92f01d61 4904 usage (stderr);
252b5132
RH
4905 }
4906 }
4907
4d6ed7c8 4908 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4909 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4910 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4911 && !do_section_groups && !do_archive_index
4912 && !do_dyn_syms)
1b513401
NC
4913 {
4914 if (do_checks)
4915 {
4916 check_all = TRUE;
4917 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = TRUE;
4918 do_segments = do_header = do_dump = do_version = TRUE;
4919 do_histogram = do_debugging = do_arch = do_notes = TRUE;
4920 do_section_groups = do_archive_index = do_dyn_syms = TRUE;
4921 }
4922 else
4923 usage (stderr);
4924 }
252b5132
RH
4925}
4926
4927static const char *
d3ba0551 4928get_elf_class (unsigned int elf_class)
252b5132 4929{
b34976b6 4930 static char buff[32];
103f02d3 4931
252b5132
RH
4932 switch (elf_class)
4933 {
4934 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4935 case ELFCLASS32: return "ELF32";
4936 case ELFCLASS64: return "ELF64";
ab5e7794 4937 default:
e9e44622 4938 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4939 return buff;
252b5132
RH
4940 }
4941}
4942
4943static const char *
d3ba0551 4944get_data_encoding (unsigned int encoding)
252b5132 4945{
b34976b6 4946 static char buff[32];
103f02d3 4947
252b5132
RH
4948 switch (encoding)
4949 {
4950 case ELFDATANONE: return _("none");
33c63f9d
CM
4951 case ELFDATA2LSB: return _("2's complement, little endian");
4952 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4953 default:
e9e44622 4954 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4955 return buff;
252b5132
RH
4956 }
4957}
4958
dda8d76d 4959/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4960
32ec8896 4961static bfd_boolean
dda8d76d 4962process_file_header (Filedata * filedata)
252b5132 4963{
dda8d76d
NC
4964 Elf_Internal_Ehdr * header = & filedata->file_header;
4965
4966 if ( header->e_ident[EI_MAG0] != ELFMAG0
4967 || header->e_ident[EI_MAG1] != ELFMAG1
4968 || header->e_ident[EI_MAG2] != ELFMAG2
4969 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4970 {
4971 error
4972 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4973 return FALSE;
252b5132
RH
4974 }
4975
955ff7fc 4976 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 4977
252b5132
RH
4978 if (do_header)
4979 {
32ec8896 4980 unsigned i;
252b5132
RH
4981
4982 printf (_("ELF Header:\n"));
4983 printf (_(" Magic: "));
b34976b6 4984 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4985 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4986 printf ("\n");
4987 printf (_(" Class: %s\n"),
dda8d76d 4988 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4989 printf (_(" Data: %s\n"),
dda8d76d 4990 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 4991 printf (_(" Version: %d%s\n"),
dda8d76d
NC
4992 header->e_ident[EI_VERSION],
4993 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 4994 ? _(" (current)")
dda8d76d 4995 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 4996 ? _(" <unknown>")
789be9f7 4997 : "")));
252b5132 4998 printf (_(" OS/ABI: %s\n"),
dda8d76d 4999 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5000 printf (_(" ABI Version: %d\n"),
dda8d76d 5001 header->e_ident[EI_ABIVERSION]);
252b5132 5002 printf (_(" Type: %s\n"),
dda8d76d 5003 get_file_type (header->e_type));
252b5132 5004 printf (_(" Machine: %s\n"),
dda8d76d 5005 get_machine_name (header->e_machine));
252b5132 5006 printf (_(" Version: 0x%lx\n"),
e8a64888 5007 header->e_version);
76da6bbe 5008
f7a99963 5009 printf (_(" Entry point address: "));
e8a64888 5010 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5011 printf (_("\n Start of program headers: "));
e8a64888 5012 print_vma (header->e_phoff, DEC);
f7a99963 5013 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5014 print_vma (header->e_shoff, DEC);
f7a99963 5015 printf (_(" (bytes into file)\n"));
76da6bbe 5016
252b5132 5017 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5018 header->e_flags,
dda8d76d 5019 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5020 printf (_(" Size of this header: %u (bytes)\n"),
5021 header->e_ehsize);
5022 printf (_(" Size of program headers: %u (bytes)\n"),
5023 header->e_phentsize);
5024 printf (_(" Number of program headers: %u"),
5025 header->e_phnum);
dda8d76d
NC
5026 if (filedata->section_headers != NULL
5027 && header->e_phnum == PN_XNUM
5028 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5029 {
5030 header->e_phnum = filedata->section_headers[0].sh_info;
5031 printf (" (%u)", header->e_phnum);
5032 }
2046a35d 5033 putc ('\n', stdout);
e8a64888
AM
5034 printf (_(" Size of section headers: %u (bytes)\n"),
5035 header->e_shentsize);
5036 printf (_(" Number of section headers: %u"),
5037 header->e_shnum);
dda8d76d 5038 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5039 {
5040 header->e_shnum = filedata->section_headers[0].sh_size;
5041 printf (" (%u)", header->e_shnum);
5042 }
560f3c1c 5043 putc ('\n', stdout);
e8a64888
AM
5044 printf (_(" Section header string table index: %u"),
5045 header->e_shstrndx);
dda8d76d
NC
5046 if (filedata->section_headers != NULL
5047 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5048 {
5049 header->e_shstrndx = filedata->section_headers[0].sh_link;
5050 printf (" (%u)", header->e_shstrndx);
5051 }
5052 if (header->e_shstrndx != SHN_UNDEF
5053 && header->e_shstrndx >= header->e_shnum)
5054 {
5055 header->e_shstrndx = SHN_UNDEF;
5056 printf (_(" <corrupt: out of range>"));
5057 }
560f3c1c
AM
5058 putc ('\n', stdout);
5059 }
5060
dda8d76d 5061 if (filedata->section_headers != NULL)
560f3c1c 5062 {
dda8d76d
NC
5063 if (header->e_phnum == PN_XNUM
5064 && filedata->section_headers[0].sh_info != 0)
5065 header->e_phnum = filedata->section_headers[0].sh_info;
5066 if (header->e_shnum == SHN_UNDEF)
5067 header->e_shnum = filedata->section_headers[0].sh_size;
5068 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5069 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5070 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5071 header->e_shstrndx = SHN_UNDEF;
5072 free (filedata->section_headers);
5073 filedata->section_headers = NULL;
252b5132 5074 }
103f02d3 5075
32ec8896 5076 return TRUE;
9ea033b2
NC
5077}
5078
dda8d76d
NC
5079/* Read in the program headers from FILEDATA and store them in PHEADERS.
5080 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5081
e0a31db1 5082static bfd_boolean
dda8d76d 5083get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5084{
2cf0635d
NC
5085 Elf32_External_Phdr * phdrs;
5086 Elf32_External_Phdr * external;
5087 Elf_Internal_Phdr * internal;
b34976b6 5088 unsigned int i;
dda8d76d
NC
5089 unsigned int size = filedata->file_header.e_phentsize;
5090 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5091
5092 /* PR binutils/17531: Cope with unexpected section header sizes. */
5093 if (size == 0 || num == 0)
5094 return FALSE;
5095 if (size < sizeof * phdrs)
5096 {
5097 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5098 return FALSE;
5099 }
5100 if (size > sizeof * phdrs)
5101 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5102
dda8d76d 5103 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5104 size, num, _("program headers"));
5105 if (phdrs == NULL)
5106 return FALSE;
9ea033b2 5107
91d6fa6a 5108 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5109 i < filedata->file_header.e_phnum;
b34976b6 5110 i++, internal++, external++)
252b5132 5111 {
9ea033b2
NC
5112 internal->p_type = BYTE_GET (external->p_type);
5113 internal->p_offset = BYTE_GET (external->p_offset);
5114 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5115 internal->p_paddr = BYTE_GET (external->p_paddr);
5116 internal->p_filesz = BYTE_GET (external->p_filesz);
5117 internal->p_memsz = BYTE_GET (external->p_memsz);
5118 internal->p_flags = BYTE_GET (external->p_flags);
5119 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5120 }
5121
9ea033b2 5122 free (phdrs);
e0a31db1 5123 return TRUE;
252b5132
RH
5124}
5125
dda8d76d
NC
5126/* Read in the program headers from FILEDATA and store them in PHEADERS.
5127 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5128
e0a31db1 5129static bfd_boolean
dda8d76d 5130get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5131{
2cf0635d
NC
5132 Elf64_External_Phdr * phdrs;
5133 Elf64_External_Phdr * external;
5134 Elf_Internal_Phdr * internal;
b34976b6 5135 unsigned int i;
dda8d76d
NC
5136 unsigned int size = filedata->file_header.e_phentsize;
5137 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5138
5139 /* PR binutils/17531: Cope with unexpected section header sizes. */
5140 if (size == 0 || num == 0)
5141 return FALSE;
5142 if (size < sizeof * phdrs)
5143 {
5144 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5145 return FALSE;
5146 }
5147 if (size > sizeof * phdrs)
5148 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5149
dda8d76d 5150 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5151 size, num, _("program headers"));
a6e9f9df 5152 if (!phdrs)
e0a31db1 5153 return FALSE;
9ea033b2 5154
91d6fa6a 5155 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5156 i < filedata->file_header.e_phnum;
b34976b6 5157 i++, internal++, external++)
9ea033b2
NC
5158 {
5159 internal->p_type = BYTE_GET (external->p_type);
5160 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5161 internal->p_offset = BYTE_GET (external->p_offset);
5162 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5163 internal->p_paddr = BYTE_GET (external->p_paddr);
5164 internal->p_filesz = BYTE_GET (external->p_filesz);
5165 internal->p_memsz = BYTE_GET (external->p_memsz);
5166 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5167 }
5168
5169 free (phdrs);
e0a31db1 5170 return TRUE;
9ea033b2 5171}
252b5132 5172
32ec8896 5173/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5174
32ec8896 5175static bfd_boolean
dda8d76d 5176get_program_headers (Filedata * filedata)
d93f0186 5177{
2cf0635d 5178 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5179
5180 /* Check cache of prior read. */
dda8d76d 5181 if (filedata->program_headers != NULL)
32ec8896 5182 return TRUE;
d93f0186 5183
82156ab7
NC
5184 /* Be kind to memory checkers by looking for
5185 e_phnum values which we know must be invalid. */
dda8d76d 5186 if (filedata->file_header.e_phnum
82156ab7 5187 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5188 >= filedata->file_size)
82156ab7
NC
5189 {
5190 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5191 filedata->file_header.e_phnum);
82156ab7
NC
5192 return FALSE;
5193 }
d93f0186 5194
dda8d76d 5195 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5196 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5197 if (phdrs == NULL)
5198 {
8b73c356 5199 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5200 filedata->file_header.e_phnum);
32ec8896 5201 return FALSE;
d93f0186
NC
5202 }
5203
5204 if (is_32bit_elf
dda8d76d
NC
5205 ? get_32bit_program_headers (filedata, phdrs)
5206 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5207 {
dda8d76d 5208 filedata->program_headers = phdrs;
32ec8896 5209 return TRUE;
d93f0186
NC
5210 }
5211
5212 free (phdrs);
32ec8896 5213 return FALSE;
d93f0186
NC
5214}
5215
32ec8896 5216/* Returns TRUE if the program headers were loaded. */
2f62977e 5217
32ec8896 5218static bfd_boolean
dda8d76d 5219process_program_headers (Filedata * filedata)
252b5132 5220{
2cf0635d 5221 Elf_Internal_Phdr * segment;
b34976b6 5222 unsigned int i;
1a9ccd70 5223 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5224
978c4450
AM
5225 filedata->dynamic_addr = 0;
5226 filedata->dynamic_size = 0;
663f67df 5227
dda8d76d 5228 if (filedata->file_header.e_phnum == 0)
252b5132 5229 {
82f2dbf7 5230 /* PR binutils/12467. */
dda8d76d 5231 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5232 {
5233 warn (_("possibly corrupt ELF header - it has a non-zero program"
5234 " header offset, but no program headers\n"));
5235 return FALSE;
5236 }
82f2dbf7 5237 else if (do_segments)
252b5132 5238 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5239 return TRUE;
252b5132
RH
5240 }
5241
5242 if (do_segments && !do_header)
5243 {
dda8d76d
NC
5244 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5245 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5246 printf (ngettext ("There is %d program header, starting at offset %s\n",
5247 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5248 filedata->file_header.e_phnum),
5249 filedata->file_header.e_phnum,
5250 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5251 }
5252
dda8d76d 5253 if (! get_program_headers (filedata))
6b4bf3bc 5254 return TRUE;
103f02d3 5255
252b5132
RH
5256 if (do_segments)
5257 {
dda8d76d 5258 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5259 printf (_("\nProgram Headers:\n"));
5260 else
5261 printf (_("\nProgram Headers:\n"));
76da6bbe 5262
f7a99963
NC
5263 if (is_32bit_elf)
5264 printf
5265 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5266 else if (do_wide)
5267 printf
5268 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5269 else
5270 {
5271 printf
5272 (_(" Type Offset VirtAddr PhysAddr\n"));
5273 printf
5274 (_(" FileSiz MemSiz Flags Align\n"));
5275 }
252b5132
RH
5276 }
5277
dda8d76d
NC
5278 for (i = 0, segment = filedata->program_headers;
5279 i < filedata->file_header.e_phnum;
b34976b6 5280 i++, segment++)
252b5132
RH
5281 {
5282 if (do_segments)
5283 {
dda8d76d 5284 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5285
5286 if (is_32bit_elf)
5287 {
5288 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5289 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5290 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5291 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5292 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5293 printf ("%c%c%c ",
5294 (segment->p_flags & PF_R ? 'R' : ' '),
5295 (segment->p_flags & PF_W ? 'W' : ' '),
5296 (segment->p_flags & PF_X ? 'E' : ' '));
5297 printf ("%#lx", (unsigned long) segment->p_align);
5298 }
d974e256
JJ
5299 else if (do_wide)
5300 {
5301 if ((unsigned long) segment->p_offset == segment->p_offset)
5302 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5303 else
5304 {
5305 print_vma (segment->p_offset, FULL_HEX);
5306 putchar (' ');
5307 }
5308
5309 print_vma (segment->p_vaddr, FULL_HEX);
5310 putchar (' ');
5311 print_vma (segment->p_paddr, FULL_HEX);
5312 putchar (' ');
5313
5314 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5315 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5316 else
5317 {
5318 print_vma (segment->p_filesz, FULL_HEX);
5319 putchar (' ');
5320 }
5321
5322 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5323 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5324 else
5325 {
f48e6c45 5326 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5327 }
5328
5329 printf (" %c%c%c ",
5330 (segment->p_flags & PF_R ? 'R' : ' '),
5331 (segment->p_flags & PF_W ? 'W' : ' '),
5332 (segment->p_flags & PF_X ? 'E' : ' '));
5333
5334 if ((unsigned long) segment->p_align == segment->p_align)
5335 printf ("%#lx", (unsigned long) segment->p_align);
5336 else
5337 {
5338 print_vma (segment->p_align, PREFIX_HEX);
5339 }
5340 }
f7a99963
NC
5341 else
5342 {
5343 print_vma (segment->p_offset, FULL_HEX);
5344 putchar (' ');
5345 print_vma (segment->p_vaddr, FULL_HEX);
5346 putchar (' ');
5347 print_vma (segment->p_paddr, FULL_HEX);
5348 printf ("\n ");
5349 print_vma (segment->p_filesz, FULL_HEX);
5350 putchar (' ');
5351 print_vma (segment->p_memsz, FULL_HEX);
5352 printf (" %c%c%c ",
5353 (segment->p_flags & PF_R ? 'R' : ' '),
5354 (segment->p_flags & PF_W ? 'W' : ' '),
5355 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5356 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5357 }
252b5132 5358
1a9ccd70
NC
5359 putc ('\n', stdout);
5360 }
f54498b4 5361
252b5132
RH
5362 switch (segment->p_type)
5363 {
1a9ccd70 5364 case PT_LOAD:
502d895c
NC
5365#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5366 required by the ELF standard, several programs, including the Linux
5367 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5368 if (previous_load
5369 && previous_load->p_vaddr > segment->p_vaddr)
5370 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5371#endif
1a9ccd70
NC
5372 if (segment->p_memsz < segment->p_filesz)
5373 error (_("the segment's file size is larger than its memory size\n"));
5374 previous_load = segment;
5375 break;
5376
5377 case PT_PHDR:
5378 /* PR 20815 - Verify that the program header is loaded into memory. */
5379 if (i > 0 && previous_load != NULL)
5380 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5381 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5382 {
5383 unsigned int j;
5384
dda8d76d 5385 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5386 {
5387 Elf_Internal_Phdr *load = filedata->program_headers + j;
5388 if (load->p_type == PT_LOAD
5389 && load->p_offset <= segment->p_offset
5390 && (load->p_offset + load->p_filesz
5391 >= segment->p_offset + segment->p_filesz)
5392 && load->p_vaddr <= segment->p_vaddr
5393 && (load->p_vaddr + load->p_filesz
5394 >= segment->p_vaddr + segment->p_filesz))
5395 break;
5396 }
dda8d76d 5397 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5398 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5399 }
5400 break;
5401
252b5132 5402 case PT_DYNAMIC:
978c4450 5403 if (filedata->dynamic_addr)
252b5132
RH
5404 error (_("more than one dynamic segment\n"));
5405
20737c13
AM
5406 /* By default, assume that the .dynamic section is the first
5407 section in the DYNAMIC segment. */
978c4450
AM
5408 filedata->dynamic_addr = segment->p_offset;
5409 filedata->dynamic_size = segment->p_filesz;
20737c13 5410
b2d38a17
NC
5411 /* Try to locate the .dynamic section. If there is
5412 a section header table, we can easily locate it. */
dda8d76d 5413 if (filedata->section_headers != NULL)
b2d38a17 5414 {
2cf0635d 5415 Elf_Internal_Shdr * sec;
b2d38a17 5416
dda8d76d 5417 sec = find_section (filedata, ".dynamic");
89fac5e3 5418 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5419 {
28f997cf
TG
5420 /* A corresponding .dynamic section is expected, but on
5421 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5422 if (!is_ia64_vms (filedata))
28f997cf 5423 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5424 break;
5425 }
5426
42bb2e33 5427 if (sec->sh_type == SHT_NOBITS)
20737c13 5428 {
978c4450 5429 filedata->dynamic_size = 0;
20737c13
AM
5430 break;
5431 }
42bb2e33 5432
978c4450
AM
5433 filedata->dynamic_addr = sec->sh_offset;
5434 filedata->dynamic_size = sec->sh_size;
b2d38a17 5435
8ac10c5b
L
5436 /* The PT_DYNAMIC segment, which is used by the run-time
5437 loader, should exactly match the .dynamic section. */
5438 if (do_checks
5439 && (filedata->dynamic_addr != segment->p_offset
5440 || filedata->dynamic_size != segment->p_filesz))
5441 warn (_("\
5442the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5443 }
39e224f6
MW
5444
5445 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5446 segment. Check this after matching against the section headers
5447 so we don't warn on debuginfo file (which have NOBITS .dynamic
5448 sections). */
978c4450
AM
5449 if (filedata->dynamic_addr > filedata->file_size
5450 || (filedata->dynamic_size
5451 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5452 {
5453 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5454 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5455 }
252b5132
RH
5456 break;
5457
5458 case PT_INTERP:
978c4450
AM
5459 if (fseek (filedata->handle,
5460 filedata->archive_file_offset + (long) segment->p_offset,
fb52b2f4 5461 SEEK_SET))
252b5132
RH
5462 error (_("Unable to find program interpreter name\n"));
5463 else
5464 {
f8eae8b2 5465 char fmt [32];
9495b2e6 5466 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5467
5468 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5469 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5470
978c4450
AM
5471 filedata->program_interpreter[0] = 0;
5472 if (fscanf (filedata->handle, fmt,
5473 filedata->program_interpreter) <= 0)
7bd7b3ef 5474 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5475
5476 if (do_segments)
f54498b4 5477 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5478 filedata->program_interpreter);
252b5132
RH
5479 }
5480 break;
5481 }
252b5132
RH
5482 }
5483
dda8d76d
NC
5484 if (do_segments
5485 && filedata->section_headers != NULL
5486 && filedata->string_table != NULL)
252b5132
RH
5487 {
5488 printf (_("\n Section to Segment mapping:\n"));
5489 printf (_(" Segment Sections...\n"));
5490
dda8d76d 5491 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5492 {
9ad5cbcf 5493 unsigned int j;
2cf0635d 5494 Elf_Internal_Shdr * section;
252b5132 5495
dda8d76d
NC
5496 segment = filedata->program_headers + i;
5497 section = filedata->section_headers + 1;
252b5132
RH
5498
5499 printf (" %2.2d ", i);
5500
dda8d76d 5501 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5502 {
f4638467
AM
5503 if (!ELF_TBSS_SPECIAL (section, segment)
5504 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5505 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5506 }
5507
5508 putc ('\n',stdout);
5509 }
5510 }
5511
32ec8896 5512 return TRUE;
252b5132
RH
5513}
5514
5515
d93f0186
NC
5516/* Find the file offset corresponding to VMA by using the program headers. */
5517
5518static long
dda8d76d 5519offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5520{
2cf0635d 5521 Elf_Internal_Phdr * seg;
d93f0186 5522
dda8d76d 5523 if (! get_program_headers (filedata))
d93f0186
NC
5524 {
5525 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5526 return (long) vma;
5527 }
5528
dda8d76d
NC
5529 for (seg = filedata->program_headers;
5530 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5531 ++seg)
5532 {
5533 if (seg->p_type != PT_LOAD)
5534 continue;
5535
5536 if (vma >= (seg->p_vaddr & -seg->p_align)
5537 && vma + size <= seg->p_vaddr + seg->p_filesz)
5538 return vma - seg->p_vaddr + seg->p_offset;
5539 }
5540
5541 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5542 (unsigned long) vma);
d93f0186
NC
5543 return (long) vma;
5544}
5545
5546
dda8d76d
NC
5547/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5548 If PROBE is true, this is just a probe and we do not generate any error
5549 messages if the load fails. */
049b0c3a
NC
5550
5551static bfd_boolean
dda8d76d 5552get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5553{
2cf0635d
NC
5554 Elf32_External_Shdr * shdrs;
5555 Elf_Internal_Shdr * internal;
dda8d76d
NC
5556 unsigned int i;
5557 unsigned int size = filedata->file_header.e_shentsize;
5558 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5559
5560 /* PR binutils/17531: Cope with unexpected section header sizes. */
5561 if (size == 0 || num == 0)
5562 return FALSE;
5563 if (size < sizeof * shdrs)
5564 {
5565 if (! probe)
5566 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5567 return FALSE;
5568 }
5569 if (!probe && size > sizeof * shdrs)
5570 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5571
dda8d76d 5572 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5573 size, num,
5574 probe ? NULL : _("section headers"));
5575 if (shdrs == NULL)
5576 return FALSE;
252b5132 5577
dda8d76d
NC
5578 free (filedata->section_headers);
5579 filedata->section_headers = (Elf_Internal_Shdr *)
5580 cmalloc (num, sizeof (Elf_Internal_Shdr));
5581 if (filedata->section_headers == NULL)
252b5132 5582 {
049b0c3a 5583 if (!probe)
8b73c356 5584 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5585 free (shdrs);
049b0c3a 5586 return FALSE;
252b5132
RH
5587 }
5588
dda8d76d 5589 for (i = 0, internal = filedata->section_headers;
560f3c1c 5590 i < num;
b34976b6 5591 i++, internal++)
252b5132
RH
5592 {
5593 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5594 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5595 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5596 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5597 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5598 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5599 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5600 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5601 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5602 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5603 if (!probe && internal->sh_link > num)
5604 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5605 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5606 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5607 }
5608
5609 free (shdrs);
049b0c3a 5610 return TRUE;
252b5132
RH
5611}
5612
dda8d76d
NC
5613/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5614
049b0c3a 5615static bfd_boolean
dda8d76d 5616get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5617{
dda8d76d
NC
5618 Elf64_External_Shdr * shdrs;
5619 Elf_Internal_Shdr * internal;
5620 unsigned int i;
5621 unsigned int size = filedata->file_header.e_shentsize;
5622 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5623
5624 /* PR binutils/17531: Cope with unexpected section header sizes. */
5625 if (size == 0 || num == 0)
5626 return FALSE;
dda8d76d 5627
049b0c3a
NC
5628 if (size < sizeof * shdrs)
5629 {
5630 if (! probe)
5631 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5632 return FALSE;
5633 }
dda8d76d 5634
049b0c3a
NC
5635 if (! probe && size > sizeof * shdrs)
5636 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5637
dda8d76d
NC
5638 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5639 filedata->file_header.e_shoff,
049b0c3a
NC
5640 size, num,
5641 probe ? NULL : _("section headers"));
5642 if (shdrs == NULL)
5643 return FALSE;
9ea033b2 5644
dda8d76d
NC
5645 free (filedata->section_headers);
5646 filedata->section_headers = (Elf_Internal_Shdr *)
5647 cmalloc (num, sizeof (Elf_Internal_Shdr));
5648 if (filedata->section_headers == NULL)
9ea033b2 5649 {
049b0c3a 5650 if (! probe)
8b73c356 5651 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5652 free (shdrs);
049b0c3a 5653 return FALSE;
9ea033b2
NC
5654 }
5655
dda8d76d 5656 for (i = 0, internal = filedata->section_headers;
560f3c1c 5657 i < num;
b34976b6 5658 i++, internal++)
9ea033b2
NC
5659 {
5660 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5661 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5662 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5663 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5664 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5665 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5666 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5667 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5668 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5669 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5670 if (!probe && internal->sh_link > num)
5671 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5672 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5673 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5674 }
5675
5676 free (shdrs);
049b0c3a 5677 return TRUE;
9ea033b2
NC
5678}
5679
252b5132 5680static Elf_Internal_Sym *
dda8d76d
NC
5681get_32bit_elf_symbols (Filedata * filedata,
5682 Elf_Internal_Shdr * section,
5683 unsigned long * num_syms_return)
252b5132 5684{
ba5cdace 5685 unsigned long number = 0;
dd24e3da 5686 Elf32_External_Sym * esyms = NULL;
ba5cdace 5687 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5688 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5689 Elf_Internal_Sym * psym;
b34976b6 5690 unsigned int j;
e3d39609 5691 elf_section_list * entry;
252b5132 5692
c9c1d674
EG
5693 if (section->sh_size == 0)
5694 {
5695 if (num_syms_return != NULL)
5696 * num_syms_return = 0;
5697 return NULL;
5698 }
5699
dd24e3da 5700 /* Run some sanity checks first. */
c9c1d674 5701 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5702 {
c9c1d674 5703 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5704 printable_section_name (filedata, section),
5705 (unsigned long) section->sh_entsize);
ba5cdace 5706 goto exit_point;
dd24e3da
NC
5707 }
5708
dda8d76d 5709 if (section->sh_size > filedata->file_size)
f54498b4
NC
5710 {
5711 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5712 printable_section_name (filedata, section),
5713 (unsigned long) section->sh_size);
f54498b4
NC
5714 goto exit_point;
5715 }
5716
dd24e3da
NC
5717 number = section->sh_size / section->sh_entsize;
5718
5719 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5720 {
c9c1d674 5721 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5722 (unsigned long) section->sh_size,
dda8d76d 5723 printable_section_name (filedata, section),
8066deb1 5724 (unsigned long) section->sh_entsize);
ba5cdace 5725 goto exit_point;
dd24e3da
NC
5726 }
5727
dda8d76d 5728 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5729 section->sh_size, _("symbols"));
dd24e3da 5730 if (esyms == NULL)
ba5cdace 5731 goto exit_point;
252b5132 5732
e3d39609 5733 shndx = NULL;
978c4450 5734 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5735 {
5736 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5737 continue;
5738
5739 if (shndx != NULL)
5740 {
5741 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5742 free (shndx);
5743 }
5744
5745 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5746 entry->hdr->sh_offset,
5747 1, entry->hdr->sh_size,
5748 _("symbol table section indices"));
5749 if (shndx == NULL)
5750 goto exit_point;
5751
5752 /* PR17531: file: heap-buffer-overflow */
5753 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5754 {
5755 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5756 printable_section_name (filedata, entry->hdr),
5757 (unsigned long) entry->hdr->sh_size,
5758 (unsigned long) section->sh_size);
5759 goto exit_point;
c9c1d674 5760 }
e3d39609 5761 }
9ad5cbcf 5762
3f5e193b 5763 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5764
5765 if (isyms == NULL)
5766 {
8b73c356
NC
5767 error (_("Out of memory reading %lu symbols\n"),
5768 (unsigned long) number);
dd24e3da 5769 goto exit_point;
252b5132
RH
5770 }
5771
dd24e3da 5772 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5773 {
5774 psym->st_name = BYTE_GET (esyms[j].st_name);
5775 psym->st_value = BYTE_GET (esyms[j].st_value);
5776 psym->st_size = BYTE_GET (esyms[j].st_size);
5777 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5778 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5779 psym->st_shndx
5780 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5781 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5782 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5783 psym->st_info = BYTE_GET (esyms[j].st_info);
5784 psym->st_other = BYTE_GET (esyms[j].st_other);
5785 }
5786
dd24e3da 5787 exit_point:
e3d39609
NC
5788 free (shndx);
5789 free (esyms);
252b5132 5790
ba5cdace
NC
5791 if (num_syms_return != NULL)
5792 * num_syms_return = isyms == NULL ? 0 : number;
5793
252b5132
RH
5794 return isyms;
5795}
5796
9ea033b2 5797static Elf_Internal_Sym *
dda8d76d
NC
5798get_64bit_elf_symbols (Filedata * filedata,
5799 Elf_Internal_Shdr * section,
5800 unsigned long * num_syms_return)
9ea033b2 5801{
ba5cdace
NC
5802 unsigned long number = 0;
5803 Elf64_External_Sym * esyms = NULL;
5804 Elf_External_Sym_Shndx * shndx = NULL;
5805 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5806 Elf_Internal_Sym * psym;
b34976b6 5807 unsigned int j;
e3d39609 5808 elf_section_list * entry;
9ea033b2 5809
c9c1d674
EG
5810 if (section->sh_size == 0)
5811 {
5812 if (num_syms_return != NULL)
5813 * num_syms_return = 0;
5814 return NULL;
5815 }
5816
dd24e3da 5817 /* Run some sanity checks first. */
c9c1d674 5818 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5819 {
c9c1d674 5820 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5821 printable_section_name (filedata, section),
8066deb1 5822 (unsigned long) section->sh_entsize);
ba5cdace 5823 goto exit_point;
dd24e3da
NC
5824 }
5825
dda8d76d 5826 if (section->sh_size > filedata->file_size)
f54498b4
NC
5827 {
5828 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5829 printable_section_name (filedata, section),
8066deb1 5830 (unsigned long) section->sh_size);
f54498b4
NC
5831 goto exit_point;
5832 }
5833
dd24e3da
NC
5834 number = section->sh_size / section->sh_entsize;
5835
5836 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5837 {
c9c1d674 5838 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5839 (unsigned long) section->sh_size,
dda8d76d 5840 printable_section_name (filedata, section),
8066deb1 5841 (unsigned long) section->sh_entsize);
ba5cdace 5842 goto exit_point;
dd24e3da
NC
5843 }
5844
dda8d76d 5845 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5846 section->sh_size, _("symbols"));
a6e9f9df 5847 if (!esyms)
ba5cdace 5848 goto exit_point;
9ea033b2 5849
e3d39609 5850 shndx = NULL;
978c4450 5851 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5852 {
5853 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5854 continue;
5855
5856 if (shndx != NULL)
5857 {
5858 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5859 free (shndx);
c9c1d674 5860 }
e3d39609
NC
5861
5862 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5863 entry->hdr->sh_offset,
5864 1, entry->hdr->sh_size,
5865 _("symbol table section indices"));
5866 if (shndx == NULL)
5867 goto exit_point;
5868
5869 /* PR17531: file: heap-buffer-overflow */
5870 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5871 {
5872 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5873 printable_section_name (filedata, entry->hdr),
5874 (unsigned long) entry->hdr->sh_size,
5875 (unsigned long) section->sh_size);
5876 goto exit_point;
5877 }
5878 }
9ad5cbcf 5879
3f5e193b 5880 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5881
5882 if (isyms == NULL)
5883 {
8b73c356
NC
5884 error (_("Out of memory reading %lu symbols\n"),
5885 (unsigned long) number);
ba5cdace 5886 goto exit_point;
9ea033b2
NC
5887 }
5888
ba5cdace 5889 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5890 {
5891 psym->st_name = BYTE_GET (esyms[j].st_name);
5892 psym->st_info = BYTE_GET (esyms[j].st_info);
5893 psym->st_other = BYTE_GET (esyms[j].st_other);
5894 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5895
4fbb74a6 5896 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5897 psym->st_shndx
5898 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5899 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5900 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5901
66543521
AM
5902 psym->st_value = BYTE_GET (esyms[j].st_value);
5903 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5904 }
5905
ba5cdace 5906 exit_point:
e3d39609
NC
5907 free (shndx);
5908 free (esyms);
ba5cdace
NC
5909
5910 if (num_syms_return != NULL)
5911 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5912
5913 return isyms;
5914}
5915
d1133906 5916static const char *
dda8d76d 5917get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5918{
5477e8a0 5919 static char buff[1024];
2cf0635d 5920 char * p = buff;
32ec8896
NC
5921 unsigned int field_size = is_32bit_elf ? 8 : 16;
5922 signed int sindex;
5923 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5924 bfd_vma os_flags = 0;
5925 bfd_vma proc_flags = 0;
5926 bfd_vma unknown_flags = 0;
148b93f2 5927 static const struct
5477e8a0 5928 {
2cf0635d 5929 const char * str;
32ec8896 5930 unsigned int len;
5477e8a0
L
5931 }
5932 flags [] =
5933 {
cfcac11d
NC
5934 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5935 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5936 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5937 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5938 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5939 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5940 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5941 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5942 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5943 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5944 /* IA-64 specific. */
5945 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5946 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5947 /* IA-64 OpenVMS specific. */
5948 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5949 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5950 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5951 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5952 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5953 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5954 /* Generic. */
cfcac11d 5955 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5956 /* SPARC specific. */
77115a4a 5957 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5958 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5959 /* ARM specific. */
5960 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5961 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5962 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5963 /* GNU specific. */
5964 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5965 /* VLE specific. */
5966 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5967 };
5968
5969 if (do_section_details)
5970 {
8d5ff12c
L
5971 sprintf (buff, "[%*.*lx]: ",
5972 field_size, field_size, (unsigned long) sh_flags);
5973 p += field_size + 4;
5477e8a0 5974 }
76da6bbe 5975
d1133906
NC
5976 while (sh_flags)
5977 {
5978 bfd_vma flag;
5979
5980 flag = sh_flags & - sh_flags;
5981 sh_flags &= ~ flag;
76da6bbe 5982
5477e8a0 5983 if (do_section_details)
d1133906 5984 {
5477e8a0
L
5985 switch (flag)
5986 {
91d6fa6a
NC
5987 case SHF_WRITE: sindex = 0; break;
5988 case SHF_ALLOC: sindex = 1; break;
5989 case SHF_EXECINSTR: sindex = 2; break;
5990 case SHF_MERGE: sindex = 3; break;
5991 case SHF_STRINGS: sindex = 4; break;
5992 case SHF_INFO_LINK: sindex = 5; break;
5993 case SHF_LINK_ORDER: sindex = 6; break;
5994 case SHF_OS_NONCONFORMING: sindex = 7; break;
5995 case SHF_GROUP: sindex = 8; break;
5996 case SHF_TLS: sindex = 9; break;
18ae9cc1 5997 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5998 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5999 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 6000
5477e8a0 6001 default:
91d6fa6a 6002 sindex = -1;
dda8d76d 6003 switch (filedata->file_header.e_machine)
148b93f2 6004 {
cfcac11d 6005 case EM_IA_64:
148b93f2 6006 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6007 sindex = 10;
148b93f2 6008 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6009 sindex = 11;
148b93f2 6010#ifdef BFD64
dda8d76d 6011 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6012 switch (flag)
6013 {
91d6fa6a
NC
6014 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6015 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6016 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6017 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6018 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6019 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6020 default: break;
6021 }
6022#endif
cfcac11d
NC
6023 break;
6024
caa83f8b 6025 case EM_386:
22abe556 6026 case EM_IAMCU:
caa83f8b 6027 case EM_X86_64:
7f502d6c 6028 case EM_L1OM:
7a9068fe 6029 case EM_K1OM:
cfcac11d
NC
6030 case EM_OLD_SPARCV9:
6031 case EM_SPARC32PLUS:
6032 case EM_SPARCV9:
6033 case EM_SPARC:
18ae9cc1 6034 if (flag == SHF_ORDERED)
91d6fa6a 6035 sindex = 19;
cfcac11d 6036 break;
ac4c9b04
MG
6037
6038 case EM_ARM:
6039 switch (flag)
6040 {
6041 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6042 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6043 case SHF_COMDEF: sindex = 23; break;
6044 default: break;
6045 }
6046 break;
83eef883
AFB
6047 case EM_PPC:
6048 if (flag == SHF_PPC_VLE)
6049 sindex = 25;
6050 break;
ac4c9b04 6051
cfcac11d
NC
6052 default:
6053 break;
148b93f2 6054 }
5477e8a0
L
6055 }
6056
91d6fa6a 6057 if (sindex != -1)
5477e8a0 6058 {
8d5ff12c
L
6059 if (p != buff + field_size + 4)
6060 {
6061 if (size < (10 + 2))
bee0ee85
NC
6062 {
6063 warn (_("Internal error: not enough buffer room for section flag info"));
6064 return _("<unknown>");
6065 }
8d5ff12c
L
6066 size -= 2;
6067 *p++ = ',';
6068 *p++ = ' ';
6069 }
6070
91d6fa6a
NC
6071 size -= flags [sindex].len;
6072 p = stpcpy (p, flags [sindex].str);
5477e8a0 6073 }
3b22753a 6074 else if (flag & SHF_MASKOS)
8d5ff12c 6075 os_flags |= flag;
d1133906 6076 else if (flag & SHF_MASKPROC)
8d5ff12c 6077 proc_flags |= flag;
d1133906 6078 else
8d5ff12c 6079 unknown_flags |= flag;
5477e8a0
L
6080 }
6081 else
6082 {
6083 switch (flag)
6084 {
6085 case SHF_WRITE: *p = 'W'; break;
6086 case SHF_ALLOC: *p = 'A'; break;
6087 case SHF_EXECINSTR: *p = 'X'; break;
6088 case SHF_MERGE: *p = 'M'; break;
6089 case SHF_STRINGS: *p = 'S'; break;
6090 case SHF_INFO_LINK: *p = 'I'; break;
6091 case SHF_LINK_ORDER: *p = 'L'; break;
6092 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6093 case SHF_GROUP: *p = 'G'; break;
6094 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6095 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6096 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 6097 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
6098
6099 default:
dda8d76d
NC
6100 if ((filedata->file_header.e_machine == EM_X86_64
6101 || filedata->file_header.e_machine == EM_L1OM
6102 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6103 && flag == SHF_X86_64_LARGE)
6104 *p = 'l';
dda8d76d 6105 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6106 && flag == SHF_ARM_PURECODE)
91f68a68 6107 *p = 'y';
dda8d76d 6108 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
6109 && flag == SHF_PPC_VLE)
6110 *p = 'v';
5477e8a0
L
6111 else if (flag & SHF_MASKOS)
6112 {
6113 *p = 'o';
6114 sh_flags &= ~ SHF_MASKOS;
6115 }
6116 else if (flag & SHF_MASKPROC)
6117 {
6118 *p = 'p';
6119 sh_flags &= ~ SHF_MASKPROC;
6120 }
6121 else
6122 *p = 'x';
6123 break;
6124 }
6125 p++;
d1133906
NC
6126 }
6127 }
76da6bbe 6128
8d5ff12c
L
6129 if (do_section_details)
6130 {
6131 if (os_flags)
6132 {
6133 size -= 5 + field_size;
6134 if (p != buff + field_size + 4)
6135 {
6136 if (size < (2 + 1))
bee0ee85
NC
6137 {
6138 warn (_("Internal error: not enough buffer room for section flag info"));
6139 return _("<unknown>");
6140 }
8d5ff12c
L
6141 size -= 2;
6142 *p++ = ',';
6143 *p++ = ' ';
6144 }
6145 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6146 (unsigned long) os_flags);
6147 p += 5 + field_size;
6148 }
6149 if (proc_flags)
6150 {
6151 size -= 7 + field_size;
6152 if (p != buff + field_size + 4)
6153 {
6154 if (size < (2 + 1))
bee0ee85
NC
6155 {
6156 warn (_("Internal error: not enough buffer room for section flag info"));
6157 return _("<unknown>");
6158 }
8d5ff12c
L
6159 size -= 2;
6160 *p++ = ',';
6161 *p++ = ' ';
6162 }
6163 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6164 (unsigned long) proc_flags);
6165 p += 7 + field_size;
6166 }
6167 if (unknown_flags)
6168 {
6169 size -= 10 + field_size;
6170 if (p != buff + field_size + 4)
6171 {
6172 if (size < (2 + 1))
bee0ee85
NC
6173 {
6174 warn (_("Internal error: not enough buffer room for section flag info"));
6175 return _("<unknown>");
6176 }
8d5ff12c
L
6177 size -= 2;
6178 *p++ = ',';
6179 *p++ = ' ';
6180 }
2b692964 6181 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6182 (unsigned long) unknown_flags);
6183 p += 10 + field_size;
6184 }
6185 }
6186
e9e44622 6187 *p = '\0';
d1133906
NC
6188 return buff;
6189}
6190
5844b465 6191static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6192get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6193{
6194 if (is_32bit_elf)
6195 {
6196 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6197
ebdf1ebf
NC
6198 if (size < sizeof (* echdr))
6199 {
6200 error (_("Compressed section is too small even for a compression header\n"));
6201 return 0;
6202 }
6203
77115a4a
L
6204 chdr->ch_type = BYTE_GET (echdr->ch_type);
6205 chdr->ch_size = BYTE_GET (echdr->ch_size);
6206 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6207 return sizeof (*echdr);
6208 }
6209 else
6210 {
6211 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6212
ebdf1ebf
NC
6213 if (size < sizeof (* echdr))
6214 {
6215 error (_("Compressed section is too small even for a compression header\n"));
6216 return 0;
6217 }
6218
77115a4a
L
6219 chdr->ch_type = BYTE_GET (echdr->ch_type);
6220 chdr->ch_size = BYTE_GET (echdr->ch_size);
6221 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6222 return sizeof (*echdr);
6223 }
6224}
6225
32ec8896 6226static bfd_boolean
dda8d76d 6227process_section_headers (Filedata * filedata)
252b5132 6228{
2cf0635d 6229 Elf_Internal_Shdr * section;
b34976b6 6230 unsigned int i;
252b5132 6231
8fb879cd 6232 free (filedata->section_headers);
dda8d76d 6233 filedata->section_headers = NULL;
978c4450
AM
6234 free (filedata->dynamic_symbols);
6235 filedata->dynamic_symbols = NULL;
6236 filedata->num_dynamic_syms = 0;
6237 free (filedata->dynamic_strings);
6238 filedata->dynamic_strings = NULL;
6239 filedata->dynamic_strings_length = 0;
6240 free (filedata->dynamic_syminfo);
6241 filedata->dynamic_syminfo = NULL;
6242 while (filedata->symtab_shndx_list != NULL)
8ff66993 6243 {
978c4450
AM
6244 elf_section_list *next = filedata->symtab_shndx_list->next;
6245 free (filedata->symtab_shndx_list);
6246 filedata->symtab_shndx_list = next;
8ff66993 6247 }
252b5132 6248
dda8d76d 6249 if (filedata->file_header.e_shnum == 0)
252b5132 6250 {
82f2dbf7 6251 /* PR binutils/12467. */
dda8d76d 6252 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6253 {
6254 warn (_("possibly corrupt ELF file header - it has a non-zero"
6255 " section header offset, but no section headers\n"));
6256 return FALSE;
6257 }
82f2dbf7 6258 else if (do_sections)
252b5132
RH
6259 printf (_("\nThere are no sections in this file.\n"));
6260
32ec8896 6261 return TRUE;
252b5132
RH
6262 }
6263
6264 if (do_sections && !do_header)
d3a49aa8
AM
6265 printf (ngettext ("There is %d section header, "
6266 "starting at offset 0x%lx:\n",
6267 "There are %d section headers, "
6268 "starting at offset 0x%lx:\n",
dda8d76d
NC
6269 filedata->file_header.e_shnum),
6270 filedata->file_header.e_shnum,
6271 (unsigned long) filedata->file_header.e_shoff);
252b5132 6272
9ea033b2
NC
6273 if (is_32bit_elf)
6274 {
dda8d76d 6275 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6276 return FALSE;
6277 }
6278 else
6279 {
dda8d76d 6280 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6281 return FALSE;
9ea033b2 6282 }
252b5132
RH
6283
6284 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6285 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6286 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6287 {
dda8d76d 6288 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6289
c256ffe7
JJ
6290 if (section->sh_size != 0)
6291 {
dda8d76d
NC
6292 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6293 1, section->sh_size,
6294 _("string table"));
0de14b54 6295
dda8d76d 6296 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6297 }
252b5132
RH
6298 }
6299
6300 /* Scan the sections for the dynamic symbol table
e3c8793a 6301 and dynamic string table and debug sections. */
89fac5e3 6302 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6303 switch (filedata->file_header.e_machine)
89fac5e3
RS
6304 {
6305 case EM_MIPS:
6306 case EM_MIPS_RS3_LE:
6307 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6308 FDE addresses. However, the ABI also has a semi-official ILP32
6309 variant for which the normal FDE address size rules apply.
6310
6311 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6312 section, where XX is the size of longs in bits. Unfortunately,
6313 earlier compilers provided no way of distinguishing ILP32 objects
6314 from LP64 objects, so if there's any doubt, we should assume that
6315 the official LP64 form is being used. */
dda8d76d
NC
6316 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6317 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6318 eh_addr_size = 8;
6319 break;
0f56a26a
DD
6320
6321 case EM_H8_300:
6322 case EM_H8_300H:
dda8d76d 6323 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6324 {
6325 case E_H8_MACH_H8300:
6326 case E_H8_MACH_H8300HN:
6327 case E_H8_MACH_H8300SN:
6328 case E_H8_MACH_H8300SXN:
6329 eh_addr_size = 2;
6330 break;
6331 case E_H8_MACH_H8300H:
6332 case E_H8_MACH_H8300S:
6333 case E_H8_MACH_H8300SX:
6334 eh_addr_size = 4;
6335 break;
6336 }
f4236fe4
DD
6337 break;
6338
ff7eeb89 6339 case EM_M32C_OLD:
f4236fe4 6340 case EM_M32C:
dda8d76d 6341 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6342 {
6343 case EF_M32C_CPU_M16C:
6344 eh_addr_size = 2;
6345 break;
6346 }
6347 break;
89fac5e3
RS
6348 }
6349
76ca31c0
NC
6350#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6351 do \
6352 { \
6353 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6354 if (section->sh_entsize != expected_entsize) \
9dd3a467 6355 { \
76ca31c0
NC
6356 char buf[40]; \
6357 sprintf_vma (buf, section->sh_entsize); \
6358 /* Note: coded this way so that there is a single string for \
6359 translation. */ \
6360 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6361 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6362 (unsigned) expected_entsize); \
9dd3a467 6363 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6364 } \
6365 } \
08d8fa11 6366 while (0)
9dd3a467
NC
6367
6368#define CHECK_ENTSIZE(section, i, type) \
1b513401 6369 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6370 sizeof (Elf64_External_##type))
6371
dda8d76d
NC
6372 for (i = 0, section = filedata->section_headers;
6373 i < filedata->file_header.e_shnum;
b34976b6 6374 i++, section++)
252b5132 6375 {
2cf0635d 6376 char * name = SECTION_NAME (section);
252b5132 6377
1b513401
NC
6378 /* Run some sanity checks on the headers and
6379 possibly fill in some file data as well. */
6380 switch (section->sh_type)
252b5132 6381 {
1b513401 6382 case SHT_DYNSYM:
978c4450 6383 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6384 {
6385 error (_("File contains multiple dynamic symbol tables\n"));
6386 continue;
6387 }
6388
08d8fa11 6389 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6390 filedata->dynamic_symbols
6391 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6392 filedata->dynamic_symtab_section = section;
1b513401
NC
6393 break;
6394
6395 case SHT_STRTAB:
6396 if (streq (name, ".dynstr"))
252b5132 6397 {
1b513401
NC
6398 if (filedata->dynamic_strings != NULL)
6399 {
6400 error (_("File contains multiple dynamic string tables\n"));
6401 continue;
6402 }
6403
6404 filedata->dynamic_strings
6405 = (char *) get_data (NULL, filedata, section->sh_offset,
6406 1, section->sh_size, _("dynamic strings"));
6407 filedata->dynamic_strings_length
6408 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6409 filedata->dynamic_strtab_section = section;
252b5132 6410 }
1b513401
NC
6411 break;
6412
6413 case SHT_SYMTAB_SHNDX:
6414 {
6415 elf_section_list * entry = xmalloc (sizeof * entry);
6416
6417 entry->hdr = section;
6418 entry->next = filedata->symtab_shndx_list;
6419 filedata->symtab_shndx_list = entry;
6420 }
6421 break;
6422
6423 case SHT_SYMTAB:
6424 CHECK_ENTSIZE (section, i, Sym);
6425 break;
6426
6427 case SHT_GROUP:
6428 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6429 break;
252b5132 6430
1b513401
NC
6431 case SHT_REL:
6432 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6433 if (do_checks && section->sh_size == 0)
1b513401
NC
6434 warn (_("Section '%s': zero-sized relocation section\n"), name);
6435 break;
6436
6437 case SHT_RELA:
6438 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6439 if (do_checks && section->sh_size == 0)
1b513401
NC
6440 warn (_("Section '%s': zero-sized relocation section\n"), name);
6441 break;
6442
6443 case SHT_NOTE:
6444 case SHT_PROGBITS:
546cb2d8
NC
6445 /* Having a zero sized section is not illegal according to the
6446 ELF standard, but it might be an indication that something
6447 is wrong. So issue a warning if we are running in lint mode. */
6448 if (do_checks && section->sh_size == 0)
1b513401
NC
6449 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6450 break;
6451
6452 default:
6453 break;
6454 }
6455
6456 if ((do_debugging || do_debug_info || do_debug_abbrevs
6457 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6458 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e4b7104b 6459 || do_debug_str || do_debug_str_offsets || do_debug_loc || do_debug_ranges
1b513401
NC
6460 || do_debug_addr || do_debug_cu_index || do_debug_links)
6461 && (const_strneq (name, ".debug_")
6462 || const_strneq (name, ".zdebug_")))
252b5132 6463 {
1b315056
CS
6464 if (name[1] == 'z')
6465 name += sizeof (".zdebug_") - 1;
6466 else
6467 name += sizeof (".debug_") - 1;
252b5132
RH
6468
6469 if (do_debugging
4723351a
CC
6470 || (do_debug_info && const_strneq (name, "info"))
6471 || (do_debug_info && const_strneq (name, "types"))
6472 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6473 || (do_debug_lines && strcmp (name, "line") == 0)
6474 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6475 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6476 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6477 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6478 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6479 || (do_debug_aranges && const_strneq (name, "aranges"))
6480 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6481 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6482 || (do_debug_frames && const_strneq (name, "frame"))
6483 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6484 || (do_debug_macinfo && const_strneq (name, "macro"))
6485 || (do_debug_str && const_strneq (name, "str"))
e4b7104b 6486 || (do_debug_str_offsets && const_strneq (name, "str_offsets"))
4723351a 6487 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6488 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6489 || (do_debug_addr && const_strneq (name, "addr"))
6490 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6491 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6492 )
6431e409 6493 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6494 }
a262ae96 6495 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6496 else if ((do_debugging || do_debug_info)
0112cd26 6497 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6498 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6499 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6500 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6501 else if (do_gdb_index && (streq (name, ".gdb_index")
6502 || streq (name, ".debug_names")))
6431e409 6503 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6504 /* Trace sections for Itanium VMS. */
6505 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6506 || do_trace_aranges)
6507 && const_strneq (name, ".trace_"))
6508 {
6509 name += sizeof (".trace_") - 1;
6510
6511 if (do_debugging
6512 || (do_trace_info && streq (name, "info"))
6513 || (do_trace_abbrevs && streq (name, "abbrev"))
6514 || (do_trace_aranges && streq (name, "aranges"))
6515 )
6431e409 6516 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6517 }
dda8d76d
NC
6518 else if ((do_debugging || do_debug_links)
6519 && (const_strneq (name, ".gnu_debuglink")
6520 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6521 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6522 }
6523
6524 if (! do_sections)
32ec8896 6525 return TRUE;
252b5132 6526
dda8d76d 6527 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6528 printf (_("\nSection Headers:\n"));
6529 else
6530 printf (_("\nSection Header:\n"));
76da6bbe 6531
f7a99963 6532 if (is_32bit_elf)
595cf52e 6533 {
5477e8a0 6534 if (do_section_details)
595cf52e
L
6535 {
6536 printf (_(" [Nr] Name\n"));
5477e8a0 6537 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6538 }
6539 else
6540 printf
6541 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6542 }
d974e256 6543 else if (do_wide)
595cf52e 6544 {
5477e8a0 6545 if (do_section_details)
595cf52e
L
6546 {
6547 printf (_(" [Nr] Name\n"));
5477e8a0 6548 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6549 }
6550 else
6551 printf
6552 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6553 }
f7a99963
NC
6554 else
6555 {
5477e8a0 6556 if (do_section_details)
595cf52e
L
6557 {
6558 printf (_(" [Nr] Name\n"));
5477e8a0
L
6559 printf (_(" Type Address Offset Link\n"));
6560 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6561 }
6562 else
6563 {
6564 printf (_(" [Nr] Name Type Address Offset\n"));
6565 printf (_(" Size EntSize Flags Link Info Align\n"));
6566 }
f7a99963 6567 }
252b5132 6568
5477e8a0
L
6569 if (do_section_details)
6570 printf (_(" Flags\n"));
6571
dda8d76d
NC
6572 for (i = 0, section = filedata->section_headers;
6573 i < filedata->file_header.e_shnum;
b34976b6 6574 i++, section++)
252b5132 6575 {
dd905818
NC
6576 /* Run some sanity checks on the section header. */
6577
6578 /* Check the sh_link field. */
6579 switch (section->sh_type)
6580 {
285e3f99
AM
6581 case SHT_REL:
6582 case SHT_RELA:
6583 if (section->sh_link == 0
6584 && (filedata->file_header.e_type == ET_EXEC
6585 || filedata->file_header.e_type == ET_DYN))
6586 /* A dynamic relocation section where all entries use a
6587 zero symbol index need not specify a symtab section. */
6588 break;
6589 /* Fall through. */
dd905818
NC
6590 case SHT_SYMTAB_SHNDX:
6591 case SHT_GROUP:
6592 case SHT_HASH:
6593 case SHT_GNU_HASH:
6594 case SHT_GNU_versym:
285e3f99 6595 if (section->sh_link == 0
dda8d76d
NC
6596 || section->sh_link >= filedata->file_header.e_shnum
6597 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6598 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6599 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6600 i, section->sh_link);
6601 break;
6602
6603 case SHT_DYNAMIC:
6604 case SHT_SYMTAB:
6605 case SHT_DYNSYM:
6606 case SHT_GNU_verneed:
6607 case SHT_GNU_verdef:
6608 case SHT_GNU_LIBLIST:
285e3f99 6609 if (section->sh_link == 0
dda8d76d
NC
6610 || section->sh_link >= filedata->file_header.e_shnum
6611 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6612 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6613 i, section->sh_link);
6614 break;
6615
6616 case SHT_INIT_ARRAY:
6617 case SHT_FINI_ARRAY:
6618 case SHT_PREINIT_ARRAY:
6619 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6620 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6621 i, section->sh_link);
6622 break;
6623
6624 default:
6625 /* FIXME: Add support for target specific section types. */
6626#if 0 /* Currently we do not check other section types as there are too
6627 many special cases. Stab sections for example have a type
6628 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6629 section. */
6630 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6631 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6632 i, section->sh_link);
6633#endif
6634 break;
6635 }
6636
6637 /* Check the sh_info field. */
6638 switch (section->sh_type)
6639 {
6640 case SHT_REL:
6641 case SHT_RELA:
285e3f99
AM
6642 if (section->sh_info == 0
6643 && (filedata->file_header.e_type == ET_EXEC
6644 || filedata->file_header.e_type == ET_DYN))
6645 /* Dynamic relocations apply to segments, so they do not
6646 need to specify the section they relocate. */
6647 break;
6648 if (section->sh_info == 0
dda8d76d
NC
6649 || section->sh_info >= filedata->file_header.e_shnum
6650 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6651 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6652 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6653 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6654 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6655 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6656 /* FIXME: Are other section types valid ? */
dda8d76d 6657 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6658 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6659 i, section->sh_info);
dd905818
NC
6660 break;
6661
6662 case SHT_DYNAMIC:
6663 case SHT_HASH:
6664 case SHT_SYMTAB_SHNDX:
6665 case SHT_INIT_ARRAY:
6666 case SHT_FINI_ARRAY:
6667 case SHT_PREINIT_ARRAY:
6668 if (section->sh_info != 0)
6669 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6670 i, section->sh_info);
6671 break;
6672
6673 case SHT_GROUP:
6674 case SHT_SYMTAB:
6675 case SHT_DYNSYM:
6676 /* A symbol index - we assume that it is valid. */
6677 break;
6678
6679 default:
6680 /* FIXME: Add support for target specific section types. */
6681 if (section->sh_type == SHT_NOBITS)
6682 /* NOBITS section headers with non-zero sh_info fields can be
6683 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6684 information. The stripped sections have their headers
6685 preserved but their types set to SHT_NOBITS. So do not check
6686 this type of section. */
dd905818
NC
6687 ;
6688 else if (section->sh_flags & SHF_INFO_LINK)
6689 {
dda8d76d 6690 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6691 warn (_("[%2u]: Expected link to another section in info field"), i);
6692 }
a91e1603
L
6693 else if (section->sh_type < SHT_LOOS
6694 && (section->sh_flags & SHF_GNU_MBIND) == 0
6695 && section->sh_info != 0)
dd905818
NC
6696 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6697 i, section->sh_info);
6698 break;
6699 }
6700
3e6b6445 6701 /* Check the sh_size field. */
dda8d76d 6702 if (section->sh_size > filedata->file_size
3e6b6445
NC
6703 && section->sh_type != SHT_NOBITS
6704 && section->sh_type != SHT_NULL
6705 && section->sh_type < SHT_LOOS)
6706 warn (_("Size of section %u is larger than the entire file!\n"), i);
6707
7bfd842d 6708 printf (" [%2u] ", i);
5477e8a0 6709 if (do_section_details)
dda8d76d 6710 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6711 else
74e1a04b 6712 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6713
ea52a088 6714 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6715 get_section_type_name (filedata, section->sh_type));
0b4362b0 6716
f7a99963
NC
6717 if (is_32bit_elf)
6718 {
cfcac11d
NC
6719 const char * link_too_big = NULL;
6720
f7a99963 6721 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6722
f7a99963
NC
6723 printf ( " %6.6lx %6.6lx %2.2lx",
6724 (unsigned long) section->sh_offset,
6725 (unsigned long) section->sh_size,
6726 (unsigned long) section->sh_entsize);
d1133906 6727
5477e8a0
L
6728 if (do_section_details)
6729 fputs (" ", stdout);
6730 else
dda8d76d 6731 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6732
dda8d76d 6733 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6734 {
6735 link_too_big = "";
6736 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6737 an error but it can have special values in Solaris binaries. */
dda8d76d 6738 switch (filedata->file_header.e_machine)
cfcac11d 6739 {
caa83f8b 6740 case EM_386:
22abe556 6741 case EM_IAMCU:
caa83f8b 6742 case EM_X86_64:
7f502d6c 6743 case EM_L1OM:
7a9068fe 6744 case EM_K1OM:
cfcac11d
NC
6745 case EM_OLD_SPARCV9:
6746 case EM_SPARC32PLUS:
6747 case EM_SPARCV9:
6748 case EM_SPARC:
6749 if (section->sh_link == (SHN_BEFORE & 0xffff))
6750 link_too_big = "BEFORE";
6751 else if (section->sh_link == (SHN_AFTER & 0xffff))
6752 link_too_big = "AFTER";
6753 break;
6754 default:
6755 break;
6756 }
6757 }
6758
6759 if (do_section_details)
6760 {
6761 if (link_too_big != NULL && * link_too_big)
6762 printf ("<%s> ", link_too_big);
6763 else
6764 printf ("%2u ", section->sh_link);
6765 printf ("%3u %2lu\n", section->sh_info,
6766 (unsigned long) section->sh_addralign);
6767 }
6768 else
6769 printf ("%2u %3u %2lu\n",
6770 section->sh_link,
6771 section->sh_info,
6772 (unsigned long) section->sh_addralign);
6773
6774 if (link_too_big && ! * link_too_big)
6775 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6776 i, section->sh_link);
f7a99963 6777 }
d974e256
JJ
6778 else if (do_wide)
6779 {
6780 print_vma (section->sh_addr, LONG_HEX);
6781
6782 if ((long) section->sh_offset == section->sh_offset)
6783 printf (" %6.6lx", (unsigned long) section->sh_offset);
6784 else
6785 {
6786 putchar (' ');
6787 print_vma (section->sh_offset, LONG_HEX);
6788 }
6789
6790 if ((unsigned long) section->sh_size == section->sh_size)
6791 printf (" %6.6lx", (unsigned long) section->sh_size);
6792 else
6793 {
6794 putchar (' ');
6795 print_vma (section->sh_size, LONG_HEX);
6796 }
6797
6798 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6799 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6800 else
6801 {
6802 putchar (' ');
6803 print_vma (section->sh_entsize, LONG_HEX);
6804 }
6805
5477e8a0
L
6806 if (do_section_details)
6807 fputs (" ", stdout);
6808 else
dda8d76d 6809 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6810
72de5009 6811 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6812
6813 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6814 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6815 else
6816 {
6817 print_vma (section->sh_addralign, DEC);
6818 putchar ('\n');
6819 }
6820 }
5477e8a0 6821 else if (do_section_details)
595cf52e 6822 {
55cc53e9 6823 putchar (' ');
595cf52e
L
6824 print_vma (section->sh_addr, LONG_HEX);
6825 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6826 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6827 else
6828 {
6829 printf (" ");
6830 print_vma (section->sh_offset, LONG_HEX);
6831 }
72de5009 6832 printf (" %u\n ", section->sh_link);
595cf52e 6833 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6834 putchar (' ');
595cf52e
L
6835 print_vma (section->sh_entsize, LONG_HEX);
6836
72de5009
AM
6837 printf (" %-16u %lu\n",
6838 section->sh_info,
595cf52e
L
6839 (unsigned long) section->sh_addralign);
6840 }
f7a99963
NC
6841 else
6842 {
6843 putchar (' ');
6844 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6845 if ((long) section->sh_offset == section->sh_offset)
6846 printf (" %8.8lx", (unsigned long) section->sh_offset);
6847 else
6848 {
6849 printf (" ");
6850 print_vma (section->sh_offset, LONG_HEX);
6851 }
f7a99963
NC
6852 printf ("\n ");
6853 print_vma (section->sh_size, LONG_HEX);
6854 printf (" ");
6855 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6856
dda8d76d 6857 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6858
72de5009
AM
6859 printf (" %2u %3u %lu\n",
6860 section->sh_link,
6861 section->sh_info,
f7a99963
NC
6862 (unsigned long) section->sh_addralign);
6863 }
5477e8a0
L
6864
6865 if (do_section_details)
77115a4a 6866 {
dda8d76d 6867 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6868 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6869 {
6870 /* Minimum section size is 12 bytes for 32-bit compression
6871 header + 12 bytes for compressed data header. */
6872 unsigned char buf[24];
d8024a91 6873
77115a4a 6874 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6875 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6876 sizeof (buf), _("compression header")))
6877 {
6878 Elf_Internal_Chdr chdr;
d8024a91 6879
5844b465
NC
6880 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
6881 printf (_(" [<corrupt>]\n"));
77115a4a 6882 else
5844b465
NC
6883 {
6884 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6885 printf (" ZLIB, ");
6886 else
6887 printf (_(" [<unknown>: 0x%x], "),
6888 chdr.ch_type);
6889 print_vma (chdr.ch_size, LONG_HEX);
6890 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6891 }
77115a4a
L
6892 }
6893 }
6894 }
252b5132
RH
6895 }
6896
5477e8a0 6897 if (!do_section_details)
3dbcc61d 6898 {
9fb71ee4
NC
6899 /* The ordering of the letters shown here matches the ordering of the
6900 corresponding SHF_xxx values, and hence the order in which these
6901 letters will be displayed to the user. */
6902 printf (_("Key to Flags:\n\
6903 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6904 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6905 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6906 if (filedata->file_header.e_machine == EM_X86_64
6907 || filedata->file_header.e_machine == EM_L1OM
6908 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6909 printf (_("l (large), "));
dda8d76d 6910 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6911 printf (_("y (purecode), "));
dda8d76d 6912 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6913 printf (_("v (VLE), "));
9fb71ee4 6914 printf ("p (processor specific)\n");
0b4362b0 6915 }
d1133906 6916
32ec8896 6917 return TRUE;
252b5132
RH
6918}
6919
28d13567
AM
6920static bfd_boolean
6921get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
6922 Elf_Internal_Sym **symtab, unsigned long *nsyms,
6923 char **strtab, unsigned long *strtablen)
6924{
6925 *strtab = NULL;
6926 *strtablen = 0;
6927 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
6928
6929 if (*symtab == NULL)
6930 return FALSE;
6931
6932 if (symsec->sh_link != 0)
6933 {
6934 Elf_Internal_Shdr *strsec;
6935
6936 if (symsec->sh_link >= filedata->file_header.e_shnum)
6937 {
6938 error (_("Bad sh_link in symbol table section\n"));
6939 free (*symtab);
6940 *symtab = NULL;
6941 *nsyms = 0;
6942 return FALSE;
6943 }
6944
6945 strsec = filedata->section_headers + symsec->sh_link;
6946
6947 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
6948 1, strsec->sh_size, _("string table"));
6949 if (*strtab == NULL)
6950 {
6951 free (*symtab);
6952 *symtab = NULL;
6953 *nsyms = 0;
6954 return FALSE;
6955 }
6956 *strtablen = strsec->sh_size;
6957 }
6958 return TRUE;
6959}
6960
f5842774
L
6961static const char *
6962get_group_flags (unsigned int flags)
6963{
1449284b 6964 static char buff[128];
220453ec 6965
6d913794
NC
6966 if (flags == 0)
6967 return "";
6968 else if (flags == GRP_COMDAT)
6969 return "COMDAT ";
f5842774 6970
89246a0e
AM
6971 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
6972 flags,
6973 flags & GRP_MASKOS ? _("<OS specific>") : "",
6974 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
6975 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
6976 ? _("<unknown>") : ""));
6d913794 6977
f5842774
L
6978 return buff;
6979}
6980
32ec8896 6981static bfd_boolean
dda8d76d 6982process_section_groups (Filedata * filedata)
f5842774 6983{
2cf0635d 6984 Elf_Internal_Shdr * section;
f5842774 6985 unsigned int i;
2cf0635d
NC
6986 struct group * group;
6987 Elf_Internal_Shdr * symtab_sec;
6988 Elf_Internal_Shdr * strtab_sec;
6989 Elf_Internal_Sym * symtab;
ba5cdace 6990 unsigned long num_syms;
2cf0635d 6991 char * strtab;
c256ffe7 6992 size_t strtab_size;
d1f5c6e3
L
6993
6994 /* Don't process section groups unless needed. */
6995 if (!do_unwind && !do_section_groups)
32ec8896 6996 return TRUE;
f5842774 6997
dda8d76d 6998 if (filedata->file_header.e_shnum == 0)
f5842774
L
6999 {
7000 if (do_section_groups)
82f2dbf7 7001 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 7002
32ec8896 7003 return TRUE;
f5842774
L
7004 }
7005
dda8d76d 7006 if (filedata->section_headers == NULL)
f5842774
L
7007 {
7008 error (_("Section headers are not available!\n"));
fa1908fd 7009 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 7010 return FALSE;
f5842774
L
7011 }
7012
978c4450
AM
7013 filedata->section_headers_groups
7014 = (struct group **) calloc (filedata->file_header.e_shnum,
7015 sizeof (struct group *));
e4b17d5c 7016
978c4450 7017 if (filedata->section_headers_groups == NULL)
e4b17d5c 7018 {
8b73c356 7019 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7020 filedata->file_header.e_shnum);
32ec8896 7021 return FALSE;
e4b17d5c
L
7022 }
7023
f5842774 7024 /* Scan the sections for the group section. */
978c4450 7025 filedata->group_count = 0;
dda8d76d
NC
7026 for (i = 0, section = filedata->section_headers;
7027 i < filedata->file_header.e_shnum;
f5842774 7028 i++, section++)
e4b17d5c 7029 if (section->sh_type == SHT_GROUP)
978c4450 7030 filedata->group_count++;
e4b17d5c 7031
978c4450 7032 if (filedata->group_count == 0)
d1f5c6e3
L
7033 {
7034 if (do_section_groups)
7035 printf (_("\nThere are no section groups in this file.\n"));
7036
32ec8896 7037 return TRUE;
d1f5c6e3
L
7038 }
7039
978c4450
AM
7040 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7041 sizeof (struct group));
e4b17d5c 7042
978c4450 7043 if (filedata->section_groups == NULL)
e4b17d5c 7044 {
8b73c356 7045 error (_("Out of memory reading %lu groups\n"),
978c4450 7046 (unsigned long) filedata->group_count);
32ec8896 7047 return FALSE;
e4b17d5c
L
7048 }
7049
d1f5c6e3
L
7050 symtab_sec = NULL;
7051 strtab_sec = NULL;
7052 symtab = NULL;
ba5cdace 7053 num_syms = 0;
d1f5c6e3 7054 strtab = NULL;
c256ffe7 7055 strtab_size = 0;
978c4450 7056 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7057 i < filedata->file_header.e_shnum;
e4b17d5c 7058 i++, section++)
f5842774
L
7059 {
7060 if (section->sh_type == SHT_GROUP)
7061 {
dda8d76d 7062 const char * name = printable_section_name (filedata, section);
74e1a04b 7063 const char * group_name;
2cf0635d
NC
7064 unsigned char * start;
7065 unsigned char * indices;
f5842774 7066 unsigned int entry, j, size;
2cf0635d
NC
7067 Elf_Internal_Shdr * sec;
7068 Elf_Internal_Sym * sym;
f5842774
L
7069
7070 /* Get the symbol table. */
dda8d76d
NC
7071 if (section->sh_link >= filedata->file_header.e_shnum
7072 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7073 != SHT_SYMTAB))
f5842774
L
7074 {
7075 error (_("Bad sh_link in group section `%s'\n"), name);
7076 continue;
7077 }
d1f5c6e3
L
7078
7079 if (symtab_sec != sec)
7080 {
7081 symtab_sec = sec;
9db70fc3 7082 free (symtab);
dda8d76d 7083 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7084 }
f5842774 7085
dd24e3da
NC
7086 if (symtab == NULL)
7087 {
7088 error (_("Corrupt header in group section `%s'\n"), name);
7089 continue;
7090 }
7091
ba5cdace
NC
7092 if (section->sh_info >= num_syms)
7093 {
7094 error (_("Bad sh_info in group section `%s'\n"), name);
7095 continue;
7096 }
7097
f5842774
L
7098 sym = symtab + section->sh_info;
7099
7100 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7101 {
4fbb74a6 7102 if (sym->st_shndx == 0
dda8d76d 7103 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7104 {
7105 error (_("Bad sh_info in group section `%s'\n"), name);
7106 continue;
7107 }
ba2685cc 7108
dda8d76d 7109 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7 7110 strtab_sec = NULL;
9db70fc3 7111 free (strtab);
f5842774 7112 strtab = NULL;
c256ffe7 7113 strtab_size = 0;
f5842774
L
7114 }
7115 else
7116 {
7117 /* Get the string table. */
dda8d76d 7118 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7119 {
7120 strtab_sec = NULL;
9db70fc3 7121 free (strtab);
c256ffe7
JJ
7122 strtab = NULL;
7123 strtab_size = 0;
7124 }
7125 else if (strtab_sec
dda8d76d 7126 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7127 {
7128 strtab_sec = sec;
9db70fc3 7129 free (strtab);
071436c6 7130
dda8d76d 7131 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7132 1, strtab_sec->sh_size,
7133 _("string table"));
c256ffe7 7134 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7135 }
c256ffe7 7136 group_name = sym->st_name < strtab_size
2b692964 7137 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7138 }
7139
c9c1d674
EG
7140 /* PR 17531: file: loop. */
7141 if (section->sh_entsize > section->sh_size)
7142 {
7143 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7144 printable_section_name (filedata, section),
8066deb1
AM
7145 (unsigned long) section->sh_entsize,
7146 (unsigned long) section->sh_size);
61dd8e19 7147 continue;
c9c1d674
EG
7148 }
7149
dda8d76d 7150 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7151 1, section->sh_size,
7152 _("section data"));
59245841
NC
7153 if (start == NULL)
7154 continue;
f5842774
L
7155
7156 indices = start;
7157 size = (section->sh_size / section->sh_entsize) - 1;
7158 entry = byte_get (indices, 4);
7159 indices += 4;
e4b17d5c
L
7160
7161 if (do_section_groups)
7162 {
2b692964 7163 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7164 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7165
e4b17d5c
L
7166 printf (_(" [Index] Name\n"));
7167 }
7168
7169 group->group_index = i;
7170
f5842774
L
7171 for (j = 0; j < size; j++)
7172 {
2cf0635d 7173 struct group_list * g;
e4b17d5c 7174
f5842774
L
7175 entry = byte_get (indices, 4);
7176 indices += 4;
7177
dda8d76d 7178 if (entry >= filedata->file_header.e_shnum)
391cb864 7179 {
57028622
NC
7180 static unsigned num_group_errors = 0;
7181
7182 if (num_group_errors ++ < 10)
7183 {
7184 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7185 entry, i, filedata->file_header.e_shnum - 1);
57028622 7186 if (num_group_errors == 10)
67ce483b 7187 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7188 }
391cb864
L
7189 continue;
7190 }
391cb864 7191
978c4450 7192 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7193 {
d1f5c6e3
L
7194 if (entry)
7195 {
57028622
NC
7196 static unsigned num_errs = 0;
7197
7198 if (num_errs ++ < 10)
7199 {
7200 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7201 entry, i,
978c4450 7202 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7203 if (num_errs == 10)
7204 warn (_("Further error messages about already contained group sections suppressed\n"));
7205 }
d1f5c6e3
L
7206 continue;
7207 }
7208 else
7209 {
7210 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7211 section group. We just warn it the first time
d1f5c6e3 7212 and ignore it afterwards. */
32ec8896 7213 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7214 if (!warned)
7215 {
7216 error (_("section 0 in group section [%5u]\n"),
978c4450 7217 filedata->section_headers_groups [entry]->group_index);
32ec8896 7218 warned = TRUE;
d1f5c6e3
L
7219 }
7220 }
e4b17d5c
L
7221 }
7222
978c4450 7223 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7224
7225 if (do_section_groups)
7226 {
dda8d76d
NC
7227 sec = filedata->section_headers + entry;
7228 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7229 }
7230
3f5e193b 7231 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7232 g->section_index = entry;
7233 g->next = group->root;
7234 group->root = g;
f5842774
L
7235 }
7236
9db70fc3 7237 free (start);
e4b17d5c
L
7238
7239 group++;
f5842774
L
7240 }
7241 }
7242
9db70fc3
AM
7243 free (symtab);
7244 free (strtab);
32ec8896 7245 return TRUE;
f5842774
L
7246}
7247
28f997cf
TG
7248/* Data used to display dynamic fixups. */
7249
7250struct ia64_vms_dynfixup
7251{
7252 bfd_vma needed_ident; /* Library ident number. */
7253 bfd_vma needed; /* Index in the dstrtab of the library name. */
7254 bfd_vma fixup_needed; /* Index of the library. */
7255 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7256 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7257};
7258
7259/* Data used to display dynamic relocations. */
7260
7261struct ia64_vms_dynimgrela
7262{
7263 bfd_vma img_rela_cnt; /* Number of relocations. */
7264 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7265};
7266
7267/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7268 library). */
7269
32ec8896 7270static bfd_boolean
dda8d76d
NC
7271dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7272 struct ia64_vms_dynfixup * fixup,
7273 const char * strtab,
7274 unsigned int strtab_sz)
28f997cf 7275{
32ec8896 7276 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7277 long i;
32ec8896 7278 const char * lib_name;
28f997cf 7279
978c4450
AM
7280 imfs = get_data (NULL, filedata,
7281 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7282 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7283 _("dynamic section image fixups"));
7284 if (!imfs)
32ec8896 7285 return FALSE;
28f997cf
TG
7286
7287 if (fixup->needed < strtab_sz)
7288 lib_name = strtab + fixup->needed;
7289 else
7290 {
32ec8896 7291 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7292 (unsigned long) fixup->needed);
28f997cf
TG
7293 lib_name = "???";
7294 }
736990c4 7295
28f997cf
TG
7296 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7297 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7298 printf
7299 (_("Seg Offset Type SymVec DataType\n"));
7300
7301 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7302 {
7303 unsigned int type;
7304 const char *rtype;
7305
7306 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7307 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7308 type = BYTE_GET (imfs [i].type);
7309 rtype = elf_ia64_reloc_type (type);
7310 if (rtype == NULL)
7311 printf (" 0x%08x ", type);
7312 else
7313 printf (" %-32s ", rtype);
7314 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7315 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7316 }
7317
7318 free (imfs);
32ec8896 7319 return TRUE;
28f997cf
TG
7320}
7321
7322/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7323
32ec8896 7324static bfd_boolean
dda8d76d 7325dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7326{
7327 Elf64_External_VMS_IMAGE_RELA *imrs;
7328 long i;
7329
978c4450
AM
7330 imrs = get_data (NULL, filedata,
7331 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7332 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7333 _("dynamic section image relocations"));
28f997cf 7334 if (!imrs)
32ec8896 7335 return FALSE;
28f997cf
TG
7336
7337 printf (_("\nImage relocs\n"));
7338 printf
7339 (_("Seg Offset Type Addend Seg Sym Off\n"));
7340
7341 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7342 {
7343 unsigned int type;
7344 const char *rtype;
7345
7346 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7347 printf ("%08" BFD_VMA_FMT "x ",
7348 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7349 type = BYTE_GET (imrs [i].type);
7350 rtype = elf_ia64_reloc_type (type);
7351 if (rtype == NULL)
7352 printf ("0x%08x ", type);
7353 else
7354 printf ("%-31s ", rtype);
7355 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7356 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7357 printf ("%08" BFD_VMA_FMT "x\n",
7358 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7359 }
7360
7361 free (imrs);
32ec8896 7362 return TRUE;
28f997cf
TG
7363}
7364
7365/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7366
32ec8896 7367static bfd_boolean
dda8d76d 7368process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7369{
7370 struct ia64_vms_dynfixup fixup;
7371 struct ia64_vms_dynimgrela imgrela;
7372 Elf_Internal_Dyn *entry;
28f997cf
TG
7373 bfd_vma strtab_off = 0;
7374 bfd_vma strtab_sz = 0;
7375 char *strtab = NULL;
32ec8896 7376 bfd_boolean res = TRUE;
28f997cf
TG
7377
7378 memset (&fixup, 0, sizeof (fixup));
7379 memset (&imgrela, 0, sizeof (imgrela));
7380
7381 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7382 for (entry = filedata->dynamic_section;
7383 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7384 entry++)
7385 {
7386 switch (entry->d_tag)
7387 {
7388 case DT_IA_64_VMS_STRTAB_OFFSET:
7389 strtab_off = entry->d_un.d_val;
7390 break;
7391 case DT_STRSZ:
7392 strtab_sz = entry->d_un.d_val;
7393 if (strtab == NULL)
978c4450
AM
7394 strtab = get_data (NULL, filedata,
7395 filedata->dynamic_addr + strtab_off,
28f997cf 7396 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7397 if (strtab == NULL)
7398 strtab_sz = 0;
28f997cf
TG
7399 break;
7400
7401 case DT_IA_64_VMS_NEEDED_IDENT:
7402 fixup.needed_ident = entry->d_un.d_val;
7403 break;
7404 case DT_NEEDED:
7405 fixup.needed = entry->d_un.d_val;
7406 break;
7407 case DT_IA_64_VMS_FIXUP_NEEDED:
7408 fixup.fixup_needed = entry->d_un.d_val;
7409 break;
7410 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7411 fixup.fixup_rela_cnt = entry->d_un.d_val;
7412 break;
7413 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7414 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7415 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7416 res = FALSE;
28f997cf 7417 break;
28f997cf
TG
7418 case DT_IA_64_VMS_IMG_RELA_CNT:
7419 imgrela.img_rela_cnt = entry->d_un.d_val;
7420 break;
7421 case DT_IA_64_VMS_IMG_RELA_OFF:
7422 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7423 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7424 res = FALSE;
28f997cf
TG
7425 break;
7426
7427 default:
7428 break;
7429 }
7430 }
7431
9db70fc3 7432 free (strtab);
28f997cf
TG
7433
7434 return res;
7435}
7436
85b1c36d 7437static struct
566b0d53 7438{
2cf0635d 7439 const char * name;
566b0d53
L
7440 int reloc;
7441 int size;
7442 int rela;
32ec8896
NC
7443}
7444 dynamic_relocations [] =
566b0d53 7445{
32ec8896
NC
7446 { "REL", DT_REL, DT_RELSZ, FALSE },
7447 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7448 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7449};
7450
252b5132 7451/* Process the reloc section. */
18bd398b 7452
32ec8896 7453static bfd_boolean
dda8d76d 7454process_relocs (Filedata * filedata)
252b5132 7455{
b34976b6
AM
7456 unsigned long rel_size;
7457 unsigned long rel_offset;
252b5132 7458
252b5132 7459 if (!do_reloc)
32ec8896 7460 return TRUE;
252b5132
RH
7461
7462 if (do_using_dynamic)
7463 {
32ec8896 7464 int is_rela;
2cf0635d 7465 const char * name;
32ec8896 7466 bfd_boolean has_dynamic_reloc;
566b0d53 7467 unsigned int i;
0de14b54 7468
32ec8896 7469 has_dynamic_reloc = FALSE;
252b5132 7470
566b0d53 7471 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7472 {
566b0d53
L
7473 is_rela = dynamic_relocations [i].rela;
7474 name = dynamic_relocations [i].name;
978c4450
AM
7475 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7476 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7477
32ec8896
NC
7478 if (rel_size)
7479 has_dynamic_reloc = TRUE;
566b0d53
L
7480
7481 if (is_rela == UNKNOWN)
aa903cfb 7482 {
566b0d53 7483 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7484 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7485 {
7486 case DT_REL:
7487 is_rela = FALSE;
7488 break;
7489 case DT_RELA:
7490 is_rela = TRUE;
7491 break;
7492 }
aa903cfb 7493 }
252b5132 7494
566b0d53
L
7495 if (rel_size)
7496 {
7497 printf
7498 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7499 name, rel_offset, rel_size);
252b5132 7500
dda8d76d
NC
7501 dump_relocations (filedata,
7502 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7503 rel_size,
978c4450
AM
7504 filedata->dynamic_symbols,
7505 filedata->num_dynamic_syms,
7506 filedata->dynamic_strings,
7507 filedata->dynamic_strings_length,
32ec8896 7508 is_rela, TRUE /* is_dynamic */);
566b0d53 7509 }
252b5132 7510 }
566b0d53 7511
dda8d76d
NC
7512 if (is_ia64_vms (filedata))
7513 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7514 has_dynamic_reloc = TRUE;
28f997cf 7515
566b0d53 7516 if (! has_dynamic_reloc)
252b5132
RH
7517 printf (_("\nThere are no dynamic relocations in this file.\n"));
7518 }
7519 else
7520 {
2cf0635d 7521 Elf_Internal_Shdr * section;
b34976b6 7522 unsigned long i;
32ec8896 7523 bfd_boolean found = FALSE;
252b5132 7524
dda8d76d
NC
7525 for (i = 0, section = filedata->section_headers;
7526 i < filedata->file_header.e_shnum;
b34976b6 7527 i++, section++)
252b5132
RH
7528 {
7529 if ( section->sh_type != SHT_RELA
7530 && section->sh_type != SHT_REL)
7531 continue;
7532
7533 rel_offset = section->sh_offset;
7534 rel_size = section->sh_size;
7535
7536 if (rel_size)
7537 {
b34976b6 7538 int is_rela;
d3a49aa8 7539 unsigned long num_rela;
103f02d3 7540
252b5132
RH
7541 printf (_("\nRelocation section "));
7542
dda8d76d 7543 if (filedata->string_table == NULL)
19936277 7544 printf ("%d", section->sh_name);
252b5132 7545 else
dda8d76d 7546 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7547
d3a49aa8
AM
7548 num_rela = rel_size / section->sh_entsize;
7549 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7550 " at offset 0x%lx contains %lu entries:\n",
7551 num_rela),
7552 rel_offset, num_rela);
252b5132 7553
d79b3d50
NC
7554 is_rela = section->sh_type == SHT_RELA;
7555
4fbb74a6 7556 if (section->sh_link != 0
dda8d76d 7557 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7558 {
2cf0635d
NC
7559 Elf_Internal_Shdr * symsec;
7560 Elf_Internal_Sym * symtab;
d79b3d50 7561 unsigned long nsyms;
c256ffe7 7562 unsigned long strtablen = 0;
2cf0635d 7563 char * strtab = NULL;
57346661 7564
dda8d76d 7565 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7566 if (symsec->sh_type != SHT_SYMTAB
7567 && symsec->sh_type != SHT_DYNSYM)
7568 continue;
7569
28d13567
AM
7570 if (!get_symtab (filedata, symsec,
7571 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7572 continue;
252b5132 7573
dda8d76d 7574 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7575 symtab, nsyms, strtab, strtablen,
7576 is_rela,
7577 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7578 free (strtab);
d79b3d50
NC
7579 free (symtab);
7580 }
7581 else
dda8d76d 7582 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7583 NULL, 0, NULL, 0, is_rela,
7584 FALSE /* is_dynamic */);
252b5132 7585
32ec8896 7586 found = TRUE;
252b5132
RH
7587 }
7588 }
7589
7590 if (! found)
45ac8f4f
NC
7591 {
7592 /* Users sometimes forget the -D option, so try to be helpful. */
7593 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7594 {
978c4450 7595 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f
NC
7596 {
7597 printf (_("\nThere are no static relocations in this file."));
7598 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7599
7600 break;
7601 }
7602 }
7603 if (i == ARRAY_SIZE (dynamic_relocations))
7604 printf (_("\nThere are no relocations in this file.\n"));
7605 }
252b5132
RH
7606 }
7607
32ec8896 7608 return TRUE;
252b5132
RH
7609}
7610
4d6ed7c8
NC
7611/* An absolute address consists of a section and an offset. If the
7612 section is NULL, the offset itself is the address, otherwise, the
7613 address equals to LOAD_ADDRESS(section) + offset. */
7614
7615struct absaddr
948f632f
DA
7616{
7617 unsigned short section;
7618 bfd_vma offset;
7619};
4d6ed7c8 7620
948f632f
DA
7621/* Find the nearest symbol at or below ADDR. Returns the symbol
7622 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7623
4d6ed7c8 7624static void
dda8d76d
NC
7625find_symbol_for_address (Filedata * filedata,
7626 Elf_Internal_Sym * symtab,
7627 unsigned long nsyms,
7628 const char * strtab,
7629 unsigned long strtab_size,
7630 struct absaddr addr,
7631 const char ** symname,
7632 bfd_vma * offset)
4d6ed7c8 7633{
d3ba0551 7634 bfd_vma dist = 0x100000;
2cf0635d 7635 Elf_Internal_Sym * sym;
948f632f
DA
7636 Elf_Internal_Sym * beg;
7637 Elf_Internal_Sym * end;
2cf0635d 7638 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7639
0b6ae522 7640 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7641 beg = symtab;
7642 end = symtab + nsyms;
0b6ae522 7643
948f632f 7644 while (beg < end)
4d6ed7c8 7645 {
948f632f
DA
7646 bfd_vma value;
7647
7648 sym = beg + (end - beg) / 2;
0b6ae522 7649
948f632f 7650 value = sym->st_value;
0b6ae522
DJ
7651 REMOVE_ARCH_BITS (value);
7652
948f632f 7653 if (sym->st_name != 0
4d6ed7c8 7654 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7655 && addr.offset >= value
7656 && addr.offset - value < dist)
4d6ed7c8
NC
7657 {
7658 best = sym;
0b6ae522 7659 dist = addr.offset - value;
4d6ed7c8
NC
7660 if (!dist)
7661 break;
7662 }
948f632f
DA
7663
7664 if (addr.offset < value)
7665 end = sym;
7666 else
7667 beg = sym + 1;
4d6ed7c8 7668 }
1b31d05e 7669
4d6ed7c8
NC
7670 if (best)
7671 {
57346661 7672 *symname = (best->st_name >= strtab_size
2b692964 7673 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7674 *offset = dist;
7675 return;
7676 }
1b31d05e 7677
4d6ed7c8
NC
7678 *symname = NULL;
7679 *offset = addr.offset;
7680}
7681
32ec8896 7682static /* signed */ int
948f632f
DA
7683symcmp (const void *p, const void *q)
7684{
7685 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7686 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7687
7688 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7689}
7690
7691/* Process the unwind section. */
7692
7693#include "unwind-ia64.h"
7694
7695struct ia64_unw_table_entry
7696{
7697 struct absaddr start;
7698 struct absaddr end;
7699 struct absaddr info;
7700};
7701
7702struct ia64_unw_aux_info
7703{
32ec8896
NC
7704 struct ia64_unw_table_entry * table; /* Unwind table. */
7705 unsigned long table_len; /* Length of unwind table. */
7706 unsigned char * info; /* Unwind info. */
7707 unsigned long info_size; /* Size of unwind info. */
7708 bfd_vma info_addr; /* Starting address of unwind info. */
7709 bfd_vma seg_base; /* Starting address of segment. */
7710 Elf_Internal_Sym * symtab; /* The symbol table. */
7711 unsigned long nsyms; /* Number of symbols. */
7712 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7713 unsigned long nfuns; /* Number of entries in funtab. */
7714 char * strtab; /* The string table. */
7715 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7716};
7717
32ec8896 7718static bfd_boolean
dda8d76d 7719dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7720{
2cf0635d 7721 struct ia64_unw_table_entry * tp;
948f632f 7722 unsigned long j, nfuns;
4d6ed7c8 7723 int in_body;
32ec8896 7724 bfd_boolean res = TRUE;
7036c0e1 7725
948f632f
DA
7726 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7727 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7728 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7729 aux->funtab[nfuns++] = aux->symtab[j];
7730 aux->nfuns = nfuns;
7731 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7732
4d6ed7c8
NC
7733 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7734 {
7735 bfd_vma stamp;
7736 bfd_vma offset;
2cf0635d
NC
7737 const unsigned char * dp;
7738 const unsigned char * head;
53774b7e 7739 const unsigned char * end;
2cf0635d 7740 const char * procname;
4d6ed7c8 7741
dda8d76d 7742 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7743 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7744
7745 fputs ("\n<", stdout);
7746
7747 if (procname)
7748 {
7749 fputs (procname, stdout);
7750
7751 if (offset)
7752 printf ("+%lx", (unsigned long) offset);
7753 }
7754
7755 fputs (">: [", stdout);
7756 print_vma (tp->start.offset, PREFIX_HEX);
7757 fputc ('-', stdout);
7758 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7759 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7760 (unsigned long) (tp->info.offset - aux->seg_base));
7761
53774b7e
NC
7762 /* PR 17531: file: 86232b32. */
7763 if (aux->info == NULL)
7764 continue;
7765
97c0a079
AM
7766 offset = tp->info.offset;
7767 if (tp->info.section)
7768 {
7769 if (tp->info.section >= filedata->file_header.e_shnum)
7770 {
7771 warn (_("Invalid section %u in table entry %ld\n"),
7772 tp->info.section, (long) (tp - aux->table));
7773 res = FALSE;
7774 continue;
7775 }
7776 offset += filedata->section_headers[tp->info.section].sh_addr;
7777 }
7778 offset -= aux->info_addr;
53774b7e 7779 /* PR 17531: file: 0997b4d1. */
90679903
AM
7780 if (offset >= aux->info_size
7781 || aux->info_size - offset < 8)
53774b7e
NC
7782 {
7783 warn (_("Invalid offset %lx in table entry %ld\n"),
7784 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7785 res = FALSE;
53774b7e
NC
7786 continue;
7787 }
7788
97c0a079 7789 head = aux->info + offset;
a4a00738 7790 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7791
86f55779 7792 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7793 (unsigned) UNW_VER (stamp),
7794 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7795 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7796 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7797 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7798
7799 if (UNW_VER (stamp) != 1)
7800 {
2b692964 7801 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7802 continue;
7803 }
7804
7805 in_body = 0;
53774b7e
NC
7806 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7807 /* PR 17531: file: 16ceda89. */
7808 if (end > aux->info + aux->info_size)
7809 end = aux->info + aux->info_size;
7810 for (dp = head + 8; dp < end;)
b4477bc8 7811 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7812 }
948f632f
DA
7813
7814 free (aux->funtab);
32ec8896
NC
7815
7816 return res;
4d6ed7c8
NC
7817}
7818
53774b7e 7819static bfd_boolean
dda8d76d
NC
7820slurp_ia64_unwind_table (Filedata * filedata,
7821 struct ia64_unw_aux_info * aux,
7822 Elf_Internal_Shdr * sec)
4d6ed7c8 7823{
89fac5e3 7824 unsigned long size, nrelas, i;
2cf0635d
NC
7825 Elf_Internal_Phdr * seg;
7826 struct ia64_unw_table_entry * tep;
7827 Elf_Internal_Shdr * relsec;
7828 Elf_Internal_Rela * rela;
7829 Elf_Internal_Rela * rp;
7830 unsigned char * table;
7831 unsigned char * tp;
7832 Elf_Internal_Sym * sym;
7833 const char * relname;
4d6ed7c8 7834
53774b7e
NC
7835 aux->table_len = 0;
7836
4d6ed7c8
NC
7837 /* First, find the starting address of the segment that includes
7838 this section: */
7839
dda8d76d 7840 if (filedata->file_header.e_phnum)
4d6ed7c8 7841 {
dda8d76d 7842 if (! get_program_headers (filedata))
53774b7e 7843 return FALSE;
4d6ed7c8 7844
dda8d76d
NC
7845 for (seg = filedata->program_headers;
7846 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7847 ++seg)
4d6ed7c8
NC
7848 {
7849 if (seg->p_type != PT_LOAD)
7850 continue;
7851
7852 if (sec->sh_addr >= seg->p_vaddr
7853 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7854 {
7855 aux->seg_base = seg->p_vaddr;
7856 break;
7857 }
7858 }
4d6ed7c8
NC
7859 }
7860
7861 /* Second, build the unwind table from the contents of the unwind section: */
7862 size = sec->sh_size;
dda8d76d 7863 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7864 _("unwind table"));
a6e9f9df 7865 if (!table)
53774b7e 7866 return FALSE;
4d6ed7c8 7867
53774b7e 7868 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7869 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7870 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7871 tep = aux->table;
53774b7e
NC
7872
7873 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7874 {
7875 tep->start.section = SHN_UNDEF;
7876 tep->end.section = SHN_UNDEF;
7877 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7878 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7879 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7880 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7881 tep->start.offset += aux->seg_base;
7882 tep->end.offset += aux->seg_base;
7883 tep->info.offset += aux->seg_base;
7884 }
7885 free (table);
7886
41e92641 7887 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7888 for (relsec = filedata->section_headers;
7889 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7890 ++relsec)
7891 {
7892 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7893 || relsec->sh_info >= filedata->file_header.e_shnum
7894 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7895 continue;
7896
dda8d76d 7897 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7898 & rela, & nrelas))
53774b7e
NC
7899 {
7900 free (aux->table);
7901 aux->table = NULL;
7902 aux->table_len = 0;
7903 return FALSE;
7904 }
4d6ed7c8
NC
7905
7906 for (rp = rela; rp < rela + nrelas; ++rp)
7907 {
4770fb94 7908 unsigned int sym_ndx;
726bd37d
AM
7909 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
7910 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 7911
82b1b41b
NC
7912 /* PR 17531: file: 9fa67536. */
7913 if (relname == NULL)
7914 {
726bd37d 7915 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
7916 continue;
7917 }
948f632f 7918
0112cd26 7919 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7920 {
82b1b41b 7921 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7922 continue;
7923 }
7924
89fac5e3 7925 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7926
53774b7e
NC
7927 /* PR 17531: file: 5bc8d9bf. */
7928 if (i >= aux->table_len)
7929 {
7930 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7931 continue;
7932 }
7933
4770fb94
AM
7934 sym_ndx = get_reloc_symindex (rp->r_info);
7935 if (sym_ndx >= aux->nsyms)
7936 {
7937 warn (_("Skipping reloc with invalid symbol index: %u\n"),
7938 sym_ndx);
7939 continue;
7940 }
7941 sym = aux->symtab + sym_ndx;
7942
53774b7e 7943 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7944 {
7945 case 0:
7946 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7947 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7948 break;
7949 case 1:
7950 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7951 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7952 break;
7953 case 2:
7954 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7955 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7956 break;
7957 default:
7958 break;
7959 }
7960 }
7961
7962 free (rela);
7963 }
7964
53774b7e 7965 return TRUE;
4d6ed7c8
NC
7966}
7967
32ec8896 7968static bfd_boolean
dda8d76d 7969ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7970{
2cf0635d
NC
7971 Elf_Internal_Shdr * sec;
7972 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 7973 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7974 struct ia64_unw_aux_info aux;
32ec8896 7975 bfd_boolean res = TRUE;
f1467e33 7976
4d6ed7c8
NC
7977 memset (& aux, 0, sizeof (aux));
7978
dda8d76d 7979 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7980 {
28d13567 7981 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 7982 {
28d13567 7983 if (aux.symtab)
4082ef84 7984 {
28d13567
AM
7985 error (_("Multiple symbol tables encountered\n"));
7986 free (aux.symtab);
7987 aux.symtab = NULL;
4082ef84 7988 free (aux.strtab);
28d13567 7989 aux.strtab = NULL;
4082ef84 7990 }
28d13567
AM
7991 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
7992 &aux.strtab, &aux.strtab_size))
7993 return FALSE;
4d6ed7c8
NC
7994 }
7995 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7996 unwcount++;
7997 }
7998
7999 if (!unwcount)
8000 printf (_("\nThere are no unwind sections in this file.\n"));
8001
8002 while (unwcount-- > 0)
8003 {
2cf0635d 8004 char * suffix;
579f31ac
JJ
8005 size_t len, len2;
8006
dda8d76d
NC
8007 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8008 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8009 if (sec->sh_type == SHT_IA_64_UNWIND)
8010 {
8011 unwsec = sec;
8012 break;
8013 }
4082ef84
NC
8014 /* We have already counted the number of SHT_IA64_UNWIND
8015 sections so the loop above should never fail. */
8016 assert (unwsec != NULL);
579f31ac
JJ
8017
8018 unwstart = i + 1;
8019 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8020
e4b17d5c
L
8021 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8022 {
8023 /* We need to find which section group it is in. */
4082ef84 8024 struct group_list * g;
e4b17d5c 8025
978c4450
AM
8026 if (filedata->section_headers_groups == NULL
8027 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8028 i = filedata->file_header.e_shnum;
4082ef84 8029 else
e4b17d5c 8030 {
978c4450 8031 g = filedata->section_headers_groups[i]->root;
18bd398b 8032
4082ef84
NC
8033 for (; g != NULL; g = g->next)
8034 {
dda8d76d 8035 sec = filedata->section_headers + g->section_index;
e4b17d5c 8036
4082ef84
NC
8037 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
8038 break;
8039 }
8040
8041 if (g == NULL)
dda8d76d 8042 i = filedata->file_header.e_shnum;
4082ef84 8043 }
e4b17d5c 8044 }
18bd398b 8045 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 8046 {
18bd398b 8047 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8048 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8049 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8050 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8051 ++i, ++sec)
18bd398b
NC
8052 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
8053 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8054 break;
8055 }
8056 else
8057 {
8058 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8059 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8060 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8061 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8062 suffix = "";
18bd398b 8063 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 8064 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8065 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8066 ++i, ++sec)
18bd398b
NC
8067 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
8068 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8069 break;
8070 }
8071
dda8d76d 8072 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8073 {
8074 printf (_("\nCould not find unwind info section for "));
8075
dda8d76d 8076 if (filedata->string_table == NULL)
579f31ac
JJ
8077 printf ("%d", unwsec->sh_name);
8078 else
dda8d76d 8079 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8080 }
8081 else
4d6ed7c8 8082 {
4d6ed7c8 8083 aux.info_addr = sec->sh_addr;
dda8d76d 8084 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8085 sec->sh_size,
8086 _("unwind info"));
59245841 8087 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8088
579f31ac 8089 printf (_("\nUnwind section "));
4d6ed7c8 8090
dda8d76d 8091 if (filedata->string_table == NULL)
579f31ac
JJ
8092 printf ("%d", unwsec->sh_name);
8093 else
dda8d76d 8094 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8095
579f31ac 8096 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8097 (unsigned long) unwsec->sh_offset,
89fac5e3 8098 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8099
dda8d76d 8100 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8101 && aux.table_len > 0)
dda8d76d 8102 dump_ia64_unwind (filedata, & aux);
579f31ac 8103
9db70fc3
AM
8104 free ((char *) aux.table);
8105 free ((char *) aux.info);
579f31ac
JJ
8106 aux.table = NULL;
8107 aux.info = NULL;
8108 }
4d6ed7c8 8109 }
4d6ed7c8 8110
9db70fc3
AM
8111 free (aux.symtab);
8112 free ((char *) aux.strtab);
32ec8896
NC
8113
8114 return res;
4d6ed7c8
NC
8115}
8116
3f5e193b 8117struct hppa_unw_table_entry
32ec8896
NC
8118{
8119 struct absaddr start;
8120 struct absaddr end;
8121 unsigned int Cannot_unwind:1; /* 0 */
8122 unsigned int Millicode:1; /* 1 */
8123 unsigned int Millicode_save_sr0:1; /* 2 */
8124 unsigned int Region_description:2; /* 3..4 */
8125 unsigned int reserved1:1; /* 5 */
8126 unsigned int Entry_SR:1; /* 6 */
8127 unsigned int Entry_FR:4; /* Number saved 7..10 */
8128 unsigned int Entry_GR:5; /* Number saved 11..15 */
8129 unsigned int Args_stored:1; /* 16 */
8130 unsigned int Variable_Frame:1; /* 17 */
8131 unsigned int Separate_Package_Body:1; /* 18 */
8132 unsigned int Frame_Extension_Millicode:1; /* 19 */
8133 unsigned int Stack_Overflow_Check:1; /* 20 */
8134 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8135 unsigned int Ada_Region:1; /* 22 */
8136 unsigned int cxx_info:1; /* 23 */
8137 unsigned int cxx_try_catch:1; /* 24 */
8138 unsigned int sched_entry_seq:1; /* 25 */
8139 unsigned int reserved2:1; /* 26 */
8140 unsigned int Save_SP:1; /* 27 */
8141 unsigned int Save_RP:1; /* 28 */
8142 unsigned int Save_MRP_in_frame:1; /* 29 */
8143 unsigned int extn_ptr_defined:1; /* 30 */
8144 unsigned int Cleanup_defined:1; /* 31 */
8145
8146 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8147 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8148 unsigned int Large_frame:1; /* 2 */
8149 unsigned int Pseudo_SP_Set:1; /* 3 */
8150 unsigned int reserved4:1; /* 4 */
8151 unsigned int Total_frame_size:27; /* 5..31 */
8152};
3f5e193b 8153
57346661 8154struct hppa_unw_aux_info
948f632f 8155{
32ec8896
NC
8156 struct hppa_unw_table_entry * table; /* Unwind table. */
8157 unsigned long table_len; /* Length of unwind table. */
8158 bfd_vma seg_base; /* Starting address of segment. */
8159 Elf_Internal_Sym * symtab; /* The symbol table. */
8160 unsigned long nsyms; /* Number of symbols. */
8161 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8162 unsigned long nfuns; /* Number of entries in funtab. */
8163 char * strtab; /* The string table. */
8164 unsigned long strtab_size; /* Size of string table. */
948f632f 8165};
57346661 8166
32ec8896 8167static bfd_boolean
dda8d76d 8168dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8169{
2cf0635d 8170 struct hppa_unw_table_entry * tp;
948f632f 8171 unsigned long j, nfuns;
32ec8896 8172 bfd_boolean res = TRUE;
948f632f
DA
8173
8174 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8175 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8176 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8177 aux->funtab[nfuns++] = aux->symtab[j];
8178 aux->nfuns = nfuns;
8179 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8180
57346661
AM
8181 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8182 {
8183 bfd_vma offset;
2cf0635d 8184 const char * procname;
57346661 8185
dda8d76d 8186 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8187 aux->strtab_size, tp->start, &procname,
8188 &offset);
8189
8190 fputs ("\n<", stdout);
8191
8192 if (procname)
8193 {
8194 fputs (procname, stdout);
8195
8196 if (offset)
8197 printf ("+%lx", (unsigned long) offset);
8198 }
8199
8200 fputs (">: [", stdout);
8201 print_vma (tp->start.offset, PREFIX_HEX);
8202 fputc ('-', stdout);
8203 print_vma (tp->end.offset, PREFIX_HEX);
8204 printf ("]\n\t");
8205
18bd398b
NC
8206#define PF(_m) if (tp->_m) printf (#_m " ");
8207#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8208 PF(Cannot_unwind);
8209 PF(Millicode);
8210 PF(Millicode_save_sr0);
18bd398b 8211 /* PV(Region_description); */
57346661
AM
8212 PF(Entry_SR);
8213 PV(Entry_FR);
8214 PV(Entry_GR);
8215 PF(Args_stored);
8216 PF(Variable_Frame);
8217 PF(Separate_Package_Body);
8218 PF(Frame_Extension_Millicode);
8219 PF(Stack_Overflow_Check);
8220 PF(Two_Instruction_SP_Increment);
8221 PF(Ada_Region);
8222 PF(cxx_info);
8223 PF(cxx_try_catch);
8224 PF(sched_entry_seq);
8225 PF(Save_SP);
8226 PF(Save_RP);
8227 PF(Save_MRP_in_frame);
8228 PF(extn_ptr_defined);
8229 PF(Cleanup_defined);
8230 PF(MPE_XL_interrupt_marker);
8231 PF(HP_UX_interrupt_marker);
8232 PF(Large_frame);
8233 PF(Pseudo_SP_Set);
8234 PV(Total_frame_size);
8235#undef PF
8236#undef PV
8237 }
8238
18bd398b 8239 printf ("\n");
948f632f
DA
8240
8241 free (aux->funtab);
32ec8896
NC
8242
8243 return res;
57346661
AM
8244}
8245
32ec8896 8246static bfd_boolean
dda8d76d
NC
8247slurp_hppa_unwind_table (Filedata * filedata,
8248 struct hppa_unw_aux_info * aux,
8249 Elf_Internal_Shdr * sec)
57346661 8250{
1c0751b2 8251 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8252 Elf_Internal_Phdr * seg;
8253 struct hppa_unw_table_entry * tep;
8254 Elf_Internal_Shdr * relsec;
8255 Elf_Internal_Rela * rela;
8256 Elf_Internal_Rela * rp;
8257 unsigned char * table;
8258 unsigned char * tp;
8259 Elf_Internal_Sym * sym;
8260 const char * relname;
57346661 8261
57346661
AM
8262 /* First, find the starting address of the segment that includes
8263 this section. */
dda8d76d 8264 if (filedata->file_header.e_phnum)
57346661 8265 {
dda8d76d 8266 if (! get_program_headers (filedata))
32ec8896 8267 return FALSE;
57346661 8268
dda8d76d
NC
8269 for (seg = filedata->program_headers;
8270 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8271 ++seg)
8272 {
8273 if (seg->p_type != PT_LOAD)
8274 continue;
8275
8276 if (sec->sh_addr >= seg->p_vaddr
8277 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8278 {
8279 aux->seg_base = seg->p_vaddr;
8280 break;
8281 }
8282 }
8283 }
8284
8285 /* Second, build the unwind table from the contents of the unwind
8286 section. */
8287 size = sec->sh_size;
dda8d76d 8288 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8289 _("unwind table"));
57346661 8290 if (!table)
32ec8896 8291 return FALSE;
57346661 8292
1c0751b2
DA
8293 unw_ent_size = 16;
8294 nentries = size / unw_ent_size;
8295 size = unw_ent_size * nentries;
57346661 8296
e3fdc001 8297 aux->table_len = nentries;
3f5e193b
NC
8298 tep = aux->table = (struct hppa_unw_table_entry *)
8299 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8300
1c0751b2 8301 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8302 {
8303 unsigned int tmp1, tmp2;
8304
8305 tep->start.section = SHN_UNDEF;
8306 tep->end.section = SHN_UNDEF;
8307
1c0751b2
DA
8308 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8309 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8310 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8311 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8312
8313 tep->start.offset += aux->seg_base;
8314 tep->end.offset += aux->seg_base;
57346661
AM
8315
8316 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8317 tep->Millicode = (tmp1 >> 30) & 0x1;
8318 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8319 tep->Region_description = (tmp1 >> 27) & 0x3;
8320 tep->reserved1 = (tmp1 >> 26) & 0x1;
8321 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8322 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8323 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8324 tep->Args_stored = (tmp1 >> 15) & 0x1;
8325 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8326 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8327 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8328 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8329 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8330 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8331 tep->cxx_info = (tmp1 >> 8) & 0x1;
8332 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8333 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8334 tep->reserved2 = (tmp1 >> 5) & 0x1;
8335 tep->Save_SP = (tmp1 >> 4) & 0x1;
8336 tep->Save_RP = (tmp1 >> 3) & 0x1;
8337 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8338 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8339 tep->Cleanup_defined = tmp1 & 0x1;
8340
8341 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8342 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8343 tep->Large_frame = (tmp2 >> 29) & 0x1;
8344 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8345 tep->reserved4 = (tmp2 >> 27) & 0x1;
8346 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8347 }
8348 free (table);
8349
8350 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8351 for (relsec = filedata->section_headers;
8352 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8353 ++relsec)
8354 {
8355 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8356 || relsec->sh_info >= filedata->file_header.e_shnum
8357 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8358 continue;
8359
dda8d76d 8360 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8361 & rela, & nrelas))
32ec8896 8362 return FALSE;
57346661
AM
8363
8364 for (rp = rela; rp < rela + nrelas; ++rp)
8365 {
4770fb94 8366 unsigned int sym_ndx;
726bd37d
AM
8367 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8368 relname = elf_hppa_reloc_type (r_type);
57346661 8369
726bd37d
AM
8370 if (relname == NULL)
8371 {
8372 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8373 continue;
8374 }
8375
57346661 8376 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8377 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8378 {
726bd37d 8379 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8380 continue;
8381 }
8382
8383 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8384 if (i >= aux->table_len)
8385 {
8386 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8387 continue;
8388 }
57346661 8389
4770fb94
AM
8390 sym_ndx = get_reloc_symindex (rp->r_info);
8391 if (sym_ndx >= aux->nsyms)
8392 {
8393 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8394 sym_ndx);
8395 continue;
8396 }
8397 sym = aux->symtab + sym_ndx;
8398
43f6cd05 8399 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8400 {
8401 case 0:
8402 aux->table[i].start.section = sym->st_shndx;
1e456d54 8403 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8404 break;
8405 case 1:
8406 aux->table[i].end.section = sym->st_shndx;
1e456d54 8407 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8408 break;
8409 default:
8410 break;
8411 }
8412 }
8413
8414 free (rela);
8415 }
8416
32ec8896 8417 return TRUE;
57346661
AM
8418}
8419
32ec8896 8420static bfd_boolean
dda8d76d 8421hppa_process_unwind (Filedata * filedata)
57346661 8422{
57346661 8423 struct hppa_unw_aux_info aux;
2cf0635d 8424 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8425 Elf_Internal_Shdr * sec;
18bd398b 8426 unsigned long i;
32ec8896 8427 bfd_boolean res = TRUE;
57346661 8428
dda8d76d 8429 if (filedata->string_table == NULL)
32ec8896 8430 return FALSE;
1b31d05e
NC
8431
8432 memset (& aux, 0, sizeof (aux));
57346661 8433
dda8d76d 8434 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8435 {
28d13567 8436 if (sec->sh_type == SHT_SYMTAB)
57346661 8437 {
28d13567 8438 if (aux.symtab)
4082ef84 8439 {
28d13567
AM
8440 error (_("Multiple symbol tables encountered\n"));
8441 free (aux.symtab);
8442 aux.symtab = NULL;
4082ef84 8443 free (aux.strtab);
28d13567 8444 aux.strtab = NULL;
4082ef84 8445 }
28d13567
AM
8446 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8447 &aux.strtab, &aux.strtab_size))
8448 return FALSE;
57346661 8449 }
18bd398b 8450 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8451 unwsec = sec;
8452 }
8453
8454 if (!unwsec)
8455 printf (_("\nThere are no unwind sections in this file.\n"));
8456
dda8d76d 8457 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8458 {
18bd398b 8459 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8460 {
43f6cd05 8461 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8462
d3a49aa8
AM
8463 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8464 "contains %lu entry:\n",
8465 "\nUnwind section '%s' at offset 0x%lx "
8466 "contains %lu entries:\n",
8467 num_unwind),
dda8d76d 8468 printable_section_name (filedata, sec),
57346661 8469 (unsigned long) sec->sh_offset,
d3a49aa8 8470 num_unwind);
57346661 8471
dda8d76d 8472 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8473 res = FALSE;
66b09c7e
S
8474
8475 if (res && aux.table_len > 0)
32ec8896 8476 {
dda8d76d 8477 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8478 res = FALSE;
8479 }
57346661 8480
9db70fc3 8481 free ((char *) aux.table);
57346661
AM
8482 aux.table = NULL;
8483 }
8484 }
8485
9db70fc3
AM
8486 free (aux.symtab);
8487 free ((char *) aux.strtab);
32ec8896
NC
8488
8489 return res;
57346661
AM
8490}
8491
0b6ae522
DJ
8492struct arm_section
8493{
a734115a
NC
8494 unsigned char * data; /* The unwind data. */
8495 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8496 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8497 unsigned long nrelas; /* The number of relocations. */
8498 unsigned int rel_type; /* REL or RELA ? */
8499 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8500};
8501
8502struct arm_unw_aux_info
8503{
dda8d76d 8504 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8505 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8506 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8507 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8508 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8509 char * strtab; /* The file's string table. */
8510 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8511};
8512
8513static const char *
dda8d76d
NC
8514arm_print_vma_and_name (Filedata * filedata,
8515 struct arm_unw_aux_info * aux,
8516 bfd_vma fn,
8517 struct absaddr addr)
0b6ae522
DJ
8518{
8519 const char *procname;
8520 bfd_vma sym_offset;
8521
8522 if (addr.section == SHN_UNDEF)
8523 addr.offset = fn;
8524
dda8d76d 8525 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8526 aux->strtab_size, addr, &procname,
8527 &sym_offset);
8528
8529 print_vma (fn, PREFIX_HEX);
8530
8531 if (procname)
8532 {
8533 fputs (" <", stdout);
8534 fputs (procname, stdout);
8535
8536 if (sym_offset)
8537 printf ("+0x%lx", (unsigned long) sym_offset);
8538 fputc ('>', stdout);
8539 }
8540
8541 return procname;
8542}
8543
8544static void
8545arm_free_section (struct arm_section *arm_sec)
8546{
9db70fc3
AM
8547 free (arm_sec->data);
8548 free (arm_sec->rela);
0b6ae522
DJ
8549}
8550
a734115a
NC
8551/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8552 cached section and install SEC instead.
8553 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8554 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8555 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8556 relocation's offset in ADDR.
1b31d05e
NC
8557 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8558 into the string table of the symbol associated with the reloc. If no
8559 reloc was applied store -1 there.
8560 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8561
8562static bfd_boolean
dda8d76d
NC
8563get_unwind_section_word (Filedata * filedata,
8564 struct arm_unw_aux_info * aux,
1b31d05e
NC
8565 struct arm_section * arm_sec,
8566 Elf_Internal_Shdr * sec,
8567 bfd_vma word_offset,
8568 unsigned int * wordp,
8569 struct absaddr * addr,
8570 bfd_vma * sym_name)
0b6ae522
DJ
8571{
8572 Elf_Internal_Rela *rp;
8573 Elf_Internal_Sym *sym;
8574 const char * relname;
8575 unsigned int word;
8576 bfd_boolean wrapped;
8577
e0a31db1
NC
8578 if (sec == NULL || arm_sec == NULL)
8579 return FALSE;
8580
0b6ae522
DJ
8581 addr->section = SHN_UNDEF;
8582 addr->offset = 0;
8583
1b31d05e
NC
8584 if (sym_name != NULL)
8585 *sym_name = (bfd_vma) -1;
8586
a734115a 8587 /* If necessary, update the section cache. */
0b6ae522
DJ
8588 if (sec != arm_sec->sec)
8589 {
8590 Elf_Internal_Shdr *relsec;
8591
8592 arm_free_section (arm_sec);
8593
8594 arm_sec->sec = sec;
dda8d76d 8595 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8596 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8597 arm_sec->rela = NULL;
8598 arm_sec->nrelas = 0;
8599
dda8d76d
NC
8600 for (relsec = filedata->section_headers;
8601 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8602 ++relsec)
8603 {
dda8d76d
NC
8604 if (relsec->sh_info >= filedata->file_header.e_shnum
8605 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8606 /* PR 15745: Check the section type as well. */
8607 || (relsec->sh_type != SHT_REL
8608 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8609 continue;
8610
a734115a 8611 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8612 if (relsec->sh_type == SHT_REL)
8613 {
dda8d76d 8614 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8615 relsec->sh_size,
8616 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8617 return FALSE;
0b6ae522 8618 }
1ae40aa4 8619 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8620 {
dda8d76d 8621 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8622 relsec->sh_size,
8623 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8624 return FALSE;
0b6ae522 8625 }
1ae40aa4 8626 break;
0b6ae522
DJ
8627 }
8628
8629 arm_sec->next_rela = arm_sec->rela;
8630 }
8631
a734115a 8632 /* If there is no unwind data we can do nothing. */
0b6ae522 8633 if (arm_sec->data == NULL)
a734115a 8634 return FALSE;
0b6ae522 8635
e0a31db1 8636 /* If the offset is invalid then fail. */
f32ba729
NC
8637 if (/* PR 21343 *//* PR 18879 */
8638 sec->sh_size < 4
8639 || word_offset > (sec->sh_size - 4)
1a915552 8640 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8641 return FALSE;
8642
a734115a 8643 /* Get the word at the required offset. */
0b6ae522
DJ
8644 word = byte_get (arm_sec->data + word_offset, 4);
8645
0eff7165
NC
8646 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8647 if (arm_sec->rela == NULL)
8648 {
8649 * wordp = word;
8650 return TRUE;
8651 }
8652
a734115a 8653 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8654 wrapped = FALSE;
8655 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8656 {
8657 bfd_vma prelval, offset;
8658
8659 if (rp->r_offset > word_offset && !wrapped)
8660 {
8661 rp = arm_sec->rela;
8662 wrapped = TRUE;
8663 }
8664 if (rp->r_offset > word_offset)
8665 break;
8666
8667 if (rp->r_offset & 3)
8668 {
8669 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8670 (unsigned long) rp->r_offset);
8671 continue;
8672 }
8673
8674 if (rp->r_offset < word_offset)
8675 continue;
8676
74e1a04b
NC
8677 /* PR 17531: file: 027-161405-0.004 */
8678 if (aux->symtab == NULL)
8679 continue;
8680
0b6ae522
DJ
8681 if (arm_sec->rel_type == SHT_REL)
8682 {
8683 offset = word & 0x7fffffff;
8684 if (offset & 0x40000000)
8685 offset |= ~ (bfd_vma) 0x7fffffff;
8686 }
a734115a 8687 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8688 offset = rp->r_addend;
a734115a 8689 else
74e1a04b
NC
8690 {
8691 error (_("Unknown section relocation type %d encountered\n"),
8692 arm_sec->rel_type);
8693 break;
8694 }
0b6ae522 8695
071436c6
NC
8696 /* PR 17531 file: 027-1241568-0.004. */
8697 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8698 {
8699 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8700 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8701 break;
8702 }
8703
8704 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8705 offset += sym->st_value;
8706 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8707
a734115a 8708 /* Check that we are processing the expected reloc type. */
dda8d76d 8709 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8710 {
8711 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8712 if (relname == NULL)
8713 {
8714 warn (_("Skipping unknown ARM relocation type: %d\n"),
8715 (int) ELF32_R_TYPE (rp->r_info));
8716 continue;
8717 }
a734115a
NC
8718
8719 if (streq (relname, "R_ARM_NONE"))
8720 continue;
0b4362b0 8721
a734115a
NC
8722 if (! streq (relname, "R_ARM_PREL31"))
8723 {
071436c6 8724 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8725 continue;
8726 }
8727 }
dda8d76d 8728 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8729 {
8730 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8731 if (relname == NULL)
8732 {
8733 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8734 (int) ELF32_R_TYPE (rp->r_info));
8735 continue;
8736 }
0b4362b0 8737
a734115a
NC
8738 if (streq (relname, "R_C6000_NONE"))
8739 continue;
8740
8741 if (! streq (relname, "R_C6000_PREL31"))
8742 {
071436c6 8743 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8744 continue;
8745 }
8746
8747 prelval >>= 1;
8748 }
8749 else
74e1a04b
NC
8750 {
8751 /* This function currently only supports ARM and TI unwinders. */
8752 warn (_("Only TI and ARM unwinders are currently supported\n"));
8753 break;
8754 }
fa197c1c 8755
0b6ae522
DJ
8756 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8757 addr->section = sym->st_shndx;
8758 addr->offset = offset;
74e1a04b 8759
1b31d05e
NC
8760 if (sym_name)
8761 * sym_name = sym->st_name;
0b6ae522
DJ
8762 break;
8763 }
8764
8765 *wordp = word;
8766 arm_sec->next_rela = rp;
8767
a734115a 8768 return TRUE;
0b6ae522
DJ
8769}
8770
a734115a
NC
8771static const char *tic6x_unwind_regnames[16] =
8772{
0b4362b0
RM
8773 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8774 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8775 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8776};
fa197c1c 8777
0b6ae522 8778static void
fa197c1c 8779decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8780{
fa197c1c
PB
8781 int i;
8782
8783 for (i = 12; mask; mask >>= 1, i--)
8784 {
8785 if (mask & 1)
8786 {
8787 fputs (tic6x_unwind_regnames[i], stdout);
8788 if (mask > 1)
8789 fputs (", ", stdout);
8790 }
8791 }
8792}
0b6ae522
DJ
8793
8794#define ADVANCE \
8795 if (remaining == 0 && more_words) \
8796 { \
8797 data_offset += 4; \
dda8d76d 8798 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8799 data_offset, & word, & addr, NULL)) \
32ec8896 8800 return FALSE; \
0b6ae522
DJ
8801 remaining = 4; \
8802 more_words--; \
8803 } \
8804
8805#define GET_OP(OP) \
8806 ADVANCE; \
8807 if (remaining) \
8808 { \
8809 remaining--; \
8810 (OP) = word >> 24; \
8811 word <<= 8; \
8812 } \
8813 else \
8814 { \
2b692964 8815 printf (_("[Truncated opcode]\n")); \
32ec8896 8816 return FALSE; \
0b6ae522 8817 } \
cc5914eb 8818 printf ("0x%02x ", OP)
0b6ae522 8819
32ec8896 8820static bfd_boolean
dda8d76d
NC
8821decode_arm_unwind_bytecode (Filedata * filedata,
8822 struct arm_unw_aux_info * aux,
948f632f
DA
8823 unsigned int word,
8824 unsigned int remaining,
8825 unsigned int more_words,
8826 bfd_vma data_offset,
8827 Elf_Internal_Shdr * data_sec,
8828 struct arm_section * data_arm_sec)
fa197c1c
PB
8829{
8830 struct absaddr addr;
32ec8896 8831 bfd_boolean res = TRUE;
0b6ae522
DJ
8832
8833 /* Decode the unwinding instructions. */
8834 while (1)
8835 {
8836 unsigned int op, op2;
8837
8838 ADVANCE;
8839 if (remaining == 0)
8840 break;
8841 remaining--;
8842 op = word >> 24;
8843 word <<= 8;
8844
cc5914eb 8845 printf (" 0x%02x ", op);
0b6ae522
DJ
8846
8847 if ((op & 0xc0) == 0x00)
8848 {
8849 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8850
cc5914eb 8851 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8852 }
8853 else if ((op & 0xc0) == 0x40)
8854 {
8855 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8856
cc5914eb 8857 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8858 }
8859 else if ((op & 0xf0) == 0x80)
8860 {
8861 GET_OP (op2);
8862 if (op == 0x80 && op2 == 0)
8863 printf (_("Refuse to unwind"));
8864 else
8865 {
8866 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8867 bfd_boolean first = TRUE;
0b6ae522 8868 int i;
2b692964 8869
0b6ae522
DJ
8870 printf ("pop {");
8871 for (i = 0; i < 12; i++)
8872 if (mask & (1 << i))
8873 {
8874 if (first)
32ec8896 8875 first = FALSE;
0b6ae522
DJ
8876 else
8877 printf (", ");
8878 printf ("r%d", 4 + i);
8879 }
8880 printf ("}");
8881 }
8882 }
8883 else if ((op & 0xf0) == 0x90)
8884 {
8885 if (op == 0x9d || op == 0x9f)
8886 printf (_(" [Reserved]"));
8887 else
cc5914eb 8888 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8889 }
8890 else if ((op & 0xf0) == 0xa0)
8891 {
8892 int end = 4 + (op & 0x07);
32ec8896 8893 bfd_boolean first = TRUE;
0b6ae522 8894 int i;
61865e30 8895
0b6ae522
DJ
8896 printf (" pop {");
8897 for (i = 4; i <= end; i++)
8898 {
8899 if (first)
32ec8896 8900 first = FALSE;
0b6ae522
DJ
8901 else
8902 printf (", ");
8903 printf ("r%d", i);
8904 }
8905 if (op & 0x08)
8906 {
1b31d05e 8907 if (!first)
0b6ae522
DJ
8908 printf (", ");
8909 printf ("r14");
8910 }
8911 printf ("}");
8912 }
8913 else if (op == 0xb0)
8914 printf (_(" finish"));
8915 else if (op == 0xb1)
8916 {
8917 GET_OP (op2);
8918 if (op2 == 0 || (op2 & 0xf0) != 0)
8919 printf (_("[Spare]"));
8920 else
8921 {
8922 unsigned int mask = op2 & 0x0f;
32ec8896 8923 bfd_boolean first = TRUE;
0b6ae522 8924 int i;
61865e30 8925
0b6ae522
DJ
8926 printf ("pop {");
8927 for (i = 0; i < 12; i++)
8928 if (mask & (1 << i))
8929 {
8930 if (first)
32ec8896 8931 first = FALSE;
0b6ae522
DJ
8932 else
8933 printf (", ");
8934 printf ("r%d", i);
8935 }
8936 printf ("}");
8937 }
8938 }
8939 else if (op == 0xb2)
8940 {
b115cf96 8941 unsigned char buf[9];
0b6ae522
DJ
8942 unsigned int i, len;
8943 unsigned long offset;
61865e30 8944
b115cf96 8945 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8946 {
8947 GET_OP (buf[i]);
8948 if ((buf[i] & 0x80) == 0)
8949 break;
8950 }
4082ef84 8951 if (i == sizeof (buf))
32ec8896 8952 {
27a45f42 8953 error (_("corrupt change to vsp\n"));
32ec8896
NC
8954 res = FALSE;
8955 }
4082ef84
NC
8956 else
8957 {
cd30bcef 8958 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
8959 assert (len == i + 1);
8960 offset = offset * 4 + 0x204;
8961 printf ("vsp = vsp + %ld", offset);
8962 }
0b6ae522 8963 }
61865e30 8964 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8965 {
61865e30
NC
8966 unsigned int first, last;
8967
8968 GET_OP (op2);
8969 first = op2 >> 4;
8970 last = op2 & 0x0f;
8971 if (op == 0xc8)
8972 first = first + 16;
8973 printf ("pop {D%d", first);
8974 if (last)
8975 printf ("-D%d", first + last);
8976 printf ("}");
8977 }
8978 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8979 {
8980 unsigned int count = op & 0x07;
8981
8982 printf ("pop {D8");
8983 if (count)
8984 printf ("-D%d", 8 + count);
8985 printf ("}");
8986 }
8987 else if (op >= 0xc0 && op <= 0xc5)
8988 {
8989 unsigned int count = op & 0x07;
8990
8991 printf (" pop {wR10");
8992 if (count)
8993 printf ("-wR%d", 10 + count);
8994 printf ("}");
8995 }
8996 else if (op == 0xc6)
8997 {
8998 unsigned int first, last;
8999
9000 GET_OP (op2);
9001 first = op2 >> 4;
9002 last = op2 & 0x0f;
9003 printf ("pop {wR%d", first);
9004 if (last)
9005 printf ("-wR%d", first + last);
9006 printf ("}");
9007 }
9008 else if (op == 0xc7)
9009 {
9010 GET_OP (op2);
9011 if (op2 == 0 || (op2 & 0xf0) != 0)
9012 printf (_("[Spare]"));
0b6ae522
DJ
9013 else
9014 {
61865e30 9015 unsigned int mask = op2 & 0x0f;
32ec8896 9016 bfd_boolean first = TRUE;
61865e30
NC
9017 int i;
9018
9019 printf ("pop {");
9020 for (i = 0; i < 4; i++)
9021 if (mask & (1 << i))
9022 {
9023 if (first)
32ec8896 9024 first = FALSE;
61865e30
NC
9025 else
9026 printf (", ");
9027 printf ("wCGR%d", i);
9028 }
9029 printf ("}");
0b6ae522
DJ
9030 }
9031 }
61865e30 9032 else
32ec8896
NC
9033 {
9034 printf (_(" [unsupported opcode]"));
9035 res = FALSE;
9036 }
9037
0b6ae522
DJ
9038 printf ("\n");
9039 }
32ec8896
NC
9040
9041 return res;
fa197c1c
PB
9042}
9043
32ec8896 9044static bfd_boolean
dda8d76d
NC
9045decode_tic6x_unwind_bytecode (Filedata * filedata,
9046 struct arm_unw_aux_info * aux,
948f632f
DA
9047 unsigned int word,
9048 unsigned int remaining,
9049 unsigned int more_words,
9050 bfd_vma data_offset,
9051 Elf_Internal_Shdr * data_sec,
9052 struct arm_section * data_arm_sec)
fa197c1c
PB
9053{
9054 struct absaddr addr;
9055
9056 /* Decode the unwinding instructions. */
9057 while (1)
9058 {
9059 unsigned int op, op2;
9060
9061 ADVANCE;
9062 if (remaining == 0)
9063 break;
9064 remaining--;
9065 op = word >> 24;
9066 word <<= 8;
9067
9cf03b7e 9068 printf (" 0x%02x ", op);
fa197c1c
PB
9069
9070 if ((op & 0xc0) == 0x00)
9071 {
9072 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9073 printf (" sp = sp + %d", offset);
fa197c1c
PB
9074 }
9075 else if ((op & 0xc0) == 0x80)
9076 {
9077 GET_OP (op2);
9078 if (op == 0x80 && op2 == 0)
9079 printf (_("Refuse to unwind"));
9080 else
9081 {
9082 unsigned int mask = ((op & 0x1f) << 8) | op2;
9083 if (op & 0x20)
9084 printf ("pop compact {");
9085 else
9086 printf ("pop {");
9087
9088 decode_tic6x_unwind_regmask (mask);
9089 printf("}");
9090 }
9091 }
9092 else if ((op & 0xf0) == 0xc0)
9093 {
9094 unsigned int reg;
9095 unsigned int nregs;
9096 unsigned int i;
9097 const char *name;
a734115a
NC
9098 struct
9099 {
32ec8896
NC
9100 unsigned int offset;
9101 unsigned int reg;
fa197c1c
PB
9102 } regpos[16];
9103
9104 /* Scan entire instruction first so that GET_OP output is not
9105 interleaved with disassembly. */
9106 nregs = 0;
9107 for (i = 0; nregs < (op & 0xf); i++)
9108 {
9109 GET_OP (op2);
9110 reg = op2 >> 4;
9111 if (reg != 0xf)
9112 {
9113 regpos[nregs].offset = i * 2;
9114 regpos[nregs].reg = reg;
9115 nregs++;
9116 }
9117
9118 reg = op2 & 0xf;
9119 if (reg != 0xf)
9120 {
9121 regpos[nregs].offset = i * 2 + 1;
9122 regpos[nregs].reg = reg;
9123 nregs++;
9124 }
9125 }
9126
9127 printf (_("pop frame {"));
18344509 9128 if (nregs == 0)
fa197c1c 9129 {
18344509
NC
9130 printf (_("*corrupt* - no registers specified"));
9131 }
9132 else
9133 {
9134 reg = nregs - 1;
9135 for (i = i * 2; i > 0; i--)
fa197c1c 9136 {
18344509
NC
9137 if (regpos[reg].offset == i - 1)
9138 {
9139 name = tic6x_unwind_regnames[regpos[reg].reg];
9140 if (reg > 0)
9141 reg--;
9142 }
9143 else
9144 name = _("[pad]");
fa197c1c 9145
18344509
NC
9146 fputs (name, stdout);
9147 if (i > 1)
9148 printf (", ");
9149 }
fa197c1c
PB
9150 }
9151
9152 printf ("}");
9153 }
9154 else if (op == 0xd0)
9155 printf (" MOV FP, SP");
9156 else if (op == 0xd1)
9157 printf (" __c6xabi_pop_rts");
9158 else if (op == 0xd2)
9159 {
9160 unsigned char buf[9];
9161 unsigned int i, len;
9162 unsigned long offset;
a734115a 9163
fa197c1c
PB
9164 for (i = 0; i < sizeof (buf); i++)
9165 {
9166 GET_OP (buf[i]);
9167 if ((buf[i] & 0x80) == 0)
9168 break;
9169 }
0eff7165
NC
9170 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9171 if (i == sizeof (buf))
9172 {
0eff7165 9173 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9174 return FALSE;
0eff7165 9175 }
948f632f 9176
cd30bcef 9177 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9178 assert (len == i + 1);
9179 offset = offset * 8 + 0x408;
9180 printf (_("sp = sp + %ld"), offset);
9181 }
9182 else if ((op & 0xf0) == 0xe0)
9183 {
9184 if ((op & 0x0f) == 7)
9185 printf (" RETURN");
9186 else
9187 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9188 }
9189 else
9190 {
9191 printf (_(" [unsupported opcode]"));
9192 }
9193 putchar ('\n');
9194 }
32ec8896
NC
9195
9196 return TRUE;
fa197c1c
PB
9197}
9198
9199static bfd_vma
dda8d76d 9200arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9201{
9202 bfd_vma offset;
9203
9204 offset = word & 0x7fffffff;
9205 if (offset & 0x40000000)
9206 offset |= ~ (bfd_vma) 0x7fffffff;
9207
dda8d76d 9208 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9209 offset <<= 1;
9210
9211 return offset + where;
9212}
9213
32ec8896 9214static bfd_boolean
dda8d76d
NC
9215decode_arm_unwind (Filedata * filedata,
9216 struct arm_unw_aux_info * aux,
1b31d05e
NC
9217 unsigned int word,
9218 unsigned int remaining,
9219 bfd_vma data_offset,
9220 Elf_Internal_Shdr * data_sec,
9221 struct arm_section * data_arm_sec)
fa197c1c
PB
9222{
9223 int per_index;
9224 unsigned int more_words = 0;
37e14bc3 9225 struct absaddr addr;
1b31d05e 9226 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9227 bfd_boolean res = TRUE;
fa197c1c
PB
9228
9229 if (remaining == 0)
9230 {
1b31d05e
NC
9231 /* Fetch the first word.
9232 Note - when decoding an object file the address extracted
9233 here will always be 0. So we also pass in the sym_name
9234 parameter so that we can find the symbol associated with
9235 the personality routine. */
dda8d76d 9236 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9237 & word, & addr, & sym_name))
32ec8896 9238 return FALSE;
1b31d05e 9239
fa197c1c
PB
9240 remaining = 4;
9241 }
c93dbb25
CZ
9242 else
9243 {
9244 addr.section = SHN_UNDEF;
9245 addr.offset = 0;
9246 }
fa197c1c
PB
9247
9248 if ((word & 0x80000000) == 0)
9249 {
9250 /* Expand prel31 for personality routine. */
9251 bfd_vma fn;
9252 const char *procname;
9253
dda8d76d 9254 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9255 printf (_(" Personality routine: "));
1b31d05e
NC
9256 if (fn == 0
9257 && addr.section == SHN_UNDEF && addr.offset == 0
9258 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9259 {
9260 procname = aux->strtab + sym_name;
9261 print_vma (fn, PREFIX_HEX);
9262 if (procname)
9263 {
9264 fputs (" <", stdout);
9265 fputs (procname, stdout);
9266 fputc ('>', stdout);
9267 }
9268 }
9269 else
dda8d76d 9270 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9271 fputc ('\n', stdout);
9272
9273 /* The GCC personality routines use the standard compact
9274 encoding, starting with one byte giving the number of
9275 words. */
9276 if (procname != NULL
9277 && (const_strneq (procname, "__gcc_personality_v0")
9278 || const_strneq (procname, "__gxx_personality_v0")
9279 || const_strneq (procname, "__gcj_personality_v0")
9280 || const_strneq (procname, "__gnu_objc_personality_v0")))
9281 {
9282 remaining = 0;
9283 more_words = 1;
9284 ADVANCE;
9285 if (!remaining)
9286 {
9287 printf (_(" [Truncated data]\n"));
32ec8896 9288 return FALSE;
fa197c1c
PB
9289 }
9290 more_words = word >> 24;
9291 word <<= 8;
9292 remaining--;
9293 per_index = -1;
9294 }
9295 else
32ec8896 9296 return TRUE;
fa197c1c
PB
9297 }
9298 else
9299 {
1b31d05e 9300 /* ARM EHABI Section 6.3:
0b4362b0 9301
1b31d05e 9302 An exception-handling table entry for the compact model looks like:
0b4362b0 9303
1b31d05e
NC
9304 31 30-28 27-24 23-0
9305 -- ----- ----- ----
9306 1 0 index Data for personalityRoutine[index] */
9307
dda8d76d 9308 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9309 && (word & 0x70000000))
32ec8896
NC
9310 {
9311 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9312 res = FALSE;
9313 }
1b31d05e 9314
fa197c1c 9315 per_index = (word >> 24) & 0x7f;
1b31d05e 9316 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9317 if (per_index == 0)
9318 {
9319 more_words = 0;
9320 word <<= 8;
9321 remaining--;
9322 }
9323 else if (per_index < 3)
9324 {
9325 more_words = (word >> 16) & 0xff;
9326 word <<= 16;
9327 remaining -= 2;
9328 }
9329 }
9330
dda8d76d 9331 switch (filedata->file_header.e_machine)
fa197c1c
PB
9332 {
9333 case EM_ARM:
9334 if (per_index < 3)
9335 {
dda8d76d 9336 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9337 data_offset, data_sec, data_arm_sec))
9338 res = FALSE;
fa197c1c
PB
9339 }
9340 else
1b31d05e
NC
9341 {
9342 warn (_("Unknown ARM compact model index encountered\n"));
9343 printf (_(" [reserved]\n"));
32ec8896 9344 res = FALSE;
1b31d05e 9345 }
fa197c1c
PB
9346 break;
9347
9348 case EM_TI_C6000:
9349 if (per_index < 3)
9350 {
dda8d76d 9351 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9352 data_offset, data_sec, data_arm_sec))
9353 res = FALSE;
fa197c1c
PB
9354 }
9355 else if (per_index < 5)
9356 {
9357 if (((word >> 17) & 0x7f) == 0x7f)
9358 printf (_(" Restore stack from frame pointer\n"));
9359 else
9360 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9361 printf (_(" Registers restored: "));
9362 if (per_index == 4)
9363 printf (" (compact) ");
9364 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9365 putchar ('\n');
9366 printf (_(" Return register: %s\n"),
9367 tic6x_unwind_regnames[word & 0xf]);
9368 }
9369 else
1b31d05e 9370 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9371 break;
9372
9373 default:
74e1a04b 9374 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9375 filedata->file_header.e_machine);
32ec8896 9376 res = FALSE;
fa197c1c 9377 }
0b6ae522
DJ
9378
9379 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9380
9381 return res;
0b6ae522
DJ
9382}
9383
32ec8896 9384static bfd_boolean
dda8d76d
NC
9385dump_arm_unwind (Filedata * filedata,
9386 struct arm_unw_aux_info * aux,
9387 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9388{
9389 struct arm_section exidx_arm_sec, extab_arm_sec;
9390 unsigned int i, exidx_len;
948f632f 9391 unsigned long j, nfuns;
32ec8896 9392 bfd_boolean res = TRUE;
0b6ae522
DJ
9393
9394 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9395 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9396 exidx_len = exidx_sec->sh_size / 8;
9397
948f632f
DA
9398 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9399 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9400 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9401 aux->funtab[nfuns++] = aux->symtab[j];
9402 aux->nfuns = nfuns;
9403 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9404
0b6ae522
DJ
9405 for (i = 0; i < exidx_len; i++)
9406 {
9407 unsigned int exidx_fn, exidx_entry;
9408 struct absaddr fn_addr, entry_addr;
9409 bfd_vma fn;
9410
9411 fputc ('\n', stdout);
9412
dda8d76d 9413 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9414 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9415 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9416 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9417 {
948f632f 9418 free (aux->funtab);
1b31d05e
NC
9419 arm_free_section (& exidx_arm_sec);
9420 arm_free_section (& extab_arm_sec);
32ec8896 9421 return FALSE;
0b6ae522
DJ
9422 }
9423
83c257ca
NC
9424 /* ARM EHABI, Section 5:
9425 An index table entry consists of 2 words.
9426 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9427 if (exidx_fn & 0x80000000)
32ec8896
NC
9428 {
9429 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9430 res = FALSE;
9431 }
83c257ca 9432
dda8d76d 9433 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9434
dda8d76d 9435 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9436 fputs (": ", stdout);
9437
9438 if (exidx_entry == 1)
9439 {
9440 print_vma (exidx_entry, PREFIX_HEX);
9441 fputs (" [cantunwind]\n", stdout);
9442 }
9443 else if (exidx_entry & 0x80000000)
9444 {
9445 print_vma (exidx_entry, PREFIX_HEX);
9446 fputc ('\n', stdout);
dda8d76d 9447 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9448 }
9449 else
9450 {
8f73510c 9451 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9452 Elf_Internal_Shdr *table_sec;
9453
9454 fputs ("@", stdout);
dda8d76d 9455 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9456 print_vma (table, PREFIX_HEX);
9457 printf ("\n");
9458
9459 /* Locate the matching .ARM.extab. */
9460 if (entry_addr.section != SHN_UNDEF
dda8d76d 9461 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9462 {
dda8d76d 9463 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9464 table_offset = entry_addr.offset;
1a915552
NC
9465 /* PR 18879 */
9466 if (table_offset > table_sec->sh_size
9467 || ((bfd_signed_vma) table_offset) < 0)
9468 {
9469 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9470 (unsigned long) table_offset,
dda8d76d 9471 printable_section_name (filedata, table_sec));
32ec8896 9472 res = FALSE;
1a915552
NC
9473 continue;
9474 }
0b6ae522
DJ
9475 }
9476 else
9477 {
dda8d76d 9478 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9479 if (table_sec != NULL)
9480 table_offset = table - table_sec->sh_addr;
9481 }
32ec8896 9482
0b6ae522
DJ
9483 if (table_sec == NULL)
9484 {
9485 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9486 (unsigned long) table);
32ec8896 9487 res = FALSE;
0b6ae522
DJ
9488 continue;
9489 }
32ec8896 9490
dda8d76d 9491 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9492 &extab_arm_sec))
9493 res = FALSE;
0b6ae522
DJ
9494 }
9495 }
9496
9497 printf ("\n");
9498
948f632f 9499 free (aux->funtab);
0b6ae522
DJ
9500 arm_free_section (&exidx_arm_sec);
9501 arm_free_section (&extab_arm_sec);
32ec8896
NC
9502
9503 return res;
0b6ae522
DJ
9504}
9505
fa197c1c 9506/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9507
32ec8896 9508static bfd_boolean
dda8d76d 9509arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9510{
9511 struct arm_unw_aux_info aux;
9512 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9513 Elf_Internal_Shdr *sec;
9514 unsigned long i;
fa197c1c 9515 unsigned int sec_type;
32ec8896 9516 bfd_boolean res = TRUE;
0b6ae522 9517
dda8d76d 9518 switch (filedata->file_header.e_machine)
fa197c1c
PB
9519 {
9520 case EM_ARM:
9521 sec_type = SHT_ARM_EXIDX;
9522 break;
9523
9524 case EM_TI_C6000:
9525 sec_type = SHT_C6000_UNWIND;
9526 break;
9527
0b4362b0 9528 default:
74e1a04b 9529 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9530 filedata->file_header.e_machine);
32ec8896 9531 return FALSE;
fa197c1c
PB
9532 }
9533
dda8d76d 9534 if (filedata->string_table == NULL)
32ec8896 9535 return FALSE;
1b31d05e
NC
9536
9537 memset (& aux, 0, sizeof (aux));
dda8d76d 9538 aux.filedata = filedata;
0b6ae522 9539
dda8d76d 9540 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9541 {
28d13567 9542 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9543 {
28d13567 9544 if (aux.symtab)
74e1a04b 9545 {
28d13567
AM
9546 error (_("Multiple symbol tables encountered\n"));
9547 free (aux.symtab);
9548 aux.symtab = NULL;
74e1a04b 9549 free (aux.strtab);
28d13567 9550 aux.strtab = NULL;
74e1a04b 9551 }
28d13567
AM
9552 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9553 &aux.strtab, &aux.strtab_size))
9554 return FALSE;
0b6ae522 9555 }
fa197c1c 9556 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9557 unwsec = sec;
9558 }
9559
1b31d05e 9560 if (unwsec == NULL)
0b6ae522 9561 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9562 else
dda8d76d 9563 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9564 {
9565 if (sec->sh_type == sec_type)
9566 {
d3a49aa8
AM
9567 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9568 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9569 "contains %lu entry:\n",
9570 "\nUnwind section '%s' at offset 0x%lx "
9571 "contains %lu entries:\n",
9572 num_unwind),
dda8d76d 9573 printable_section_name (filedata, sec),
1b31d05e 9574 (unsigned long) sec->sh_offset,
d3a49aa8 9575 num_unwind);
0b6ae522 9576
dda8d76d 9577 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9578 res = FALSE;
1b31d05e
NC
9579 }
9580 }
0b6ae522 9581
9db70fc3
AM
9582 free (aux.symtab);
9583 free ((char *) aux.strtab);
32ec8896
NC
9584
9585 return res;
0b6ae522
DJ
9586}
9587
32ec8896 9588static bfd_boolean
dda8d76d 9589process_unwind (Filedata * filedata)
57346661 9590{
2cf0635d
NC
9591 struct unwind_handler
9592 {
32ec8896 9593 unsigned int machtype;
dda8d76d 9594 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9595 } handlers[] =
9596 {
0b6ae522 9597 { EM_ARM, arm_process_unwind },
57346661
AM
9598 { EM_IA_64, ia64_process_unwind },
9599 { EM_PARISC, hppa_process_unwind },
fa197c1c 9600 { EM_TI_C6000, arm_process_unwind },
32ec8896 9601 { 0, NULL }
57346661
AM
9602 };
9603 int i;
9604
9605 if (!do_unwind)
32ec8896 9606 return TRUE;
57346661
AM
9607
9608 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9609 if (filedata->file_header.e_machine == handlers[i].machtype)
9610 return handlers[i].handler (filedata);
57346661 9611
1b31d05e 9612 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9613 get_machine_name (filedata->file_header.e_machine));
32ec8896 9614 return TRUE;
57346661
AM
9615}
9616
37c18eed
SD
9617static void
9618dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9619{
9620 switch (entry->d_tag)
9621 {
9622 case DT_AARCH64_BTI_PLT:
1dbade74 9623 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9624 break;
9625 default:
9626 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9627 break;
9628 }
9629 putchar ('\n');
9630}
9631
252b5132 9632static void
978c4450 9633dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9634{
9635 switch (entry->d_tag)
9636 {
9637 case DT_MIPS_FLAGS:
9638 if (entry->d_un.d_val == 0)
4b68bca3 9639 printf (_("NONE"));
252b5132
RH
9640 else
9641 {
9642 static const char * opts[] =
9643 {
9644 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9645 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9646 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9647 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9648 "RLD_ORDER_SAFE"
9649 };
9650 unsigned int cnt;
32ec8896 9651 bfd_boolean first = TRUE;
2b692964 9652
60bca95a 9653 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9654 if (entry->d_un.d_val & (1 << cnt))
9655 {
9656 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9657 first = FALSE;
252b5132 9658 }
252b5132
RH
9659 }
9660 break;
103f02d3 9661
252b5132 9662 case DT_MIPS_IVERSION:
978c4450
AM
9663 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9664 printf (_("Interface Version: %s"),
9665 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9666 else
76ca31c0
NC
9667 {
9668 char buf[40];
9669 sprintf_vma (buf, entry->d_un.d_ptr);
9670 /* Note: coded this way so that there is a single string for translation. */
9671 printf (_("<corrupt: %s>"), buf);
9672 }
252b5132 9673 break;
103f02d3 9674
252b5132
RH
9675 case DT_MIPS_TIME_STAMP:
9676 {
d5b07ef4 9677 char timebuf[128];
2cf0635d 9678 struct tm * tmp;
91d6fa6a 9679 time_t atime = entry->d_un.d_val;
82b1b41b 9680
91d6fa6a 9681 tmp = gmtime (&atime);
82b1b41b
NC
9682 /* PR 17531: file: 6accc532. */
9683 if (tmp == NULL)
9684 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9685 else
9686 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9687 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9688 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9689 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9690 }
9691 break;
103f02d3 9692
252b5132
RH
9693 case DT_MIPS_RLD_VERSION:
9694 case DT_MIPS_LOCAL_GOTNO:
9695 case DT_MIPS_CONFLICTNO:
9696 case DT_MIPS_LIBLISTNO:
9697 case DT_MIPS_SYMTABNO:
9698 case DT_MIPS_UNREFEXTNO:
9699 case DT_MIPS_HIPAGENO:
9700 case DT_MIPS_DELTA_CLASS_NO:
9701 case DT_MIPS_DELTA_INSTANCE_NO:
9702 case DT_MIPS_DELTA_RELOC_NO:
9703 case DT_MIPS_DELTA_SYM_NO:
9704 case DT_MIPS_DELTA_CLASSSYM_NO:
9705 case DT_MIPS_COMPACT_SIZE:
c69075ac 9706 print_vma (entry->d_un.d_val, DEC);
252b5132 9707 break;
103f02d3 9708
f16a9783 9709 case DT_MIPS_XHASH:
978c4450
AM
9710 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9711 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9712 /* Falls through. */
9713
103f02d3 9714 default:
4b68bca3 9715 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9716 }
4b68bca3 9717 putchar ('\n');
103f02d3
UD
9718}
9719
103f02d3 9720static void
2cf0635d 9721dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9722{
9723 switch (entry->d_tag)
9724 {
9725 case DT_HP_DLD_FLAGS:
9726 {
9727 static struct
9728 {
9729 long int bit;
2cf0635d 9730 const char * str;
5e220199
NC
9731 }
9732 flags[] =
9733 {
9734 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9735 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9736 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9737 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9738 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9739 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9740 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9741 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9742 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9743 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9744 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9745 { DT_HP_GST, "HP_GST" },
9746 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9747 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9748 { DT_HP_NODELETE, "HP_NODELETE" },
9749 { DT_HP_GROUP, "HP_GROUP" },
9750 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9751 };
32ec8896 9752 bfd_boolean first = TRUE;
5e220199 9753 size_t cnt;
f7a99963 9754 bfd_vma val = entry->d_un.d_val;
103f02d3 9755
60bca95a 9756 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9757 if (val & flags[cnt].bit)
30800947
NC
9758 {
9759 if (! first)
9760 putchar (' ');
9761 fputs (flags[cnt].str, stdout);
32ec8896 9762 first = FALSE;
30800947
NC
9763 val ^= flags[cnt].bit;
9764 }
76da6bbe 9765
103f02d3 9766 if (val != 0 || first)
f7a99963
NC
9767 {
9768 if (! first)
9769 putchar (' ');
9770 print_vma (val, HEX);
9771 }
103f02d3
UD
9772 }
9773 break;
76da6bbe 9774
252b5132 9775 default:
f7a99963
NC
9776 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9777 break;
252b5132 9778 }
35b1837e 9779 putchar ('\n');
252b5132
RH
9780}
9781
28f997cf
TG
9782#ifdef BFD64
9783
9784/* VMS vs Unix time offset and factor. */
9785
9786#define VMS_EPOCH_OFFSET 35067168000000000LL
9787#define VMS_GRANULARITY_FACTOR 10000000
9788
9789/* Display a VMS time in a human readable format. */
9790
9791static void
9792print_vms_time (bfd_int64_t vmstime)
9793{
9794 struct tm *tm;
9795 time_t unxtime;
9796
9797 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9798 tm = gmtime (&unxtime);
9799 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9800 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9801 tm->tm_hour, tm->tm_min, tm->tm_sec);
9802}
9803#endif /* BFD64 */
9804
ecc51f48 9805static void
2cf0635d 9806dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9807{
9808 switch (entry->d_tag)
9809 {
0de14b54 9810 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9811 /* First 3 slots reserved. */
ecc51f48
NC
9812 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9813 printf (" -- ");
9814 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9815 break;
9816
28f997cf
TG
9817 case DT_IA_64_VMS_LINKTIME:
9818#ifdef BFD64
9819 print_vms_time (entry->d_un.d_val);
9820#endif
9821 break;
9822
9823 case DT_IA_64_VMS_LNKFLAGS:
9824 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9825 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9826 printf (" CALL_DEBUG");
9827 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9828 printf (" NOP0BUFS");
9829 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9830 printf (" P0IMAGE");
9831 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9832 printf (" MKTHREADS");
9833 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9834 printf (" UPCALLS");
9835 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9836 printf (" IMGSTA");
9837 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9838 printf (" INITIALIZE");
9839 if (entry->d_un.d_val & VMS_LF_MAIN)
9840 printf (" MAIN");
9841 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9842 printf (" EXE_INIT");
9843 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9844 printf (" TBK_IN_IMG");
9845 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9846 printf (" DBG_IN_IMG");
9847 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9848 printf (" TBK_IN_DSF");
9849 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9850 printf (" DBG_IN_DSF");
9851 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9852 printf (" SIGNATURES");
9853 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9854 printf (" REL_SEG_OFF");
9855 break;
9856
bdf4d63a
JJ
9857 default:
9858 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9859 break;
ecc51f48 9860 }
bdf4d63a 9861 putchar ('\n');
ecc51f48
NC
9862}
9863
32ec8896 9864static bfd_boolean
dda8d76d 9865get_32bit_dynamic_section (Filedata * filedata)
252b5132 9866{
2cf0635d
NC
9867 Elf32_External_Dyn * edyn;
9868 Elf32_External_Dyn * ext;
9869 Elf_Internal_Dyn * entry;
103f02d3 9870
978c4450
AM
9871 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
9872 filedata->dynamic_addr, 1,
9873 filedata->dynamic_size,
9874 _("dynamic section"));
a6e9f9df 9875 if (!edyn)
32ec8896 9876 return FALSE;
103f02d3 9877
071436c6
NC
9878 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9879 might not have the luxury of section headers. Look for the DT_NULL
9880 terminator to determine the number of entries. */
978c4450
AM
9881 for (ext = edyn, filedata->dynamic_nent = 0;
9882 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9883 ext++)
9884 {
978c4450 9885 filedata->dynamic_nent++;
ba2685cc
AM
9886 if (BYTE_GET (ext->d_tag) == DT_NULL)
9887 break;
9888 }
252b5132 9889
978c4450
AM
9890 filedata->dynamic_section
9891 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9892 if (filedata->dynamic_section == NULL)
252b5132 9893 {
8b73c356 9894 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9895 (unsigned long) filedata->dynamic_nent);
9ea033b2 9896 free (edyn);
32ec8896 9897 return FALSE;
9ea033b2 9898 }
252b5132 9899
978c4450
AM
9900 for (ext = edyn, entry = filedata->dynamic_section;
9901 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9902 ext++, entry++)
9ea033b2 9903 {
fb514b26
AM
9904 entry->d_tag = BYTE_GET (ext->d_tag);
9905 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9906 }
9907
9ea033b2
NC
9908 free (edyn);
9909
32ec8896 9910 return TRUE;
9ea033b2
NC
9911}
9912
32ec8896 9913static bfd_boolean
dda8d76d 9914get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9915{
2cf0635d
NC
9916 Elf64_External_Dyn * edyn;
9917 Elf64_External_Dyn * ext;
9918 Elf_Internal_Dyn * entry;
103f02d3 9919
071436c6 9920 /* Read in the data. */
978c4450
AM
9921 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
9922 filedata->dynamic_addr, 1,
9923 filedata->dynamic_size,
9924 _("dynamic section"));
a6e9f9df 9925 if (!edyn)
32ec8896 9926 return FALSE;
103f02d3 9927
071436c6
NC
9928 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9929 might not have the luxury of section headers. Look for the DT_NULL
9930 terminator to determine the number of entries. */
978c4450 9931 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 9932 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 9933 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9934 ext++)
9935 {
978c4450 9936 filedata->dynamic_nent++;
66543521 9937 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9938 break;
9939 }
252b5132 9940
978c4450
AM
9941 filedata->dynamic_section
9942 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9943 if (filedata->dynamic_section == NULL)
252b5132 9944 {
8b73c356 9945 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9946 (unsigned long) filedata->dynamic_nent);
252b5132 9947 free (edyn);
32ec8896 9948 return FALSE;
252b5132
RH
9949 }
9950
071436c6 9951 /* Convert from external to internal formats. */
978c4450
AM
9952 for (ext = edyn, entry = filedata->dynamic_section;
9953 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9954 ext++, entry++)
252b5132 9955 {
66543521
AM
9956 entry->d_tag = BYTE_GET (ext->d_tag);
9957 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9958 }
9959
9960 free (edyn);
9961
32ec8896 9962 return TRUE;
9ea033b2
NC
9963}
9964
e9e44622
JJ
9965static void
9966print_dynamic_flags (bfd_vma flags)
d1133906 9967{
32ec8896 9968 bfd_boolean first = TRUE;
13ae64f3 9969
d1133906
NC
9970 while (flags)
9971 {
9972 bfd_vma flag;
9973
9974 flag = flags & - flags;
9975 flags &= ~ flag;
9976
e9e44622 9977 if (first)
32ec8896 9978 first = FALSE;
e9e44622
JJ
9979 else
9980 putc (' ', stdout);
13ae64f3 9981
d1133906
NC
9982 switch (flag)
9983 {
e9e44622
JJ
9984 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9985 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9986 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9987 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9988 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9989 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9990 }
9991 }
e9e44622 9992 puts ("");
d1133906
NC
9993}
9994
10ca4b04
L
9995static bfd_vma *
9996get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
9997{
9998 unsigned char * e_data;
9999 bfd_vma * i_data;
10000
10001 /* If the size_t type is smaller than the bfd_size_type, eg because
10002 you are building a 32-bit tool on a 64-bit host, then make sure
10003 that when (number) is cast to (size_t) no information is lost. */
10004 if (sizeof (size_t) < sizeof (bfd_size_type)
10005 && (bfd_size_type) ((size_t) number) != number)
10006 {
10007 error (_("Size truncation prevents reading %s elements of size %u\n"),
10008 bfd_vmatoa ("u", number), ent_size);
10009 return NULL;
10010 }
10011
10012 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10013 attempting to allocate memory when the read is bound to fail. */
10014 if (ent_size * number > filedata->file_size)
10015 {
10016 error (_("Invalid number of dynamic entries: %s\n"),
10017 bfd_vmatoa ("u", number));
10018 return NULL;
10019 }
10020
10021 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10022 if (e_data == NULL)
10023 {
10024 error (_("Out of memory reading %s dynamic entries\n"),
10025 bfd_vmatoa ("u", number));
10026 return NULL;
10027 }
10028
10029 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10030 {
10031 error (_("Unable to read in %s bytes of dynamic data\n"),
10032 bfd_vmatoa ("u", number * ent_size));
10033 free (e_data);
10034 return NULL;
10035 }
10036
10037 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10038 if (i_data == NULL)
10039 {
10040 error (_("Out of memory allocating space for %s dynamic entries\n"),
10041 bfd_vmatoa ("u", number));
10042 free (e_data);
10043 return NULL;
10044 }
10045
10046 while (number--)
10047 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10048
10049 free (e_data);
10050
10051 return i_data;
10052}
10053
10054static unsigned long
10055get_num_dynamic_syms (Filedata * filedata)
10056{
10057 unsigned long num_of_syms = 0;
10058
10059 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10060 return num_of_syms;
10061
978c4450 10062 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10063 {
10064 unsigned char nb[8];
10065 unsigned char nc[8];
10066 unsigned int hash_ent_size = 4;
10067
10068 if ((filedata->file_header.e_machine == EM_ALPHA
10069 || filedata->file_header.e_machine == EM_S390
10070 || filedata->file_header.e_machine == EM_S390_OLD)
10071 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10072 hash_ent_size = 8;
10073
10074 if (fseek (filedata->handle,
978c4450
AM
10075 (filedata->archive_file_offset
10076 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10077 sizeof nb + sizeof nc)),
10078 SEEK_SET))
10079 {
10080 error (_("Unable to seek to start of dynamic information\n"));
10081 goto no_hash;
10082 }
10083
10084 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10085 {
10086 error (_("Failed to read in number of buckets\n"));
10087 goto no_hash;
10088 }
10089
10090 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10091 {
10092 error (_("Failed to read in number of chains\n"));
10093 goto no_hash;
10094 }
10095
978c4450
AM
10096 filedata->nbuckets = byte_get (nb, hash_ent_size);
10097 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10098
2482f306
AM
10099 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10100 {
10101 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10102 hash_ent_size);
10103 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10104 hash_ent_size);
001890e1 10105
2482f306
AM
10106 if (filedata->buckets != NULL && filedata->chains != NULL)
10107 num_of_syms = filedata->nchains;
10108 }
ceb9bf11 10109 no_hash:
10ca4b04
L
10110 if (num_of_syms == 0)
10111 {
9db70fc3
AM
10112 free (filedata->buckets);
10113 filedata->buckets = NULL;
10114 free (filedata->chains);
10115 filedata->chains = NULL;
978c4450 10116 filedata->nbuckets = 0;
10ca4b04
L
10117 }
10118 }
10119
978c4450 10120 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10121 {
10122 unsigned char nb[16];
10123 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10124 bfd_vma buckets_vma;
10125 unsigned long hn;
10ca4b04
L
10126
10127 if (fseek (filedata->handle,
978c4450
AM
10128 (filedata->archive_file_offset
10129 + offset_from_vma (filedata,
10130 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10131 sizeof nb)),
10132 SEEK_SET))
10133 {
10134 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10135 goto no_gnu_hash;
10136 }
10137
10138 if (fread (nb, 16, 1, filedata->handle) != 1)
10139 {
10140 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10141 goto no_gnu_hash;
10142 }
10143
978c4450
AM
10144 filedata->ngnubuckets = byte_get (nb, 4);
10145 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10146 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10147 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10148 if (is_32bit_elf)
10149 buckets_vma += bitmaskwords * 4;
10150 else
10151 buckets_vma += bitmaskwords * 8;
10152
10153 if (fseek (filedata->handle,
978c4450 10154 (filedata->archive_file_offset
10ca4b04
L
10155 + offset_from_vma (filedata, buckets_vma, 4)),
10156 SEEK_SET))
10157 {
10158 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10159 goto no_gnu_hash;
10160 }
10161
978c4450
AM
10162 filedata->gnubuckets
10163 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10164
978c4450 10165 if (filedata->gnubuckets == NULL)
90837ea7 10166 goto no_gnu_hash;
10ca4b04 10167
978c4450
AM
10168 for (i = 0; i < filedata->ngnubuckets; i++)
10169 if (filedata->gnubuckets[i] != 0)
10ca4b04 10170 {
978c4450 10171 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10172 goto no_gnu_hash;
10ca4b04 10173
978c4450
AM
10174 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10175 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10176 }
10177
10178 if (maxchain == 0xffffffff)
90837ea7 10179 goto no_gnu_hash;
10ca4b04 10180
978c4450 10181 maxchain -= filedata->gnusymidx;
10ca4b04
L
10182
10183 if (fseek (filedata->handle,
978c4450
AM
10184 (filedata->archive_file_offset
10185 + offset_from_vma (filedata,
10186 buckets_vma + 4 * (filedata->ngnubuckets
10187 + maxchain),
10188 4)),
10ca4b04
L
10189 SEEK_SET))
10190 {
10191 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10192 goto no_gnu_hash;
10193 }
10194
10195 do
10196 {
10197 if (fread (nb, 4, 1, filedata->handle) != 1)
10198 {
10199 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10200 goto no_gnu_hash;
10201 }
10202
10203 if (maxchain + 1 == 0)
90837ea7 10204 goto no_gnu_hash;
10ca4b04
L
10205
10206 ++maxchain;
10207 }
10208 while ((byte_get (nb, 4) & 1) == 0);
10209
10210 if (fseek (filedata->handle,
978c4450
AM
10211 (filedata->archive_file_offset
10212 + offset_from_vma (filedata, (buckets_vma
10213 + 4 * filedata->ngnubuckets),
10214 4)),
10ca4b04
L
10215 SEEK_SET))
10216 {
10217 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10218 goto no_gnu_hash;
10219 }
10220
978c4450
AM
10221 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10222 filedata->ngnuchains = maxchain;
10ca4b04 10223
978c4450 10224 if (filedata->gnuchains == NULL)
90837ea7 10225 goto no_gnu_hash;
10ca4b04 10226
978c4450 10227 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10228 {
10229 if (fseek (filedata->handle,
978c4450 10230 (filedata->archive_file_offset
10ca4b04 10231 + offset_from_vma (filedata, (buckets_vma
978c4450 10232 + 4 * (filedata->ngnubuckets
10ca4b04
L
10233 + maxchain)), 4)),
10234 SEEK_SET))
10235 {
10236 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10237 goto no_gnu_hash;
10238 }
10239
978c4450 10240 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10241 if (filedata->mipsxlat == NULL)
10242 goto no_gnu_hash;
10ca4b04
L
10243 }
10244
978c4450
AM
10245 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10246 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10247 {
978c4450
AM
10248 bfd_vma si = filedata->gnubuckets[hn];
10249 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10250
10251 do
10252 {
978c4450 10253 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10254 {
c31ab5a0
AM
10255 if (off < filedata->ngnuchains
10256 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10257 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10258 }
10259 else
10260 {
10261 if (si >= num_of_syms)
10262 num_of_syms = si + 1;
10263 }
10264 si++;
10265 }
978c4450
AM
10266 while (off < filedata->ngnuchains
10267 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10268 }
10269
90837ea7 10270 if (num_of_syms == 0)
10ca4b04 10271 {
90837ea7 10272 no_gnu_hash:
9db70fc3
AM
10273 free (filedata->mipsxlat);
10274 filedata->mipsxlat = NULL;
10275 free (filedata->gnuchains);
10276 filedata->gnuchains = NULL;
10277 free (filedata->gnubuckets);
10278 filedata->gnubuckets = NULL;
978c4450
AM
10279 filedata->ngnubuckets = 0;
10280 filedata->ngnuchains = 0;
10ca4b04
L
10281 }
10282 }
10283
10284 return num_of_syms;
10285}
10286
b2d38a17
NC
10287/* Parse and display the contents of the dynamic section. */
10288
32ec8896 10289static bfd_boolean
dda8d76d 10290process_dynamic_section (Filedata * filedata)
9ea033b2 10291{
2cf0635d 10292 Elf_Internal_Dyn * entry;
9ea033b2 10293
978c4450 10294 if (filedata->dynamic_size == 0)
9ea033b2
NC
10295 {
10296 if (do_dynamic)
b2d38a17 10297 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 10298
32ec8896 10299 return TRUE;
9ea033b2
NC
10300 }
10301
10302 if (is_32bit_elf)
10303 {
dda8d76d 10304 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10305 return FALSE;
10306 }
10307 else
10308 {
dda8d76d 10309 if (! get_64bit_dynamic_section (filedata))
32ec8896 10310 return FALSE;
9ea033b2 10311 }
9ea033b2 10312
252b5132 10313 /* Find the appropriate symbol table. */
978c4450 10314 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10315 {
2482f306
AM
10316 unsigned long num_of_syms;
10317
978c4450
AM
10318 for (entry = filedata->dynamic_section;
10319 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10320 ++entry)
10ca4b04 10321 if (entry->d_tag == DT_SYMTAB)
978c4450 10322 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10323 else if (entry->d_tag == DT_SYMENT)
978c4450 10324 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10325 else if (entry->d_tag == DT_HASH)
978c4450 10326 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10327 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10328 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10329 else if ((filedata->file_header.e_machine == EM_MIPS
10330 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10331 && entry->d_tag == DT_MIPS_XHASH)
10332 {
978c4450
AM
10333 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10334 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10335 }
252b5132 10336
2482f306
AM
10337 num_of_syms = get_num_dynamic_syms (filedata);
10338
10339 if (num_of_syms != 0
10340 && filedata->dynamic_symbols == NULL
10341 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10342 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10343 {
10344 Elf_Internal_Phdr *seg;
2482f306 10345 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10346
2482f306
AM
10347 if (! get_program_headers (filedata))
10348 {
10349 error (_("Cannot interpret virtual addresses "
10350 "without program headers.\n"));
10351 return FALSE;
10352 }
252b5132 10353
2482f306
AM
10354 for (seg = filedata->program_headers;
10355 seg < filedata->program_headers + filedata->file_header.e_phnum;
10356 ++seg)
10357 {
10358 if (seg->p_type != PT_LOAD)
10359 continue;
252b5132 10360
2482f306
AM
10361 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10362 {
10363 /* See PR 21379 for a reproducer. */
10364 error (_("Invalid PT_LOAD entry\n"));
10365 return FALSE;
10366 }
252b5132 10367
2482f306
AM
10368 if (vma >= (seg->p_vaddr & -seg->p_align)
10369 && vma < seg->p_vaddr + seg->p_filesz)
10370 {
10371 /* Since we do not know how big the symbol table is,
10372 we default to reading in up to the end of PT_LOAD
10373 segment and processing that. This is overkill, I
10374 know, but it should work. */
10375 Elf_Internal_Shdr section;
10376 section.sh_offset = (vma - seg->p_vaddr
10377 + seg->p_offset);
10378 section.sh_size = (num_of_syms
10379 * filedata->dynamic_info[DT_SYMENT]);
10380 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10381
10382 if (do_checks
10383 && filedata->dynamic_symtab_section != NULL
10384 && ((filedata->dynamic_symtab_section->sh_offset
10385 != section.sh_offset)
10386 || (filedata->dynamic_symtab_section->sh_size
10387 != section.sh_size)
10388 || (filedata->dynamic_symtab_section->sh_entsize
10389 != section.sh_entsize)))
10390 warn (_("\
10391the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10392
2482f306
AM
10393 section.sh_name = filedata->string_table_length;
10394 filedata->dynamic_symbols
10395 = GET_ELF_SYMBOLS (filedata, &section,
10396 &filedata->num_dynamic_syms);
10397 if (filedata->dynamic_symbols == NULL
10398 || filedata->num_dynamic_syms != num_of_syms)
10399 {
10400 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10401 return FALSE;
10402 }
10403 break;
10404 }
10405 }
10406 }
10407 }
252b5132
RH
10408
10409 /* Similarly find a string table. */
978c4450
AM
10410 if (filedata->dynamic_strings == NULL)
10411 for (entry = filedata->dynamic_section;
10412 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10413 ++entry)
10414 {
10415 if (entry->d_tag == DT_STRTAB)
978c4450 10416 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10417
10ca4b04 10418 if (entry->d_tag == DT_STRSZ)
978c4450 10419 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10420
978c4450
AM
10421 if (filedata->dynamic_info[DT_STRTAB]
10422 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10423 {
10424 unsigned long offset;
978c4450 10425 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10426
10427 offset = offset_from_vma (filedata,
978c4450 10428 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10429 str_tab_len);
8ac10c5b
L
10430 if (do_checks
10431 && filedata->dynamic_strtab_section
10432 && ((filedata->dynamic_strtab_section->sh_offset
10433 != (file_ptr) offset)
10434 || (filedata->dynamic_strtab_section->sh_size
10435 != str_tab_len)))
10436 warn (_("\
10437the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10438
978c4450
AM
10439 filedata->dynamic_strings
10440 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10441 _("dynamic string table"));
10442 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10443 {
10444 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10445 break;
10446 }
e3d39609 10447
978c4450 10448 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10449 break;
10450 }
10451 }
252b5132
RH
10452
10453 /* And find the syminfo section if available. */
978c4450 10454 if (filedata->dynamic_syminfo == NULL)
252b5132 10455 {
3e8bba36 10456 unsigned long syminsz = 0;
252b5132 10457
978c4450
AM
10458 for (entry = filedata->dynamic_section;
10459 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10460 ++entry)
252b5132
RH
10461 {
10462 if (entry->d_tag == DT_SYMINENT)
10463 {
10464 /* Note: these braces are necessary to avoid a syntax
10465 error from the SunOS4 C compiler. */
049b0c3a
NC
10466 /* PR binutils/17531: A corrupt file can trigger this test.
10467 So do not use an assert, instead generate an error message. */
10468 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10469 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10470 (int) entry->d_un.d_val);
252b5132
RH
10471 }
10472 else if (entry->d_tag == DT_SYMINSZ)
10473 syminsz = entry->d_un.d_val;
10474 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10475 filedata->dynamic_syminfo_offset
10476 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10477 }
10478
978c4450 10479 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10480 {
2cf0635d
NC
10481 Elf_External_Syminfo * extsyminfo;
10482 Elf_External_Syminfo * extsym;
10483 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10484
10485 /* There is a syminfo section. Read the data. */
3f5e193b 10486 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10487 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10488 1, syminsz, _("symbol information"));
a6e9f9df 10489 if (!extsyminfo)
32ec8896 10490 return FALSE;
252b5132 10491
978c4450 10492 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10493 {
10494 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10495 free (filedata->dynamic_syminfo);
e3d39609 10496 }
978c4450
AM
10497 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10498 if (filedata->dynamic_syminfo == NULL)
252b5132 10499 {
2482f306
AM
10500 error (_("Out of memory allocating %lu bytes "
10501 "for dynamic symbol info\n"),
8b73c356 10502 (unsigned long) syminsz);
32ec8896 10503 return FALSE;
252b5132
RH
10504 }
10505
2482f306
AM
10506 filedata->dynamic_syminfo_nent
10507 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10508 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10509 syminfo < (filedata->dynamic_syminfo
10510 + filedata->dynamic_syminfo_nent);
86dba8ee 10511 ++syminfo, ++extsym)
252b5132 10512 {
86dba8ee
AM
10513 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10514 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10515 }
10516
10517 free (extsyminfo);
10518 }
10519 }
10520
978c4450 10521 if (do_dynamic && filedata->dynamic_addr)
d3a49aa8
AM
10522 printf (ngettext ("\nDynamic section at offset 0x%lx "
10523 "contains %lu entry:\n",
10524 "\nDynamic section at offset 0x%lx "
10525 "contains %lu entries:\n",
978c4450
AM
10526 filedata->dynamic_nent),
10527 filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent);
252b5132
RH
10528 if (do_dynamic)
10529 printf (_(" Tag Type Name/Value\n"));
10530
978c4450
AM
10531 for (entry = filedata->dynamic_section;
10532 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10533 entry++)
252b5132
RH
10534 {
10535 if (do_dynamic)
f7a99963 10536 {
2cf0635d 10537 const char * dtype;
e699b9ff 10538
f7a99963
NC
10539 putchar (' ');
10540 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10541 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10542 printf (" (%s)%*s", dtype,
32ec8896 10543 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10544 }
252b5132
RH
10545
10546 switch (entry->d_tag)
10547 {
d1133906
NC
10548 case DT_FLAGS:
10549 if (do_dynamic)
e9e44622 10550 print_dynamic_flags (entry->d_un.d_val);
d1133906 10551 break;
76da6bbe 10552
252b5132
RH
10553 case DT_AUXILIARY:
10554 case DT_FILTER:
019148e4
L
10555 case DT_CONFIG:
10556 case DT_DEPAUDIT:
10557 case DT_AUDIT:
252b5132
RH
10558 if (do_dynamic)
10559 {
019148e4 10560 switch (entry->d_tag)
b34976b6 10561 {
019148e4
L
10562 case DT_AUXILIARY:
10563 printf (_("Auxiliary library"));
10564 break;
10565
10566 case DT_FILTER:
10567 printf (_("Filter library"));
10568 break;
10569
b34976b6 10570 case DT_CONFIG:
019148e4
L
10571 printf (_("Configuration file"));
10572 break;
10573
10574 case DT_DEPAUDIT:
10575 printf (_("Dependency audit library"));
10576 break;
10577
10578 case DT_AUDIT:
10579 printf (_("Audit library"));
10580 break;
10581 }
252b5132 10582
978c4450
AM
10583 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10584 printf (": [%s]\n",
10585 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10586 else
f7a99963
NC
10587 {
10588 printf (": ");
10589 print_vma (entry->d_un.d_val, PREFIX_HEX);
10590 putchar ('\n');
10591 }
252b5132
RH
10592 }
10593 break;
10594
dcefbbbd 10595 case DT_FEATURE:
252b5132
RH
10596 if (do_dynamic)
10597 {
10598 printf (_("Flags:"));
86f55779 10599
252b5132
RH
10600 if (entry->d_un.d_val == 0)
10601 printf (_(" None\n"));
10602 else
10603 {
10604 unsigned long int val = entry->d_un.d_val;
86f55779 10605
252b5132
RH
10606 if (val & DTF_1_PARINIT)
10607 {
10608 printf (" PARINIT");
10609 val ^= DTF_1_PARINIT;
10610 }
dcefbbbd
L
10611 if (val & DTF_1_CONFEXP)
10612 {
10613 printf (" CONFEXP");
10614 val ^= DTF_1_CONFEXP;
10615 }
252b5132
RH
10616 if (val != 0)
10617 printf (" %lx", val);
10618 puts ("");
10619 }
10620 }
10621 break;
10622
10623 case DT_POSFLAG_1:
10624 if (do_dynamic)
10625 {
10626 printf (_("Flags:"));
86f55779 10627
252b5132
RH
10628 if (entry->d_un.d_val == 0)
10629 printf (_(" None\n"));
10630 else
10631 {
10632 unsigned long int val = entry->d_un.d_val;
86f55779 10633
252b5132
RH
10634 if (val & DF_P1_LAZYLOAD)
10635 {
10636 printf (" LAZYLOAD");
10637 val ^= DF_P1_LAZYLOAD;
10638 }
10639 if (val & DF_P1_GROUPPERM)
10640 {
10641 printf (" GROUPPERM");
10642 val ^= DF_P1_GROUPPERM;
10643 }
10644 if (val != 0)
10645 printf (" %lx", val);
10646 puts ("");
10647 }
10648 }
10649 break;
10650
10651 case DT_FLAGS_1:
10652 if (do_dynamic)
10653 {
10654 printf (_("Flags:"));
10655 if (entry->d_un.d_val == 0)
10656 printf (_(" None\n"));
10657 else
10658 {
10659 unsigned long int val = entry->d_un.d_val;
86f55779 10660
252b5132
RH
10661 if (val & DF_1_NOW)
10662 {
10663 printf (" NOW");
10664 val ^= DF_1_NOW;
10665 }
10666 if (val & DF_1_GLOBAL)
10667 {
10668 printf (" GLOBAL");
10669 val ^= DF_1_GLOBAL;
10670 }
10671 if (val & DF_1_GROUP)
10672 {
10673 printf (" GROUP");
10674 val ^= DF_1_GROUP;
10675 }
10676 if (val & DF_1_NODELETE)
10677 {
10678 printf (" NODELETE");
10679 val ^= DF_1_NODELETE;
10680 }
10681 if (val & DF_1_LOADFLTR)
10682 {
10683 printf (" LOADFLTR");
10684 val ^= DF_1_LOADFLTR;
10685 }
10686 if (val & DF_1_INITFIRST)
10687 {
10688 printf (" INITFIRST");
10689 val ^= DF_1_INITFIRST;
10690 }
10691 if (val & DF_1_NOOPEN)
10692 {
10693 printf (" NOOPEN");
10694 val ^= DF_1_NOOPEN;
10695 }
10696 if (val & DF_1_ORIGIN)
10697 {
10698 printf (" ORIGIN");
10699 val ^= DF_1_ORIGIN;
10700 }
10701 if (val & DF_1_DIRECT)
10702 {
10703 printf (" DIRECT");
10704 val ^= DF_1_DIRECT;
10705 }
10706 if (val & DF_1_TRANS)
10707 {
10708 printf (" TRANS");
10709 val ^= DF_1_TRANS;
10710 }
10711 if (val & DF_1_INTERPOSE)
10712 {
10713 printf (" INTERPOSE");
10714 val ^= DF_1_INTERPOSE;
10715 }
f7db6139 10716 if (val & DF_1_NODEFLIB)
dcefbbbd 10717 {
f7db6139
L
10718 printf (" NODEFLIB");
10719 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10720 }
10721 if (val & DF_1_NODUMP)
10722 {
10723 printf (" NODUMP");
10724 val ^= DF_1_NODUMP;
10725 }
34b60028 10726 if (val & DF_1_CONFALT)
dcefbbbd 10727 {
34b60028
L
10728 printf (" CONFALT");
10729 val ^= DF_1_CONFALT;
10730 }
10731 if (val & DF_1_ENDFILTEE)
10732 {
10733 printf (" ENDFILTEE");
10734 val ^= DF_1_ENDFILTEE;
10735 }
10736 if (val & DF_1_DISPRELDNE)
10737 {
10738 printf (" DISPRELDNE");
10739 val ^= DF_1_DISPRELDNE;
10740 }
10741 if (val & DF_1_DISPRELPND)
10742 {
10743 printf (" DISPRELPND");
10744 val ^= DF_1_DISPRELPND;
10745 }
10746 if (val & DF_1_NODIRECT)
10747 {
10748 printf (" NODIRECT");
10749 val ^= DF_1_NODIRECT;
10750 }
10751 if (val & DF_1_IGNMULDEF)
10752 {
10753 printf (" IGNMULDEF");
10754 val ^= DF_1_IGNMULDEF;
10755 }
10756 if (val & DF_1_NOKSYMS)
10757 {
10758 printf (" NOKSYMS");
10759 val ^= DF_1_NOKSYMS;
10760 }
10761 if (val & DF_1_NOHDR)
10762 {
10763 printf (" NOHDR");
10764 val ^= DF_1_NOHDR;
10765 }
10766 if (val & DF_1_EDITED)
10767 {
10768 printf (" EDITED");
10769 val ^= DF_1_EDITED;
10770 }
10771 if (val & DF_1_NORELOC)
10772 {
10773 printf (" NORELOC");
10774 val ^= DF_1_NORELOC;
10775 }
10776 if (val & DF_1_SYMINTPOSE)
10777 {
10778 printf (" SYMINTPOSE");
10779 val ^= DF_1_SYMINTPOSE;
10780 }
10781 if (val & DF_1_GLOBAUDIT)
10782 {
10783 printf (" GLOBAUDIT");
10784 val ^= DF_1_GLOBAUDIT;
10785 }
10786 if (val & DF_1_SINGLETON)
10787 {
10788 printf (" SINGLETON");
10789 val ^= DF_1_SINGLETON;
dcefbbbd 10790 }
5c383f02
RO
10791 if (val & DF_1_STUB)
10792 {
10793 printf (" STUB");
10794 val ^= DF_1_STUB;
10795 }
10796 if (val & DF_1_PIE)
10797 {
10798 printf (" PIE");
10799 val ^= DF_1_PIE;
10800 }
b1202ffa
L
10801 if (val & DF_1_KMOD)
10802 {
10803 printf (" KMOD");
10804 val ^= DF_1_KMOD;
10805 }
10806 if (val & DF_1_WEAKFILTER)
10807 {
10808 printf (" WEAKFILTER");
10809 val ^= DF_1_WEAKFILTER;
10810 }
10811 if (val & DF_1_NOCOMMON)
10812 {
10813 printf (" NOCOMMON");
10814 val ^= DF_1_NOCOMMON;
10815 }
252b5132
RH
10816 if (val != 0)
10817 printf (" %lx", val);
10818 puts ("");
10819 }
10820 }
10821 break;
10822
10823 case DT_PLTREL:
978c4450 10824 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10825 if (do_dynamic)
dda8d76d 10826 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10827 break;
10828
10829 case DT_NULL :
10830 case DT_NEEDED :
10831 case DT_PLTGOT :
10832 case DT_HASH :
10833 case DT_STRTAB :
10834 case DT_SYMTAB :
10835 case DT_RELA :
10836 case DT_INIT :
10837 case DT_FINI :
10838 case DT_SONAME :
10839 case DT_RPATH :
10840 case DT_SYMBOLIC:
10841 case DT_REL :
10842 case DT_DEBUG :
10843 case DT_TEXTREL :
10844 case DT_JMPREL :
019148e4 10845 case DT_RUNPATH :
978c4450 10846 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
10847
10848 if (do_dynamic)
10849 {
2cf0635d 10850 char * name;
252b5132 10851
978c4450
AM
10852 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10853 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10854 else
d79b3d50 10855 name = NULL;
252b5132
RH
10856
10857 if (name)
10858 {
10859 switch (entry->d_tag)
10860 {
10861 case DT_NEEDED:
10862 printf (_("Shared library: [%s]"), name);
10863
978c4450 10864 if (streq (name, filedata->program_interpreter))
f7a99963 10865 printf (_(" program interpreter"));
252b5132
RH
10866 break;
10867
10868 case DT_SONAME:
f7a99963 10869 printf (_("Library soname: [%s]"), name);
252b5132
RH
10870 break;
10871
10872 case DT_RPATH:
f7a99963 10873 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10874 break;
10875
019148e4
L
10876 case DT_RUNPATH:
10877 printf (_("Library runpath: [%s]"), name);
10878 break;
10879
252b5132 10880 default:
f7a99963
NC
10881 print_vma (entry->d_un.d_val, PREFIX_HEX);
10882 break;
252b5132
RH
10883 }
10884 }
10885 else
f7a99963
NC
10886 print_vma (entry->d_un.d_val, PREFIX_HEX);
10887
10888 putchar ('\n');
252b5132
RH
10889 }
10890 break;
10891
10892 case DT_PLTRELSZ:
10893 case DT_RELASZ :
10894 case DT_STRSZ :
10895 case DT_RELSZ :
10896 case DT_RELAENT :
10897 case DT_SYMENT :
10898 case DT_RELENT :
978c4450 10899 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10900 /* Fall through. */
252b5132
RH
10901 case DT_PLTPADSZ:
10902 case DT_MOVEENT :
10903 case DT_MOVESZ :
10904 case DT_INIT_ARRAYSZ:
10905 case DT_FINI_ARRAYSZ:
047b2264
JJ
10906 case DT_GNU_CONFLICTSZ:
10907 case DT_GNU_LIBLISTSZ:
252b5132 10908 if (do_dynamic)
f7a99963
NC
10909 {
10910 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10911 printf (_(" (bytes)\n"));
f7a99963 10912 }
252b5132
RH
10913 break;
10914
10915 case DT_VERDEFNUM:
10916 case DT_VERNEEDNUM:
10917 case DT_RELACOUNT:
10918 case DT_RELCOUNT:
10919 if (do_dynamic)
f7a99963
NC
10920 {
10921 print_vma (entry->d_un.d_val, UNSIGNED);
10922 putchar ('\n');
10923 }
252b5132
RH
10924 break;
10925
10926 case DT_SYMINSZ:
10927 case DT_SYMINENT:
10928 case DT_SYMINFO:
10929 case DT_USED:
10930 case DT_INIT_ARRAY:
10931 case DT_FINI_ARRAY:
10932 if (do_dynamic)
10933 {
d79b3d50 10934 if (entry->d_tag == DT_USED
978c4450 10935 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 10936 {
978c4450 10937 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10938
b34976b6 10939 if (*name)
252b5132
RH
10940 {
10941 printf (_("Not needed object: [%s]\n"), name);
10942 break;
10943 }
10944 }
103f02d3 10945
f7a99963
NC
10946 print_vma (entry->d_un.d_val, PREFIX_HEX);
10947 putchar ('\n');
252b5132
RH
10948 }
10949 break;
10950
10951 case DT_BIND_NOW:
10952 /* The value of this entry is ignored. */
35b1837e
AM
10953 if (do_dynamic)
10954 putchar ('\n');
252b5132 10955 break;
103f02d3 10956
047b2264
JJ
10957 case DT_GNU_PRELINKED:
10958 if (do_dynamic)
10959 {
2cf0635d 10960 struct tm * tmp;
91d6fa6a 10961 time_t atime = entry->d_un.d_val;
047b2264 10962
91d6fa6a 10963 tmp = gmtime (&atime);
071436c6
NC
10964 /* PR 17533 file: 041-1244816-0.004. */
10965 if (tmp == NULL)
5a2cbcf4
L
10966 printf (_("<corrupt time val: %lx"),
10967 (unsigned long) atime);
071436c6
NC
10968 else
10969 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10970 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10971 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10972
10973 }
10974 break;
10975
fdc90cb4 10976 case DT_GNU_HASH:
978c4450 10977 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
10978 if (do_dynamic)
10979 {
10980 print_vma (entry->d_un.d_val, PREFIX_HEX);
10981 putchar ('\n');
10982 }
10983 break;
10984
252b5132
RH
10985 default:
10986 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
10987 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
10988 = entry->d_un.d_val;
252b5132
RH
10989
10990 if (do_dynamic)
10991 {
dda8d76d 10992 switch (filedata->file_header.e_machine)
252b5132 10993 {
37c18eed
SD
10994 case EM_AARCH64:
10995 dynamic_section_aarch64_val (entry);
10996 break;
252b5132 10997 case EM_MIPS:
4fe85591 10998 case EM_MIPS_RS3_LE:
978c4450 10999 dynamic_section_mips_val (filedata, entry);
252b5132 11000 break;
103f02d3 11001 case EM_PARISC:
b2d38a17 11002 dynamic_section_parisc_val (entry);
103f02d3 11003 break;
ecc51f48 11004 case EM_IA_64:
b2d38a17 11005 dynamic_section_ia64_val (entry);
ecc51f48 11006 break;
252b5132 11007 default:
f7a99963
NC
11008 print_vma (entry->d_un.d_val, PREFIX_HEX);
11009 putchar ('\n');
252b5132
RH
11010 }
11011 }
11012 break;
11013 }
11014 }
11015
32ec8896 11016 return TRUE;
252b5132
RH
11017}
11018
11019static char *
d3ba0551 11020get_ver_flags (unsigned int flags)
252b5132 11021{
6d4f21f6 11022 static char buff[128];
252b5132
RH
11023
11024 buff[0] = 0;
11025
11026 if (flags == 0)
11027 return _("none");
11028
11029 if (flags & VER_FLG_BASE)
7bb1ad17 11030 strcat (buff, "BASE");
252b5132
RH
11031
11032 if (flags & VER_FLG_WEAK)
11033 {
11034 if (flags & VER_FLG_BASE)
7bb1ad17 11035 strcat (buff, " | ");
252b5132 11036
7bb1ad17 11037 strcat (buff, "WEAK");
252b5132
RH
11038 }
11039
44ec90b9
RO
11040 if (flags & VER_FLG_INFO)
11041 {
11042 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11043 strcat (buff, " | ");
44ec90b9 11044
7bb1ad17 11045 strcat (buff, "INFO");
44ec90b9
RO
11046 }
11047
11048 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11049 {
11050 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11051 strcat (buff, " | ");
11052
11053 strcat (buff, _("<unknown>"));
11054 }
252b5132
RH
11055
11056 return buff;
11057}
11058
11059/* Display the contents of the version sections. */
98fb390a 11060
32ec8896 11061static bfd_boolean
dda8d76d 11062process_version_sections (Filedata * filedata)
252b5132 11063{
2cf0635d 11064 Elf_Internal_Shdr * section;
b34976b6 11065 unsigned i;
32ec8896 11066 bfd_boolean found = FALSE;
252b5132
RH
11067
11068 if (! do_version)
32ec8896 11069 return TRUE;
252b5132 11070
dda8d76d
NC
11071 for (i = 0, section = filedata->section_headers;
11072 i < filedata->file_header.e_shnum;
b34976b6 11073 i++, section++)
252b5132
RH
11074 {
11075 switch (section->sh_type)
11076 {
11077 case SHT_GNU_verdef:
11078 {
2cf0635d 11079 Elf_External_Verdef * edefs;
452bf675
AM
11080 unsigned long idx;
11081 unsigned long cnt;
2cf0635d 11082 char * endbuf;
252b5132 11083
32ec8896 11084 found = TRUE;
252b5132 11085
d3a49aa8
AM
11086 printf (ngettext ("\nVersion definition section '%s' "
11087 "contains %u entry:\n",
11088 "\nVersion definition section '%s' "
11089 "contains %u entries:\n",
11090 section->sh_info),
dda8d76d 11091 printable_section_name (filedata, section),
74e1a04b 11092 section->sh_info);
252b5132 11093
ae9ac79e 11094 printf (_(" Addr: 0x"));
252b5132 11095 printf_vma (section->sh_addr);
233f82cf 11096 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11097 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11098 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11099
3f5e193b 11100 edefs = (Elf_External_Verdef *)
dda8d76d 11101 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11102 _("version definition section"));
a6e9f9df
AM
11103 if (!edefs)
11104 break;
59245841 11105 endbuf = (char *) edefs + section->sh_size;
252b5132 11106
1445030f 11107 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11108 {
2cf0635d
NC
11109 char * vstart;
11110 Elf_External_Verdef * edef;
b34976b6 11111 Elf_Internal_Verdef ent;
2cf0635d 11112 Elf_External_Verdaux * eaux;
b34976b6 11113 Elf_Internal_Verdaux aux;
452bf675 11114 unsigned long isum;
b34976b6 11115 int j;
103f02d3 11116
252b5132 11117 vstart = ((char *) edefs) + idx;
54806181
AM
11118 if (vstart + sizeof (*edef) > endbuf)
11119 break;
252b5132
RH
11120
11121 edef = (Elf_External_Verdef *) vstart;
11122
11123 ent.vd_version = BYTE_GET (edef->vd_version);
11124 ent.vd_flags = BYTE_GET (edef->vd_flags);
11125 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11126 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11127 ent.vd_hash = BYTE_GET (edef->vd_hash);
11128 ent.vd_aux = BYTE_GET (edef->vd_aux);
11129 ent.vd_next = BYTE_GET (edef->vd_next);
11130
452bf675 11131 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11132 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11133
11134 printf (_(" Index: %d Cnt: %d "),
11135 ent.vd_ndx, ent.vd_cnt);
11136
452bf675 11137 /* Check for overflow. */
1445030f 11138 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11139 break;
11140
252b5132
RH
11141 vstart += ent.vd_aux;
11142
1445030f
AM
11143 if (vstart + sizeof (*eaux) > endbuf)
11144 break;
252b5132
RH
11145 eaux = (Elf_External_Verdaux *) vstart;
11146
11147 aux.vda_name = BYTE_GET (eaux->vda_name);
11148 aux.vda_next = BYTE_GET (eaux->vda_next);
11149
978c4450
AM
11150 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11151 printf (_("Name: %s\n"),
11152 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11153 else
11154 printf (_("Name index: %ld\n"), aux.vda_name);
11155
11156 isum = idx + ent.vd_aux;
11157
b34976b6 11158 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11159 {
1445030f
AM
11160 if (aux.vda_next < sizeof (*eaux)
11161 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11162 {
11163 warn (_("Invalid vda_next field of %lx\n"),
11164 aux.vda_next);
11165 j = ent.vd_cnt;
11166 break;
11167 }
dd24e3da 11168 /* Check for overflow. */
7e26601c 11169 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11170 break;
11171
252b5132
RH
11172 isum += aux.vda_next;
11173 vstart += aux.vda_next;
11174
54806181
AM
11175 if (vstart + sizeof (*eaux) > endbuf)
11176 break;
1445030f 11177 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11178
11179 aux.vda_name = BYTE_GET (eaux->vda_name);
11180 aux.vda_next = BYTE_GET (eaux->vda_next);
11181
978c4450 11182 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11183 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11184 isum, j,
11185 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11186 else
452bf675 11187 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11188 isum, j, aux.vda_name);
11189 }
dd24e3da 11190
54806181
AM
11191 if (j < ent.vd_cnt)
11192 printf (_(" Version def aux past end of section\n"));
252b5132 11193
c9f02c3e
MR
11194 /* PR 17531:
11195 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11196 if (ent.vd_next < sizeof (*edef)
11197 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11198 {
11199 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11200 cnt = section->sh_info;
11201 break;
11202 }
452bf675 11203 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11204 break;
11205
252b5132
RH
11206 idx += ent.vd_next;
11207 }
dd24e3da 11208
54806181
AM
11209 if (cnt < section->sh_info)
11210 printf (_(" Version definition past end of section\n"));
252b5132
RH
11211
11212 free (edefs);
11213 }
11214 break;
103f02d3 11215
252b5132
RH
11216 case SHT_GNU_verneed:
11217 {
2cf0635d 11218 Elf_External_Verneed * eneed;
452bf675
AM
11219 unsigned long idx;
11220 unsigned long cnt;
2cf0635d 11221 char * endbuf;
252b5132 11222
32ec8896 11223 found = TRUE;
252b5132 11224
d3a49aa8
AM
11225 printf (ngettext ("\nVersion needs section '%s' "
11226 "contains %u entry:\n",
11227 "\nVersion needs section '%s' "
11228 "contains %u entries:\n",
11229 section->sh_info),
dda8d76d 11230 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11231
11232 printf (_(" Addr: 0x"));
11233 printf_vma (section->sh_addr);
72de5009 11234 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11235 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11236 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11237
dda8d76d 11238 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11239 section->sh_offset, 1,
11240 section->sh_size,
9cf03b7e 11241 _("Version Needs section"));
a6e9f9df
AM
11242 if (!eneed)
11243 break;
59245841 11244 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11245
11246 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11247 {
2cf0635d 11248 Elf_External_Verneed * entry;
b34976b6 11249 Elf_Internal_Verneed ent;
452bf675 11250 unsigned long isum;
b34976b6 11251 int j;
2cf0635d 11252 char * vstart;
252b5132
RH
11253
11254 vstart = ((char *) eneed) + idx;
54806181
AM
11255 if (vstart + sizeof (*entry) > endbuf)
11256 break;
252b5132
RH
11257
11258 entry = (Elf_External_Verneed *) vstart;
11259
11260 ent.vn_version = BYTE_GET (entry->vn_version);
11261 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11262 ent.vn_file = BYTE_GET (entry->vn_file);
11263 ent.vn_aux = BYTE_GET (entry->vn_aux);
11264 ent.vn_next = BYTE_GET (entry->vn_next);
11265
452bf675 11266 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11267
978c4450
AM
11268 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11269 printf (_(" File: %s"),
11270 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11271 else
11272 printf (_(" File: %lx"), ent.vn_file);
11273
11274 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11275
dd24e3da 11276 /* Check for overflow. */
7e26601c 11277 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11278 break;
252b5132
RH
11279 vstart += ent.vn_aux;
11280
11281 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11282 {
2cf0635d 11283 Elf_External_Vernaux * eaux;
b34976b6 11284 Elf_Internal_Vernaux aux;
252b5132 11285
54806181
AM
11286 if (vstart + sizeof (*eaux) > endbuf)
11287 break;
252b5132
RH
11288 eaux = (Elf_External_Vernaux *) vstart;
11289
11290 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11291 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11292 aux.vna_other = BYTE_GET (eaux->vna_other);
11293 aux.vna_name = BYTE_GET (eaux->vna_name);
11294 aux.vna_next = BYTE_GET (eaux->vna_next);
11295
978c4450 11296 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11297 printf (_(" %#06lx: Name: %s"),
978c4450 11298 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11299 else
452bf675 11300 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11301 isum, aux.vna_name);
11302
11303 printf (_(" Flags: %s Version: %d\n"),
11304 get_ver_flags (aux.vna_flags), aux.vna_other);
11305
1445030f
AM
11306 if (aux.vna_next < sizeof (*eaux)
11307 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11308 {
11309 warn (_("Invalid vna_next field of %lx\n"),
11310 aux.vna_next);
11311 j = ent.vn_cnt;
11312 break;
11313 }
1445030f
AM
11314 /* Check for overflow. */
11315 if (aux.vna_next > (size_t) (endbuf - vstart))
11316 break;
252b5132
RH
11317 isum += aux.vna_next;
11318 vstart += aux.vna_next;
11319 }
9cf03b7e 11320
54806181 11321 if (j < ent.vn_cnt)
9cf03b7e 11322 warn (_("Missing Version Needs auxillary information\n"));
252b5132 11323
1445030f
AM
11324 if (ent.vn_next < sizeof (*entry)
11325 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11326 {
452bf675 11327 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11328 cnt = section->sh_info;
11329 break;
11330 }
1445030f
AM
11331 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11332 break;
252b5132
RH
11333 idx += ent.vn_next;
11334 }
9cf03b7e 11335
54806181 11336 if (cnt < section->sh_info)
9cf03b7e 11337 warn (_("Missing Version Needs information\n"));
103f02d3 11338
252b5132
RH
11339 free (eneed);
11340 }
11341 break;
11342
11343 case SHT_GNU_versym:
11344 {
2cf0635d 11345 Elf_Internal_Shdr * link_section;
8b73c356
NC
11346 size_t total;
11347 unsigned int cnt;
2cf0635d
NC
11348 unsigned char * edata;
11349 unsigned short * data;
11350 char * strtab;
11351 Elf_Internal_Sym * symbols;
11352 Elf_Internal_Shdr * string_sec;
ba5cdace 11353 unsigned long num_syms;
d3ba0551 11354 long off;
252b5132 11355
dda8d76d 11356 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11357 break;
11358
dda8d76d 11359 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11360 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11361
dda8d76d 11362 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11363 break;
11364
32ec8896 11365 found = TRUE;
252b5132 11366
dda8d76d 11367 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11368 if (symbols == NULL)
11369 break;
252b5132 11370
dda8d76d 11371 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11372
dda8d76d 11373 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11374 string_sec->sh_size,
11375 _("version string table"));
a6e9f9df 11376 if (!strtab)
0429c154
MS
11377 {
11378 free (symbols);
11379 break;
11380 }
252b5132 11381
d3a49aa8
AM
11382 printf (ngettext ("\nVersion symbols section '%s' "
11383 "contains %lu entry:\n",
11384 "\nVersion symbols section '%s' "
11385 "contains %lu entries:\n",
11386 total),
dda8d76d 11387 printable_section_name (filedata, section), (unsigned long) total);
252b5132 11388
ae9ac79e 11389 printf (_(" Addr: 0x"));
252b5132 11390 printf_vma (section->sh_addr);
72de5009 11391 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11392 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11393 printable_section_name (filedata, link_section));
252b5132 11394
dda8d76d 11395 off = offset_from_vma (filedata,
978c4450 11396 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11397 total * sizeof (short));
95099889
AM
11398 edata = (unsigned char *) get_data (NULL, filedata, off,
11399 sizeof (short), total,
11400 _("version symbol data"));
a6e9f9df
AM
11401 if (!edata)
11402 {
11403 free (strtab);
0429c154 11404 free (symbols);
a6e9f9df
AM
11405 break;
11406 }
252b5132 11407
3f5e193b 11408 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11409
11410 for (cnt = total; cnt --;)
b34976b6
AM
11411 data[cnt] = byte_get (edata + cnt * sizeof (short),
11412 sizeof (short));
252b5132
RH
11413
11414 free (edata);
11415
11416 for (cnt = 0; cnt < total; cnt += 4)
11417 {
11418 int j, nn;
ab273396
AM
11419 char *name;
11420 char *invalid = _("*invalid*");
252b5132
RH
11421
11422 printf (" %03x:", cnt);
11423
11424 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11425 switch (data[cnt + j])
252b5132
RH
11426 {
11427 case 0:
11428 fputs (_(" 0 (*local*) "), stdout);
11429 break;
11430
11431 case 1:
11432 fputs (_(" 1 (*global*) "), stdout);
11433 break;
11434
11435 default:
c244d050
NC
11436 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11437 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11438
dd24e3da 11439 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11440 array, break to avoid an out-of-bounds read. */
11441 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11442 {
11443 warn (_("invalid index into symbol array\n"));
11444 break;
11445 }
11446
ab273396 11447 name = NULL;
978c4450 11448 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11449 {
b34976b6
AM
11450 Elf_Internal_Verneed ivn;
11451 unsigned long offset;
252b5132 11452
d93f0186 11453 offset = offset_from_vma
978c4450
AM
11454 (filedata,
11455 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11456 sizeof (Elf_External_Verneed));
252b5132 11457
b34976b6 11458 do
252b5132 11459 {
b34976b6
AM
11460 Elf_Internal_Vernaux ivna;
11461 Elf_External_Verneed evn;
11462 Elf_External_Vernaux evna;
11463 unsigned long a_off;
252b5132 11464
dda8d76d 11465 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11466 _("version need")) == NULL)
11467 break;
0b4362b0 11468
252b5132
RH
11469 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11470 ivn.vn_next = BYTE_GET (evn.vn_next);
11471
11472 a_off = offset + ivn.vn_aux;
11473
11474 do
11475 {
dda8d76d 11476 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11477 1, _("version need aux (2)")) == NULL)
11478 {
11479 ivna.vna_next = 0;
11480 ivna.vna_other = 0;
11481 }
11482 else
11483 {
11484 ivna.vna_next = BYTE_GET (evna.vna_next);
11485 ivna.vna_other = BYTE_GET (evna.vna_other);
11486 }
252b5132
RH
11487
11488 a_off += ivna.vna_next;
11489 }
b34976b6 11490 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11491 && ivna.vna_next != 0);
11492
b34976b6 11493 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11494 {
11495 ivna.vna_name = BYTE_GET (evna.vna_name);
11496
54806181 11497 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11498 name = invalid;
54806181
AM
11499 else
11500 name = strtab + ivna.vna_name;
252b5132
RH
11501 break;
11502 }
11503
11504 offset += ivn.vn_next;
11505 }
11506 while (ivn.vn_next);
11507 }
00d93f34 11508
ab273396 11509 if (data[cnt + j] != 0x8001
978c4450 11510 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11511 {
b34976b6
AM
11512 Elf_Internal_Verdef ivd;
11513 Elf_External_Verdef evd;
11514 unsigned long offset;
252b5132 11515
d93f0186 11516 offset = offset_from_vma
978c4450
AM
11517 (filedata,
11518 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11519 sizeof evd);
252b5132
RH
11520
11521 do
11522 {
dda8d76d 11523 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11524 _("version def")) == NULL)
11525 {
11526 ivd.vd_next = 0;
948f632f 11527 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11528 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11529 break;
59245841
NC
11530 }
11531 else
11532 {
11533 ivd.vd_next = BYTE_GET (evd.vd_next);
11534 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11535 }
252b5132
RH
11536
11537 offset += ivd.vd_next;
11538 }
c244d050 11539 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11540 && ivd.vd_next != 0);
11541
c244d050 11542 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11543 {
b34976b6
AM
11544 Elf_External_Verdaux evda;
11545 Elf_Internal_Verdaux ivda;
252b5132
RH
11546
11547 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11548
dda8d76d 11549 if (get_data (&evda, filedata,
59245841
NC
11550 offset - ivd.vd_next + ivd.vd_aux,
11551 sizeof (evda), 1,
11552 _("version def aux")) == NULL)
11553 break;
252b5132
RH
11554
11555 ivda.vda_name = BYTE_GET (evda.vda_name);
11556
54806181 11557 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11558 name = invalid;
11559 else if (name != NULL && name != invalid)
11560 name = _("*both*");
54806181
AM
11561 else
11562 name = strtab + ivda.vda_name;
252b5132
RH
11563 }
11564 }
ab273396
AM
11565 if (name != NULL)
11566 nn += printf ("(%s%-*s",
11567 name,
11568 12 - (int) strlen (name),
11569 ")");
252b5132
RH
11570
11571 if (nn < 18)
11572 printf ("%*c", 18 - nn, ' ');
11573 }
11574
11575 putchar ('\n');
11576 }
11577
11578 free (data);
11579 free (strtab);
11580 free (symbols);
11581 }
11582 break;
103f02d3 11583
252b5132
RH
11584 default:
11585 break;
11586 }
11587 }
11588
11589 if (! found)
11590 printf (_("\nNo version information found in this file.\n"));
11591
32ec8896 11592 return TRUE;
252b5132
RH
11593}
11594
d1133906 11595static const char *
dda8d76d 11596get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11597{
89246a0e 11598 static char buff[64];
252b5132
RH
11599
11600 switch (binding)
11601 {
b34976b6
AM
11602 case STB_LOCAL: return "LOCAL";
11603 case STB_GLOBAL: return "GLOBAL";
11604 case STB_WEAK: return "WEAK";
252b5132
RH
11605 default:
11606 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11607 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11608 binding);
252b5132 11609 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11610 {
11611 if (binding == STB_GNU_UNIQUE
df3a023b 11612 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11613 return "UNIQUE";
11614 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11615 }
252b5132 11616 else
e9e44622 11617 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11618 return buff;
11619 }
11620}
11621
d1133906 11622static const char *
dda8d76d 11623get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11624{
89246a0e 11625 static char buff[64];
252b5132
RH
11626
11627 switch (type)
11628 {
b34976b6
AM
11629 case STT_NOTYPE: return "NOTYPE";
11630 case STT_OBJECT: return "OBJECT";
11631 case STT_FUNC: return "FUNC";
11632 case STT_SECTION: return "SECTION";
11633 case STT_FILE: return "FILE";
11634 case STT_COMMON: return "COMMON";
11635 case STT_TLS: return "TLS";
15ab5209
DB
11636 case STT_RELC: return "RELC";
11637 case STT_SRELC: return "SRELC";
252b5132
RH
11638 default:
11639 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11640 {
dda8d76d 11641 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11642 return "THUMB_FUNC";
103f02d3 11643
dda8d76d 11644 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11645 return "REGISTER";
11646
dda8d76d 11647 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11648 return "PARISC_MILLI";
11649
e9e44622 11650 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11651 }
252b5132 11652 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11653 {
dda8d76d 11654 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11655 {
11656 if (type == STT_HP_OPAQUE)
11657 return "HP_OPAQUE";
11658 if (type == STT_HP_STUB)
11659 return "HP_STUB";
11660 }
11661
d8045f23 11662 if (type == STT_GNU_IFUNC
dda8d76d 11663 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11664 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11665 return "IFUNC";
11666
e9e44622 11667 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11668 }
252b5132 11669 else
e9e44622 11670 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11671 return buff;
11672 }
11673}
11674
d1133906 11675static const char *
d3ba0551 11676get_symbol_visibility (unsigned int visibility)
d1133906
NC
11677{
11678 switch (visibility)
11679 {
b34976b6
AM
11680 case STV_DEFAULT: return "DEFAULT";
11681 case STV_INTERNAL: return "INTERNAL";
11682 case STV_HIDDEN: return "HIDDEN";
d1133906 11683 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11684 default:
27a45f42 11685 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11686 return _("<unknown>");
d1133906
NC
11687 }
11688}
11689
2057d69d
CZ
11690static const char *
11691get_alpha_symbol_other (unsigned int other)
9abca702 11692{
2057d69d
CZ
11693 switch (other)
11694 {
11695 case STO_ALPHA_NOPV: return "NOPV";
11696 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11697 default:
27a45f42 11698 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11699 return _("<unknown>");
9abca702 11700 }
2057d69d
CZ
11701}
11702
fd85a6a1
NC
11703static const char *
11704get_solaris_symbol_visibility (unsigned int visibility)
11705{
11706 switch (visibility)
11707 {
11708 case 4: return "EXPORTED";
11709 case 5: return "SINGLETON";
11710 case 6: return "ELIMINATE";
11711 default: return get_symbol_visibility (visibility);
11712 }
11713}
11714
2301ed1c
SN
11715static const char *
11716get_aarch64_symbol_other (unsigned int other)
11717{
11718 static char buf[32];
11719
11720 if (other & STO_AARCH64_VARIANT_PCS)
11721 {
11722 other &= ~STO_AARCH64_VARIANT_PCS;
11723 if (other == 0)
11724 return "VARIANT_PCS";
11725 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
11726 return buf;
11727 }
11728 return NULL;
11729}
11730
5e2b0d47
NC
11731static const char *
11732get_mips_symbol_other (unsigned int other)
11733{
11734 switch (other)
11735 {
32ec8896
NC
11736 case STO_OPTIONAL: return "OPTIONAL";
11737 case STO_MIPS_PLT: return "MIPS PLT";
11738 case STO_MIPS_PIC: return "MIPS PIC";
11739 case STO_MICROMIPS: return "MICROMIPS";
11740 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11741 case STO_MIPS16: return "MIPS16";
11742 default: return NULL;
5e2b0d47
NC
11743 }
11744}
11745
28f997cf 11746static const char *
dda8d76d 11747get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11748{
dda8d76d 11749 if (is_ia64_vms (filedata))
28f997cf
TG
11750 {
11751 static char res[32];
11752
11753 res[0] = 0;
11754
11755 /* Function types is for images and .STB files only. */
dda8d76d 11756 switch (filedata->file_header.e_type)
28f997cf
TG
11757 {
11758 case ET_DYN:
11759 case ET_EXEC:
11760 switch (VMS_ST_FUNC_TYPE (other))
11761 {
11762 case VMS_SFT_CODE_ADDR:
11763 strcat (res, " CA");
11764 break;
11765 case VMS_SFT_SYMV_IDX:
11766 strcat (res, " VEC");
11767 break;
11768 case VMS_SFT_FD:
11769 strcat (res, " FD");
11770 break;
11771 case VMS_SFT_RESERVE:
11772 strcat (res, " RSV");
11773 break;
11774 default:
bee0ee85
NC
11775 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11776 VMS_ST_FUNC_TYPE (other));
11777 strcat (res, " <unknown>");
11778 break;
28f997cf
TG
11779 }
11780 break;
11781 default:
11782 break;
11783 }
11784 switch (VMS_ST_LINKAGE (other))
11785 {
11786 case VMS_STL_IGNORE:
11787 strcat (res, " IGN");
11788 break;
11789 case VMS_STL_RESERVE:
11790 strcat (res, " RSV");
11791 break;
11792 case VMS_STL_STD:
11793 strcat (res, " STD");
11794 break;
11795 case VMS_STL_LNK:
11796 strcat (res, " LNK");
11797 break;
11798 default:
bee0ee85
NC
11799 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11800 VMS_ST_LINKAGE (other));
11801 strcat (res, " <unknown>");
11802 break;
28f997cf
TG
11803 }
11804
11805 if (res[0] != 0)
11806 return res + 1;
11807 else
11808 return res;
11809 }
11810 return NULL;
11811}
11812
6911b7dc
AM
11813static const char *
11814get_ppc64_symbol_other (unsigned int other)
11815{
14732552
AM
11816 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11817 return NULL;
11818
11819 other >>= STO_PPC64_LOCAL_BIT;
11820 if (other <= 6)
6911b7dc 11821 {
89246a0e 11822 static char buf[64];
14732552
AM
11823 if (other >= 2)
11824 other = ppc64_decode_local_entry (other);
11825 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11826 return buf;
11827 }
11828 return NULL;
11829}
11830
5e2b0d47 11831static const char *
dda8d76d 11832get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11833{
11834 const char * result = NULL;
89246a0e 11835 static char buff [64];
5e2b0d47
NC
11836
11837 if (other == 0)
11838 return "";
11839
dda8d76d 11840 switch (filedata->file_header.e_machine)
5e2b0d47 11841 {
2057d69d
CZ
11842 case EM_ALPHA:
11843 result = get_alpha_symbol_other (other);
11844 break;
2301ed1c
SN
11845 case EM_AARCH64:
11846 result = get_aarch64_symbol_other (other);
11847 break;
5e2b0d47
NC
11848 case EM_MIPS:
11849 result = get_mips_symbol_other (other);
28f997cf
TG
11850 break;
11851 case EM_IA_64:
dda8d76d 11852 result = get_ia64_symbol_other (filedata, other);
28f997cf 11853 break;
6911b7dc
AM
11854 case EM_PPC64:
11855 result = get_ppc64_symbol_other (other);
11856 break;
5e2b0d47 11857 default:
fd85a6a1 11858 result = NULL;
5e2b0d47
NC
11859 break;
11860 }
11861
11862 if (result)
11863 return result;
11864
11865 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11866 return buff;
11867}
11868
d1133906 11869static const char *
dda8d76d 11870get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11871{
b34976b6 11872 static char buff[32];
5cf1065c 11873
252b5132
RH
11874 switch (type)
11875 {
b34976b6
AM
11876 case SHN_UNDEF: return "UND";
11877 case SHN_ABS: return "ABS";
11878 case SHN_COMMON: return "COM";
252b5132 11879 default:
9ce701e2 11880 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
11881 && filedata->file_header.e_machine == EM_IA_64
11882 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
11883 return "ANSI_COM";
11884 else if ((filedata->file_header.e_machine == EM_X86_64
11885 || filedata->file_header.e_machine == EM_L1OM
11886 || filedata->file_header.e_machine == EM_K1OM)
11887 && type == SHN_X86_64_LCOMMON)
11888 return "LARGE_COM";
11889 else if ((type == SHN_MIPS_SCOMMON
11890 && filedata->file_header.e_machine == EM_MIPS)
11891 || (type == SHN_TIC6X_SCOMMON
11892 && filedata->file_header.e_machine == EM_TI_C6000))
11893 return "SCOM";
11894 else if (type == SHN_MIPS_SUNDEFINED
11895 && filedata->file_header.e_machine == EM_MIPS)
11896 return "SUND";
11897 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
11898 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
11899 else if (type >= SHN_LOOS && type <= SHN_HIOS)
11900 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11901 else if (type >= SHN_LORESERVE)
11902 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
11903 else if (filedata->file_header.e_shnum != 0
11904 && type >= filedata->file_header.e_shnum)
11905 sprintf (buff, _("bad section index[%3d]"), type);
11906 else
11907 sprintf (buff, "%3d", type);
11908 break;
fd85a6a1
NC
11909 }
11910
10ca4b04 11911 return buff;
6bd1a22c
L
11912}
11913
bb4d2ac2 11914static const char *
dda8d76d 11915get_symbol_version_string (Filedata * filedata,
1449284b
NC
11916 bfd_boolean is_dynsym,
11917 const char * strtab,
11918 unsigned long int strtab_size,
11919 unsigned int si,
11920 Elf_Internal_Sym * psym,
11921 enum versioned_symbol_info * sym_info,
11922 unsigned short * vna_other)
bb4d2ac2 11923{
ab273396
AM
11924 unsigned char data[2];
11925 unsigned short vers_data;
11926 unsigned long offset;
7a815dd5 11927 unsigned short max_vd_ndx;
bb4d2ac2 11928
ab273396 11929 if (!is_dynsym
978c4450 11930 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 11931 return NULL;
bb4d2ac2 11932
978c4450
AM
11933 offset = offset_from_vma (filedata,
11934 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11935 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11936
dda8d76d 11937 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11938 sizeof (data), 1, _("version data")) == NULL)
11939 return NULL;
11940
11941 vers_data = byte_get (data, 2);
bb4d2ac2 11942
1f6f5dba 11943 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11944 return NULL;
bb4d2ac2 11945
0b8b7609 11946 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
11947 max_vd_ndx = 0;
11948
ab273396
AM
11949 /* Usually we'd only see verdef for defined symbols, and verneed for
11950 undefined symbols. However, symbols defined by the linker in
11951 .dynbss for variables copied from a shared library in order to
11952 avoid text relocations are defined yet have verneed. We could
11953 use a heuristic to detect the special case, for example, check
11954 for verneed first on symbols defined in SHT_NOBITS sections, but
11955 it is simpler and more reliable to just look for both verdef and
11956 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11957
ab273396
AM
11958 if (psym->st_shndx != SHN_UNDEF
11959 && vers_data != 0x8001
978c4450 11960 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
11961 {
11962 Elf_Internal_Verdef ivd;
11963 Elf_Internal_Verdaux ivda;
11964 Elf_External_Verdaux evda;
11965 unsigned long off;
bb4d2ac2 11966
dda8d76d 11967 off = offset_from_vma (filedata,
978c4450 11968 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
11969 sizeof (Elf_External_Verdef));
11970
11971 do
bb4d2ac2 11972 {
ab273396
AM
11973 Elf_External_Verdef evd;
11974
dda8d76d 11975 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11976 _("version def")) == NULL)
11977 {
11978 ivd.vd_ndx = 0;
11979 ivd.vd_aux = 0;
11980 ivd.vd_next = 0;
1f6f5dba 11981 ivd.vd_flags = 0;
ab273396
AM
11982 }
11983 else
bb4d2ac2 11984 {
ab273396
AM
11985 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11986 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11987 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 11988 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 11989 }
bb4d2ac2 11990
7a815dd5
L
11991 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
11992 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
11993
ab273396
AM
11994 off += ivd.vd_next;
11995 }
11996 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11997
ab273396
AM
11998 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11999 {
9abca702 12000 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12001 return NULL;
12002
ab273396
AM
12003 off -= ivd.vd_next;
12004 off += ivd.vd_aux;
bb4d2ac2 12005
dda8d76d 12006 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12007 _("version def aux")) != NULL)
12008 {
12009 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12010
ab273396 12011 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12012 return (ivda.vda_name < strtab_size
12013 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12014 }
12015 }
12016 }
bb4d2ac2 12017
978c4450 12018 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12019 {
12020 Elf_External_Verneed evn;
12021 Elf_Internal_Verneed ivn;
12022 Elf_Internal_Vernaux ivna;
bb4d2ac2 12023
dda8d76d 12024 offset = offset_from_vma (filedata,
978c4450 12025 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12026 sizeof evn);
12027 do
12028 {
12029 unsigned long vna_off;
bb4d2ac2 12030
dda8d76d 12031 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12032 _("version need")) == NULL)
12033 {
12034 ivna.vna_next = 0;
12035 ivna.vna_other = 0;
12036 ivna.vna_name = 0;
12037 break;
12038 }
bb4d2ac2 12039
ab273396
AM
12040 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12041 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12042
ab273396 12043 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12044
ab273396
AM
12045 do
12046 {
12047 Elf_External_Vernaux evna;
bb4d2ac2 12048
dda8d76d 12049 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12050 _("version need aux (3)")) == NULL)
bb4d2ac2 12051 {
ab273396
AM
12052 ivna.vna_next = 0;
12053 ivna.vna_other = 0;
12054 ivna.vna_name = 0;
bb4d2ac2 12055 }
bb4d2ac2 12056 else
bb4d2ac2 12057 {
ab273396
AM
12058 ivna.vna_other = BYTE_GET (evna.vna_other);
12059 ivna.vna_next = BYTE_GET (evna.vna_next);
12060 ivna.vna_name = BYTE_GET (evna.vna_name);
12061 }
bb4d2ac2 12062
ab273396
AM
12063 vna_off += ivna.vna_next;
12064 }
12065 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12066
ab273396
AM
12067 if (ivna.vna_other == vers_data)
12068 break;
bb4d2ac2 12069
ab273396
AM
12070 offset += ivn.vn_next;
12071 }
12072 while (ivn.vn_next != 0);
bb4d2ac2 12073
ab273396
AM
12074 if (ivna.vna_other == vers_data)
12075 {
12076 *sym_info = symbol_undefined;
12077 *vna_other = ivna.vna_other;
12078 return (ivna.vna_name < strtab_size
12079 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12080 }
7a815dd5
L
12081 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12082 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12083 return _("<corrupt>");
bb4d2ac2 12084 }
ab273396 12085 return NULL;
bb4d2ac2
L
12086}
12087
10ca4b04
L
12088static void
12089print_dynamic_symbol (Filedata *filedata, unsigned long si,
12090 Elf_Internal_Sym *symtab,
12091 Elf_Internal_Shdr *section,
12092 char *strtab, size_t strtab_size)
252b5132 12093{
10ca4b04
L
12094 const char *version_string;
12095 enum versioned_symbol_info sym_info;
12096 unsigned short vna_other;
12097 Elf_Internal_Sym *psym = symtab + si;
0942c7ab 12098
10ca4b04
L
12099 printf ("%6ld: ", si);
12100 print_vma (psym->st_value, LONG_HEX);
12101 putchar (' ');
12102 print_vma (psym->st_size, DEC_5);
12103 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12104 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12105 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12106 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12107 else
252b5132 12108 {
10ca4b04 12109 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12110
10ca4b04
L
12111 printf (" %-7s", get_symbol_visibility (vis));
12112 /* Check to see if any other bits in the st_other field are set.
12113 Note - displaying this information disrupts the layout of the
12114 table being generated, but for the moment this case is very rare. */
12115 if (psym->st_other ^ vis)
12116 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12117 }
10ca4b04 12118 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab
NC
12119
12120 bfd_boolean is_valid = VALID_SYMBOL_NAME (strtab, strtab_size,
12121 psym->st_name);
12122 const char * sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
10ca4b04
L
12123
12124 version_string
12125 = get_symbol_version_string (filedata,
12126 (section == NULL
12127 || section->sh_type == SHT_DYNSYM),
12128 strtab, strtab_size, si,
12129 psym, &sym_info, &vna_other);
0942c7ab
NC
12130
12131 int len_avail = 21;
12132 if (! do_wide && version_string != NULL)
12133 {
ddb43bab 12134 char buffer[16];
0942c7ab 12135
ddb43bab 12136 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12137
12138 if (sym_info == symbol_undefined)
12139 len_avail -= sprintf (buffer," (%d)", vna_other);
12140 else if (sym_info != symbol_hidden)
12141 len_avail -= 1;
12142 }
12143
12144 print_symbol (len_avail, sstr);
12145
10ca4b04
L
12146 if (version_string)
12147 {
12148 if (sym_info == symbol_undefined)
12149 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12150 else
10ca4b04
L
12151 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12152 version_string);
12153 }
6bd1a22c 12154
10ca4b04 12155 putchar ('\n');
6bd1a22c 12156
10ca4b04
L
12157 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12158 && section != NULL
12159 && si >= section->sh_info
12160 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12161 && filedata->file_header.e_machine != EM_MIPS
12162 /* Solaris binaries have been found to violate this requirement as
12163 well. Not sure if this is a bug or an ABI requirement. */
12164 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12165 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12166 si, printable_section_name (filedata, section), section->sh_info);
12167}
f16a9783 12168
10ca4b04
L
12169/* Dump the symbol table. */
12170static bfd_boolean
12171process_symbol_table (Filedata * filedata)
12172{
12173 Elf_Internal_Shdr * section;
f16a9783 12174
10ca4b04
L
12175 if (!do_syms && !do_dyn_syms && !do_histogram)
12176 return TRUE;
6bd1a22c 12177
978c4450 12178 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12179 && do_syms
12180 && do_using_dynamic
978c4450
AM
12181 && filedata->dynamic_strings != NULL
12182 && filedata->dynamic_symbols != NULL)
6bd1a22c 12183 {
10ca4b04 12184 unsigned long si;
6bd1a22c 12185
10ca4b04
L
12186 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12187 "\nSymbol table for image contains %lu entries:\n",
978c4450
AM
12188 filedata->num_dynamic_syms),
12189 filedata->num_dynamic_syms);
10ca4b04
L
12190 if (is_32bit_elf)
12191 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12192 else
12193 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12194
978c4450
AM
12195 for (si = 0; si < filedata->num_dynamic_syms; si++)
12196 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12197 filedata->dynamic_strings,
12198 filedata->dynamic_strings_length);
252b5132 12199 }
8b73c356 12200 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12201 && filedata->section_headers != NULL)
252b5132 12202 {
b34976b6 12203 unsigned int i;
252b5132 12204
dda8d76d
NC
12205 for (i = 0, section = filedata->section_headers;
12206 i < filedata->file_header.e_shnum;
252b5132
RH
12207 i++, section++)
12208 {
2cf0635d 12209 char * strtab = NULL;
c256ffe7 12210 unsigned long int strtab_size = 0;
2cf0635d 12211 Elf_Internal_Sym * symtab;
ef3df110 12212 unsigned long si, num_syms;
252b5132 12213
2c610e4b
L
12214 if ((section->sh_type != SHT_SYMTAB
12215 && section->sh_type != SHT_DYNSYM)
12216 || (!do_syms
12217 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12218 continue;
12219
dd24e3da
NC
12220 if (section->sh_entsize == 0)
12221 {
12222 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12223 printable_section_name (filedata, section));
dd24e3da
NC
12224 continue;
12225 }
12226
d3a49aa8
AM
12227 num_syms = section->sh_size / section->sh_entsize;
12228 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12229 "\nSymbol table '%s' contains %lu entries:\n",
12230 num_syms),
dda8d76d 12231 printable_section_name (filedata, section),
d3a49aa8 12232 num_syms);
dd24e3da 12233
f7a99963 12234 if (is_32bit_elf)
ca47b30c 12235 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12236 else
ca47b30c 12237 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12238
dda8d76d 12239 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12240 if (symtab == NULL)
12241 continue;
12242
dda8d76d 12243 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12244 {
dda8d76d
NC
12245 strtab = filedata->string_table;
12246 strtab_size = filedata->string_table_length;
c256ffe7 12247 }
dda8d76d 12248 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12249 {
2cf0635d 12250 Elf_Internal_Shdr * string_sec;
252b5132 12251
dda8d76d 12252 string_sec = filedata->section_headers + section->sh_link;
252b5132 12253
dda8d76d 12254 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12255 1, string_sec->sh_size,
12256 _("string table"));
c256ffe7 12257 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12258 }
12259
10ca4b04
L
12260 for (si = 0; si < num_syms; si++)
12261 print_dynamic_symbol (filedata, si, symtab, section,
12262 strtab, strtab_size);
252b5132
RH
12263
12264 free (symtab);
dda8d76d 12265 if (strtab != filedata->string_table)
252b5132
RH
12266 free (strtab);
12267 }
12268 }
12269 else if (do_syms)
12270 printf
12271 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12272
978c4450 12273 if (do_histogram && filedata->buckets != NULL)
252b5132 12274 {
2cf0635d
NC
12275 unsigned long * lengths;
12276 unsigned long * counts;
66543521
AM
12277 unsigned long hn;
12278 bfd_vma si;
12279 unsigned long maxlength = 0;
12280 unsigned long nzero_counts = 0;
12281 unsigned long nsyms = 0;
6bd6a03d 12282 char *visited;
252b5132 12283
d3a49aa8
AM
12284 printf (ngettext ("\nHistogram for bucket list length "
12285 "(total of %lu bucket):\n",
12286 "\nHistogram for bucket list length "
12287 "(total of %lu buckets):\n",
978c4450
AM
12288 (unsigned long) filedata->nbuckets),
12289 (unsigned long) filedata->nbuckets);
252b5132 12290
978c4450
AM
12291 lengths = (unsigned long *) calloc (filedata->nbuckets,
12292 sizeof (*lengths));
252b5132
RH
12293 if (lengths == NULL)
12294 {
8b73c356 12295 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12296 goto err_out;
252b5132 12297 }
978c4450
AM
12298 visited = xcmalloc (filedata->nchains, 1);
12299 memset (visited, 0, filedata->nchains);
8b73c356
NC
12300
12301 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12302 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12303 {
978c4450 12304 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12305 {
b34976b6 12306 ++nsyms;
252b5132 12307 if (maxlength < ++lengths[hn])
b34976b6 12308 ++maxlength;
978c4450 12309 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12310 {
12311 error (_("histogram chain is corrupt\n"));
12312 break;
12313 }
12314 visited[si] = 1;
252b5132
RH
12315 }
12316 }
6bd6a03d 12317 free (visited);
252b5132 12318
3f5e193b 12319 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12320 if (counts == NULL)
12321 {
b2e951ec 12322 free (lengths);
8b73c356 12323 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12324 goto err_out;
252b5132
RH
12325 }
12326
978c4450 12327 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12328 ++counts[lengths[hn]];
252b5132 12329
978c4450 12330 if (filedata->nbuckets > 0)
252b5132 12331 {
66543521
AM
12332 unsigned long i;
12333 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12334 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12335 for (i = 1; i <= maxlength; ++i)
103f02d3 12336 {
66543521
AM
12337 nzero_counts += counts[i] * i;
12338 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12339 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12340 (nzero_counts * 100.0) / nsyms);
12341 }
252b5132
RH
12342 }
12343
12344 free (counts);
12345 free (lengths);
12346 }
12347
978c4450
AM
12348 free (filedata->buckets);
12349 filedata->buckets = NULL;
12350 filedata->nbuckets = 0;
12351 free (filedata->chains);
12352 filedata->chains = NULL;
252b5132 12353
978c4450 12354 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 12355 {
2cf0635d
NC
12356 unsigned long * lengths;
12357 unsigned long * counts;
fdc90cb4
JJ
12358 unsigned long hn;
12359 unsigned long maxlength = 0;
12360 unsigned long nzero_counts = 0;
12361 unsigned long nsyms = 0;
fdc90cb4 12362
f16a9783 12363 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12364 "(total of %lu bucket):\n",
f16a9783 12365 "\nHistogram for `%s' bucket list length "
d3a49aa8 12366 "(total of %lu buckets):\n",
978c4450
AM
12367 (unsigned long) filedata->ngnubuckets),
12368 GNU_HASH_SECTION_NAME (filedata),
12369 (unsigned long) filedata->ngnubuckets);
8b73c356 12370
978c4450
AM
12371 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
12372 sizeof (*lengths));
fdc90cb4
JJ
12373 if (lengths == NULL)
12374 {
8b73c356 12375 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12376 goto err_out;
fdc90cb4
JJ
12377 }
12378
fdc90cb4
JJ
12379 printf (_(" Length Number %% of total Coverage\n"));
12380
978c4450
AM
12381 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12382 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
12383 {
12384 bfd_vma off, length = 1;
12385
978c4450 12386 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 12387 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
12388 off < filedata->ngnuchains
12389 && (filedata->gnuchains[off] & 1) == 0;
071436c6 12390 ++off)
fdc90cb4
JJ
12391 ++length;
12392 lengths[hn] = length;
12393 if (length > maxlength)
12394 maxlength = length;
12395 nsyms += length;
12396 }
12397
3f5e193b 12398 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12399 if (counts == NULL)
12400 {
b2e951ec 12401 free (lengths);
8b73c356 12402 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12403 goto err_out;
fdc90cb4
JJ
12404 }
12405
978c4450 12406 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
12407 ++counts[lengths[hn]];
12408
978c4450 12409 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
12410 {
12411 unsigned long j;
12412 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12413 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
12414 for (j = 1; j <= maxlength; ++j)
12415 {
12416 nzero_counts += counts[j] * j;
12417 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12418 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
12419 (nzero_counts * 100.0) / nsyms);
12420 }
12421 }
12422
12423 free (counts);
12424 free (lengths);
fdc90cb4 12425 }
978c4450
AM
12426 free (filedata->gnubuckets);
12427 filedata->gnubuckets = NULL;
12428 filedata->ngnubuckets = 0;
12429 free (filedata->gnuchains);
12430 filedata->gnuchains = NULL;
12431 filedata->ngnuchains = 0;
12432 free (filedata->mipsxlat);
12433 filedata->mipsxlat = NULL;
32ec8896 12434 return TRUE;
fd486f32
AM
12435
12436 err_out:
978c4450
AM
12437 free (filedata->gnubuckets);
12438 filedata->gnubuckets = NULL;
12439 filedata->ngnubuckets = 0;
12440 free (filedata->gnuchains);
12441 filedata->gnuchains = NULL;
12442 filedata->ngnuchains = 0;
12443 free (filedata->mipsxlat);
12444 filedata->mipsxlat = NULL;
12445 free (filedata->buckets);
12446 filedata->buckets = NULL;
12447 filedata->nbuckets = 0;
12448 free (filedata->chains);
12449 filedata->chains = NULL;
fd486f32 12450 return FALSE;
252b5132
RH
12451}
12452
32ec8896 12453static bfd_boolean
dda8d76d 12454process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12455{
b4c96d0d 12456 unsigned int i;
252b5132 12457
978c4450 12458 if (filedata->dynamic_syminfo == NULL
252b5132
RH
12459 || !do_dynamic)
12460 /* No syminfo, this is ok. */
32ec8896 12461 return TRUE;
252b5132
RH
12462
12463 /* There better should be a dynamic symbol section. */
978c4450 12464 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
32ec8896 12465 return FALSE;
252b5132 12466
978c4450 12467 if (filedata->dynamic_addr)
d3a49aa8
AM
12468 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12469 "contains %d entry:\n",
12470 "\nDynamic info segment at offset 0x%lx "
12471 "contains %d entries:\n",
978c4450
AM
12472 filedata->dynamic_syminfo_nent),
12473 filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent);
252b5132
RH
12474
12475 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 12476 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 12477 {
978c4450 12478 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 12479
31104126 12480 printf ("%4d: ", i);
978c4450 12481 if (i >= filedata->num_dynamic_syms)
4082ef84 12482 printf (_("<corrupt index>"));
978c4450
AM
12483 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
12484 print_symbol (30, GET_DYNAMIC_NAME (filedata,
12485 filedata->dynamic_symbols[i].st_name));
d79b3d50 12486 else
978c4450 12487 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 12488 putchar (' ');
252b5132 12489
978c4450 12490 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
12491 {
12492 case SYMINFO_BT_SELF:
12493 fputs ("SELF ", stdout);
12494 break;
12495 case SYMINFO_BT_PARENT:
12496 fputs ("PARENT ", stdout);
12497 break;
12498 default:
978c4450
AM
12499 if (filedata->dynamic_syminfo[i].si_boundto > 0
12500 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
12501 && VALID_DYNAMIC_NAME (filedata,
12502 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12503 {
978c4450
AM
12504 print_symbol (10, GET_DYNAMIC_NAME (filedata,
12505 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12506 putchar (' ' );
12507 }
252b5132 12508 else
978c4450 12509 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
12510 break;
12511 }
12512
12513 if (flags & SYMINFO_FLG_DIRECT)
12514 printf (" DIRECT");
12515 if (flags & SYMINFO_FLG_PASSTHRU)
12516 printf (" PASSTHRU");
12517 if (flags & SYMINFO_FLG_COPY)
12518 printf (" COPY");
12519 if (flags & SYMINFO_FLG_LAZYLOAD)
12520 printf (" LAZYLOAD");
12521
12522 puts ("");
12523 }
12524
32ec8896 12525 return TRUE;
252b5132
RH
12526}
12527
75802ccb
CE
12528/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
12529 is contained by the region START .. END. The types of ADDR, START
12530 and END should all be the same. Note both ADDR + NELEM and END
12531 point to just beyond the end of the regions that are being tested. */
12532#define IN_RANGE(START,END,ADDR,NELEM) \
12533 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 12534
cf13d699
NC
12535/* Check to see if the given reloc needs to be handled in a target specific
12536 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12537 FALSE.
12538
12539 If called with reloc == NULL, then this is a signal that reloc processing
12540 for the current section has finished, and any saved state should be
12541 discarded. */
09c11c86 12542
cf13d699 12543static bfd_boolean
dda8d76d
NC
12544target_specific_reloc_handling (Filedata * filedata,
12545 Elf_Internal_Rela * reloc,
12546 unsigned char * start,
12547 unsigned char * end,
12548 Elf_Internal_Sym * symtab,
12549 unsigned long num_syms)
252b5132 12550{
f84ce13b
NC
12551 unsigned int reloc_type = 0;
12552 unsigned long sym_index = 0;
12553
12554 if (reloc)
12555 {
dda8d76d 12556 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12557 sym_index = get_reloc_symindex (reloc->r_info);
12558 }
252b5132 12559
dda8d76d 12560 switch (filedata->file_header.e_machine)
252b5132 12561 {
13761a11
NC
12562 case EM_MSP430:
12563 case EM_MSP430_OLD:
12564 {
12565 static Elf_Internal_Sym * saved_sym = NULL;
12566
f84ce13b
NC
12567 if (reloc == NULL)
12568 {
12569 saved_sym = NULL;
12570 return TRUE;
12571 }
12572
13761a11
NC
12573 switch (reloc_type)
12574 {
12575 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12576 if (uses_msp430x_relocs (filedata))
13761a11 12577 break;
1a0670f3 12578 /* Fall through. */
13761a11 12579 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12580 /* PR 21139. */
12581 if (sym_index >= num_syms)
12582 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12583 sym_index);
12584 else
12585 saved_sym = symtab + sym_index;
13761a11
NC
12586 return TRUE;
12587
12588 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12589 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12590 goto handle_sym_diff;
0b4362b0 12591
13761a11
NC
12592 case 5: /* R_MSP430_16_BYTE */
12593 case 9: /* R_MSP430_8 */
dda8d76d 12594 if (uses_msp430x_relocs (filedata))
13761a11
NC
12595 break;
12596 goto handle_sym_diff;
12597
12598 case 2: /* R_MSP430_ABS16 */
12599 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12600 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12601 break;
12602 goto handle_sym_diff;
0b4362b0 12603
13761a11
NC
12604 handle_sym_diff:
12605 if (saved_sym != NULL)
12606 {
03f7786e 12607 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12608 bfd_vma value;
12609
f84ce13b
NC
12610 if (sym_index >= num_syms)
12611 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12612 sym_index);
03f7786e 12613 else
f84ce13b
NC
12614 {
12615 value = reloc->r_addend + (symtab[sym_index].st_value
12616 - saved_sym->st_value);
12617
b32e566b 12618 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12619 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12620 else
12621 /* PR 21137 */
12622 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12623 (long) reloc->r_offset);
f84ce13b 12624 }
13761a11
NC
12625
12626 saved_sym = NULL;
12627 return TRUE;
12628 }
12629 break;
12630
12631 default:
12632 if (saved_sym != NULL)
071436c6 12633 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12634 break;
12635 }
12636 break;
12637 }
12638
cf13d699
NC
12639 case EM_MN10300:
12640 case EM_CYGNUS_MN10300:
12641 {
12642 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12643
f84ce13b
NC
12644 if (reloc == NULL)
12645 {
12646 saved_sym = NULL;
12647 return TRUE;
12648 }
12649
cf13d699
NC
12650 switch (reloc_type)
12651 {
12652 case 34: /* R_MN10300_ALIGN */
12653 return TRUE;
12654 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12655 if (sym_index >= num_syms)
12656 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12657 sym_index);
12658 else
12659 saved_sym = symtab + sym_index;
cf13d699 12660 return TRUE;
f84ce13b 12661
cf13d699
NC
12662 case 1: /* R_MN10300_32 */
12663 case 2: /* R_MN10300_16 */
12664 if (saved_sym != NULL)
12665 {
03f7786e 12666 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12667 bfd_vma value;
252b5132 12668
f84ce13b
NC
12669 if (sym_index >= num_syms)
12670 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12671 sym_index);
03f7786e 12672 else
f84ce13b
NC
12673 {
12674 value = reloc->r_addend + (symtab[sym_index].st_value
12675 - saved_sym->st_value);
12676
b32e566b 12677 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12678 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12679 else
12680 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12681 (long) reloc->r_offset);
f84ce13b 12682 }
252b5132 12683
cf13d699
NC
12684 saved_sym = NULL;
12685 return TRUE;
12686 }
12687 break;
12688 default:
12689 if (saved_sym != NULL)
071436c6 12690 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12691 break;
12692 }
12693 break;
12694 }
6ff71e76
NC
12695
12696 case EM_RL78:
12697 {
12698 static bfd_vma saved_sym1 = 0;
12699 static bfd_vma saved_sym2 = 0;
12700 static bfd_vma value;
12701
f84ce13b
NC
12702 if (reloc == NULL)
12703 {
12704 saved_sym1 = saved_sym2 = 0;
12705 return TRUE;
12706 }
12707
6ff71e76
NC
12708 switch (reloc_type)
12709 {
12710 case 0x80: /* R_RL78_SYM. */
12711 saved_sym1 = saved_sym2;
f84ce13b
NC
12712 if (sym_index >= num_syms)
12713 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12714 sym_index);
12715 else
12716 {
12717 saved_sym2 = symtab[sym_index].st_value;
12718 saved_sym2 += reloc->r_addend;
12719 }
6ff71e76
NC
12720 return TRUE;
12721
12722 case 0x83: /* R_RL78_OPsub. */
12723 value = saved_sym1 - saved_sym2;
12724 saved_sym2 = saved_sym1 = 0;
12725 return TRUE;
12726 break;
12727
12728 case 0x41: /* R_RL78_ABS32. */
b32e566b 12729 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12730 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12731 else
12732 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12733 (long) reloc->r_offset);
6ff71e76
NC
12734 value = 0;
12735 return TRUE;
12736
12737 case 0x43: /* R_RL78_ABS16. */
b32e566b 12738 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12739 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12740 else
12741 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12742 (long) reloc->r_offset);
6ff71e76
NC
12743 value = 0;
12744 return TRUE;
12745
12746 default:
12747 break;
12748 }
12749 break;
12750 }
252b5132
RH
12751 }
12752
cf13d699 12753 return FALSE;
252b5132
RH
12754}
12755
aca88567
NC
12756/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12757 DWARF debug sections. This is a target specific test. Note - we do not
12758 go through the whole including-target-headers-multiple-times route, (as
12759 we have already done with <elf/h8.h>) because this would become very
12760 messy and even then this function would have to contain target specific
12761 information (the names of the relocs instead of their numeric values).
12762 FIXME: This is not the correct way to solve this problem. The proper way
12763 is to have target specific reloc sizing and typing functions created by
12764 the reloc-macros.h header, in the same way that it already creates the
12765 reloc naming functions. */
12766
12767static bfd_boolean
dda8d76d 12768is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12769{
d347c9df 12770 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12771 switch (filedata->file_header.e_machine)
aca88567 12772 {
41e92641 12773 case EM_386:
22abe556 12774 case EM_IAMCU:
41e92641 12775 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12776 case EM_68K:
12777 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12778 case EM_860:
12779 return reloc_type == 1; /* R_860_32. */
12780 case EM_960:
12781 return reloc_type == 2; /* R_960_32. */
a06ea964 12782 case EM_AARCH64:
9282b95a
JW
12783 return (reloc_type == 258
12784 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
12785 case EM_BPF:
12786 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
12787 case EM_ADAPTEVA_EPIPHANY:
12788 return reloc_type == 3;
aca88567 12789 case EM_ALPHA:
137b6b5f 12790 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12791 case EM_ARC:
12792 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12793 case EM_ARC_COMPACT:
12794 case EM_ARC_COMPACT2:
12795 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12796 case EM_ARM:
12797 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12798 case EM_AVR_OLD:
aca88567
NC
12799 case EM_AVR:
12800 return reloc_type == 1;
12801 case EM_BLACKFIN:
12802 return reloc_type == 0x12; /* R_byte4_data. */
12803 case EM_CRIS:
12804 return reloc_type == 3; /* R_CRIS_32. */
12805 case EM_CR16:
12806 return reloc_type == 3; /* R_CR16_NUM32. */
12807 case EM_CRX:
12808 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
12809 case EM_CSKY:
12810 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
12811 case EM_CYGNUS_FRV:
12812 return reloc_type == 1;
41e92641
NC
12813 case EM_CYGNUS_D10V:
12814 case EM_D10V:
12815 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12816 case EM_CYGNUS_D30V:
12817 case EM_D30V:
12818 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12819 case EM_DLX:
12820 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12821 case EM_CYGNUS_FR30:
12822 case EM_FR30:
12823 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12824 case EM_FT32:
12825 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12826 case EM_H8S:
12827 case EM_H8_300:
12828 case EM_H8_300H:
12829 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12830 case EM_IA_64:
262cdac7
AM
12831 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12832 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12833 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12834 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12835 case EM_IP2K_OLD:
12836 case EM_IP2K:
12837 return reloc_type == 2; /* R_IP2K_32. */
12838 case EM_IQ2000:
12839 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12840 case EM_LATTICEMICO32:
12841 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12842 case EM_M32C_OLD:
aca88567
NC
12843 case EM_M32C:
12844 return reloc_type == 3; /* R_M32C_32. */
12845 case EM_M32R:
12846 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12847 case EM_68HC11:
12848 case EM_68HC12:
12849 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 12850 case EM_S12Z:
2849d19f
JD
12851 return reloc_type == 7 || /* R_S12Z_EXT32 */
12852 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
12853 case EM_MCORE:
12854 return reloc_type == 1; /* R_MCORE_ADDR32. */
12855 case EM_CYGNUS_MEP:
12856 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12857 case EM_METAG:
12858 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12859 case EM_MICROBLAZE:
12860 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12861 case EM_MIPS:
12862 return reloc_type == 2; /* R_MIPS_32. */
12863 case EM_MMIX:
12864 return reloc_type == 4; /* R_MMIX_32. */
12865 case EM_CYGNUS_MN10200:
12866 case EM_MN10200:
12867 return reloc_type == 1; /* R_MN10200_32. */
12868 case EM_CYGNUS_MN10300:
12869 case EM_MN10300:
12870 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12871 case EM_MOXIE:
12872 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12873 case EM_MSP430_OLD:
12874 case EM_MSP430:
13761a11 12875 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12876 case EM_MT:
12877 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12878 case EM_NDS32:
12879 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12880 case EM_ALTERA_NIOS2:
36591ba1 12881 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12882 case EM_NIOS32:
12883 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12884 case EM_OR1K:
12885 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12886 case EM_PARISC:
9abca702 12887 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 12888 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12889 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12890 case EM_PJ:
12891 case EM_PJ_OLD:
12892 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12893 case EM_PPC64:
12894 return reloc_type == 1; /* R_PPC64_ADDR32. */
12895 case EM_PPC:
12896 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12897 case EM_TI_PRU:
12898 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12899 case EM_RISCV:
12900 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12901 case EM_RL78:
12902 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12903 case EM_RX:
12904 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12905 case EM_S370:
12906 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12907 case EM_S390_OLD:
12908 case EM_S390:
12909 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12910 case EM_SCORE:
12911 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12912 case EM_SH:
12913 return reloc_type == 1; /* R_SH_DIR32. */
12914 case EM_SPARC32PLUS:
12915 case EM_SPARCV9:
12916 case EM_SPARC:
12917 return reloc_type == 3 /* R_SPARC_32. */
12918 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12919 case EM_SPU:
12920 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12921 case EM_TI_C6000:
12922 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12923 case EM_TILEGX:
12924 return reloc_type == 2; /* R_TILEGX_32. */
12925 case EM_TILEPRO:
12926 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12927 case EM_CYGNUS_V850:
12928 case EM_V850:
12929 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12930 case EM_V800:
12931 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12932 case EM_VAX:
12933 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12934 case EM_VISIUM:
12935 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12936 case EM_WEBASSEMBLY:
12937 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12938 case EM_X86_64:
8a9036a4 12939 case EM_L1OM:
7a9068fe 12940 case EM_K1OM:
aca88567 12941 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12942 case EM_XC16X:
12943 case EM_C166:
12944 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12945 case EM_XGATE:
12946 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12947 case EM_XSTORMY16:
12948 return reloc_type == 1; /* R_XSTROMY16_32. */
12949 case EM_XTENSA_OLD:
12950 case EM_XTENSA:
12951 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
12952 case EM_Z80:
12953 return reloc_type == 6; /* R_Z80_32. */
aca88567 12954 default:
bee0ee85
NC
12955 {
12956 static unsigned int prev_warn = 0;
12957
12958 /* Avoid repeating the same warning multiple times. */
dda8d76d 12959 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12960 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12961 filedata->file_header.e_machine);
12962 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12963 return FALSE;
12964 }
aca88567
NC
12965 }
12966}
12967
12968/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12969 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12970
12971static bfd_boolean
dda8d76d 12972is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12973{
dda8d76d 12974 switch (filedata->file_header.e_machine)
d347c9df 12975 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12976 {
41e92641 12977 case EM_386:
22abe556 12978 case EM_IAMCU:
3e0873ac 12979 return reloc_type == 2; /* R_386_PC32. */
aca88567 12980 case EM_68K:
3e0873ac 12981 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12982 case EM_AARCH64:
12983 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12984 case EM_ADAPTEVA_EPIPHANY:
12985 return reloc_type == 6;
aca88567
NC
12986 case EM_ALPHA:
12987 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12988 case EM_ARC_COMPACT:
12989 case EM_ARC_COMPACT2:
12990 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12991 case EM_ARM:
3e0873ac 12992 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12993 case EM_AVR_OLD:
12994 case EM_AVR:
12995 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12996 case EM_MICROBLAZE:
12997 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12998 case EM_OR1K:
12999 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13000 case EM_PARISC:
85acf597 13001 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13002 case EM_PPC:
13003 return reloc_type == 26; /* R_PPC_REL32. */
13004 case EM_PPC64:
3e0873ac 13005 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13006 case EM_RISCV:
13007 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13008 case EM_S390_OLD:
13009 case EM_S390:
3e0873ac 13010 return reloc_type == 5; /* R_390_PC32. */
aca88567 13011 case EM_SH:
3e0873ac 13012 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13013 case EM_SPARC32PLUS:
13014 case EM_SPARCV9:
13015 case EM_SPARC:
3e0873ac 13016 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13017 case EM_SPU:
13018 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13019 case EM_TILEGX:
13020 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13021 case EM_TILEPRO:
13022 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13023 case EM_VISIUM:
13024 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13025 case EM_X86_64:
8a9036a4 13026 case EM_L1OM:
7a9068fe 13027 case EM_K1OM:
3e0873ac 13028 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13029 case EM_VAX:
13030 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13031 case EM_XTENSA_OLD:
13032 case EM_XTENSA:
13033 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13034 default:
13035 /* Do not abort or issue an error message here. Not all targets use
13036 pc-relative 32-bit relocs in their DWARF debug information and we
13037 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13038 more helpful warning message will be generated by apply_relocations
13039 anyway, so just return. */
aca88567
NC
13040 return FALSE;
13041 }
13042}
13043
13044/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13045 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13046
13047static bfd_boolean
dda8d76d 13048is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13049{
dda8d76d 13050 switch (filedata->file_header.e_machine)
aca88567 13051 {
a06ea964
NC
13052 case EM_AARCH64:
13053 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13054 case EM_ALPHA:
13055 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13056 case EM_IA_64:
262cdac7
AM
13057 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13058 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13059 case EM_PARISC:
13060 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13061 case EM_PPC64:
13062 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13063 case EM_RISCV:
13064 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13065 case EM_SPARC32PLUS:
13066 case EM_SPARCV9:
13067 case EM_SPARC:
714da62f
NC
13068 return reloc_type == 32 /* R_SPARC_64. */
13069 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13070 case EM_X86_64:
8a9036a4 13071 case EM_L1OM:
7a9068fe 13072 case EM_K1OM:
aca88567 13073 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13074 case EM_S390_OLD:
13075 case EM_S390:
aa137e4d
NC
13076 return reloc_type == 22; /* R_S390_64. */
13077 case EM_TILEGX:
13078 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13079 case EM_MIPS:
aa137e4d 13080 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
13081 default:
13082 return FALSE;
13083 }
13084}
13085
85acf597
RH
13086/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13087 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13088
13089static bfd_boolean
dda8d76d 13090is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13091{
dda8d76d 13092 switch (filedata->file_header.e_machine)
85acf597 13093 {
a06ea964
NC
13094 case EM_AARCH64:
13095 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13096 case EM_ALPHA:
aa137e4d 13097 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13098 case EM_IA_64:
262cdac7
AM
13099 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13100 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13101 case EM_PARISC:
aa137e4d 13102 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13103 case EM_PPC64:
aa137e4d 13104 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13105 case EM_SPARC32PLUS:
13106 case EM_SPARCV9:
13107 case EM_SPARC:
aa137e4d 13108 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13109 case EM_X86_64:
8a9036a4 13110 case EM_L1OM:
7a9068fe 13111 case EM_K1OM:
aa137e4d 13112 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13113 case EM_S390_OLD:
13114 case EM_S390:
aa137e4d
NC
13115 return reloc_type == 23; /* R_S390_PC64. */
13116 case EM_TILEGX:
13117 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
13118 default:
13119 return FALSE;
13120 }
13121}
13122
4dc3c23d
AM
13123/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13124 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13125
13126static bfd_boolean
dda8d76d 13127is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13128{
dda8d76d 13129 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13130 {
13131 case EM_CYGNUS_MN10200:
13132 case EM_MN10200:
13133 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13134 case EM_FT32:
13135 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13136 case EM_Z80:
13137 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
13138 default:
13139 return FALSE;
13140 }
13141}
13142
aca88567
NC
13143/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13144 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13145
13146static bfd_boolean
dda8d76d 13147is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13148{
d347c9df 13149 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13150 switch (filedata->file_header.e_machine)
4b78141a 13151 {
886a2506
NC
13152 case EM_ARC:
13153 case EM_ARC_COMPACT:
13154 case EM_ARC_COMPACT2:
13155 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13156 case EM_ADAPTEVA_EPIPHANY:
13157 return reloc_type == 5;
aca88567
NC
13158 case EM_AVR_OLD:
13159 case EM_AVR:
13160 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13161 case EM_CYGNUS_D10V:
13162 case EM_D10V:
13163 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13164 case EM_FT32:
13165 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13166 case EM_H8S:
13167 case EM_H8_300:
13168 case EM_H8_300H:
aca88567
NC
13169 return reloc_type == R_H8_DIR16;
13170 case EM_IP2K_OLD:
13171 case EM_IP2K:
13172 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13173 case EM_M32C_OLD:
f4236fe4
DD
13174 case EM_M32C:
13175 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13176 case EM_CYGNUS_MN10200:
13177 case EM_MN10200:
13178 return reloc_type == 2; /* R_MN10200_16. */
13179 case EM_CYGNUS_MN10300:
13180 case EM_MN10300:
13181 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13182 case EM_MSP430:
dda8d76d 13183 if (uses_msp430x_relocs (filedata))
13761a11 13184 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13185 /* Fall through. */
78c8d46c 13186 case EM_MSP430_OLD:
aca88567 13187 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13188 case EM_NDS32:
13189 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13190 case EM_ALTERA_NIOS2:
36591ba1 13191 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13192 case EM_NIOS32:
13193 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13194 case EM_OR1K:
13195 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13196 case EM_RISCV:
13197 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13198 case EM_TI_PRU:
13199 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13200 case EM_TI_C6000:
13201 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13202 case EM_VISIUM:
13203 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13204 case EM_XC16X:
13205 case EM_C166:
13206 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13207 case EM_XGATE:
13208 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13209 case EM_Z80:
13210 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13211 default:
aca88567 13212 return FALSE;
4b78141a
NC
13213 }
13214}
13215
39e07931
AS
13216/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13217 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13218
13219static bfd_boolean
13220is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13221{
13222 switch (filedata->file_header.e_machine)
13223 {
13224 case EM_RISCV:
13225 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13226 case EM_Z80:
13227 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13228 default:
13229 return FALSE;
13230 }
13231}
13232
13233/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13234 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13235
13236static bfd_boolean
13237is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13238{
13239 switch (filedata->file_header.e_machine)
13240 {
13241 case EM_RISCV:
13242 return reloc_type == 53; /* R_RISCV_SET6. */
13243 default:
13244 return FALSE;
13245 }
13246}
13247
03336641
JW
13248/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13249 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13250
13251static bfd_boolean
13252is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13253{
13254 /* Please keep this table alpha-sorted for ease of visual lookup. */
13255 switch (filedata->file_header.e_machine)
13256 {
13257 case EM_RISCV:
13258 return reloc_type == 35; /* R_RISCV_ADD32. */
13259 default:
13260 return FALSE;
13261 }
13262}
13263
13264/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13265 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13266
13267static bfd_boolean
13268is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13269{
13270 /* Please keep this table alpha-sorted for ease of visual lookup. */
13271 switch (filedata->file_header.e_machine)
13272 {
13273 case EM_RISCV:
13274 return reloc_type == 39; /* R_RISCV_SUB32. */
13275 default:
13276 return FALSE;
13277 }
13278}
13279
13280/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13281 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13282
13283static bfd_boolean
13284is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13285{
13286 /* Please keep this table alpha-sorted for ease of visual lookup. */
13287 switch (filedata->file_header.e_machine)
13288 {
13289 case EM_RISCV:
13290 return reloc_type == 36; /* R_RISCV_ADD64. */
13291 default:
13292 return FALSE;
13293 }
13294}
13295
13296/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13297 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13298
13299static bfd_boolean
13300is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13301{
13302 /* Please keep this table alpha-sorted for ease of visual lookup. */
13303 switch (filedata->file_header.e_machine)
13304 {
13305 case EM_RISCV:
13306 return reloc_type == 40; /* R_RISCV_SUB64. */
13307 default:
13308 return FALSE;
13309 }
13310}
13311
13312/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13313 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13314
13315static bfd_boolean
13316is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13317{
13318 /* Please keep this table alpha-sorted for ease of visual lookup. */
13319 switch (filedata->file_header.e_machine)
13320 {
13321 case EM_RISCV:
13322 return reloc_type == 34; /* R_RISCV_ADD16. */
13323 default:
13324 return FALSE;
13325 }
13326}
13327
13328/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13329 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13330
13331static bfd_boolean
13332is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13333{
13334 /* Please keep this table alpha-sorted for ease of visual lookup. */
13335 switch (filedata->file_header.e_machine)
13336 {
13337 case EM_RISCV:
13338 return reloc_type == 38; /* R_RISCV_SUB16. */
13339 default:
13340 return FALSE;
13341 }
13342}
13343
13344/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13345 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13346
13347static bfd_boolean
13348is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13349{
13350 /* Please keep this table alpha-sorted for ease of visual lookup. */
13351 switch (filedata->file_header.e_machine)
13352 {
13353 case EM_RISCV:
13354 return reloc_type == 33; /* R_RISCV_ADD8. */
13355 default:
13356 return FALSE;
13357 }
13358}
13359
13360/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13361 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13362
13363static bfd_boolean
13364is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13365{
13366 /* Please keep this table alpha-sorted for ease of visual lookup. */
13367 switch (filedata->file_header.e_machine)
13368 {
13369 case EM_RISCV:
13370 return reloc_type == 37; /* R_RISCV_SUB8. */
13371 default:
13372 return FALSE;
13373 }
13374}
13375
39e07931
AS
13376/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13377 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13378
13379static bfd_boolean
13380is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13381{
13382 switch (filedata->file_header.e_machine)
13383 {
13384 case EM_RISCV:
13385 return reloc_type == 52; /* R_RISCV_SUB6. */
13386 default:
13387 return FALSE;
13388 }
13389}
13390
2a7b2e88
JK
13391/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13392 relocation entries (possibly formerly used for SHT_GROUP sections). */
13393
13394static bfd_boolean
dda8d76d 13395is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13396{
dda8d76d 13397 switch (filedata->file_header.e_machine)
2a7b2e88 13398 {
cb8f3167 13399 case EM_386: /* R_386_NONE. */
d347c9df 13400 case EM_68K: /* R_68K_NONE. */
cfb8c092 13401 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13402 case EM_ALPHA: /* R_ALPHA_NONE. */
13403 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13404 case EM_ARC: /* R_ARC_NONE. */
886a2506 13405 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13406 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13407 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13408 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13409 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13410 case EM_FT32: /* R_FT32_NONE. */
13411 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13412 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13413 case EM_L1OM: /* R_X86_64_NONE. */
13414 case EM_M32R: /* R_M32R_NONE. */
13415 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13416 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13417 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13418 case EM_NIOS32: /* R_NIOS_NONE. */
13419 case EM_OR1K: /* R_OR1K_NONE. */
13420 case EM_PARISC: /* R_PARISC_NONE. */
13421 case EM_PPC64: /* R_PPC64_NONE. */
13422 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13423 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13424 case EM_S390: /* R_390_NONE. */
13425 case EM_S390_OLD:
13426 case EM_SH: /* R_SH_NONE. */
13427 case EM_SPARC32PLUS:
13428 case EM_SPARC: /* R_SPARC_NONE. */
13429 case EM_SPARCV9:
aa137e4d
NC
13430 case EM_TILEGX: /* R_TILEGX_NONE. */
13431 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13432 case EM_TI_C6000:/* R_C6000_NONE. */
13433 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13434 case EM_XC16X:
6655dba2 13435 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 13436 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13437 return reloc_type == 0;
d347c9df 13438
a06ea964
NC
13439 case EM_AARCH64:
13440 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13441 case EM_AVR_OLD:
13442 case EM_AVR:
13443 return (reloc_type == 0 /* R_AVR_NONE. */
13444 || reloc_type == 30 /* R_AVR_DIFF8. */
13445 || reloc_type == 31 /* R_AVR_DIFF16. */
13446 || reloc_type == 32 /* R_AVR_DIFF32. */);
13447 case EM_METAG:
13448 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13449 case EM_NDS32:
13450 return (reloc_type == 0 /* R_XTENSA_NONE. */
13451 || reloc_type == 204 /* R_NDS32_DIFF8. */
13452 || reloc_type == 205 /* R_NDS32_DIFF16. */
13453 || reloc_type == 206 /* R_NDS32_DIFF32. */
13454 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13455 case EM_TI_PRU:
13456 return (reloc_type == 0 /* R_PRU_NONE. */
13457 || reloc_type == 65 /* R_PRU_DIFF8. */
13458 || reloc_type == 66 /* R_PRU_DIFF16. */
13459 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13460 case EM_XTENSA_OLD:
13461 case EM_XTENSA:
4dc3c23d
AM
13462 return (reloc_type == 0 /* R_XTENSA_NONE. */
13463 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13464 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
13465 || reloc_type == 19 /* R_XTENSA_DIFF32. */
13466 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
13467 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
13468 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
13469 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
13470 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
13471 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88
JK
13472 }
13473 return FALSE;
13474}
13475
d1c4b12b
NC
13476/* Returns TRUE if there is a relocation against
13477 section NAME at OFFSET bytes. */
13478
13479bfd_boolean
13480reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13481{
13482 Elf_Internal_Rela * relocs;
13483 Elf_Internal_Rela * rp;
13484
13485 if (dsec == NULL || dsec->reloc_info == NULL)
13486 return FALSE;
13487
13488 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13489
13490 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13491 if (rp->r_offset == offset)
13492 return TRUE;
13493
13494 return FALSE;
13495}
13496
cf13d699 13497/* Apply relocations to a section.
32ec8896
NC
13498 Returns TRUE upon success, FALSE otherwise.
13499 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13500 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13501 will be set to the number of relocs loaded.
13502
cf13d699 13503 Note: So far support has been added only for those relocations
32ec8896
NC
13504 which can be found in debug sections. FIXME: Add support for
13505 more relocations ? */
1b315056 13506
32ec8896 13507static bfd_boolean
dda8d76d 13508apply_relocations (Filedata * filedata,
d1c4b12b
NC
13509 const Elf_Internal_Shdr * section,
13510 unsigned char * start,
13511 bfd_size_type size,
1449284b 13512 void ** relocs_return,
d1c4b12b 13513 unsigned long * num_relocs_return)
1b315056 13514{
cf13d699 13515 Elf_Internal_Shdr * relsec;
0d2a7a93 13516 unsigned char * end = start + size;
cb8f3167 13517
d1c4b12b
NC
13518 if (relocs_return != NULL)
13519 {
13520 * (Elf_Internal_Rela **) relocs_return = NULL;
13521 * num_relocs_return = 0;
13522 }
13523
dda8d76d 13524 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13525 /* No relocs to apply. */
13526 return TRUE;
1b315056 13527
cf13d699 13528 /* Find the reloc section associated with the section. */
dda8d76d
NC
13529 for (relsec = filedata->section_headers;
13530 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13531 ++relsec)
252b5132 13532 {
41e92641
NC
13533 bfd_boolean is_rela;
13534 unsigned long num_relocs;
2cf0635d
NC
13535 Elf_Internal_Rela * relocs;
13536 Elf_Internal_Rela * rp;
13537 Elf_Internal_Shdr * symsec;
13538 Elf_Internal_Sym * symtab;
ba5cdace 13539 unsigned long num_syms;
2cf0635d 13540 Elf_Internal_Sym * sym;
252b5132 13541
41e92641 13542 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13543 || relsec->sh_info >= filedata->file_header.e_shnum
13544 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13545 || relsec->sh_size == 0
dda8d76d 13546 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13547 continue;
428409d5 13548
a788aedd
AM
13549 symsec = filedata->section_headers + relsec->sh_link;
13550 if (symsec->sh_type != SHT_SYMTAB
13551 && symsec->sh_type != SHT_DYNSYM)
13552 return FALSE;
13553
41e92641
NC
13554 is_rela = relsec->sh_type == SHT_RELA;
13555
13556 if (is_rela)
13557 {
dda8d76d 13558 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13559 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13560 return FALSE;
41e92641
NC
13561 }
13562 else
13563 {
dda8d76d 13564 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13565 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13566 return FALSE;
41e92641
NC
13567 }
13568
13569 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13570 if (filedata->file_header.e_machine == EM_SH)
41e92641 13571 is_rela = FALSE;
428409d5 13572
dda8d76d 13573 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13574
41e92641 13575 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13576 {
41e92641
NC
13577 bfd_vma addend;
13578 unsigned int reloc_type;
13579 unsigned int reloc_size;
03336641
JW
13580 bfd_boolean reloc_inplace = FALSE;
13581 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13582 unsigned char * rloc;
ba5cdace 13583 unsigned long sym_index;
4b78141a 13584
dda8d76d 13585 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13586
dda8d76d 13587 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13588 continue;
dda8d76d 13589 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13590 continue;
dda8d76d
NC
13591 else if (is_32bit_abs_reloc (filedata, reloc_type)
13592 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13593 reloc_size = 4;
dda8d76d
NC
13594 else if (is_64bit_abs_reloc (filedata, reloc_type)
13595 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13596 reloc_size = 8;
dda8d76d 13597 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13598 reloc_size = 3;
dda8d76d 13599 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13600 reloc_size = 2;
39e07931
AS
13601 else if (is_8bit_abs_reloc (filedata, reloc_type)
13602 || is_6bit_abs_reloc (filedata, reloc_type))
13603 reloc_size = 1;
03336641
JW
13604 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13605 reloc_type))
13606 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13607 {
13608 reloc_size = 4;
13609 reloc_inplace = TRUE;
13610 }
13611 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13612 reloc_type))
13613 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13614 {
13615 reloc_size = 8;
13616 reloc_inplace = TRUE;
13617 }
13618 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13619 reloc_type))
13620 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13621 {
13622 reloc_size = 2;
13623 reloc_inplace = TRUE;
13624 }
13625 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13626 reloc_type))
13627 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13628 {
13629 reloc_size = 1;
13630 reloc_inplace = TRUE;
13631 }
39e07931
AS
13632 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13633 reloc_type)))
13634 {
13635 reloc_size = 1;
13636 reloc_inplace = TRUE;
13637 }
aca88567 13638 else
4b78141a 13639 {
bee0ee85 13640 static unsigned int prev_reloc = 0;
dda8d76d 13641
bee0ee85
NC
13642 if (reloc_type != prev_reloc)
13643 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13644 reloc_type, printable_section_name (filedata, section));
bee0ee85 13645 prev_reloc = reloc_type;
4b78141a
NC
13646 continue;
13647 }
103f02d3 13648
91d6fa6a 13649 rloc = start + rp->r_offset;
75802ccb 13650 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
13651 {
13652 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13653 (unsigned long) rp->r_offset,
dda8d76d 13654 printable_section_name (filedata, section));
700dd8b7
L
13655 continue;
13656 }
103f02d3 13657
ba5cdace
NC
13658 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13659 if (sym_index >= num_syms)
13660 {
13661 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13662 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
13663 continue;
13664 }
13665 sym = symtab + sym_index;
41e92641
NC
13666
13667 /* If the reloc has a symbol associated with it,
55f25fc3
L
13668 make sure that it is of an appropriate type.
13669
13670 Relocations against symbols without type can happen.
13671 Gcc -feliminate-dwarf2-dups may generate symbols
13672 without type for debug info.
13673
13674 Icc generates relocations against function symbols
13675 instead of local labels.
13676
13677 Relocations against object symbols can happen, eg when
13678 referencing a global array. For an example of this see
13679 the _clz.o binary in libgcc.a. */
aca88567 13680 if (sym != symtab
b8871f35 13681 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13682 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13683 {
d3a49aa8 13684 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13685 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13686 printable_section_name (filedata, relsec),
d3a49aa8 13687 (long int)(rp - relocs));
aca88567 13688 continue;
5b18a4bc 13689 }
252b5132 13690
4dc3c23d
AM
13691 addend = 0;
13692 if (is_rela)
13693 addend += rp->r_addend;
c47320c3
AM
13694 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13695 partial_inplace. */
4dc3c23d 13696 if (!is_rela
dda8d76d 13697 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13698 && reloc_type == 1)
dda8d76d
NC
13699 || ((filedata->file_header.e_machine == EM_PJ
13700 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13701 && reloc_type == 1)
dda8d76d
NC
13702 || ((filedata->file_header.e_machine == EM_D30V
13703 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13704 && reloc_type == 12)
13705 || reloc_inplace)
39e07931
AS
13706 {
13707 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
13708 addend += byte_get (rloc, reloc_size) & 0x3f;
13709 else
13710 addend += byte_get (rloc, reloc_size);
13711 }
cb8f3167 13712
dda8d76d
NC
13713 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13714 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13715 {
13716 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13717 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13718 addend -= 8;
91d6fa6a 13719 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13720 reloc_size);
13721 }
39e07931
AS
13722 else if (is_6bit_abs_reloc (filedata, reloc_type)
13723 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
13724 {
13725 if (reloc_subtract)
13726 addend -= sym->st_value;
13727 else
13728 addend += sym->st_value;
13729 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
13730 byte_put (rloc, addend, reloc_size);
13731 }
03336641
JW
13732 else if (reloc_subtract)
13733 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13734 else
91d6fa6a 13735 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13736 }
252b5132 13737
5b18a4bc 13738 free (symtab);
f84ce13b
NC
13739 /* Let the target specific reloc processing code know that
13740 we have finished with these relocs. */
dda8d76d 13741 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13742
13743 if (relocs_return)
13744 {
13745 * (Elf_Internal_Rela **) relocs_return = relocs;
13746 * num_relocs_return = num_relocs;
13747 }
13748 else
13749 free (relocs);
13750
5b18a4bc
NC
13751 break;
13752 }
32ec8896 13753
dfc616fa 13754 return TRUE;
5b18a4bc 13755}
103f02d3 13756
cf13d699 13757#ifdef SUPPORT_DISASSEMBLY
32ec8896 13758static bfd_boolean
dda8d76d 13759disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13760{
dda8d76d 13761 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13762
74e1a04b 13763 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13764
32ec8896 13765 return TRUE;
cf13d699
NC
13766}
13767#endif
13768
13769/* Reads in the contents of SECTION from FILE, returning a pointer
13770 to a malloc'ed buffer or NULL if something went wrong. */
13771
13772static char *
dda8d76d 13773get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13774{
dda8d76d 13775 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13776
13777 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13778 {
c6b78c96 13779 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13780 printable_section_name (filedata, section));
cf13d699
NC
13781 return NULL;
13782 }
13783
dda8d76d 13784 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13785 _("section contents"));
cf13d699
NC
13786}
13787
0e602686
NC
13788/* Uncompresses a section that was compressed using zlib, in place. */
13789
13790static bfd_boolean
dda8d76d
NC
13791uncompress_section_contents (unsigned char ** buffer,
13792 dwarf_size_type uncompressed_size,
13793 dwarf_size_type * size)
0e602686
NC
13794{
13795 dwarf_size_type compressed_size = *size;
13796 unsigned char * compressed_buffer = *buffer;
13797 unsigned char * uncompressed_buffer;
13798 z_stream strm;
13799 int rc;
13800
13801 /* It is possible the section consists of several compressed
13802 buffers concatenated together, so we uncompress in a loop. */
13803 /* PR 18313: The state field in the z_stream structure is supposed
13804 to be invisible to the user (ie us), but some compilers will
13805 still complain about it being used without initialisation. So
13806 we first zero the entire z_stream structure and then set the fields
13807 that we need. */
13808 memset (& strm, 0, sizeof strm);
13809 strm.avail_in = compressed_size;
13810 strm.next_in = (Bytef *) compressed_buffer;
13811 strm.avail_out = uncompressed_size;
13812 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13813
13814 rc = inflateInit (& strm);
13815 while (strm.avail_in > 0)
13816 {
13817 if (rc != Z_OK)
13818 goto fail;
13819 strm.next_out = ((Bytef *) uncompressed_buffer
13820 + (uncompressed_size - strm.avail_out));
13821 rc = inflate (&strm, Z_FINISH);
13822 if (rc != Z_STREAM_END)
13823 goto fail;
13824 rc = inflateReset (& strm);
13825 }
13826 rc = inflateEnd (& strm);
13827 if (rc != Z_OK
13828 || strm.avail_out != 0)
13829 goto fail;
13830
13831 *buffer = uncompressed_buffer;
13832 *size = uncompressed_size;
13833 return TRUE;
13834
13835 fail:
13836 free (uncompressed_buffer);
13837 /* Indicate decompression failure. */
13838 *buffer = NULL;
13839 return FALSE;
13840}
dd24e3da 13841
32ec8896 13842static bfd_boolean
dda8d76d 13843dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13844{
0e602686
NC
13845 Elf_Internal_Shdr * relsec;
13846 bfd_size_type num_bytes;
fd8008d8
L
13847 unsigned char * data;
13848 unsigned char * end;
13849 unsigned char * real_start;
13850 unsigned char * start;
0e602686 13851 bfd_boolean some_strings_shown;
cf13d699 13852
dda8d76d 13853 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13854 if (start == NULL)
c6b78c96
NC
13855 /* PR 21820: Do not fail if the section was empty. */
13856 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13857
0e602686 13858 num_bytes = section->sh_size;
cf13d699 13859
dda8d76d 13860 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13861
0e602686
NC
13862 if (decompress_dumps)
13863 {
13864 dwarf_size_type new_size = num_bytes;
13865 dwarf_size_type uncompressed_size = 0;
13866
13867 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13868 {
13869 Elf_Internal_Chdr chdr;
13870 unsigned int compression_header_size
ebdf1ebf
NC
13871 = get_compression_header (& chdr, (unsigned char *) start,
13872 num_bytes);
5844b465
NC
13873 if (compression_header_size == 0)
13874 /* An error message will have already been generated
13875 by get_compression_header. */
13876 goto error_out;
0e602686 13877
813dabb9 13878 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13879 {
813dabb9 13880 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13881 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 13882 goto error_out;
813dabb9 13883 }
813dabb9
L
13884 uncompressed_size = chdr.ch_size;
13885 start += compression_header_size;
13886 new_size -= compression_header_size;
0e602686
NC
13887 }
13888 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13889 {
13890 /* Read the zlib header. In this case, it should be "ZLIB"
13891 followed by the uncompressed section size, 8 bytes in
13892 big-endian order. */
13893 uncompressed_size = start[4]; uncompressed_size <<= 8;
13894 uncompressed_size += start[5]; uncompressed_size <<= 8;
13895 uncompressed_size += start[6]; uncompressed_size <<= 8;
13896 uncompressed_size += start[7]; uncompressed_size <<= 8;
13897 uncompressed_size += start[8]; uncompressed_size <<= 8;
13898 uncompressed_size += start[9]; uncompressed_size <<= 8;
13899 uncompressed_size += start[10]; uncompressed_size <<= 8;
13900 uncompressed_size += start[11];
13901 start += 12;
13902 new_size -= 12;
13903 }
13904
1835f746
NC
13905 if (uncompressed_size)
13906 {
13907 if (uncompress_section_contents (& start,
13908 uncompressed_size, & new_size))
13909 num_bytes = new_size;
13910 else
13911 {
13912 error (_("Unable to decompress section %s\n"),
dda8d76d 13913 printable_section_name (filedata, section));
f761cb13 13914 goto error_out;
1835f746
NC
13915 }
13916 }
bc303e5d
NC
13917 else
13918 start = real_start;
0e602686 13919 }
fd8008d8 13920
cf13d699
NC
13921 /* If the section being dumped has relocations against it the user might
13922 be expecting these relocations to have been applied. Check for this
13923 case and issue a warning message in order to avoid confusion.
13924 FIXME: Maybe we ought to have an option that dumps a section with
13925 relocs applied ? */
dda8d76d
NC
13926 for (relsec = filedata->section_headers;
13927 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13928 ++relsec)
13929 {
13930 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13931 || relsec->sh_info >= filedata->file_header.e_shnum
13932 || filedata->section_headers + relsec->sh_info != section
cf13d699 13933 || relsec->sh_size == 0
dda8d76d 13934 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13935 continue;
13936
13937 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13938 break;
13939 }
13940
cf13d699
NC
13941 data = start;
13942 end = start + num_bytes;
13943 some_strings_shown = FALSE;
13944
ba3265d0
NC
13945#ifdef HAVE_MBSTATE_T
13946 mbstate_t state;
13947 /* Initialise the multibyte conversion state. */
13948 memset (& state, 0, sizeof (state));
13949#endif
13950
13951 bfd_boolean continuing = FALSE;
13952
cf13d699
NC
13953 while (data < end)
13954 {
13955 while (!ISPRINT (* data))
13956 if (++ data >= end)
13957 break;
13958
13959 if (data < end)
13960 {
071436c6
NC
13961 size_t maxlen = end - data;
13962
ba3265d0
NC
13963 if (continuing)
13964 {
13965 printf (" ");
13966 continuing = FALSE;
13967 }
13968 else
13969 {
d1ce973e 13970 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
13971 }
13972
4082ef84
NC
13973 if (maxlen > 0)
13974 {
f3da8a96 13975 char c = 0;
ba3265d0
NC
13976
13977 while (maxlen)
13978 {
13979 c = *data++;
13980
13981 if (c == 0)
13982 break;
13983
13984 /* PR 25543: Treat new-lines as string-ending characters. */
13985 if (c == '\n')
13986 {
13987 printf ("\\n\n");
13988 if (*data != 0)
13989 continuing = TRUE;
13990 break;
13991 }
13992
13993 /* Do not print control characters directly as they can affect terminal
13994 settings. Such characters usually appear in the names generated
13995 by the assembler for local labels. */
13996 if (ISCNTRL (c))
13997 {
13998 printf ("^%c", c + 0x40);
13999 }
14000 else if (ISPRINT (c))
14001 {
14002 putchar (c);
14003 }
14004 else
14005 {
14006 size_t n;
14007#ifdef HAVE_MBSTATE_T
14008 wchar_t w;
14009#endif
14010 /* Let printf do the hard work of displaying multibyte characters. */
14011 printf ("%.1s", data - 1);
14012#ifdef HAVE_MBSTATE_T
14013 /* Try to find out how many bytes made up the character that was
14014 just printed. Advance the symbol pointer past the bytes that
14015 were displayed. */
14016 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14017#else
14018 n = 1;
14019#endif
14020 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14021 data += (n - 1);
14022 }
14023 }
14024
14025 if (c != '\n')
14026 putchar ('\n');
4082ef84
NC
14027 }
14028 else
14029 {
14030 printf (_("<corrupt>\n"));
14031 data = end;
14032 }
cf13d699
NC
14033 some_strings_shown = TRUE;
14034 }
14035 }
14036
14037 if (! some_strings_shown)
14038 printf (_(" No strings found in this section."));
14039
0e602686 14040 free (real_start);
cf13d699
NC
14041
14042 putchar ('\n');
32ec8896 14043 return TRUE;
f761cb13
AM
14044
14045error_out:
14046 free (real_start);
14047 return FALSE;
cf13d699
NC
14048}
14049
32ec8896 14050static bfd_boolean
dda8d76d
NC
14051dump_section_as_bytes (Elf_Internal_Shdr * section,
14052 Filedata * filedata,
14053 bfd_boolean relocate)
cf13d699
NC
14054{
14055 Elf_Internal_Shdr * relsec;
0e602686
NC
14056 bfd_size_type bytes;
14057 bfd_size_type section_size;
14058 bfd_vma addr;
14059 unsigned char * data;
14060 unsigned char * real_start;
14061 unsigned char * start;
14062
dda8d76d 14063 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14064 if (start == NULL)
c6b78c96
NC
14065 /* PR 21820: Do not fail if the section was empty. */
14066 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 14067
0e602686 14068 section_size = section->sh_size;
cf13d699 14069
dda8d76d 14070 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14071
0e602686
NC
14072 if (decompress_dumps)
14073 {
14074 dwarf_size_type new_size = section_size;
14075 dwarf_size_type uncompressed_size = 0;
14076
14077 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14078 {
14079 Elf_Internal_Chdr chdr;
14080 unsigned int compression_header_size
ebdf1ebf 14081 = get_compression_header (& chdr, start, section_size);
0e602686 14082
5844b465
NC
14083 if (compression_header_size == 0)
14084 /* An error message will have already been generated
14085 by get_compression_header. */
14086 goto error_out;
14087
813dabb9 14088 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14089 {
813dabb9 14090 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14091 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14092 goto error_out;
0e602686 14093 }
813dabb9
L
14094 uncompressed_size = chdr.ch_size;
14095 start += compression_header_size;
14096 new_size -= compression_header_size;
0e602686
NC
14097 }
14098 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14099 {
14100 /* Read the zlib header. In this case, it should be "ZLIB"
14101 followed by the uncompressed section size, 8 bytes in
14102 big-endian order. */
14103 uncompressed_size = start[4]; uncompressed_size <<= 8;
14104 uncompressed_size += start[5]; uncompressed_size <<= 8;
14105 uncompressed_size += start[6]; uncompressed_size <<= 8;
14106 uncompressed_size += start[7]; uncompressed_size <<= 8;
14107 uncompressed_size += start[8]; uncompressed_size <<= 8;
14108 uncompressed_size += start[9]; uncompressed_size <<= 8;
14109 uncompressed_size += start[10]; uncompressed_size <<= 8;
14110 uncompressed_size += start[11];
14111 start += 12;
14112 new_size -= 12;
14113 }
14114
f055032e
NC
14115 if (uncompressed_size)
14116 {
14117 if (uncompress_section_contents (& start, uncompressed_size,
14118 & new_size))
bc303e5d
NC
14119 {
14120 section_size = new_size;
14121 }
f055032e
NC
14122 else
14123 {
14124 error (_("Unable to decompress section %s\n"),
dda8d76d 14125 printable_section_name (filedata, section));
bc303e5d 14126 /* FIXME: Print the section anyway ? */
f761cb13 14127 goto error_out;
f055032e
NC
14128 }
14129 }
bc303e5d
NC
14130 else
14131 start = real_start;
0e602686 14132 }
14ae95f2 14133
cf13d699
NC
14134 if (relocate)
14135 {
dda8d76d 14136 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14137 goto error_out;
cf13d699
NC
14138 }
14139 else
14140 {
14141 /* If the section being dumped has relocations against it the user might
14142 be expecting these relocations to have been applied. Check for this
14143 case and issue a warning message in order to avoid confusion.
14144 FIXME: Maybe we ought to have an option that dumps a section with
14145 relocs applied ? */
dda8d76d
NC
14146 for (relsec = filedata->section_headers;
14147 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14148 ++relsec)
14149 {
14150 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14151 || relsec->sh_info >= filedata->file_header.e_shnum
14152 || filedata->section_headers + relsec->sh_info != section
cf13d699 14153 || relsec->sh_size == 0
dda8d76d 14154 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14155 continue;
14156
14157 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14158 break;
14159 }
14160 }
14161
14162 addr = section->sh_addr;
0e602686 14163 bytes = section_size;
cf13d699
NC
14164 data = start;
14165
14166 while (bytes)
14167 {
14168 int j;
14169 int k;
14170 int lbytes;
14171
14172 lbytes = (bytes > 16 ? 16 : bytes);
14173
14174 printf (" 0x%8.8lx ", (unsigned long) addr);
14175
14176 for (j = 0; j < 16; j++)
14177 {
14178 if (j < lbytes)
14179 printf ("%2.2x", data[j]);
14180 else
14181 printf (" ");
14182
14183 if ((j & 3) == 3)
14184 printf (" ");
14185 }
14186
14187 for (j = 0; j < lbytes; j++)
14188 {
14189 k = data[j];
14190 if (k >= ' ' && k < 0x7f)
14191 printf ("%c", k);
14192 else
14193 printf (".");
14194 }
14195
14196 putchar ('\n');
14197
14198 data += lbytes;
14199 addr += lbytes;
14200 bytes -= lbytes;
14201 }
14202
0e602686 14203 free (real_start);
cf13d699
NC
14204
14205 putchar ('\n');
32ec8896 14206 return TRUE;
f761cb13
AM
14207
14208 error_out:
14209 free (real_start);
14210 return FALSE;
cf13d699
NC
14211}
14212
094e34f2 14213#ifdef ENABLE_LIBCTF
7d9813f1
NA
14214static ctf_sect_t *
14215shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14216{
90bd5423 14217 buf->cts_name = SECTION_NAME (shdr);
7d9813f1
NA
14218 buf->cts_size = shdr->sh_size;
14219 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14220
14221 return buf;
14222}
14223
14224/* Formatting callback function passed to ctf_dump. Returns either the pointer
14225 it is passed, or a pointer to newly-allocated storage, in which case
14226 dump_ctf() will free it when it no longer needs it. */
14227
2f6ecaed
NA
14228static char *
14229dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14230 char *s, void *arg)
7d9813f1 14231{
3e50a591 14232 const char *blanks = arg;
7d9813f1
NA
14233 char *new_s;
14234
3e50a591 14235 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14236 return s;
14237 return new_s;
14238}
14239
926c9e76
NA
14240/* Dump CTF errors/warnings. */
14241static void
14242dump_ctf_errs (ctf_file_t *fp)
14243{
14244 ctf_next_t *it = NULL;
14245 char *errtext;
14246 int is_warning;
14247 int err;
14248
14249 /* Dump accumulated errors and warnings. */
14250 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
14251 {
5e9b84f7 14252 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
14253 errtext);
14254 free (errtext);
14255 }
14256 if (err != ECTF_NEXT_END)
14257 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
14258}
14259
2f6ecaed
NA
14260/* Dump one CTF archive member. */
14261
14262static int
14263dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
14264{
14265 ctf_file_t *parent = (ctf_file_t *) arg;
14266 const char *things[] = {"Header", "Labels", "Data objects",
14267 "Function objects", "Variables", "Types", "Strings",
14268 ""};
14269 const char **thing;
14270 size_t i;
8b37e7b6 14271 int err = 0;
2f6ecaed
NA
14272
14273 /* Only print out the name of non-default-named archive members.
14274 The name .ctf appears everywhere, even for things that aren't
14275 really archives, so printing it out is liable to be confusing.
14276
14277 The parent, if there is one, is the default-owned archive member:
14278 avoid importing it into itself. (This does no harm, but looks
14279 confusing.) */
14280
14281 if (strcmp (name, ".ctf") != 0)
14282 {
14283 printf (_("\nCTF archive member: %s:\n"), name);
14284 ctf_import (ctf, parent);
14285 }
14286
14287 for (i = 0, thing = things; *thing[0]; thing++, i++)
14288 {
14289 ctf_dump_state_t *s = NULL;
14290 char *item;
14291
14292 printf ("\n %s:\n", *thing);
14293 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14294 (void *) " ")) != NULL)
14295 {
14296 printf ("%s\n", item);
14297 free (item);
14298 }
14299
14300 if (ctf_errno (ctf))
14301 {
14302 error (_("Iteration failed: %s, %s\n"), *thing,
14303 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
14304 err = 1;
14305 goto out;
2f6ecaed
NA
14306 }
14307 }
8b37e7b6
NA
14308
14309 out:
926c9e76 14310 dump_ctf_errs (ctf);
8b37e7b6 14311 return err;
2f6ecaed
NA
14312}
14313
7d9813f1
NA
14314static bfd_boolean
14315dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14316{
14317 Elf_Internal_Shdr * parent_sec = NULL;
14318 Elf_Internal_Shdr * symtab_sec = NULL;
14319 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14320 void * data = NULL;
14321 void * symdata = NULL;
14322 void * strdata = NULL;
14323 void * parentdata = NULL;
14324 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14325 ctf_sect_t * symsectp = NULL;
14326 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
14327 ctf_archive_t * ctfa = NULL;
14328 ctf_archive_t * parenta = NULL, *lookparent;
14329 ctf_file_t * parent = NULL;
7d9813f1 14330
7d9813f1
NA
14331 int err;
14332 bfd_boolean ret = FALSE;
7d9813f1
NA
14333
14334 shdr_to_ctf_sect (&ctfsect, section, filedata);
14335 data = get_section_contents (section, filedata);
14336 ctfsect.cts_data = data;
14337
616febde
NA
14338 if (!dump_ctf_symtab_name)
14339 dump_ctf_symtab_name = strdup (".symtab");
14340
14341 if (!dump_ctf_strtab_name)
14342 dump_ctf_strtab_name = strdup (".strtab");
14343
14344 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14345 {
14346 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14347 {
14348 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14349 goto fail;
14350 }
14351 if ((symdata = (void *) get_data (NULL, filedata,
14352 symtab_sec->sh_offset, 1,
14353 symtab_sec->sh_size,
14354 _("symbols"))) == NULL)
14355 goto fail;
14356 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14357 symsect.cts_data = symdata;
14358 }
df16e041 14359 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
14360 {
14361 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14362 {
14363 error (_("No string table section named %s\n"),
14364 dump_ctf_strtab_name);
14365 goto fail;
14366 }
14367 if ((strdata = (void *) get_data (NULL, filedata,
14368 strtab_sec->sh_offset, 1,
14369 strtab_sec->sh_size,
14370 _("strings"))) == NULL)
14371 goto fail;
14372 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14373 strsect.cts_data = strdata;
14374 }
14375 if (dump_ctf_parent_name)
14376 {
14377 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14378 {
14379 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14380 goto fail;
14381 }
14382 if ((parentdata = (void *) get_data (NULL, filedata,
14383 parent_sec->sh_offset, 1,
14384 parent_sec->sh_size,
14385 _("CTF parent"))) == NULL)
14386 goto fail;
14387 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14388 parentsect.cts_data = parentdata;
14389 }
14390
2f6ecaed
NA
14391 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
14392 libctf papers over the difference, so we can pretend it is always an
14393 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 14394
2f6ecaed 14395 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 14396 {
926c9e76 14397 dump_ctf_errs (NULL);
7d9813f1
NA
14398 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14399 goto fail;
14400 }
14401
14402 if (parentdata)
14403 {
2f6ecaed
NA
14404 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
14405 &err)) == NULL)
7d9813f1 14406 {
926c9e76 14407 dump_ctf_errs (NULL);
7d9813f1
NA
14408 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14409 goto fail;
14410 }
2f6ecaed
NA
14411 lookparent = parenta;
14412 }
14413 else
14414 lookparent = ctfa;
7d9813f1 14415
2f6ecaed
NA
14416 /* Assume that the applicable parent archive member is the default one.
14417 (This is what all known implementations are expected to do, if they
14418 put CTFs and their parents in archives together.) */
14419 if ((parent = ctf_arc_open_by_name (lookparent, NULL, &err)) == NULL)
14420 {
926c9e76 14421 dump_ctf_errs (NULL);
2f6ecaed
NA
14422 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14423 goto fail;
7d9813f1
NA
14424 }
14425
14426 ret = TRUE;
14427
14428 printf (_("\nDump of CTF section '%s':\n"),
14429 printable_section_name (filedata, section));
14430
2f6ecaed
NA
14431 if (ctf_archive_iter (ctfa, dump_ctf_archive_member, parent) != 0)
14432 ret = FALSE;
7d9813f1
NA
14433
14434 fail:
7d9813f1 14435 ctf_file_close (parent);
2f6ecaed
NA
14436 ctf_close (ctfa);
14437 ctf_close (parenta);
7d9813f1
NA
14438 free (parentdata);
14439 free (data);
14440 free (symdata);
14441 free (strdata);
14442 return ret;
14443}
094e34f2 14444#endif
7d9813f1 14445
32ec8896 14446static bfd_boolean
dda8d76d
NC
14447load_specific_debug_section (enum dwarf_section_display_enum debug,
14448 const Elf_Internal_Shdr * sec,
14449 void * data)
1007acb3 14450{
2cf0635d 14451 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 14452 char buf [64];
dda8d76d 14453 Filedata * filedata = (Filedata *) data;
9abca702 14454
19e6b90e 14455 if (section->start != NULL)
dda8d76d
NC
14456 {
14457 /* If it is already loaded, do nothing. */
14458 if (streq (section->filename, filedata->file_name))
14459 return TRUE;
14460 free (section->start);
14461 }
1007acb3 14462
19e6b90e
L
14463 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
14464 section->address = sec->sh_addr;
06614111 14465 section->user_data = NULL;
dda8d76d
NC
14466 section->filename = filedata->file_name;
14467 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
14468 sec->sh_offset, 1,
14469 sec->sh_size, buf);
59245841
NC
14470 if (section->start == NULL)
14471 section->size = 0;
14472 else
14473 {
77115a4a
L
14474 unsigned char *start = section->start;
14475 dwarf_size_type size = sec->sh_size;
dab394de 14476 dwarf_size_type uncompressed_size = 0;
77115a4a
L
14477
14478 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
14479 {
14480 Elf_Internal_Chdr chdr;
d8024a91
NC
14481 unsigned int compression_header_size;
14482
f53be977
L
14483 if (size < (is_32bit_elf
14484 ? sizeof (Elf32_External_Chdr)
14485 : sizeof (Elf64_External_Chdr)))
d8024a91 14486 {
55be8fd0 14487 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 14488 section->name);
32ec8896 14489 return FALSE;
d8024a91
NC
14490 }
14491
ebdf1ebf 14492 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
14493 if (compression_header_size == 0)
14494 /* An error message will have already been generated
14495 by get_compression_header. */
14496 return FALSE;
d8024a91 14497
813dabb9
L
14498 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
14499 {
14500 warn (_("section '%s' has unsupported compress type: %d\n"),
14501 section->name, chdr.ch_type);
32ec8896 14502 return FALSE;
813dabb9 14503 }
dab394de 14504 uncompressed_size = chdr.ch_size;
77115a4a
L
14505 start += compression_header_size;
14506 size -= compression_header_size;
14507 }
dab394de
L
14508 else if (size > 12 && streq ((char *) start, "ZLIB"))
14509 {
14510 /* Read the zlib header. In this case, it should be "ZLIB"
14511 followed by the uncompressed section size, 8 bytes in
14512 big-endian order. */
14513 uncompressed_size = start[4]; uncompressed_size <<= 8;
14514 uncompressed_size += start[5]; uncompressed_size <<= 8;
14515 uncompressed_size += start[6]; uncompressed_size <<= 8;
14516 uncompressed_size += start[7]; uncompressed_size <<= 8;
14517 uncompressed_size += start[8]; uncompressed_size <<= 8;
14518 uncompressed_size += start[9]; uncompressed_size <<= 8;
14519 uncompressed_size += start[10]; uncompressed_size <<= 8;
14520 uncompressed_size += start[11];
14521 start += 12;
14522 size -= 12;
14523 }
14524
1835f746 14525 if (uncompressed_size)
77115a4a 14526 {
1835f746
NC
14527 if (uncompress_section_contents (&start, uncompressed_size,
14528 &size))
14529 {
14530 /* Free the compressed buffer, update the section buffer
14531 and the section size if uncompress is successful. */
14532 free (section->start);
14533 section->start = start;
14534 }
14535 else
14536 {
14537 error (_("Unable to decompress section %s\n"),
dda8d76d 14538 printable_section_name (filedata, sec));
32ec8896 14539 return FALSE;
1835f746 14540 }
77115a4a 14541 }
bc303e5d 14542
77115a4a 14543 section->size = size;
59245841 14544 }
4a114e3e 14545
1b315056 14546 if (section->start == NULL)
32ec8896 14547 return FALSE;
1b315056 14548
19e6b90e 14549 if (debug_displays [debug].relocate)
32ec8896 14550 {
dda8d76d 14551 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
14552 & section->reloc_info, & section->num_relocs))
14553 return FALSE;
14554 }
d1c4b12b
NC
14555 else
14556 {
14557 section->reloc_info = NULL;
14558 section->num_relocs = 0;
14559 }
1007acb3 14560
32ec8896 14561 return TRUE;
1007acb3
L
14562}
14563
301a9420
AM
14564#if HAVE_LIBDEBUGINFOD
14565/* Return a hex string representation of the build-id. */
14566unsigned char *
14567get_build_id (void * data)
14568{
14569 Filedata * filedata = (Filedata *)data;
14570 Elf_Internal_Shdr * shdr;
14571 unsigned long i;
14572
55be8fd0
NC
14573 /* Iterate through notes to find note.gnu.build-id.
14574 FIXME: Only the first note in any note section is examined. */
301a9420
AM
14575 for (i = 0, shdr = filedata->section_headers;
14576 i < filedata->file_header.e_shnum && shdr != NULL;
14577 i++, shdr++)
14578 {
14579 if (shdr->sh_type != SHT_NOTE)
14580 continue;
14581
14582 char * next;
14583 char * end;
14584 size_t data_remaining;
14585 size_t min_notesz;
14586 Elf_External_Note * enote;
14587 Elf_Internal_Note inote;
14588
14589 bfd_vma offset = shdr->sh_offset;
14590 bfd_vma align = shdr->sh_addralign;
14591 bfd_vma length = shdr->sh_size;
14592
14593 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
14594 if (enote == NULL)
14595 continue;
14596
14597 if (align < 4)
14598 align = 4;
14599 else if (align != 4 && align != 8)
f761cb13
AM
14600 {
14601 free (enote);
14602 continue;
14603 }
301a9420
AM
14604
14605 end = (char *) enote + length;
14606 data_remaining = end - (char *) enote;
14607
14608 if (!is_ia64_vms (filedata))
14609 {
14610 min_notesz = offsetof (Elf_External_Note, name);
14611 if (data_remaining < min_notesz)
14612 {
55be8fd0
NC
14613 warn (_("\
14614malformed note encountered in section %s whilst scanning for build-id note\n"),
14615 printable_section_name (filedata, shdr));
f761cb13 14616 free (enote);
55be8fd0 14617 continue;
301a9420
AM
14618 }
14619 data_remaining -= min_notesz;
14620
14621 inote.type = BYTE_GET (enote->type);
14622 inote.namesz = BYTE_GET (enote->namesz);
14623 inote.namedata = enote->name;
14624 inote.descsz = BYTE_GET (enote->descsz);
14625 inote.descdata = ((char *) enote
14626 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
14627 inote.descpos = offset + (inote.descdata - (char *) enote);
14628 next = ((char *) enote
14629 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
14630 }
14631 else
14632 {
14633 Elf64_External_VMS_Note *vms_enote;
14634
14635 /* PR binutils/15191
14636 Make sure that there is enough data to read. */
14637 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14638 if (data_remaining < min_notesz)
14639 {
55be8fd0
NC
14640 warn (_("\
14641malformed note encountered in section %s whilst scanning for build-id note\n"),
14642 printable_section_name (filedata, shdr));
f761cb13 14643 free (enote);
55be8fd0 14644 continue;
301a9420
AM
14645 }
14646 data_remaining -= min_notesz;
14647
14648 vms_enote = (Elf64_External_VMS_Note *) enote;
14649 inote.type = BYTE_GET (vms_enote->type);
14650 inote.namesz = BYTE_GET (vms_enote->namesz);
14651 inote.namedata = vms_enote->name;
14652 inote.descsz = BYTE_GET (vms_enote->descsz);
14653 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14654 inote.descpos = offset + (inote.descdata - (char *) enote);
14655 next = inote.descdata + align_power (inote.descsz, 3);
14656 }
14657
14658 /* Skip malformed notes. */
14659 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
14660 || (size_t) (inote.descdata - inote.namedata) > data_remaining
14661 || (size_t) (next - inote.descdata) < inote.descsz
14662 || ((size_t) (next - inote.descdata)
14663 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
14664 {
55be8fd0
NC
14665 warn (_("\
14666malformed note encountered in section %s whilst scanning for build-id note\n"),
14667 printable_section_name (filedata, shdr));
f761cb13 14668 free (enote);
301a9420
AM
14669 continue;
14670 }
14671
14672 /* Check if this is the build-id note. If so then convert the build-id
14673 bytes to a hex string. */
14674 if (inote.namesz > 0
14675 && const_strneq (inote.namedata, "GNU")
14676 && inote.type == NT_GNU_BUILD_ID)
14677 {
14678 unsigned long j;
14679 char * build_id;
14680
14681 build_id = malloc (inote.descsz * 2 + 1);
14682 if (build_id == NULL)
f761cb13
AM
14683 {
14684 free (enote);
14685 return NULL;
14686 }
301a9420
AM
14687
14688 for (j = 0; j < inote.descsz; ++j)
14689 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
14690 build_id[inote.descsz * 2] = '\0';
f761cb13 14691 free (enote);
301a9420 14692
55be8fd0 14693 return (unsigned char *) build_id;
301a9420 14694 }
f761cb13 14695 free (enote);
301a9420
AM
14696 }
14697
14698 return NULL;
14699}
14700#endif /* HAVE_LIBDEBUGINFOD */
14701
657d0d47
CC
14702/* If this is not NULL, load_debug_section will only look for sections
14703 within the list of sections given here. */
32ec8896 14704static unsigned int * section_subset = NULL;
657d0d47 14705
32ec8896 14706bfd_boolean
dda8d76d 14707load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 14708{
2cf0635d
NC
14709 struct dwarf_section * section = &debug_displays [debug].section;
14710 Elf_Internal_Shdr * sec;
dda8d76d
NC
14711 Filedata * filedata = (Filedata *) data;
14712
f425ec66
NC
14713 /* Without section headers we cannot find any sections. */
14714 if (filedata->section_headers == NULL)
14715 return FALSE;
14716
9c1ce108
AM
14717 if (filedata->string_table == NULL
14718 && filedata->file_header.e_shstrndx != SHN_UNDEF
14719 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
14720 {
14721 Elf_Internal_Shdr * strs;
14722
14723 /* Read in the string table, so that we have section names to scan. */
14724 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
14725
4dff97b2 14726 if (strs != NULL && strs->sh_size != 0)
dda8d76d 14727 {
9c1ce108
AM
14728 filedata->string_table
14729 = (char *) get_data (NULL, filedata, strs->sh_offset,
14730 1, strs->sh_size, _("string table"));
dda8d76d 14731
9c1ce108
AM
14732 filedata->string_table_length
14733 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
14734 }
14735 }
d966045b
DJ
14736
14737 /* Locate the debug section. */
dda8d76d 14738 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
14739 if (sec != NULL)
14740 section->name = section->uncompressed_name;
14741 else
14742 {
dda8d76d 14743 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
14744 if (sec != NULL)
14745 section->name = section->compressed_name;
14746 }
14747 if (sec == NULL)
32ec8896 14748 return FALSE;
d966045b 14749
657d0d47
CC
14750 /* If we're loading from a subset of sections, and we've loaded
14751 a section matching this name before, it's likely that it's a
14752 different one. */
14753 if (section_subset != NULL)
14754 free_debug_section (debug);
14755
dda8d76d 14756 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
14757}
14758
19e6b90e
L
14759void
14760free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 14761{
2cf0635d 14762 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 14763
19e6b90e
L
14764 if (section->start == NULL)
14765 return;
1007acb3 14766
19e6b90e
L
14767 free ((char *) section->start);
14768 section->start = NULL;
14769 section->address = 0;
14770 section->size = 0;
a788aedd 14771
9db70fc3
AM
14772 free (section->reloc_info);
14773 section->reloc_info = NULL;
14774 section->num_relocs = 0;
1007acb3
L
14775}
14776
32ec8896 14777static bfd_boolean
dda8d76d 14778display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 14779{
2cf0635d 14780 char * name = SECTION_NAME (section);
dda8d76d 14781 const char * print_name = printable_section_name (filedata, section);
19e6b90e 14782 bfd_size_type length;
32ec8896 14783 bfd_boolean result = TRUE;
3f5e193b 14784 int i;
1007acb3 14785
19e6b90e
L
14786 length = section->sh_size;
14787 if (length == 0)
1007acb3 14788 {
74e1a04b 14789 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 14790 return TRUE;
1007acb3 14791 }
5dff79d8
NC
14792 if (section->sh_type == SHT_NOBITS)
14793 {
14794 /* There is no point in dumping the contents of a debugging section
14795 which has the NOBITS type - the bits in the file will be random.
14796 This can happen when a file containing a .eh_frame section is
14797 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
14798 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
14799 print_name);
32ec8896 14800 return FALSE;
5dff79d8 14801 }
1007acb3 14802
0112cd26 14803 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 14804 name = ".debug_info";
1007acb3 14805
19e6b90e
L
14806 /* See if we know how to display the contents of this section. */
14807 for (i = 0; i < max; i++)
d85bf2ba
NC
14808 {
14809 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
14810 struct dwarf_section_display * display = debug_displays + i;
14811 struct dwarf_section * sec = & display->section;
d966045b 14812
d85bf2ba
NC
14813 if (streq (sec->uncompressed_name, name)
14814 || (id == line && const_strneq (name, ".debug_line."))
14815 || streq (sec->compressed_name, name))
14816 {
14817 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 14818
d85bf2ba
NC
14819 if (secondary)
14820 free_debug_section (id);
dda8d76d 14821
d85bf2ba
NC
14822 if (i == line && const_strneq (name, ".debug_line."))
14823 sec->name = name;
14824 else if (streq (sec->uncompressed_name, name))
14825 sec->name = sec->uncompressed_name;
14826 else
14827 sec->name = sec->compressed_name;
657d0d47 14828
d85bf2ba
NC
14829 if (load_specific_debug_section (id, section, filedata))
14830 {
14831 /* If this debug section is part of a CU/TU set in a .dwp file,
14832 restrict load_debug_section to the sections in that set. */
14833 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 14834
d85bf2ba 14835 result &= display->display (sec, filedata);
657d0d47 14836
d85bf2ba 14837 section_subset = NULL;
1007acb3 14838
d85bf2ba
NC
14839 if (secondary || (id != info && id != abbrev))
14840 free_debug_section (id);
14841 }
14842 break;
14843 }
14844 }
1007acb3 14845
19e6b90e 14846 if (i == max)
1007acb3 14847 {
74e1a04b 14848 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 14849 result = FALSE;
1007acb3
L
14850 }
14851
19e6b90e 14852 return result;
5b18a4bc 14853}
103f02d3 14854
aef1f6d0
DJ
14855/* Set DUMP_SECTS for all sections where dumps were requested
14856 based on section name. */
14857
14858static void
dda8d76d 14859initialise_dumps_byname (Filedata * filedata)
aef1f6d0 14860{
2cf0635d 14861 struct dump_list_entry * cur;
aef1f6d0
DJ
14862
14863 for (cur = dump_sects_byname; cur; cur = cur->next)
14864 {
14865 unsigned int i;
32ec8896 14866 bfd_boolean any = FALSE;
aef1f6d0 14867
dda8d76d
NC
14868 for (i = 0; i < filedata->file_header.e_shnum; i++)
14869 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 14870 {
6431e409 14871 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 14872 any = TRUE;
aef1f6d0
DJ
14873 }
14874
14875 if (!any)
14876 warn (_("Section '%s' was not dumped because it does not exist!\n"),
14877 cur->name);
14878 }
14879}
14880
32ec8896 14881static bfd_boolean
dda8d76d 14882process_section_contents (Filedata * filedata)
5b18a4bc 14883{
2cf0635d 14884 Elf_Internal_Shdr * section;
19e6b90e 14885 unsigned int i;
32ec8896 14886 bfd_boolean res = TRUE;
103f02d3 14887
19e6b90e 14888 if (! do_dump)
32ec8896 14889 return TRUE;
103f02d3 14890
dda8d76d 14891 initialise_dumps_byname (filedata);
aef1f6d0 14892
dda8d76d 14893 for (i = 0, section = filedata->section_headers;
6431e409 14894 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
14895 i++, section++)
14896 {
6431e409 14897 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 14898
19e6b90e 14899#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
14900 if (dump & DISASS_DUMP)
14901 {
14902 if (! disassemble_section (section, filedata))
14903 res = FALSE;
14904 }
19e6b90e 14905#endif
dda8d76d 14906 if (dump & HEX_DUMP)
32ec8896 14907 {
dda8d76d 14908 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
14909 res = FALSE;
14910 }
103f02d3 14911
dda8d76d 14912 if (dump & RELOC_DUMP)
32ec8896 14913 {
dda8d76d 14914 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
14915 res = FALSE;
14916 }
09c11c86 14917
dda8d76d 14918 if (dump & STRING_DUMP)
32ec8896 14919 {
dda8d76d 14920 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
14921 res = FALSE;
14922 }
cf13d699 14923
dda8d76d 14924 if (dump & DEBUG_DUMP)
32ec8896 14925 {
dda8d76d 14926 if (! display_debug_section (i, section, filedata))
32ec8896
NC
14927 res = FALSE;
14928 }
7d9813f1 14929
094e34f2 14930#ifdef ENABLE_LIBCTF
7d9813f1
NA
14931 if (dump & CTF_DUMP)
14932 {
14933 if (! dump_section_as_ctf (section, filedata))
14934 res = FALSE;
14935 }
094e34f2 14936#endif
5b18a4bc 14937 }
103f02d3 14938
19e6b90e
L
14939 /* Check to see if the user requested a
14940 dump of a section that does not exist. */
6431e409 14941 while (i < filedata->dump.num_dump_sects)
0ee3043f 14942 {
6431e409 14943 if (filedata->dump.dump_sects[i])
32ec8896
NC
14944 {
14945 warn (_("Section %d was not dumped because it does not exist!\n"), i);
14946 res = FALSE;
14947 }
0ee3043f
NC
14948 i++;
14949 }
32ec8896
NC
14950
14951 return res;
5b18a4bc 14952}
103f02d3 14953
5b18a4bc 14954static void
19e6b90e 14955process_mips_fpe_exception (int mask)
5b18a4bc 14956{
19e6b90e
L
14957 if (mask)
14958 {
32ec8896
NC
14959 bfd_boolean first = TRUE;
14960
19e6b90e 14961 if (mask & OEX_FPU_INEX)
32ec8896 14962 fputs ("INEX", stdout), first = FALSE;
19e6b90e 14963 if (mask & OEX_FPU_UFLO)
32ec8896 14964 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14965 if (mask & OEX_FPU_OFLO)
32ec8896 14966 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14967 if (mask & OEX_FPU_DIV0)
32ec8896 14968 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
14969 if (mask & OEX_FPU_INVAL)
14970 printf ("%sINVAL", first ? "" : "|");
14971 }
5b18a4bc 14972 else
19e6b90e 14973 fputs ("0", stdout);
5b18a4bc 14974}
103f02d3 14975
f6f0e17b
NC
14976/* Display's the value of TAG at location P. If TAG is
14977 greater than 0 it is assumed to be an unknown tag, and
14978 a message is printed to this effect. Otherwise it is
14979 assumed that a message has already been printed.
14980
14981 If the bottom bit of TAG is set it assumed to have a
14982 string value, otherwise it is assumed to have an integer
14983 value.
14984
14985 Returns an updated P pointing to the first unread byte
14986 beyond the end of TAG's value.
14987
14988 Reads at or beyond END will not be made. */
14989
14990static unsigned char *
60abdbed 14991display_tag_value (signed int tag,
f6f0e17b
NC
14992 unsigned char * p,
14993 const unsigned char * const end)
14994{
14995 unsigned long val;
14996
14997 if (tag > 0)
14998 printf (" Tag_unknown_%d: ", tag);
14999
15000 if (p >= end)
15001 {
4082ef84 15002 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15003 }
15004 else if (tag & 1)
15005 {
071436c6
NC
15006 /* PR 17531 file: 027-19978-0.004. */
15007 size_t maxlen = (end - p) - 1;
15008
15009 putchar ('"');
4082ef84
NC
15010 if (maxlen > 0)
15011 {
15012 print_symbol ((int) maxlen, (const char *) p);
15013 p += strnlen ((char *) p, maxlen) + 1;
15014 }
15015 else
15016 {
15017 printf (_("<corrupt string tag>"));
15018 p = (unsigned char *) end;
15019 }
071436c6 15020 printf ("\"\n");
f6f0e17b
NC
15021 }
15022 else
15023 {
cd30bcef 15024 READ_ULEB (val, p, end);
f6f0e17b
NC
15025 printf ("%ld (0x%lx)\n", val, val);
15026 }
15027
4082ef84 15028 assert (p <= end);
f6f0e17b
NC
15029 return p;
15030}
15031
53a346d8
CZ
15032/* ARC ABI attributes section. */
15033
15034static unsigned char *
15035display_arc_attribute (unsigned char * p,
15036 const unsigned char * const end)
15037{
15038 unsigned int tag;
53a346d8
CZ
15039 unsigned int val;
15040
cd30bcef 15041 READ_ULEB (tag, p, end);
53a346d8
CZ
15042
15043 switch (tag)
15044 {
15045 case Tag_ARC_PCS_config:
cd30bcef 15046 READ_ULEB (val, p, end);
53a346d8
CZ
15047 printf (" Tag_ARC_PCS_config: ");
15048 switch (val)
15049 {
15050 case 0:
15051 printf (_("Absent/Non standard\n"));
15052 break;
15053 case 1:
15054 printf (_("Bare metal/mwdt\n"));
15055 break;
15056 case 2:
15057 printf (_("Bare metal/newlib\n"));
15058 break;
15059 case 3:
15060 printf (_("Linux/uclibc\n"));
15061 break;
15062 case 4:
15063 printf (_("Linux/glibc\n"));
15064 break;
15065 default:
15066 printf (_("Unknown\n"));
15067 break;
15068 }
15069 break;
15070
15071 case Tag_ARC_CPU_base:
cd30bcef 15072 READ_ULEB (val, p, end);
53a346d8
CZ
15073 printf (" Tag_ARC_CPU_base: ");
15074 switch (val)
15075 {
15076 default:
15077 case TAG_CPU_NONE:
15078 printf (_("Absent\n"));
15079 break;
15080 case TAG_CPU_ARC6xx:
15081 printf ("ARC6xx\n");
15082 break;
15083 case TAG_CPU_ARC7xx:
15084 printf ("ARC7xx\n");
15085 break;
15086 case TAG_CPU_ARCEM:
15087 printf ("ARCEM\n");
15088 break;
15089 case TAG_CPU_ARCHS:
15090 printf ("ARCHS\n");
15091 break;
15092 }
15093 break;
15094
15095 case Tag_ARC_CPU_variation:
cd30bcef 15096 READ_ULEB (val, p, end);
53a346d8
CZ
15097 printf (" Tag_ARC_CPU_variation: ");
15098 switch (val)
15099 {
15100 default:
15101 if (val > 0 && val < 16)
53a346d8 15102 printf ("Core%d\n", val);
d8cbc93b
JL
15103 else
15104 printf ("Unknown\n");
15105 break;
15106
53a346d8
CZ
15107 case 0:
15108 printf (_("Absent\n"));
15109 break;
15110 }
15111 break;
15112
15113 case Tag_ARC_CPU_name:
15114 printf (" Tag_ARC_CPU_name: ");
15115 p = display_tag_value (-1, p, end);
15116 break;
15117
15118 case Tag_ARC_ABI_rf16:
cd30bcef 15119 READ_ULEB (val, p, end);
53a346d8
CZ
15120 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15121 break;
15122
15123 case Tag_ARC_ABI_osver:
cd30bcef 15124 READ_ULEB (val, p, end);
53a346d8
CZ
15125 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15126 break;
15127
15128 case Tag_ARC_ABI_pic:
15129 case Tag_ARC_ABI_sda:
cd30bcef 15130 READ_ULEB (val, p, end);
53a346d8
CZ
15131 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15132 : " Tag_ARC_ABI_pic: ");
15133 switch (val)
15134 {
15135 case 0:
15136 printf (_("Absent\n"));
15137 break;
15138 case 1:
15139 printf ("MWDT\n");
15140 break;
15141 case 2:
15142 printf ("GNU\n");
15143 break;
15144 default:
15145 printf (_("Unknown\n"));
15146 break;
15147 }
15148 break;
15149
15150 case Tag_ARC_ABI_tls:
cd30bcef 15151 READ_ULEB (val, p, end);
53a346d8
CZ
15152 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15153 break;
15154
15155 case Tag_ARC_ABI_enumsize:
cd30bcef 15156 READ_ULEB (val, p, end);
53a346d8
CZ
15157 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15158 _("smallest"));
15159 break;
15160
15161 case Tag_ARC_ABI_exceptions:
cd30bcef 15162 READ_ULEB (val, p, end);
53a346d8
CZ
15163 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15164 : _("default"));
15165 break;
15166
15167 case Tag_ARC_ABI_double_size:
cd30bcef 15168 READ_ULEB (val, p, end);
53a346d8
CZ
15169 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15170 break;
15171
15172 case Tag_ARC_ISA_config:
15173 printf (" Tag_ARC_ISA_config: ");
15174 p = display_tag_value (-1, p, end);
15175 break;
15176
15177 case Tag_ARC_ISA_apex:
15178 printf (" Tag_ARC_ISA_apex: ");
15179 p = display_tag_value (-1, p, end);
15180 break;
15181
15182 case Tag_ARC_ISA_mpy_option:
cd30bcef 15183 READ_ULEB (val, p, end);
53a346d8
CZ
15184 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15185 break;
15186
db1e1b45 15187 case Tag_ARC_ATR_version:
cd30bcef 15188 READ_ULEB (val, p, end);
db1e1b45 15189 printf (" Tag_ARC_ATR_version: %d\n", val);
15190 break;
15191
53a346d8
CZ
15192 default:
15193 return display_tag_value (tag & 1, p, end);
15194 }
15195
15196 return p;
15197}
15198
11c1ff18
PB
15199/* ARM EABI attributes section. */
15200typedef struct
15201{
70e99720 15202 unsigned int tag;
2cf0635d 15203 const char * name;
11c1ff18 15204 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15205 unsigned int type;
2cf0635d 15206 const char ** table;
11c1ff18
PB
15207} arm_attr_public_tag;
15208
2cf0635d 15209static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 15210 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15211 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15212 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
2cf0635d
NC
15213static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15214static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15215 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 15216static const char * arm_attr_tag_FP_arch[] =
bca38921 15217 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15218 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 15219static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 15220static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15221 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15222 "NEON for ARMv8.1"};
2cf0635d 15223static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
15224 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15225 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 15226static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15227 {"V6", "SB", "TLS", "Unused"};
2cf0635d 15228static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15229 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 15230static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15231 {"Absolute", "PC-relative", "None"};
2cf0635d 15232static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15233 {"None", "direct", "GOT-indirect"};
2cf0635d 15234static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15235 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
15236static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15237static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15238 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
15239static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15240static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15241static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15242 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 15243static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 15244 {"Unused", "small", "int", "forced to int"};
2cf0635d 15245static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15246 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 15247static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 15248 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 15249static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15250 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 15251static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15252 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15253 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 15254static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15255 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15256 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 15257static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 15258static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 15259 {"Not Allowed", "Allowed"};
2cf0635d 15260static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15261 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
15262static const char * arm_attr_tag_DSP_extension[] =
15263 {"Follow architecture", "Allowed"};
dd24e3da 15264static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
15265 {"Not Allowed", "Allowed"};
15266static const char * arm_attr_tag_DIV_use[] =
dd24e3da 15267 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15268 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
15269static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15270static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 15271 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15272 "TrustZone and Virtualization Extensions"};
dd24e3da 15273static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15274 {"Not Allowed", "Allowed"};
11c1ff18 15275
a7ad558c
AV
15276static const char * arm_attr_tag_MVE_arch[] =
15277 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15278
11c1ff18
PB
15279#define LOOKUP(id, name) \
15280 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15281static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15282{
15283 {4, "CPU_raw_name", 1, NULL},
15284 {5, "CPU_name", 1, NULL},
15285 LOOKUP(6, CPU_arch),
15286 {7, "CPU_arch_profile", 0, NULL},
15287 LOOKUP(8, ARM_ISA_use),
15288 LOOKUP(9, THUMB_ISA_use),
75375b3e 15289 LOOKUP(10, FP_arch),
11c1ff18 15290 LOOKUP(11, WMMX_arch),
f5f53991
AS
15291 LOOKUP(12, Advanced_SIMD_arch),
15292 LOOKUP(13, PCS_config),
11c1ff18
PB
15293 LOOKUP(14, ABI_PCS_R9_use),
15294 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15295 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15296 LOOKUP(17, ABI_PCS_GOT_use),
15297 LOOKUP(18, ABI_PCS_wchar_t),
15298 LOOKUP(19, ABI_FP_rounding),
15299 LOOKUP(20, ABI_FP_denormal),
15300 LOOKUP(21, ABI_FP_exceptions),
15301 LOOKUP(22, ABI_FP_user_exceptions),
15302 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15303 {24, "ABI_align_needed", 0, NULL},
15304 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15305 LOOKUP(26, ABI_enum_size),
15306 LOOKUP(27, ABI_HardFP_use),
15307 LOOKUP(28, ABI_VFP_args),
15308 LOOKUP(29, ABI_WMMX_args),
15309 LOOKUP(30, ABI_optimization_goals),
15310 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15311 {32, "compatibility", 0, NULL},
f5f53991 15312 LOOKUP(34, CPU_unaligned_access),
75375b3e 15313 LOOKUP(36, FP_HP_extension),
8e79c3df 15314 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15315 LOOKUP(42, MPextension_use),
15316 LOOKUP(44, DIV_use),
15afaa63 15317 LOOKUP(46, DSP_extension),
a7ad558c 15318 LOOKUP(48, MVE_arch),
f5f53991
AS
15319 {64, "nodefaults", 0, NULL},
15320 {65, "also_compatible_with", 0, NULL},
15321 LOOKUP(66, T2EE_use),
15322 {67, "conformance", 1, NULL},
15323 LOOKUP(68, Virtualization_use),
cd21e546 15324 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15325};
15326#undef LOOKUP
15327
11c1ff18 15328static unsigned char *
f6f0e17b
NC
15329display_arm_attribute (unsigned char * p,
15330 const unsigned char * const end)
11c1ff18 15331{
70e99720 15332 unsigned int tag;
70e99720 15333 unsigned int val;
2cf0635d 15334 arm_attr_public_tag * attr;
11c1ff18 15335 unsigned i;
70e99720 15336 unsigned int type;
11c1ff18 15337
cd30bcef 15338 READ_ULEB (tag, p, end);
11c1ff18 15339 attr = NULL;
2cf0635d 15340 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15341 {
15342 if (arm_attr_public_tags[i].tag == tag)
15343 {
15344 attr = &arm_attr_public_tags[i];
15345 break;
15346 }
15347 }
15348
15349 if (attr)
15350 {
15351 printf (" Tag_%s: ", attr->name);
15352 switch (attr->type)
15353 {
15354 case 0:
15355 switch (tag)
15356 {
15357 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15358 READ_ULEB (val, p, end);
11c1ff18
PB
15359 switch (val)
15360 {
2b692964
NC
15361 case 0: printf (_("None\n")); break;
15362 case 'A': printf (_("Application\n")); break;
15363 case 'R': printf (_("Realtime\n")); break;
15364 case 'M': printf (_("Microcontroller\n")); break;
15365 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15366 default: printf ("??? (%d)\n", val); break;
15367 }
15368 break;
15369
75375b3e 15370 case 24: /* Tag_align_needed. */
cd30bcef 15371 READ_ULEB (val, p, end);
75375b3e
MGD
15372 switch (val)
15373 {
2b692964
NC
15374 case 0: printf (_("None\n")); break;
15375 case 1: printf (_("8-byte\n")); break;
15376 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15377 case 3: printf ("??? 3\n"); break;
15378 default:
15379 if (val <= 12)
dd24e3da 15380 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15381 1 << val);
15382 else
15383 printf ("??? (%d)\n", val);
15384 break;
15385 }
15386 break;
15387
15388 case 25: /* Tag_align_preserved. */
cd30bcef 15389 READ_ULEB (val, p, end);
75375b3e
MGD
15390 switch (val)
15391 {
2b692964
NC
15392 case 0: printf (_("None\n")); break;
15393 case 1: printf (_("8-byte, except leaf SP\n")); break;
15394 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
15395 case 3: printf ("??? 3\n"); break;
15396 default:
15397 if (val <= 12)
dd24e3da 15398 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15399 1 << val);
15400 else
15401 printf ("??? (%d)\n", val);
15402 break;
15403 }
15404 break;
15405
11c1ff18 15406 case 32: /* Tag_compatibility. */
071436c6 15407 {
cd30bcef 15408 READ_ULEB (val, p, end);
071436c6 15409 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15410 if (p < end - 1)
15411 {
15412 size_t maxlen = (end - p) - 1;
15413
15414 print_symbol ((int) maxlen, (const char *) p);
15415 p += strnlen ((char *) p, maxlen) + 1;
15416 }
15417 else
15418 {
15419 printf (_("<corrupt>"));
15420 p = (unsigned char *) end;
15421 }
071436c6 15422 putchar ('\n');
071436c6 15423 }
11c1ff18
PB
15424 break;
15425
f5f53991 15426 case 64: /* Tag_nodefaults. */
541a3cbd
NC
15427 /* PR 17531: file: 001-505008-0.01. */
15428 if (p < end)
15429 p++;
2b692964 15430 printf (_("True\n"));
f5f53991
AS
15431 break;
15432
15433 case 65: /* Tag_also_compatible_with. */
cd30bcef 15434 READ_ULEB (val, p, end);
f5f53991
AS
15435 if (val == 6 /* Tag_CPU_arch. */)
15436 {
cd30bcef 15437 READ_ULEB (val, p, end);
071436c6 15438 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
15439 printf ("??? (%d)\n", val);
15440 else
15441 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
15442 }
15443 else
15444 printf ("???\n");
071436c6
NC
15445 while (p < end && *(p++) != '\0' /* NUL terminator. */)
15446 ;
f5f53991
AS
15447 break;
15448
11c1ff18 15449 default:
bee0ee85
NC
15450 printf (_("<unknown: %d>\n"), tag);
15451 break;
11c1ff18
PB
15452 }
15453 return p;
15454
15455 case 1:
f6f0e17b 15456 return display_tag_value (-1, p, end);
11c1ff18 15457 case 2:
f6f0e17b 15458 return display_tag_value (0, p, end);
11c1ff18
PB
15459
15460 default:
15461 assert (attr->type & 0x80);
cd30bcef 15462 READ_ULEB (val, p, end);
11c1ff18
PB
15463 type = attr->type & 0x7f;
15464 if (val >= type)
15465 printf ("??? (%d)\n", val);
15466 else
15467 printf ("%s\n", attr->table[val]);
15468 return p;
15469 }
15470 }
11c1ff18 15471
f6f0e17b 15472 return display_tag_value (tag, p, end);
11c1ff18
PB
15473}
15474
104d59d1 15475static unsigned char *
60bca95a 15476display_gnu_attribute (unsigned char * p,
60abdbed 15477 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 15478 const unsigned char * const end)
104d59d1 15479{
cd30bcef 15480 unsigned int tag;
60abdbed 15481 unsigned int val;
104d59d1 15482
cd30bcef 15483 READ_ULEB (tag, p, end);
104d59d1
JM
15484
15485 /* Tag_compatibility is the only generic GNU attribute defined at
15486 present. */
15487 if (tag == 32)
15488 {
cd30bcef 15489 READ_ULEB (val, p, end);
071436c6
NC
15490
15491 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
15492 if (p == end)
15493 {
071436c6 15494 printf (_("<corrupt>\n"));
f6f0e17b
NC
15495 warn (_("corrupt vendor attribute\n"));
15496 }
15497 else
15498 {
4082ef84
NC
15499 if (p < end - 1)
15500 {
15501 size_t maxlen = (end - p) - 1;
071436c6 15502
4082ef84
NC
15503 print_symbol ((int) maxlen, (const char *) p);
15504 p += strnlen ((char *) p, maxlen) + 1;
15505 }
15506 else
15507 {
15508 printf (_("<corrupt>"));
15509 p = (unsigned char *) end;
15510 }
071436c6 15511 putchar ('\n');
f6f0e17b 15512 }
104d59d1
JM
15513 return p;
15514 }
15515
15516 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 15517 return display_proc_gnu_attribute (p, tag, end);
104d59d1 15518
f6f0e17b 15519 return display_tag_value (tag, p, end);
104d59d1
JM
15520}
15521
85f7484a
PB
15522static unsigned char *
15523display_m68k_gnu_attribute (unsigned char * p,
15524 unsigned int tag,
15525 const unsigned char * const end)
15526{
15527 unsigned int val;
15528
15529 if (tag == Tag_GNU_M68K_ABI_FP)
15530 {
15531 printf (" Tag_GNU_M68K_ABI_FP: ");
15532 if (p == end)
15533 {
15534 printf (_("<corrupt>\n"));
15535 return p;
15536 }
15537 READ_ULEB (val, p, end);
15538
15539 if (val > 3)
15540 printf ("(%#x), ", val);
15541
15542 switch (val & 3)
15543 {
15544 case 0:
15545 printf (_("unspecified hard/soft float\n"));
15546 break;
15547 case 1:
15548 printf (_("hard float\n"));
15549 break;
15550 case 2:
15551 printf (_("soft float\n"));
15552 break;
15553 }
15554 return p;
15555 }
15556
15557 return display_tag_value (tag & 1, p, end);
15558}
15559
34c8bcba 15560static unsigned char *
f6f0e17b 15561display_power_gnu_attribute (unsigned char * p,
60abdbed 15562 unsigned int tag,
f6f0e17b 15563 const unsigned char * const end)
34c8bcba 15564{
005d79fd 15565 unsigned int val;
34c8bcba
JM
15566
15567 if (tag == Tag_GNU_Power_ABI_FP)
15568 {
34c8bcba 15569 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 15570 if (p == end)
005d79fd
AM
15571 {
15572 printf (_("<corrupt>\n"));
15573 return p;
15574 }
cd30bcef 15575 READ_ULEB (val, p, end);
60bca95a 15576
005d79fd
AM
15577 if (val > 15)
15578 printf ("(%#x), ", val);
15579
15580 switch (val & 3)
34c8bcba
JM
15581 {
15582 case 0:
005d79fd 15583 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
15584 break;
15585 case 1:
005d79fd 15586 printf (_("hard float, "));
34c8bcba
JM
15587 break;
15588 case 2:
005d79fd 15589 printf (_("soft float, "));
34c8bcba 15590 break;
3c7b9897 15591 case 3:
005d79fd 15592 printf (_("single-precision hard float, "));
3c7b9897 15593 break;
005d79fd
AM
15594 }
15595
15596 switch (val & 0xC)
15597 {
15598 case 0:
15599 printf (_("unspecified long double\n"));
15600 break;
15601 case 4:
15602 printf (_("128-bit IBM long double\n"));
15603 break;
15604 case 8:
15605 printf (_("64-bit long double\n"));
15606 break;
15607 case 12:
15608 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
15609 break;
15610 }
15611 return p;
005d79fd 15612 }
34c8bcba 15613
c6e65352
DJ
15614 if (tag == Tag_GNU_Power_ABI_Vector)
15615 {
c6e65352 15616 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 15617 if (p == end)
005d79fd
AM
15618 {
15619 printf (_("<corrupt>\n"));
15620 return p;
15621 }
cd30bcef 15622 READ_ULEB (val, p, end);
005d79fd
AM
15623
15624 if (val > 3)
15625 printf ("(%#x), ", val);
15626
15627 switch (val & 3)
c6e65352
DJ
15628 {
15629 case 0:
005d79fd 15630 printf (_("unspecified\n"));
c6e65352
DJ
15631 break;
15632 case 1:
005d79fd 15633 printf (_("generic\n"));
c6e65352
DJ
15634 break;
15635 case 2:
15636 printf ("AltiVec\n");
15637 break;
15638 case 3:
15639 printf ("SPE\n");
15640 break;
c6e65352
DJ
15641 }
15642 return p;
005d79fd 15643 }
c6e65352 15644
f82e0623
NF
15645 if (tag == Tag_GNU_Power_ABI_Struct_Return)
15646 {
005d79fd 15647 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 15648 if (p == end)
f6f0e17b 15649 {
005d79fd 15650 printf (_("<corrupt>\n"));
f6f0e17b
NC
15651 return p;
15652 }
cd30bcef 15653 READ_ULEB (val, p, end);
0b4362b0 15654
005d79fd
AM
15655 if (val > 2)
15656 printf ("(%#x), ", val);
15657
15658 switch (val & 3)
15659 {
15660 case 0:
15661 printf (_("unspecified\n"));
15662 break;
15663 case 1:
15664 printf ("r3/r4\n");
15665 break;
15666 case 2:
15667 printf (_("memory\n"));
15668 break;
15669 case 3:
15670 printf ("???\n");
15671 break;
15672 }
f82e0623
NF
15673 return p;
15674 }
15675
f6f0e17b 15676 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
15677}
15678
643f7afb
AK
15679static unsigned char *
15680display_s390_gnu_attribute (unsigned char * p,
60abdbed 15681 unsigned int tag,
643f7afb
AK
15682 const unsigned char * const end)
15683{
cd30bcef 15684 unsigned int val;
643f7afb
AK
15685
15686 if (tag == Tag_GNU_S390_ABI_Vector)
15687 {
643f7afb 15688 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 15689 READ_ULEB (val, p, end);
643f7afb
AK
15690
15691 switch (val)
15692 {
15693 case 0:
15694 printf (_("any\n"));
15695 break;
15696 case 1:
15697 printf (_("software\n"));
15698 break;
15699 case 2:
15700 printf (_("hardware\n"));
15701 break;
15702 default:
15703 printf ("??? (%d)\n", val);
15704 break;
15705 }
15706 return p;
15707 }
15708
15709 return display_tag_value (tag & 1, p, end);
15710}
15711
9e8c70f9 15712static void
60abdbed 15713display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
15714{
15715 if (mask)
15716 {
32ec8896 15717 bfd_boolean first = TRUE;
071436c6 15718
9e8c70f9 15719 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 15720 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 15721 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 15722 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 15723 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 15724 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 15725 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 15726 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 15727 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 15728 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 15729 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 15730 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 15731 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 15732 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 15733 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 15734 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 15735 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 15736 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 15737 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 15738 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 15739 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 15740 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 15741 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 15742 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 15743 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 15744 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 15745 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 15746 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 15747 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 15748 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 15749 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 15750 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
15751 }
15752 else
071436c6
NC
15753 fputc ('0', stdout);
15754 fputc ('\n', stdout);
9e8c70f9
DM
15755}
15756
3d68f91c 15757static void
60abdbed 15758display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
15759{
15760 if (mask)
15761 {
32ec8896 15762 bfd_boolean first = TRUE;
071436c6 15763
3d68f91c 15764 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 15765 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 15766 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 15767 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 15768 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 15769 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 15770 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 15771 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 15772 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 15773 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 15774 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 15775 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 15776 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 15777 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 15778 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 15779 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 15780 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 15781 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 15782 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 15783 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 15784 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 15785 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
15786 }
15787 else
071436c6
NC
15788 fputc ('0', stdout);
15789 fputc ('\n', stdout);
3d68f91c
JM
15790}
15791
9e8c70f9 15792static unsigned char *
f6f0e17b 15793display_sparc_gnu_attribute (unsigned char * p,
60abdbed 15794 unsigned int tag,
f6f0e17b 15795 const unsigned char * const end)
9e8c70f9 15796{
cd30bcef 15797 unsigned int val;
3d68f91c 15798
9e8c70f9
DM
15799 if (tag == Tag_GNU_Sparc_HWCAPS)
15800 {
cd30bcef 15801 READ_ULEB (val, p, end);
9e8c70f9 15802 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
15803 display_sparc_hwcaps (val);
15804 return p;
3d68f91c
JM
15805 }
15806 if (tag == Tag_GNU_Sparc_HWCAPS2)
15807 {
cd30bcef 15808 READ_ULEB (val, p, end);
3d68f91c
JM
15809 printf (" Tag_GNU_Sparc_HWCAPS2: ");
15810 display_sparc_hwcaps2 (val);
15811 return p;
15812 }
9e8c70f9 15813
f6f0e17b 15814 return display_tag_value (tag, p, end);
9e8c70f9
DM
15815}
15816
351cdf24 15817static void
32ec8896 15818print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
15819{
15820 switch (val)
15821 {
15822 case Val_GNU_MIPS_ABI_FP_ANY:
15823 printf (_("Hard or soft float\n"));
15824 break;
15825 case Val_GNU_MIPS_ABI_FP_DOUBLE:
15826 printf (_("Hard float (double precision)\n"));
15827 break;
15828 case Val_GNU_MIPS_ABI_FP_SINGLE:
15829 printf (_("Hard float (single precision)\n"));
15830 break;
15831 case Val_GNU_MIPS_ABI_FP_SOFT:
15832 printf (_("Soft float\n"));
15833 break;
15834 case Val_GNU_MIPS_ABI_FP_OLD_64:
15835 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
15836 break;
15837 case Val_GNU_MIPS_ABI_FP_XX:
15838 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
15839 break;
15840 case Val_GNU_MIPS_ABI_FP_64:
15841 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
15842 break;
15843 case Val_GNU_MIPS_ABI_FP_64A:
15844 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
15845 break;
3350cc01
CM
15846 case Val_GNU_MIPS_ABI_FP_NAN2008:
15847 printf (_("NaN 2008 compatibility\n"));
15848 break;
351cdf24
MF
15849 default:
15850 printf ("??? (%d)\n", val);
15851 break;
15852 }
15853}
15854
2cf19d5c 15855static unsigned char *
f6f0e17b 15856display_mips_gnu_attribute (unsigned char * p,
60abdbed 15857 unsigned int tag,
f6f0e17b 15858 const unsigned char * const end)
2cf19d5c 15859{
2cf19d5c
JM
15860 if (tag == Tag_GNU_MIPS_ABI_FP)
15861 {
32ec8896 15862 unsigned int val;
f6f0e17b 15863
2cf19d5c 15864 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 15865 READ_ULEB (val, p, end);
351cdf24 15866 print_mips_fp_abi_value (val);
2cf19d5c
JM
15867 return p;
15868 }
15869
a9f58168
CF
15870 if (tag == Tag_GNU_MIPS_ABI_MSA)
15871 {
32ec8896 15872 unsigned int val;
a9f58168 15873
a9f58168 15874 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 15875 READ_ULEB (val, p, end);
a9f58168
CF
15876
15877 switch (val)
15878 {
15879 case Val_GNU_MIPS_ABI_MSA_ANY:
15880 printf (_("Any MSA or not\n"));
15881 break;
15882 case Val_GNU_MIPS_ABI_MSA_128:
15883 printf (_("128-bit MSA\n"));
15884 break;
15885 default:
15886 printf ("??? (%d)\n", val);
15887 break;
15888 }
15889 return p;
15890 }
15891
f6f0e17b 15892 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
15893}
15894
59e6276b 15895static unsigned char *
f6f0e17b
NC
15896display_tic6x_attribute (unsigned char * p,
15897 const unsigned char * const end)
59e6276b 15898{
60abdbed 15899 unsigned int tag;
cd30bcef 15900 unsigned int val;
59e6276b 15901
cd30bcef 15902 READ_ULEB (tag, p, end);
59e6276b
JM
15903
15904 switch (tag)
15905 {
75fa6dc1 15906 case Tag_ISA:
75fa6dc1 15907 printf (" Tag_ISA: ");
cd30bcef 15908 READ_ULEB (val, p, end);
59e6276b
JM
15909
15910 switch (val)
15911 {
75fa6dc1 15912 case C6XABI_Tag_ISA_none:
59e6276b
JM
15913 printf (_("None\n"));
15914 break;
75fa6dc1 15915 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
15916 printf ("C62x\n");
15917 break;
75fa6dc1 15918 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
15919 printf ("C67x\n");
15920 break;
75fa6dc1 15921 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
15922 printf ("C67x+\n");
15923 break;
75fa6dc1 15924 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
15925 printf ("C64x\n");
15926 break;
75fa6dc1 15927 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
15928 printf ("C64x+\n");
15929 break;
75fa6dc1 15930 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
15931 printf ("C674x\n");
15932 break;
15933 default:
15934 printf ("??? (%d)\n", val);
15935 break;
15936 }
15937 return p;
15938
87779176 15939 case Tag_ABI_wchar_t:
87779176 15940 printf (" Tag_ABI_wchar_t: ");
cd30bcef 15941 READ_ULEB (val, p, end);
87779176
JM
15942 switch (val)
15943 {
15944 case 0:
15945 printf (_("Not used\n"));
15946 break;
15947 case 1:
15948 printf (_("2 bytes\n"));
15949 break;
15950 case 2:
15951 printf (_("4 bytes\n"));
15952 break;
15953 default:
15954 printf ("??? (%d)\n", val);
15955 break;
15956 }
15957 return p;
15958
15959 case Tag_ABI_stack_align_needed:
87779176 15960 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 15961 READ_ULEB (val, p, end);
87779176
JM
15962 switch (val)
15963 {
15964 case 0:
15965 printf (_("8-byte\n"));
15966 break;
15967 case 1:
15968 printf (_("16-byte\n"));
15969 break;
15970 default:
15971 printf ("??? (%d)\n", val);
15972 break;
15973 }
15974 return p;
15975
15976 case Tag_ABI_stack_align_preserved:
cd30bcef 15977 READ_ULEB (val, p, end);
87779176
JM
15978 printf (" Tag_ABI_stack_align_preserved: ");
15979 switch (val)
15980 {
15981 case 0:
15982 printf (_("8-byte\n"));
15983 break;
15984 case 1:
15985 printf (_("16-byte\n"));
15986 break;
15987 default:
15988 printf ("??? (%d)\n", val);
15989 break;
15990 }
15991 return p;
15992
b5593623 15993 case Tag_ABI_DSBT:
cd30bcef 15994 READ_ULEB (val, p, end);
b5593623
JM
15995 printf (" Tag_ABI_DSBT: ");
15996 switch (val)
15997 {
15998 case 0:
15999 printf (_("DSBT addressing not used\n"));
16000 break;
16001 case 1:
16002 printf (_("DSBT addressing used\n"));
16003 break;
16004 default:
16005 printf ("??? (%d)\n", val);
16006 break;
16007 }
16008 return p;
16009
87779176 16010 case Tag_ABI_PID:
cd30bcef 16011 READ_ULEB (val, p, end);
87779176
JM
16012 printf (" Tag_ABI_PID: ");
16013 switch (val)
16014 {
16015 case 0:
16016 printf (_("Data addressing position-dependent\n"));
16017 break;
16018 case 1:
16019 printf (_("Data addressing position-independent, GOT near DP\n"));
16020 break;
16021 case 2:
16022 printf (_("Data addressing position-independent, GOT far from DP\n"));
16023 break;
16024 default:
16025 printf ("??? (%d)\n", val);
16026 break;
16027 }
16028 return p;
16029
16030 case Tag_ABI_PIC:
cd30bcef 16031 READ_ULEB (val, p, end);
87779176
JM
16032 printf (" Tag_ABI_PIC: ");
16033 switch (val)
16034 {
16035 case 0:
16036 printf (_("Code addressing position-dependent\n"));
16037 break;
16038 case 1:
16039 printf (_("Code addressing position-independent\n"));
16040 break;
16041 default:
16042 printf ("??? (%d)\n", val);
16043 break;
16044 }
16045 return p;
16046
16047 case Tag_ABI_array_object_alignment:
cd30bcef 16048 READ_ULEB (val, p, end);
87779176
JM
16049 printf (" Tag_ABI_array_object_alignment: ");
16050 switch (val)
16051 {
16052 case 0:
16053 printf (_("8-byte\n"));
16054 break;
16055 case 1:
16056 printf (_("4-byte\n"));
16057 break;
16058 case 2:
16059 printf (_("16-byte\n"));
16060 break;
16061 default:
16062 printf ("??? (%d)\n", val);
16063 break;
16064 }
16065 return p;
16066
16067 case Tag_ABI_array_object_align_expected:
cd30bcef 16068 READ_ULEB (val, p, end);
87779176
JM
16069 printf (" Tag_ABI_array_object_align_expected: ");
16070 switch (val)
16071 {
16072 case 0:
16073 printf (_("8-byte\n"));
16074 break;
16075 case 1:
16076 printf (_("4-byte\n"));
16077 break;
16078 case 2:
16079 printf (_("16-byte\n"));
16080 break;
16081 default:
16082 printf ("??? (%d)\n", val);
16083 break;
16084 }
16085 return p;
16086
3cbd1c06 16087 case Tag_ABI_compatibility:
071436c6 16088 {
cd30bcef 16089 READ_ULEB (val, p, end);
071436c6 16090 printf (" Tag_ABI_compatibility: ");
071436c6 16091 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16092 if (p < end - 1)
16093 {
16094 size_t maxlen = (end - p) - 1;
16095
16096 print_symbol ((int) maxlen, (const char *) p);
16097 p += strnlen ((char *) p, maxlen) + 1;
16098 }
16099 else
16100 {
16101 printf (_("<corrupt>"));
16102 p = (unsigned char *) end;
16103 }
071436c6 16104 putchar ('\n');
071436c6
NC
16105 return p;
16106 }
87779176
JM
16107
16108 case Tag_ABI_conformance:
071436c6 16109 {
4082ef84
NC
16110 printf (" Tag_ABI_conformance: \"");
16111 if (p < end - 1)
16112 {
16113 size_t maxlen = (end - p) - 1;
071436c6 16114
4082ef84
NC
16115 print_symbol ((int) maxlen, (const char *) p);
16116 p += strnlen ((char *) p, maxlen) + 1;
16117 }
16118 else
16119 {
16120 printf (_("<corrupt>"));
16121 p = (unsigned char *) end;
16122 }
071436c6 16123 printf ("\"\n");
071436c6
NC
16124 return p;
16125 }
59e6276b
JM
16126 }
16127
f6f0e17b
NC
16128 return display_tag_value (tag, p, end);
16129}
59e6276b 16130
f6f0e17b 16131static void
60abdbed 16132display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16133{
16134 unsigned long addr = 0;
16135 size_t bytes = end - p;
16136
feceaa59 16137 assert (end >= p);
f6f0e17b 16138 while (bytes)
87779176 16139 {
f6f0e17b
NC
16140 int j;
16141 int k;
16142 int lbytes = (bytes > 16 ? 16 : bytes);
16143
16144 printf (" 0x%8.8lx ", addr);
16145
16146 for (j = 0; j < 16; j++)
16147 {
16148 if (j < lbytes)
16149 printf ("%2.2x", p[j]);
16150 else
16151 printf (" ");
16152
16153 if ((j & 3) == 3)
16154 printf (" ");
16155 }
16156
16157 for (j = 0; j < lbytes; j++)
16158 {
16159 k = p[j];
16160 if (k >= ' ' && k < 0x7f)
16161 printf ("%c", k);
16162 else
16163 printf (".");
16164 }
16165
16166 putchar ('\n');
16167
16168 p += lbytes;
16169 bytes -= lbytes;
16170 addr += lbytes;
87779176 16171 }
59e6276b 16172
f6f0e17b 16173 putchar ('\n');
59e6276b
JM
16174}
16175
13761a11
NC
16176static unsigned char *
16177display_msp430x_attribute (unsigned char * p,
16178 const unsigned char * const end)
16179{
60abdbed
NC
16180 unsigned int val;
16181 unsigned int tag;
13761a11 16182
cd30bcef 16183 READ_ULEB (tag, p, end);
0b4362b0 16184
13761a11
NC
16185 switch (tag)
16186 {
16187 case OFBA_MSPABI_Tag_ISA:
13761a11 16188 printf (" Tag_ISA: ");
cd30bcef 16189 READ_ULEB (val, p, end);
13761a11
NC
16190 switch (val)
16191 {
16192 case 0: printf (_("None\n")); break;
16193 case 1: printf (_("MSP430\n")); break;
16194 case 2: printf (_("MSP430X\n")); break;
16195 default: printf ("??? (%d)\n", val); break;
16196 }
16197 break;
16198
16199 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16200 printf (" Tag_Code_Model: ");
cd30bcef 16201 READ_ULEB (val, p, end);
13761a11
NC
16202 switch (val)
16203 {
16204 case 0: printf (_("None\n")); break;
16205 case 1: printf (_("Small\n")); break;
16206 case 2: printf (_("Large\n")); break;
16207 default: printf ("??? (%d)\n", val); break;
16208 }
16209 break;
16210
16211 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16212 printf (" Tag_Data_Model: ");
cd30bcef 16213 READ_ULEB (val, p, end);
13761a11
NC
16214 switch (val)
16215 {
16216 case 0: printf (_("None\n")); break;
16217 case 1: printf (_("Small\n")); break;
16218 case 2: printf (_("Large\n")); break;
16219 case 3: printf (_("Restricted Large\n")); break;
16220 default: printf ("??? (%d)\n", val); break;
16221 }
16222 break;
16223
16224 default:
16225 printf (_(" <unknown tag %d>: "), tag);
16226
16227 if (tag & 1)
16228 {
071436c6 16229 putchar ('"');
4082ef84
NC
16230 if (p < end - 1)
16231 {
16232 size_t maxlen = (end - p) - 1;
16233
16234 print_symbol ((int) maxlen, (const char *) p);
16235 p += strnlen ((char *) p, maxlen) + 1;
16236 }
16237 else
16238 {
16239 printf (_("<corrupt>"));
16240 p = (unsigned char *) end;
16241 }
071436c6 16242 printf ("\"\n");
13761a11
NC
16243 }
16244 else
16245 {
cd30bcef 16246 READ_ULEB (val, p, end);
13761a11
NC
16247 printf ("%d (0x%x)\n", val, val);
16248 }
16249 break;
16250 }
16251
4082ef84 16252 assert (p <= end);
13761a11
NC
16253 return p;
16254}
16255
c0ea7c52
JL
16256static unsigned char *
16257display_msp430_gnu_attribute (unsigned char * p,
16258 unsigned int tag,
16259 const unsigned char * const end)
16260{
16261 if (tag == Tag_GNU_MSP430_Data_Region)
16262 {
cd30bcef 16263 unsigned int val;
c0ea7c52 16264
c0ea7c52 16265 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16266 READ_ULEB (val, p, end);
c0ea7c52
JL
16267
16268 switch (val)
16269 {
16270 case Val_GNU_MSP430_Data_Region_Any:
16271 printf (_("Any Region\n"));
16272 break;
16273 case Val_GNU_MSP430_Data_Region_Lower:
16274 printf (_("Lower Region Only\n"));
16275 break;
16276 default:
cd30bcef 16277 printf ("??? (%u)\n", val);
c0ea7c52
JL
16278 }
16279 return p;
16280 }
16281 return display_tag_value (tag & 1, p, end);
16282}
16283
2dc8dd17
JW
16284struct riscv_attr_tag_t {
16285 const char *name;
cd30bcef 16286 unsigned int tag;
2dc8dd17
JW
16287};
16288
16289static struct riscv_attr_tag_t riscv_attr_tag[] =
16290{
16291#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16292 T(arch),
16293 T(priv_spec),
16294 T(priv_spec_minor),
16295 T(priv_spec_revision),
16296 T(unaligned_access),
16297 T(stack_align),
16298#undef T
16299};
16300
16301static unsigned char *
16302display_riscv_attribute (unsigned char *p,
16303 const unsigned char * const end)
16304{
cd30bcef
AM
16305 unsigned int val;
16306 unsigned int tag;
2dc8dd17
JW
16307 struct riscv_attr_tag_t *attr = NULL;
16308 unsigned i;
16309
cd30bcef 16310 READ_ULEB (tag, p, end);
2dc8dd17
JW
16311
16312 /* Find the name of attribute. */
16313 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16314 {
16315 if (riscv_attr_tag[i].tag == tag)
16316 {
16317 attr = &riscv_attr_tag[i];
16318 break;
16319 }
16320 }
16321
16322 if (attr)
16323 printf (" %s: ", attr->name);
16324 else
16325 return display_tag_value (tag, p, end);
16326
16327 switch (tag)
16328 {
16329 case Tag_RISCV_priv_spec:
16330 case Tag_RISCV_priv_spec_minor:
16331 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16332 READ_ULEB (val, p, end);
16333 printf (_("%u\n"), val);
2dc8dd17
JW
16334 break;
16335 case Tag_RISCV_unaligned_access:
cd30bcef 16336 READ_ULEB (val, p, end);
2dc8dd17
JW
16337 switch (val)
16338 {
16339 case 0:
16340 printf (_("No unaligned access\n"));
16341 break;
16342 case 1:
16343 printf (_("Unaligned access\n"));
16344 break;
16345 }
16346 break;
16347 case Tag_RISCV_stack_align:
cd30bcef
AM
16348 READ_ULEB (val, p, end);
16349 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16350 break;
16351 case Tag_RISCV_arch:
16352 p = display_tag_value (-1, p, end);
16353 break;
16354 default:
16355 return display_tag_value (tag, p, end);
16356 }
16357
16358 return p;
16359}
16360
32ec8896 16361static bfd_boolean
dda8d76d 16362process_attributes (Filedata * filedata,
60bca95a 16363 const char * public_name,
104d59d1 16364 unsigned int proc_type,
f6f0e17b 16365 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 16366 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 16367{
2cf0635d 16368 Elf_Internal_Shdr * sect;
11c1ff18 16369 unsigned i;
32ec8896 16370 bfd_boolean res = TRUE;
11c1ff18
PB
16371
16372 /* Find the section header so that we get the size. */
dda8d76d
NC
16373 for (i = 0, sect = filedata->section_headers;
16374 i < filedata->file_header.e_shnum;
11c1ff18
PB
16375 i++, sect++)
16376 {
071436c6
NC
16377 unsigned char * contents;
16378 unsigned char * p;
16379
104d59d1 16380 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
16381 continue;
16382
dda8d76d 16383 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 16384 sect->sh_size, _("attributes"));
60bca95a 16385 if (contents == NULL)
32ec8896
NC
16386 {
16387 res = FALSE;
16388 continue;
16389 }
60bca95a 16390
11c1ff18 16391 p = contents;
60abdbed
NC
16392 /* The first character is the version of the attributes.
16393 Currently only version 1, (aka 'A') is recognised here. */
16394 if (*p != 'A')
32ec8896
NC
16395 {
16396 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
16397 res = FALSE;
16398 }
60abdbed 16399 else
11c1ff18 16400 {
071436c6
NC
16401 bfd_vma section_len;
16402
16403 section_len = sect->sh_size - 1;
11c1ff18 16404 p++;
60bca95a 16405
071436c6 16406 while (section_len > 0)
11c1ff18 16407 {
071436c6 16408 bfd_vma attr_len;
e9847026 16409 unsigned int namelen;
11c1ff18 16410 bfd_boolean public_section;
104d59d1 16411 bfd_boolean gnu_section;
11c1ff18 16412
071436c6 16413 if (section_len <= 4)
e0a31db1
NC
16414 {
16415 error (_("Tag section ends prematurely\n"));
32ec8896 16416 res = FALSE;
e0a31db1
NC
16417 break;
16418 }
071436c6 16419 attr_len = byte_get (p, 4);
11c1ff18 16420 p += 4;
60bca95a 16421
071436c6 16422 if (attr_len > section_len)
11c1ff18 16423 {
071436c6
NC
16424 error (_("Bad attribute length (%u > %u)\n"),
16425 (unsigned) attr_len, (unsigned) section_len);
16426 attr_len = section_len;
32ec8896 16427 res = FALSE;
11c1ff18 16428 }
74e1a04b 16429 /* PR 17531: file: 001-101425-0.004 */
071436c6 16430 else if (attr_len < 5)
74e1a04b 16431 {
071436c6 16432 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 16433 res = FALSE;
74e1a04b
NC
16434 break;
16435 }
e9847026 16436
071436c6
NC
16437 section_len -= attr_len;
16438 attr_len -= 4;
16439
16440 namelen = strnlen ((char *) p, attr_len) + 1;
16441 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
16442 {
16443 error (_("Corrupt attribute section name\n"));
32ec8896 16444 res = FALSE;
e9847026
NC
16445 break;
16446 }
16447
071436c6
NC
16448 printf (_("Attribute Section: "));
16449 print_symbol (INT_MAX, (const char *) p);
16450 putchar ('\n');
60bca95a
NC
16451
16452 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
16453 public_section = TRUE;
16454 else
16455 public_section = FALSE;
60bca95a
NC
16456
16457 if (streq ((char *) p, "gnu"))
104d59d1
JM
16458 gnu_section = TRUE;
16459 else
16460 gnu_section = FALSE;
60bca95a 16461
11c1ff18 16462 p += namelen;
071436c6 16463 attr_len -= namelen;
e0a31db1 16464
071436c6 16465 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 16466 {
e0a31db1 16467 int tag;
cd30bcef 16468 unsigned int val;
11c1ff18 16469 bfd_vma size;
071436c6 16470 unsigned char * end;
60bca95a 16471
e0a31db1 16472 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 16473 if (attr_len < 6)
e0a31db1
NC
16474 {
16475 error (_("Unused bytes at end of section\n"));
32ec8896 16476 res = FALSE;
e0a31db1
NC
16477 section_len = 0;
16478 break;
16479 }
16480
16481 tag = *(p++);
11c1ff18 16482 size = byte_get (p, 4);
071436c6 16483 if (size > attr_len)
11c1ff18 16484 {
e9847026 16485 error (_("Bad subsection length (%u > %u)\n"),
071436c6 16486 (unsigned) size, (unsigned) attr_len);
32ec8896 16487 res = FALSE;
071436c6 16488 size = attr_len;
11c1ff18 16489 }
e0a31db1
NC
16490 /* PR binutils/17531: Safe handling of corrupt files. */
16491 if (size < 6)
16492 {
16493 error (_("Bad subsection length (%u < 6)\n"),
16494 (unsigned) size);
32ec8896 16495 res = FALSE;
e0a31db1
NC
16496 section_len = 0;
16497 break;
16498 }
60bca95a 16499
071436c6 16500 attr_len -= size;
11c1ff18 16501 end = p + size - 1;
071436c6 16502 assert (end <= contents + sect->sh_size);
11c1ff18 16503 p += 4;
60bca95a 16504
11c1ff18
PB
16505 switch (tag)
16506 {
16507 case 1:
2b692964 16508 printf (_("File Attributes\n"));
11c1ff18
PB
16509 break;
16510 case 2:
2b692964 16511 printf (_("Section Attributes:"));
11c1ff18
PB
16512 goto do_numlist;
16513 case 3:
2b692964 16514 printf (_("Symbol Attributes:"));
1a0670f3 16515 /* Fall through. */
11c1ff18
PB
16516 do_numlist:
16517 for (;;)
16518 {
cd30bcef 16519 READ_ULEB (val, p, end);
11c1ff18
PB
16520 if (val == 0)
16521 break;
16522 printf (" %d", val);
16523 }
16524 printf ("\n");
16525 break;
16526 default:
2b692964 16527 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
16528 public_section = FALSE;
16529 break;
16530 }
60bca95a 16531
071436c6 16532 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
16533 {
16534 while (p < end)
f6f0e17b 16535 p = display_pub_attribute (p, end);
60abdbed 16536 assert (p == end);
104d59d1 16537 }
071436c6 16538 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
16539 {
16540 while (p < end)
16541 p = display_gnu_attribute (p,
f6f0e17b
NC
16542 display_proc_gnu_attribute,
16543 end);
60abdbed 16544 assert (p == end);
11c1ff18 16545 }
071436c6 16546 else if (p < end)
11c1ff18 16547 {
071436c6 16548 printf (_(" Unknown attribute:\n"));
f6f0e17b 16549 display_raw_attribute (p, end);
11c1ff18
PB
16550 p = end;
16551 }
071436c6
NC
16552 else
16553 attr_len = 0;
11c1ff18
PB
16554 }
16555 }
16556 }
d70c5fc7 16557
60bca95a 16558 free (contents);
11c1ff18 16559 }
32ec8896
NC
16560
16561 return res;
11c1ff18
PB
16562}
16563
ccb4c951
RS
16564/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
16565 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
16566 and return the VMA of the next entry, or -1 if there was a problem.
16567 Does not read from DATA_END or beyond. */
ccb4c951
RS
16568
16569static bfd_vma
82b1b41b
NC
16570print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
16571 unsigned char * data_end)
ccb4c951
RS
16572{
16573 printf (" ");
16574 print_vma (addr, LONG_HEX);
16575 printf (" ");
16576 if (addr < pltgot + 0xfff0)
16577 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
16578 else
16579 printf ("%10s", "");
16580 printf (" ");
16581 if (data == NULL)
2b692964 16582 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
16583 else
16584 {
16585 bfd_vma entry;
82b1b41b 16586 unsigned char * from = data + addr - pltgot;
ccb4c951 16587
82b1b41b
NC
16588 if (from + (is_32bit_elf ? 4 : 8) > data_end)
16589 {
16590 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
16591 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
16592 return (bfd_vma) -1;
16593 }
16594 else
16595 {
16596 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16597 print_vma (entry, LONG_HEX);
16598 }
ccb4c951
RS
16599 }
16600 return addr + (is_32bit_elf ? 4 : 8);
16601}
16602
861fb55a
DJ
16603/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
16604 PLTGOT. Print the Address and Initial fields of an entry at VMA
16605 ADDR and return the VMA of the next entry. */
16606
16607static bfd_vma
2cf0635d 16608print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
16609{
16610 printf (" ");
16611 print_vma (addr, LONG_HEX);
16612 printf (" ");
16613 if (data == NULL)
2b692964 16614 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
16615 else
16616 {
16617 bfd_vma entry;
16618
16619 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16620 print_vma (entry, LONG_HEX);
16621 }
16622 return addr + (is_32bit_elf ? 4 : 8);
16623}
16624
351cdf24
MF
16625static void
16626print_mips_ases (unsigned int mask)
16627{
16628 if (mask & AFL_ASE_DSP)
16629 fputs ("\n\tDSP ASE", stdout);
16630 if (mask & AFL_ASE_DSPR2)
16631 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
16632 if (mask & AFL_ASE_DSPR3)
16633 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
16634 if (mask & AFL_ASE_EVA)
16635 fputs ("\n\tEnhanced VA Scheme", stdout);
16636 if (mask & AFL_ASE_MCU)
16637 fputs ("\n\tMCU (MicroController) ASE", stdout);
16638 if (mask & AFL_ASE_MDMX)
16639 fputs ("\n\tMDMX ASE", stdout);
16640 if (mask & AFL_ASE_MIPS3D)
16641 fputs ("\n\tMIPS-3D ASE", stdout);
16642 if (mask & AFL_ASE_MT)
16643 fputs ("\n\tMT ASE", stdout);
16644 if (mask & AFL_ASE_SMARTMIPS)
16645 fputs ("\n\tSmartMIPS ASE", stdout);
16646 if (mask & AFL_ASE_VIRT)
16647 fputs ("\n\tVZ ASE", stdout);
16648 if (mask & AFL_ASE_MSA)
16649 fputs ("\n\tMSA ASE", stdout);
16650 if (mask & AFL_ASE_MIPS16)
16651 fputs ("\n\tMIPS16 ASE", stdout);
16652 if (mask & AFL_ASE_MICROMIPS)
16653 fputs ("\n\tMICROMIPS ASE", stdout);
16654 if (mask & AFL_ASE_XPA)
16655 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
16656 if (mask & AFL_ASE_MIPS16E2)
16657 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
16658 if (mask & AFL_ASE_CRC)
16659 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
16660 if (mask & AFL_ASE_GINV)
16661 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
16662 if (mask & AFL_ASE_LOONGSON_MMI)
16663 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
16664 if (mask & AFL_ASE_LOONGSON_CAM)
16665 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
16666 if (mask & AFL_ASE_LOONGSON_EXT)
16667 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
16668 if (mask & AFL_ASE_LOONGSON_EXT2)
16669 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
16670 if (mask == 0)
16671 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
16672 else if ((mask & ~AFL_ASE_MASK) != 0)
16673 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
16674}
16675
16676static void
16677print_mips_isa_ext (unsigned int isa_ext)
16678{
16679 switch (isa_ext)
16680 {
16681 case 0:
16682 fputs (_("None"), stdout);
16683 break;
16684 case AFL_EXT_XLR:
16685 fputs ("RMI XLR", stdout);
16686 break;
2c629856
N
16687 case AFL_EXT_OCTEON3:
16688 fputs ("Cavium Networks Octeon3", stdout);
16689 break;
351cdf24
MF
16690 case AFL_EXT_OCTEON2:
16691 fputs ("Cavium Networks Octeon2", stdout);
16692 break;
16693 case AFL_EXT_OCTEONP:
16694 fputs ("Cavium Networks OcteonP", stdout);
16695 break;
351cdf24
MF
16696 case AFL_EXT_OCTEON:
16697 fputs ("Cavium Networks Octeon", stdout);
16698 break;
16699 case AFL_EXT_5900:
16700 fputs ("Toshiba R5900", stdout);
16701 break;
16702 case AFL_EXT_4650:
16703 fputs ("MIPS R4650", stdout);
16704 break;
16705 case AFL_EXT_4010:
16706 fputs ("LSI R4010", stdout);
16707 break;
16708 case AFL_EXT_4100:
16709 fputs ("NEC VR4100", stdout);
16710 break;
16711 case AFL_EXT_3900:
16712 fputs ("Toshiba R3900", stdout);
16713 break;
16714 case AFL_EXT_10000:
16715 fputs ("MIPS R10000", stdout);
16716 break;
16717 case AFL_EXT_SB1:
16718 fputs ("Broadcom SB-1", stdout);
16719 break;
16720 case AFL_EXT_4111:
16721 fputs ("NEC VR4111/VR4181", stdout);
16722 break;
16723 case AFL_EXT_4120:
16724 fputs ("NEC VR4120", stdout);
16725 break;
16726 case AFL_EXT_5400:
16727 fputs ("NEC VR5400", stdout);
16728 break;
16729 case AFL_EXT_5500:
16730 fputs ("NEC VR5500", stdout);
16731 break;
16732 case AFL_EXT_LOONGSON_2E:
16733 fputs ("ST Microelectronics Loongson 2E", stdout);
16734 break;
16735 case AFL_EXT_LOONGSON_2F:
16736 fputs ("ST Microelectronics Loongson 2F", stdout);
16737 break;
38bf472a
MR
16738 case AFL_EXT_INTERAPTIV_MR2:
16739 fputs ("Imagination interAptiv MR2", stdout);
16740 break;
351cdf24 16741 default:
00ac7aa0 16742 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
16743 }
16744}
16745
32ec8896 16746static signed int
351cdf24
MF
16747get_mips_reg_size (int reg_size)
16748{
16749 return (reg_size == AFL_REG_NONE) ? 0
16750 : (reg_size == AFL_REG_32) ? 32
16751 : (reg_size == AFL_REG_64) ? 64
16752 : (reg_size == AFL_REG_128) ? 128
16753 : -1;
16754}
16755
32ec8896 16756static bfd_boolean
dda8d76d 16757process_mips_specific (Filedata * filedata)
5b18a4bc 16758{
2cf0635d 16759 Elf_Internal_Dyn * entry;
351cdf24 16760 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
16761 size_t liblist_offset = 0;
16762 size_t liblistno = 0;
16763 size_t conflictsno = 0;
16764 size_t options_offset = 0;
16765 size_t conflicts_offset = 0;
861fb55a
DJ
16766 size_t pltrelsz = 0;
16767 size_t pltrel = 0;
ccb4c951 16768 bfd_vma pltgot = 0;
861fb55a
DJ
16769 bfd_vma mips_pltgot = 0;
16770 bfd_vma jmprel = 0;
ccb4c951
RS
16771 bfd_vma local_gotno = 0;
16772 bfd_vma gotsym = 0;
16773 bfd_vma symtabno = 0;
32ec8896 16774 bfd_boolean res = TRUE;
103f02d3 16775
dda8d76d 16776 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
16777 display_mips_gnu_attribute))
16778 res = FALSE;
2cf19d5c 16779
dda8d76d 16780 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
16781
16782 if (sect != NULL)
16783 {
16784 Elf_External_ABIFlags_v0 *abiflags_ext;
16785 Elf_Internal_ABIFlags_v0 abiflags_in;
16786
16787 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
16788 {
16789 error (_("Corrupt MIPS ABI Flags section.\n"));
16790 res = FALSE;
16791 }
351cdf24
MF
16792 else
16793 {
dda8d76d 16794 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
16795 sect->sh_size, _("MIPS ABI Flags section"));
16796 if (abiflags_ext)
16797 {
16798 abiflags_in.version = BYTE_GET (abiflags_ext->version);
16799 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
16800 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
16801 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
16802 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
16803 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
16804 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
16805 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
16806 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
16807 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
16808 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
16809
16810 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
16811 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
16812 if (abiflags_in.isa_rev > 1)
16813 printf ("r%d", abiflags_in.isa_rev);
16814 printf ("\nGPR size: %d",
16815 get_mips_reg_size (abiflags_in.gpr_size));
16816 printf ("\nCPR1 size: %d",
16817 get_mips_reg_size (abiflags_in.cpr1_size));
16818 printf ("\nCPR2 size: %d",
16819 get_mips_reg_size (abiflags_in.cpr2_size));
16820 fputs ("\nFP ABI: ", stdout);
16821 print_mips_fp_abi_value (abiflags_in.fp_abi);
16822 fputs ("ISA Extension: ", stdout);
16823 print_mips_isa_ext (abiflags_in.isa_ext);
16824 fputs ("\nASEs:", stdout);
16825 print_mips_ases (abiflags_in.ases);
16826 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
16827 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
16828 fputc ('\n', stdout);
16829 free (abiflags_ext);
16830 }
16831 }
16832 }
16833
19e6b90e 16834 /* We have a lot of special sections. Thanks SGI! */
978c4450 16835 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
16836 {
16837 /* No dynamic information available. See if there is static GOT. */
dda8d76d 16838 sect = find_section (filedata, ".got");
bbdd9a68
MR
16839 if (sect != NULL)
16840 {
16841 unsigned char *data_end;
16842 unsigned char *data;
16843 bfd_vma ent, end;
16844 int addr_size;
16845
16846 pltgot = sect->sh_addr;
16847
16848 ent = pltgot;
16849 addr_size = (is_32bit_elf ? 4 : 8);
16850 end = pltgot + sect->sh_size;
16851
dda8d76d 16852 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
16853 end - pltgot, 1,
16854 _("Global Offset Table data"));
16855 /* PR 12855: Null data is handled gracefully throughout. */
16856 data_end = data + (end - pltgot);
16857
16858 printf (_("\nStatic GOT:\n"));
16859 printf (_(" Canonical gp value: "));
16860 print_vma (ent + 0x7ff0, LONG_HEX);
16861 printf ("\n\n");
16862
16863 /* In a dynamic binary GOT[0] is reserved for the dynamic
16864 loader to store the lazy resolver pointer, however in
16865 a static binary it may well have been omitted and GOT
16866 reduced to a table of addresses.
16867 PR 21344: Check for the entry being fully available
16868 before fetching it. */
16869 if (data
16870 && data + ent - pltgot + addr_size <= data_end
16871 && byte_get (data + ent - pltgot, addr_size) == 0)
16872 {
16873 printf (_(" Reserved entries:\n"));
16874 printf (_(" %*s %10s %*s\n"),
16875 addr_size * 2, _("Address"), _("Access"),
16876 addr_size * 2, _("Value"));
16877 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16878 printf ("\n");
16879 if (ent == (bfd_vma) -1)
16880 goto sgot_print_fail;
16881
16882 /* Check for the MSB of GOT[1] being set, identifying a
16883 GNU object. This entry will be used by some runtime
16884 loaders, to store the module pointer. Otherwise this
16885 is an ordinary local entry.
16886 PR 21344: Check for the entry being fully available
16887 before fetching it. */
16888 if (data
16889 && data + ent - pltgot + addr_size <= data_end
16890 && (byte_get (data + ent - pltgot, addr_size)
16891 >> (addr_size * 8 - 1)) != 0)
16892 {
16893 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16894 printf ("\n");
16895 if (ent == (bfd_vma) -1)
16896 goto sgot_print_fail;
16897 }
16898 printf ("\n");
16899 }
16900
f17e9d8a 16901 if (data != NULL && ent < end)
bbdd9a68
MR
16902 {
16903 printf (_(" Local entries:\n"));
16904 printf (" %*s %10s %*s\n",
16905 addr_size * 2, _("Address"), _("Access"),
16906 addr_size * 2, _("Value"));
16907 while (ent < end)
16908 {
16909 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16910 printf ("\n");
16911 if (ent == (bfd_vma) -1)
16912 goto sgot_print_fail;
16913 }
16914 printf ("\n");
16915 }
16916
16917 sgot_print_fail:
9db70fc3 16918 free (data);
bbdd9a68
MR
16919 }
16920 return res;
16921 }
252b5132 16922
978c4450 16923 for (entry = filedata->dynamic_section;
071436c6 16924 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
16925 (entry < filedata->dynamic_section + filedata->dynamic_nent
16926 && entry->d_tag != DT_NULL);
071436c6 16927 ++entry)
252b5132
RH
16928 switch (entry->d_tag)
16929 {
16930 case DT_MIPS_LIBLIST:
d93f0186 16931 liblist_offset
dda8d76d 16932 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16933 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
16934 break;
16935 case DT_MIPS_LIBLISTNO:
16936 liblistno = entry->d_un.d_val;
16937 break;
16938 case DT_MIPS_OPTIONS:
dda8d76d 16939 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
16940 break;
16941 case DT_MIPS_CONFLICT:
d93f0186 16942 conflicts_offset
dda8d76d 16943 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16944 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
16945 break;
16946 case DT_MIPS_CONFLICTNO:
16947 conflictsno = entry->d_un.d_val;
16948 break;
ccb4c951 16949 case DT_PLTGOT:
861fb55a
DJ
16950 pltgot = entry->d_un.d_ptr;
16951 break;
ccb4c951
RS
16952 case DT_MIPS_LOCAL_GOTNO:
16953 local_gotno = entry->d_un.d_val;
16954 break;
16955 case DT_MIPS_GOTSYM:
16956 gotsym = entry->d_un.d_val;
16957 break;
16958 case DT_MIPS_SYMTABNO:
16959 symtabno = entry->d_un.d_val;
16960 break;
861fb55a
DJ
16961 case DT_MIPS_PLTGOT:
16962 mips_pltgot = entry->d_un.d_ptr;
16963 break;
16964 case DT_PLTREL:
16965 pltrel = entry->d_un.d_val;
16966 break;
16967 case DT_PLTRELSZ:
16968 pltrelsz = entry->d_un.d_val;
16969 break;
16970 case DT_JMPREL:
16971 jmprel = entry->d_un.d_ptr;
16972 break;
252b5132
RH
16973 default:
16974 break;
16975 }
16976
16977 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
16978 {
2cf0635d 16979 Elf32_External_Lib * elib;
252b5132
RH
16980 size_t cnt;
16981
dda8d76d 16982 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
16983 sizeof (Elf32_External_Lib),
16984 liblistno,
16985 _("liblist section data"));
a6e9f9df 16986 if (elib)
252b5132 16987 {
d3a49aa8
AM
16988 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
16989 "\nSection '.liblist' contains %lu entries:\n",
16990 (unsigned long) liblistno),
a6e9f9df 16991 (unsigned long) liblistno);
2b692964 16992 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
16993 stdout);
16994
16995 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 16996 {
a6e9f9df 16997 Elf32_Lib liblist;
91d6fa6a 16998 time_t atime;
d5b07ef4 16999 char timebuf[128];
2cf0635d 17000 struct tm * tmp;
a6e9f9df
AM
17001
17002 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17003 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17004 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17005 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17006 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17007
91d6fa6a 17008 tmp = gmtime (&atime);
e9e44622
JJ
17009 snprintf (timebuf, sizeof (timebuf),
17010 "%04u-%02u-%02uT%02u:%02u:%02u",
17011 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17012 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17013
31104126 17014 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17015 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17016 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17017 else
2b692964 17018 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17019 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17020 liblist.l_version);
a6e9f9df
AM
17021
17022 if (liblist.l_flags == 0)
2b692964 17023 puts (_(" NONE"));
a6e9f9df
AM
17024 else
17025 {
17026 static const struct
252b5132 17027 {
2cf0635d 17028 const char * name;
a6e9f9df 17029 int bit;
252b5132 17030 }
a6e9f9df
AM
17031 l_flags_vals[] =
17032 {
17033 { " EXACT_MATCH", LL_EXACT_MATCH },
17034 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17035 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17036 { " EXPORTS", LL_EXPORTS },
17037 { " DELAY_LOAD", LL_DELAY_LOAD },
17038 { " DELTA", LL_DELTA }
17039 };
17040 int flags = liblist.l_flags;
17041 size_t fcnt;
17042
60bca95a 17043 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17044 if ((flags & l_flags_vals[fcnt].bit) != 0)
17045 {
17046 fputs (l_flags_vals[fcnt].name, stdout);
17047 flags ^= l_flags_vals[fcnt].bit;
17048 }
17049 if (flags != 0)
17050 printf (" %#x", (unsigned int) flags);
252b5132 17051
a6e9f9df
AM
17052 puts ("");
17053 }
252b5132 17054 }
252b5132 17055
a6e9f9df
AM
17056 free (elib);
17057 }
32ec8896
NC
17058 else
17059 res = FALSE;
252b5132
RH
17060 }
17061
17062 if (options_offset != 0)
17063 {
2cf0635d 17064 Elf_External_Options * eopt;
252b5132
RH
17065 size_t offset;
17066 int cnt;
dda8d76d 17067 sect = filedata->section_headers;
252b5132
RH
17068
17069 /* Find the section header so that we get the size. */
dda8d76d 17070 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17071 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17072 if (sect == NULL)
17073 {
17074 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 17075 return FALSE;
071436c6 17076 }
7fc0c668
NC
17077 /* PR 24243 */
17078 if (sect->sh_size < sizeof (* eopt))
17079 {
17080 error (_("The MIPS options section is too small.\n"));
17081 return FALSE;
17082 }
252b5132 17083
dda8d76d 17084 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17085 sect->sh_size, _("options"));
a6e9f9df 17086 if (eopt)
252b5132 17087 {
fd17d1e6 17088 Elf_Internal_Options option;
76da6bbe 17089
a6e9f9df 17090 offset = cnt = 0;
82b1b41b 17091 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17092 {
2cf0635d 17093 Elf_External_Options * eoption;
fd17d1e6 17094 unsigned int optsize;
252b5132 17095
a6e9f9df 17096 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17097
fd17d1e6 17098 optsize = BYTE_GET (eoption->size);
76da6bbe 17099
82b1b41b 17100 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17101 if (optsize < sizeof (* eopt)
17102 || optsize > sect->sh_size - offset)
82b1b41b 17103 {
645f43a8 17104 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17105 optsize);
645f43a8 17106 free (eopt);
32ec8896 17107 return FALSE;
82b1b41b 17108 }
fd17d1e6 17109 offset += optsize;
a6e9f9df
AM
17110 ++cnt;
17111 }
252b5132 17112
d3a49aa8
AM
17113 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17114 "\nSection '%s' contains %d entries:\n",
17115 cnt),
dda8d76d 17116 printable_section_name (filedata, sect), cnt);
76da6bbe 17117
82b1b41b 17118 offset = 0;
a6e9f9df 17119 while (cnt-- > 0)
252b5132 17120 {
a6e9f9df 17121 size_t len;
fd17d1e6
AM
17122 Elf_External_Options * eoption;
17123
17124 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17125
17126 option.kind = BYTE_GET (eoption->kind);
17127 option.size = BYTE_GET (eoption->size);
17128 option.section = BYTE_GET (eoption->section);
17129 option.info = BYTE_GET (eoption->info);
a6e9f9df 17130
fd17d1e6 17131 switch (option.kind)
252b5132 17132 {
a6e9f9df
AM
17133 case ODK_NULL:
17134 /* This shouldn't happen. */
d0c4e780 17135 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 17136 option.section, option.info);
a6e9f9df 17137 break;
2e6be59c 17138
a6e9f9df
AM
17139 case ODK_REGINFO:
17140 printf (" REGINFO ");
dda8d76d 17141 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17142 {
2cf0635d 17143 Elf32_External_RegInfo * ereg;
b34976b6 17144 Elf32_RegInfo reginfo;
a6e9f9df 17145
2e6be59c 17146 /* 32bit form. */
fd17d1e6
AM
17147 if (option.size < (sizeof (Elf_External_Options)
17148 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
17149 {
17150 printf (_("<corrupt>\n"));
17151 error (_("Truncated MIPS REGINFO option\n"));
17152 cnt = 0;
17153 break;
17154 }
17155
fd17d1e6 17156 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 17157
a6e9f9df
AM
17158 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17159 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17160 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17161 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17162 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17163 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17164
d0c4e780
AM
17165 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
17166 reginfo.ri_gprmask, reginfo.ri_gp_value);
17167 printf (" "
17168 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17169 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17170 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17171 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17172 }
17173 else
17174 {
17175 /* 64 bit form. */
2cf0635d 17176 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17177 Elf64_Internal_RegInfo reginfo;
17178
fd17d1e6
AM
17179 if (option.size < (sizeof (Elf_External_Options)
17180 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
17181 {
17182 printf (_("<corrupt>\n"));
17183 error (_("Truncated MIPS REGINFO option\n"));
17184 cnt = 0;
17185 break;
17186 }
17187
fd17d1e6 17188 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
17189 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17190 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17191 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17192 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17193 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 17194 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 17195
d0c4e780
AM
17196 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
17197 reginfo.ri_gprmask, reginfo.ri_gp_value);
17198 printf (" "
17199 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17200 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17201 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17202 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17203 }
fd17d1e6 17204 offset += option.size;
a6e9f9df 17205 continue;
2e6be59c 17206
a6e9f9df
AM
17207 case ODK_EXCEPTIONS:
17208 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 17209 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 17210 fputs (") fpe_max(", stdout);
fd17d1e6 17211 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
17212 fputs (")", stdout);
17213
fd17d1e6 17214 if (option.info & OEX_PAGE0)
a6e9f9df 17215 fputs (" PAGE0", stdout);
fd17d1e6 17216 if (option.info & OEX_SMM)
a6e9f9df 17217 fputs (" SMM", stdout);
fd17d1e6 17218 if (option.info & OEX_FPDBUG)
a6e9f9df 17219 fputs (" FPDBUG", stdout);
fd17d1e6 17220 if (option.info & OEX_DISMISS)
a6e9f9df
AM
17221 fputs (" DISMISS", stdout);
17222 break;
2e6be59c 17223
a6e9f9df
AM
17224 case ODK_PAD:
17225 fputs (" PAD ", stdout);
fd17d1e6 17226 if (option.info & OPAD_PREFIX)
a6e9f9df 17227 fputs (" PREFIX", stdout);
fd17d1e6 17228 if (option.info & OPAD_POSTFIX)
a6e9f9df 17229 fputs (" POSTFIX", stdout);
fd17d1e6 17230 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
17231 fputs (" SYMBOL", stdout);
17232 break;
2e6be59c 17233
a6e9f9df
AM
17234 case ODK_HWPATCH:
17235 fputs (" HWPATCH ", stdout);
fd17d1e6 17236 if (option.info & OHW_R4KEOP)
a6e9f9df 17237 fputs (" R4KEOP", stdout);
fd17d1e6 17238 if (option.info & OHW_R8KPFETCH)
a6e9f9df 17239 fputs (" R8KPFETCH", stdout);
fd17d1e6 17240 if (option.info & OHW_R5KEOP)
a6e9f9df 17241 fputs (" R5KEOP", stdout);
fd17d1e6 17242 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
17243 fputs (" R5KCVTL", stdout);
17244 break;
2e6be59c 17245
a6e9f9df
AM
17246 case ODK_FILL:
17247 fputs (" FILL ", stdout);
17248 /* XXX Print content of info word? */
17249 break;
2e6be59c 17250
a6e9f9df
AM
17251 case ODK_TAGS:
17252 fputs (" TAGS ", stdout);
17253 /* XXX Print content of info word? */
17254 break;
2e6be59c 17255
a6e9f9df
AM
17256 case ODK_HWAND:
17257 fputs (" HWAND ", stdout);
fd17d1e6 17258 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17259 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17260 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17261 fputs (" R4KEOP_CLEAN", stdout);
17262 break;
2e6be59c 17263
a6e9f9df
AM
17264 case ODK_HWOR:
17265 fputs (" HWOR ", stdout);
fd17d1e6 17266 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17267 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17268 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17269 fputs (" R4KEOP_CLEAN", stdout);
17270 break;
2e6be59c 17271
a6e9f9df 17272 case ODK_GP_GROUP:
d0c4e780 17273 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
17274 option.info & OGP_GROUP,
17275 (option.info & OGP_SELF) >> 16);
a6e9f9df 17276 break;
2e6be59c 17277
a6e9f9df 17278 case ODK_IDENT:
d0c4e780 17279 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
17280 option.info & OGP_GROUP,
17281 (option.info & OGP_SELF) >> 16);
a6e9f9df 17282 break;
2e6be59c 17283
a6e9f9df
AM
17284 default:
17285 /* This shouldn't happen. */
d0c4e780 17286 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 17287 option.kind, option.section, option.info);
a6e9f9df 17288 break;
252b5132 17289 }
a6e9f9df 17290
2cf0635d 17291 len = sizeof (* eopt);
fd17d1e6 17292 while (len < option.size)
82b1b41b 17293 {
fd17d1e6 17294 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 17295
82b1b41b
NC
17296 if (ISPRINT (datum))
17297 printf ("%c", datum);
17298 else
17299 printf ("\\%03o", datum);
17300 len ++;
17301 }
a6e9f9df 17302 fputs ("\n", stdout);
82b1b41b 17303
fd17d1e6 17304 offset += option.size;
252b5132 17305 }
a6e9f9df 17306 free (eopt);
252b5132 17307 }
32ec8896
NC
17308 else
17309 res = FALSE;
252b5132
RH
17310 }
17311
17312 if (conflicts_offset != 0 && conflictsno != 0)
17313 {
2cf0635d 17314 Elf32_Conflict * iconf;
252b5132
RH
17315 size_t cnt;
17316
978c4450 17317 if (filedata->dynamic_symbols == NULL)
252b5132 17318 {
591a748a 17319 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 17320 return FALSE;
252b5132
RH
17321 }
17322
7296a62a
NC
17323 /* PR 21345 - print a slightly more helpful error message
17324 if we are sure that the cmalloc will fail. */
645f43a8 17325 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
17326 {
17327 error (_("Overlarge number of conflicts detected: %lx\n"),
17328 (long) conflictsno);
17329 return FALSE;
17330 }
17331
3f5e193b 17332 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
17333 if (iconf == NULL)
17334 {
8b73c356 17335 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 17336 return FALSE;
252b5132
RH
17337 }
17338
9ea033b2 17339 if (is_32bit_elf)
252b5132 17340 {
2cf0635d 17341 Elf32_External_Conflict * econf32;
a6e9f9df 17342
3f5e193b 17343 econf32 = (Elf32_External_Conflict *)
95099889
AM
17344 get_data (NULL, filedata, conflicts_offset,
17345 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 17346 if (!econf32)
5a814d6d
AM
17347 {
17348 free (iconf);
17349 return FALSE;
17350 }
252b5132
RH
17351
17352 for (cnt = 0; cnt < conflictsno; ++cnt)
17353 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
17354
17355 free (econf32);
252b5132
RH
17356 }
17357 else
17358 {
2cf0635d 17359 Elf64_External_Conflict * econf64;
a6e9f9df 17360
3f5e193b 17361 econf64 = (Elf64_External_Conflict *)
95099889
AM
17362 get_data (NULL, filedata, conflicts_offset,
17363 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 17364 if (!econf64)
5a814d6d
AM
17365 {
17366 free (iconf);
17367 return FALSE;
17368 }
252b5132
RH
17369
17370 for (cnt = 0; cnt < conflictsno; ++cnt)
17371 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
17372
17373 free (econf64);
252b5132
RH
17374 }
17375
d3a49aa8
AM
17376 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
17377 "\nSection '.conflict' contains %lu entries:\n",
17378 (unsigned long) conflictsno),
c7e7ca54 17379 (unsigned long) conflictsno);
252b5132
RH
17380 puts (_(" Num: Index Value Name"));
17381
17382 for (cnt = 0; cnt < conflictsno; ++cnt)
17383 {
b34976b6 17384 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 17385
978c4450 17386 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 17387 printf (_("<corrupt symbol index>"));
d79b3d50 17388 else
e0a31db1
NC
17389 {
17390 Elf_Internal_Sym * psym;
17391
978c4450 17392 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
17393 print_vma (psym->st_value, FULL_HEX);
17394 putchar (' ');
978c4450
AM
17395 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17396 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17397 else
17398 printf (_("<corrupt: %14ld>"), psym->st_name);
17399 }
31104126 17400 putchar ('\n');
252b5132
RH
17401 }
17402
252b5132
RH
17403 free (iconf);
17404 }
17405
ccb4c951
RS
17406 if (pltgot != 0 && local_gotno != 0)
17407 {
91d6fa6a 17408 bfd_vma ent, local_end, global_end;
bbeee7ea 17409 size_t i, offset;
2cf0635d 17410 unsigned char * data;
82b1b41b 17411 unsigned char * data_end;
bbeee7ea 17412 int addr_size;
ccb4c951 17413
91d6fa6a 17414 ent = pltgot;
ccb4c951
RS
17415 addr_size = (is_32bit_elf ? 4 : 8);
17416 local_end = pltgot + local_gotno * addr_size;
ccb4c951 17417
74e1a04b
NC
17418 /* PR binutils/17533 file: 012-111227-0.004 */
17419 if (symtabno < gotsym)
17420 {
17421 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 17422 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 17423 return FALSE;
74e1a04b 17424 }
82b1b41b 17425
74e1a04b 17426 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
17427 /* PR 17531: file: 54c91a34. */
17428 if (global_end < local_end)
17429 {
17430 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 17431 return FALSE;
82b1b41b 17432 }
948f632f 17433
dda8d76d
NC
17434 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
17435 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
17436 global_end - pltgot, 1,
17437 _("Global Offset Table data"));
919383ac 17438 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 17439 data_end = data + (global_end - pltgot);
59245841 17440
ccb4c951
RS
17441 printf (_("\nPrimary GOT:\n"));
17442 printf (_(" Canonical gp value: "));
17443 print_vma (pltgot + 0x7ff0, LONG_HEX);
17444 printf ("\n\n");
17445
17446 printf (_(" Reserved entries:\n"));
17447 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
17448 addr_size * 2, _("Address"), _("Access"),
17449 addr_size * 2, _("Initial"));
82b1b41b 17450 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 17451 printf (_(" Lazy resolver\n"));
82b1b41b
NC
17452 if (ent == (bfd_vma) -1)
17453 goto got_print_fail;
75ec1fdb 17454
c4ab9505
MR
17455 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
17456 This entry will be used by some runtime loaders, to store the
17457 module pointer. Otherwise this is an ordinary local entry.
17458 PR 21344: Check for the entry being fully available before
17459 fetching it. */
17460 if (data
17461 && data + ent - pltgot + addr_size <= data_end
17462 && (byte_get (data + ent - pltgot, addr_size)
17463 >> (addr_size * 8 - 1)) != 0)
17464 {
17465 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17466 printf (_(" Module pointer (GNU extension)\n"));
17467 if (ent == (bfd_vma) -1)
17468 goto got_print_fail;
ccb4c951
RS
17469 }
17470 printf ("\n");
17471
f17e9d8a 17472 if (data != NULL && ent < local_end)
ccb4c951
RS
17473 {
17474 printf (_(" Local entries:\n"));
cc5914eb 17475 printf (" %*s %10s %*s\n",
2b692964
NC
17476 addr_size * 2, _("Address"), _("Access"),
17477 addr_size * 2, _("Initial"));
91d6fa6a 17478 while (ent < local_end)
ccb4c951 17479 {
82b1b41b 17480 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17481 printf ("\n");
82b1b41b
NC
17482 if (ent == (bfd_vma) -1)
17483 goto got_print_fail;
ccb4c951
RS
17484 }
17485 printf ("\n");
17486 }
17487
f17e9d8a 17488 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
17489 {
17490 int sym_width;
17491
17492 printf (_(" Global entries:\n"));
cc5914eb 17493 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
17494 addr_size * 2, _("Address"),
17495 _("Access"),
2b692964 17496 addr_size * 2, _("Initial"),
9cf03b7e
NC
17497 addr_size * 2, _("Sym.Val."),
17498 _("Type"),
17499 /* Note for translators: "Ndx" = abbreviated form of "Index". */
17500 _("Ndx"), _("Name"));
0b4362b0 17501
ccb4c951 17502 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 17503
ccb4c951
RS
17504 for (i = gotsym; i < symtabno; i++)
17505 {
82b1b41b 17506 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17507 printf (" ");
e0a31db1 17508
978c4450 17509 if (filedata->dynamic_symbols == NULL)
e0a31db1 17510 printf (_("<no dynamic symbols>"));
978c4450 17511 else if (i < filedata->num_dynamic_syms)
e0a31db1 17512 {
978c4450 17513 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
17514
17515 print_vma (psym->st_value, LONG_HEX);
17516 printf (" %-7s %3s ",
dda8d76d
NC
17517 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17518 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 17519
978c4450
AM
17520 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17521 print_symbol (sym_width,
17522 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17523 else
17524 printf (_("<corrupt: %14ld>"), psym->st_name);
17525 }
ccb4c951 17526 else
7fc5ac57
JBG
17527 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
17528 (unsigned long) i);
e0a31db1 17529
ccb4c951 17530 printf ("\n");
82b1b41b
NC
17531 if (ent == (bfd_vma) -1)
17532 break;
ccb4c951
RS
17533 }
17534 printf ("\n");
17535 }
17536
82b1b41b 17537 got_print_fail:
9db70fc3 17538 free (data);
ccb4c951
RS
17539 }
17540
861fb55a
DJ
17541 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
17542 {
91d6fa6a 17543 bfd_vma ent, end;
861fb55a
DJ
17544 size_t offset, rel_offset;
17545 unsigned long count, i;
2cf0635d 17546 unsigned char * data;
861fb55a 17547 int addr_size, sym_width;
2cf0635d 17548 Elf_Internal_Rela * rels;
861fb55a 17549
dda8d76d 17550 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
17551 if (pltrel == DT_RELA)
17552 {
dda8d76d 17553 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17554 return FALSE;
861fb55a
DJ
17555 }
17556 else
17557 {
dda8d76d 17558 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17559 return FALSE;
861fb55a
DJ
17560 }
17561
91d6fa6a 17562 ent = mips_pltgot;
861fb55a
DJ
17563 addr_size = (is_32bit_elf ? 4 : 8);
17564 end = mips_pltgot + (2 + count) * addr_size;
17565
dda8d76d
NC
17566 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
17567 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 17568 1, _("Procedure Linkage Table data"));
59245841 17569 if (data == NULL)
32ec8896 17570 return FALSE;
59245841 17571
9cf03b7e 17572 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
17573 printf (_(" Reserved entries:\n"));
17574 printf (_(" %*s %*s Purpose\n"),
2b692964 17575 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 17576 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17577 printf (_(" PLT lazy resolver\n"));
91d6fa6a 17578 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17579 printf (_(" Module pointer\n"));
861fb55a
DJ
17580 printf ("\n");
17581
17582 printf (_(" Entries:\n"));
cc5914eb 17583 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
17584 addr_size * 2, _("Address"),
17585 addr_size * 2, _("Initial"),
17586 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
17587 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
17588 for (i = 0; i < count; i++)
17589 {
df97ab2a 17590 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 17591
91d6fa6a 17592 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 17593 printf (" ");
e0a31db1 17594
978c4450 17595 if (idx >= filedata->num_dynamic_syms)
df97ab2a 17596 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 17597 else
e0a31db1 17598 {
978c4450 17599 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
17600
17601 print_vma (psym->st_value, LONG_HEX);
17602 printf (" %-7s %3s ",
dda8d76d
NC
17603 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17604 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
17605 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17606 print_symbol (sym_width,
17607 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17608 else
17609 printf (_("<corrupt: %14ld>"), psym->st_name);
17610 }
861fb55a
DJ
17611 printf ("\n");
17612 }
17613 printf ("\n");
17614
9db70fc3 17615 free (data);
861fb55a
DJ
17616 free (rels);
17617 }
17618
32ec8896 17619 return res;
252b5132
RH
17620}
17621
32ec8896 17622static bfd_boolean
dda8d76d 17623process_nds32_specific (Filedata * filedata)
35c08157
KLC
17624{
17625 Elf_Internal_Shdr *sect = NULL;
17626
dda8d76d 17627 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 17628 if (sect != NULL && sect->sh_size >= 4)
35c08157 17629 {
9c7b8e9b
AM
17630 unsigned char *buf;
17631 unsigned int flag;
35c08157
KLC
17632
17633 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
17634 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
17635 _("NDS32 elf flags section"));
35c08157 17636
9c7b8e9b 17637 if (buf == NULL)
32ec8896
NC
17638 return FALSE;
17639
9c7b8e9b
AM
17640 flag = byte_get (buf, 4);
17641 free (buf);
17642 switch (flag & 0x3)
35c08157
KLC
17643 {
17644 case 0:
17645 printf ("(VEC_SIZE):\tNo entry.\n");
17646 break;
17647 case 1:
17648 printf ("(VEC_SIZE):\t4 bytes\n");
17649 break;
17650 case 2:
17651 printf ("(VEC_SIZE):\t16 bytes\n");
17652 break;
17653 case 3:
17654 printf ("(VEC_SIZE):\treserved\n");
17655 break;
17656 }
17657 }
17658
17659 return TRUE;
17660}
17661
32ec8896 17662static bfd_boolean
dda8d76d 17663process_gnu_liblist (Filedata * filedata)
047b2264 17664{
2cf0635d
NC
17665 Elf_Internal_Shdr * section;
17666 Elf_Internal_Shdr * string_sec;
17667 Elf32_External_Lib * elib;
17668 char * strtab;
c256ffe7 17669 size_t strtab_size;
047b2264 17670 size_t cnt;
d3a49aa8 17671 unsigned long num_liblist;
047b2264 17672 unsigned i;
32ec8896 17673 bfd_boolean res = TRUE;
047b2264
JJ
17674
17675 if (! do_arch)
32ec8896 17676 return TRUE;
047b2264 17677
dda8d76d
NC
17678 for (i = 0, section = filedata->section_headers;
17679 i < filedata->file_header.e_shnum;
b34976b6 17680 i++, section++)
047b2264
JJ
17681 {
17682 switch (section->sh_type)
17683 {
17684 case SHT_GNU_LIBLIST:
dda8d76d 17685 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
17686 break;
17687
3f5e193b 17688 elib = (Elf32_External_Lib *)
dda8d76d 17689 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 17690 _("liblist section data"));
047b2264
JJ
17691
17692 if (elib == NULL)
32ec8896
NC
17693 {
17694 res = FALSE;
17695 break;
17696 }
047b2264 17697
dda8d76d
NC
17698 string_sec = filedata->section_headers + section->sh_link;
17699 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
17700 string_sec->sh_size,
17701 _("liblist string table"));
047b2264
JJ
17702 if (strtab == NULL
17703 || section->sh_entsize != sizeof (Elf32_External_Lib))
17704 {
17705 free (elib);
2842702f 17706 free (strtab);
32ec8896 17707 res = FALSE;
047b2264
JJ
17708 break;
17709 }
59245841 17710 strtab_size = string_sec->sh_size;
047b2264 17711
d3a49aa8
AM
17712 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
17713 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
17714 "\nLibrary list section '%s' contains %lu entries:\n",
17715 num_liblist),
dda8d76d 17716 printable_section_name (filedata, section),
d3a49aa8 17717 num_liblist);
047b2264 17718
2b692964 17719 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
17720
17721 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
17722 ++cnt)
17723 {
17724 Elf32_Lib liblist;
91d6fa6a 17725 time_t atime;
d5b07ef4 17726 char timebuf[128];
2cf0635d 17727 struct tm * tmp;
047b2264
JJ
17728
17729 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17730 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
17731 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17732 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17733 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17734
91d6fa6a 17735 tmp = gmtime (&atime);
e9e44622
JJ
17736 snprintf (timebuf, sizeof (timebuf),
17737 "%04u-%02u-%02uT%02u:%02u:%02u",
17738 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17739 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
17740
17741 printf ("%3lu: ", (unsigned long) cnt);
17742 if (do_wide)
c256ffe7 17743 printf ("%-20s", liblist.l_name < strtab_size
2b692964 17744 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 17745 else
c256ffe7 17746 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 17747 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
17748 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
17749 liblist.l_version, liblist.l_flags);
17750 }
17751
17752 free (elib);
2842702f 17753 free (strtab);
047b2264
JJ
17754 }
17755 }
17756
32ec8896 17757 return res;
047b2264
JJ
17758}
17759
9437c45b 17760static const char *
dda8d76d 17761get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
17762{
17763 static char buff[64];
103f02d3 17764
dda8d76d 17765 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
17766 switch (e_type)
17767 {
57346661 17768 case NT_AUXV:
1ec5cd37 17769 return _("NT_AUXV (auxiliary vector)");
57346661 17770 case NT_PRSTATUS:
1ec5cd37 17771 return _("NT_PRSTATUS (prstatus structure)");
57346661 17772 case NT_FPREGSET:
1ec5cd37 17773 return _("NT_FPREGSET (floating point registers)");
57346661 17774 case NT_PRPSINFO:
1ec5cd37 17775 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 17776 case NT_TASKSTRUCT:
1ec5cd37 17777 return _("NT_TASKSTRUCT (task structure)");
57346661 17778 case NT_PRXFPREG:
1ec5cd37 17779 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
17780 case NT_PPC_VMX:
17781 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
17782 case NT_PPC_VSX:
17783 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
17784 case NT_PPC_TAR:
17785 return _("NT_PPC_TAR (ppc TAR register)");
17786 case NT_PPC_PPR:
17787 return _("NT_PPC_PPR (ppc PPR register)");
17788 case NT_PPC_DSCR:
17789 return _("NT_PPC_DSCR (ppc DSCR register)");
17790 case NT_PPC_EBB:
17791 return _("NT_PPC_EBB (ppc EBB registers)");
17792 case NT_PPC_PMU:
17793 return _("NT_PPC_PMU (ppc PMU registers)");
17794 case NT_PPC_TM_CGPR:
17795 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
17796 case NT_PPC_TM_CFPR:
17797 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
17798 case NT_PPC_TM_CVMX:
17799 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
17800 case NT_PPC_TM_CVSX:
3fd21718 17801 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
17802 case NT_PPC_TM_SPR:
17803 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
17804 case NT_PPC_TM_CTAR:
17805 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
17806 case NT_PPC_TM_CPPR:
17807 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
17808 case NT_PPC_TM_CDSCR:
17809 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
17810 case NT_386_TLS:
17811 return _("NT_386_TLS (x86 TLS information)");
17812 case NT_386_IOPERM:
17813 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
17814 case NT_X86_XSTATE:
17815 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
17816 case NT_S390_HIGH_GPRS:
17817 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
17818 case NT_S390_TIMER:
17819 return _("NT_S390_TIMER (s390 timer register)");
17820 case NT_S390_TODCMP:
17821 return _("NT_S390_TODCMP (s390 TOD comparator register)");
17822 case NT_S390_TODPREG:
17823 return _("NT_S390_TODPREG (s390 TOD programmable register)");
17824 case NT_S390_CTRS:
17825 return _("NT_S390_CTRS (s390 control registers)");
17826 case NT_S390_PREFIX:
17827 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
17828 case NT_S390_LAST_BREAK:
17829 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
17830 case NT_S390_SYSTEM_CALL:
17831 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
17832 case NT_S390_TDB:
17833 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
17834 case NT_S390_VXRS_LOW:
17835 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
17836 case NT_S390_VXRS_HIGH:
17837 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
17838 case NT_S390_GS_CB:
17839 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
17840 case NT_S390_GS_BC:
17841 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
17842 case NT_ARM_VFP:
17843 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
17844 case NT_ARM_TLS:
17845 return _("NT_ARM_TLS (AArch TLS registers)");
17846 case NT_ARM_HW_BREAK:
17847 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
17848 case NT_ARM_HW_WATCH:
17849 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
17850 case NT_ARC_V2:
17851 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
57346661 17852 case NT_PSTATUS:
1ec5cd37 17853 return _("NT_PSTATUS (pstatus structure)");
57346661 17854 case NT_FPREGS:
1ec5cd37 17855 return _("NT_FPREGS (floating point registers)");
57346661 17856 case NT_PSINFO:
1ec5cd37 17857 return _("NT_PSINFO (psinfo structure)");
57346661 17858 case NT_LWPSTATUS:
1ec5cd37 17859 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 17860 case NT_LWPSINFO:
1ec5cd37 17861 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 17862 case NT_WIN32PSTATUS:
1ec5cd37 17863 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
17864 case NT_SIGINFO:
17865 return _("NT_SIGINFO (siginfo_t data)");
17866 case NT_FILE:
17867 return _("NT_FILE (mapped files)");
1ec5cd37
NC
17868 default:
17869 break;
17870 }
17871 else
17872 switch (e_type)
17873 {
17874 case NT_VERSION:
17875 return _("NT_VERSION (version)");
17876 case NT_ARCH:
17877 return _("NT_ARCH (architecture)");
9ef920e9 17878 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 17879 return _("OPEN");
9ef920e9 17880 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 17881 return _("func");
1ec5cd37
NC
17882 default:
17883 break;
17884 }
17885
e9e44622 17886 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 17887 return buff;
779fe533
NC
17888}
17889
32ec8896 17890static bfd_boolean
9ece1fa9
TT
17891print_core_note (Elf_Internal_Note *pnote)
17892{
17893 unsigned int addr_size = is_32bit_elf ? 4 : 8;
17894 bfd_vma count, page_size;
17895 unsigned char *descdata, *filenames, *descend;
17896
17897 if (pnote->type != NT_FILE)
04ac15ab
AS
17898 {
17899 if (do_wide)
17900 printf ("\n");
17901 return TRUE;
17902 }
9ece1fa9
TT
17903
17904#ifndef BFD64
17905 if (!is_32bit_elf)
17906 {
17907 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
17908 /* Still "successful". */
32ec8896 17909 return TRUE;
9ece1fa9
TT
17910 }
17911#endif
17912
17913 if (pnote->descsz < 2 * addr_size)
17914 {
32ec8896
NC
17915 error (_(" Malformed note - too short for header\n"));
17916 return FALSE;
9ece1fa9
TT
17917 }
17918
17919 descdata = (unsigned char *) pnote->descdata;
17920 descend = descdata + pnote->descsz;
17921
17922 if (descdata[pnote->descsz - 1] != '\0')
17923 {
32ec8896
NC
17924 error (_(" Malformed note - does not end with \\0\n"));
17925 return FALSE;
9ece1fa9
TT
17926 }
17927
17928 count = byte_get (descdata, addr_size);
17929 descdata += addr_size;
17930
17931 page_size = byte_get (descdata, addr_size);
17932 descdata += addr_size;
17933
5396a86e
AM
17934 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
17935 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 17936 {
32ec8896
NC
17937 error (_(" Malformed note - too short for supplied file count\n"));
17938 return FALSE;
9ece1fa9
TT
17939 }
17940
17941 printf (_(" Page size: "));
17942 print_vma (page_size, DEC);
17943 printf ("\n");
17944
17945 printf (_(" %*s%*s%*s\n"),
17946 (int) (2 + 2 * addr_size), _("Start"),
17947 (int) (4 + 2 * addr_size), _("End"),
17948 (int) (4 + 2 * addr_size), _("Page Offset"));
17949 filenames = descdata + count * 3 * addr_size;
595712bb 17950 while (count-- > 0)
9ece1fa9
TT
17951 {
17952 bfd_vma start, end, file_ofs;
17953
17954 if (filenames == descend)
17955 {
32ec8896
NC
17956 error (_(" Malformed note - filenames end too early\n"));
17957 return FALSE;
9ece1fa9
TT
17958 }
17959
17960 start = byte_get (descdata, addr_size);
17961 descdata += addr_size;
17962 end = byte_get (descdata, addr_size);
17963 descdata += addr_size;
17964 file_ofs = byte_get (descdata, addr_size);
17965 descdata += addr_size;
17966
17967 printf (" ");
17968 print_vma (start, FULL_HEX);
17969 printf (" ");
17970 print_vma (end, FULL_HEX);
17971 printf (" ");
17972 print_vma (file_ofs, FULL_HEX);
17973 printf ("\n %s\n", filenames);
17974
17975 filenames += 1 + strlen ((char *) filenames);
17976 }
17977
32ec8896 17978 return TRUE;
9ece1fa9
TT
17979}
17980
1118d252
RM
17981static const char *
17982get_gnu_elf_note_type (unsigned e_type)
17983{
1449284b 17984 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
17985 switch (e_type)
17986 {
17987 case NT_GNU_ABI_TAG:
17988 return _("NT_GNU_ABI_TAG (ABI version tag)");
17989 case NT_GNU_HWCAP:
17990 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
17991 case NT_GNU_BUILD_ID:
17992 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
17993 case NT_GNU_GOLD_VERSION:
17994 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
17995 case NT_GNU_PROPERTY_TYPE_0:
17996 return _("NT_GNU_PROPERTY_TYPE_0");
17997 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
17998 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
17999 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18000 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18001 default:
1449284b
NC
18002 {
18003 static char buff[64];
1118d252 18004
1449284b
NC
18005 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18006 return buff;
18007 }
18008 }
1118d252
RM
18009}
18010
a9eafb08
L
18011static void
18012decode_x86_compat_isa (unsigned int bitmask)
18013{
18014 while (bitmask)
18015 {
18016 unsigned int bit = bitmask & (- bitmask);
18017
18018 bitmask &= ~ bit;
18019 switch (bit)
18020 {
18021 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18022 printf ("i486");
18023 break;
18024 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18025 printf ("586");
18026 break;
18027 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18028 printf ("686");
18029 break;
18030 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18031 printf ("SSE");
18032 break;
18033 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18034 printf ("SSE2");
18035 break;
18036 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18037 printf ("SSE3");
18038 break;
18039 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18040 printf ("SSSE3");
18041 break;
18042 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18043 printf ("SSE4_1");
18044 break;
18045 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18046 printf ("SSE4_2");
18047 break;
18048 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18049 printf ("AVX");
18050 break;
18051 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18052 printf ("AVX2");
18053 break;
18054 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18055 printf ("AVX512F");
18056 break;
18057 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18058 printf ("AVX512CD");
18059 break;
18060 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18061 printf ("AVX512ER");
18062 break;
18063 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18064 printf ("AVX512PF");
18065 break;
18066 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18067 printf ("AVX512VL");
18068 break;
18069 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18070 printf ("AVX512DQ");
18071 break;
18072 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18073 printf ("AVX512BW");
18074 break;
65b3d26e
L
18075 default:
18076 printf (_("<unknown: %x>"), bit);
18077 break;
a9eafb08
L
18078 }
18079 if (bitmask)
18080 printf (", ");
18081 }
18082}
18083
9ef920e9 18084static void
1fc87489 18085decode_x86_isa (unsigned int bitmask)
9ef920e9 18086{
0a59decb 18087 if (!bitmask)
90c745dc
L
18088 {
18089 printf (_("<None>"));
18090 return;
18091 }
90c745dc 18092
9ef920e9
NC
18093 while (bitmask)
18094 {
1fc87489 18095 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18096
18097 bitmask &= ~ bit;
18098 switch (bit)
18099 {
a9eafb08
L
18100 case GNU_PROPERTY_X86_ISA_1_CMOV:
18101 printf ("CMOV");
18102 break;
18103 case GNU_PROPERTY_X86_ISA_1_SSE:
18104 printf ("SSE");
18105 break;
18106 case GNU_PROPERTY_X86_ISA_1_SSE2:
18107 printf ("SSE2");
18108 break;
18109 case GNU_PROPERTY_X86_ISA_1_SSE3:
18110 printf ("SSE3");
18111 break;
18112 case GNU_PROPERTY_X86_ISA_1_SSSE3:
18113 printf ("SSSE3");
18114 break;
18115 case GNU_PROPERTY_X86_ISA_1_SSE4_1:
18116 printf ("SSE4_1");
18117 break;
18118 case GNU_PROPERTY_X86_ISA_1_SSE4_2:
18119 printf ("SSE4_2");
18120 break;
18121 case GNU_PROPERTY_X86_ISA_1_AVX:
18122 printf ("AVX");
18123 break;
18124 case GNU_PROPERTY_X86_ISA_1_AVX2:
18125 printf ("AVX2");
18126 break;
18127 case GNU_PROPERTY_X86_ISA_1_FMA:
18128 printf ("FMA");
18129 break;
18130 case GNU_PROPERTY_X86_ISA_1_AVX512F:
18131 printf ("AVX512F");
18132 break;
18133 case GNU_PROPERTY_X86_ISA_1_AVX512CD:
18134 printf ("AVX512CD");
18135 break;
18136 case GNU_PROPERTY_X86_ISA_1_AVX512ER:
18137 printf ("AVX512ER");
18138 break;
18139 case GNU_PROPERTY_X86_ISA_1_AVX512PF:
18140 printf ("AVX512PF");
18141 break;
18142 case GNU_PROPERTY_X86_ISA_1_AVX512VL:
18143 printf ("AVX512VL");
18144 break;
18145 case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
18146 printf ("AVX512DQ");
18147 break;
18148 case GNU_PROPERTY_X86_ISA_1_AVX512BW:
18149 printf ("AVX512BW");
18150 break;
18151 case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
18152 printf ("AVX512_4FMAPS");
18153 break;
18154 case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
18155 printf ("AVX512_4VNNIW");
18156 break;
18157 case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
18158 printf ("AVX512_BITALG");
18159 break;
18160 case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
18161 printf ("AVX512_IFMA");
18162 break;
18163 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
18164 printf ("AVX512_VBMI");
18165 break;
18166 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
18167 printf ("AVX512_VBMI2");
18168 break;
18169 case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
18170 printf ("AVX512_VNNI");
18171 break;
462cac58
L
18172 case GNU_PROPERTY_X86_ISA_1_AVX512_BF16:
18173 printf ("AVX512_BF16");
18174 break;
65b3d26e
L
18175 default:
18176 printf (_("<unknown: %x>"), bit);
18177 break;
9ef920e9
NC
18178 }
18179 if (bitmask)
18180 printf (", ");
18181 }
18182}
18183
ee2fdd6f 18184static void
a9eafb08 18185decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 18186{
0a59decb 18187 if (!bitmask)
90c745dc
L
18188 {
18189 printf (_("<None>"));
18190 return;
18191 }
90c745dc 18192
ee2fdd6f
L
18193 while (bitmask)
18194 {
18195 unsigned int bit = bitmask & (- bitmask);
18196
18197 bitmask &= ~ bit;
18198 switch (bit)
18199 {
18200 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 18201 printf ("IBT");
ee2fdd6f 18202 break;
48580982 18203 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 18204 printf ("SHSTK");
48580982 18205 break;
ee2fdd6f
L
18206 default:
18207 printf (_("<unknown: %x>"), bit);
18208 break;
18209 }
18210 if (bitmask)
18211 printf (", ");
18212 }
18213}
18214
a9eafb08
L
18215static void
18216decode_x86_feature_2 (unsigned int bitmask)
18217{
0a59decb 18218 if (!bitmask)
90c745dc
L
18219 {
18220 printf (_("<None>"));
18221 return;
18222 }
90c745dc 18223
a9eafb08
L
18224 while (bitmask)
18225 {
18226 unsigned int bit = bitmask & (- bitmask);
18227
18228 bitmask &= ~ bit;
18229 switch (bit)
18230 {
18231 case GNU_PROPERTY_X86_FEATURE_2_X86:
18232 printf ("x86");
18233 break;
18234 case GNU_PROPERTY_X86_FEATURE_2_X87:
18235 printf ("x87");
18236 break;
18237 case GNU_PROPERTY_X86_FEATURE_2_MMX:
18238 printf ("MMX");
18239 break;
18240 case GNU_PROPERTY_X86_FEATURE_2_XMM:
18241 printf ("XMM");
18242 break;
18243 case GNU_PROPERTY_X86_FEATURE_2_YMM:
18244 printf ("YMM");
18245 break;
18246 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
18247 printf ("ZMM");
18248 break;
a308b89d
L
18249 case GNU_PROPERTY_X86_FEATURE_2_TMM:
18250 printf ("TMM");
18251 break;
a9eafb08
L
18252 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
18253 printf ("FXSR");
18254 break;
18255 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
18256 printf ("XSAVE");
18257 break;
18258 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
18259 printf ("XSAVEOPT");
18260 break;
18261 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
18262 printf ("XSAVEC");
18263 break;
65b3d26e
L
18264 default:
18265 printf (_("<unknown: %x>"), bit);
18266 break;
a9eafb08
L
18267 }
18268 if (bitmask)
18269 printf (", ");
18270 }
18271}
18272
cd702818
SD
18273static void
18274decode_aarch64_feature_1_and (unsigned int bitmask)
18275{
18276 while (bitmask)
18277 {
18278 unsigned int bit = bitmask & (- bitmask);
18279
18280 bitmask &= ~ bit;
18281 switch (bit)
18282 {
18283 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
18284 printf ("BTI");
18285 break;
18286
18287 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
18288 printf ("PAC");
18289 break;
18290
18291 default:
18292 printf (_("<unknown: %x>"), bit);
18293 break;
18294 }
18295 if (bitmask)
18296 printf (", ");
18297 }
18298}
18299
9ef920e9 18300static void
dda8d76d 18301print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
18302{
18303 unsigned char * ptr = (unsigned char *) pnote->descdata;
18304 unsigned char * ptr_end = ptr + pnote->descsz;
18305 unsigned int size = is_32bit_elf ? 4 : 8;
18306
18307 printf (_(" Properties: "));
18308
1fc87489 18309 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
18310 {
18311 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
18312 return;
18313 }
18314
6ab2c4ed 18315 while (ptr < ptr_end)
9ef920e9 18316 {
1fc87489 18317 unsigned int j;
6ab2c4ed
MC
18318 unsigned int type;
18319 unsigned int datasz;
18320
18321 if ((size_t) (ptr_end - ptr) < 8)
18322 {
18323 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
18324 break;
18325 }
18326
18327 type = byte_get (ptr, 4);
18328 datasz = byte_get (ptr + 4, 4);
9ef920e9 18329
1fc87489 18330 ptr += 8;
9ef920e9 18331
6ab2c4ed 18332 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 18333 {
1fc87489
L
18334 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
18335 type, datasz);
9ef920e9 18336 break;
1fc87489 18337 }
9ef920e9 18338
1fc87489
L
18339 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
18340 {
dda8d76d
NC
18341 if (filedata->file_header.e_machine == EM_X86_64
18342 || filedata->file_header.e_machine == EM_IAMCU
18343 || filedata->file_header.e_machine == EM_386)
1fc87489 18344 {
aa7bca9b
L
18345 unsigned int bitmask;
18346
18347 if (datasz == 4)
0a59decb 18348 bitmask = byte_get (ptr, 4);
aa7bca9b
L
18349 else
18350 bitmask = 0;
18351
1fc87489
L
18352 switch (type)
18353 {
18354 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 18355 if (datasz != 4)
aa7bca9b
L
18356 printf (_("x86 ISA used: <corrupt length: %#x> "),
18357 datasz);
1fc87489 18358 else
aa7bca9b
L
18359 {
18360 printf ("x86 ISA used: ");
18361 decode_x86_isa (bitmask);
18362 }
1fc87489 18363 goto next;
9ef920e9 18364
1fc87489 18365 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 18366 if (datasz != 4)
aa7bca9b
L
18367 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18368 datasz);
1fc87489 18369 else
aa7bca9b
L
18370 {
18371 printf ("x86 ISA needed: ");
18372 decode_x86_isa (bitmask);
18373 }
1fc87489 18374 goto next;
9ef920e9 18375
ee2fdd6f 18376 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 18377 if (datasz != 4)
aa7bca9b
L
18378 printf (_("x86 feature: <corrupt length: %#x> "),
18379 datasz);
ee2fdd6f 18380 else
aa7bca9b
L
18381 {
18382 printf ("x86 feature: ");
a9eafb08
L
18383 decode_x86_feature_1 (bitmask);
18384 }
18385 goto next;
18386
18387 case GNU_PROPERTY_X86_FEATURE_2_USED:
18388 if (datasz != 4)
18389 printf (_("x86 feature used: <corrupt length: %#x> "),
18390 datasz);
18391 else
18392 {
18393 printf ("x86 feature used: ");
18394 decode_x86_feature_2 (bitmask);
18395 }
18396 goto next;
18397
18398 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
18399 if (datasz != 4)
18400 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
18401 else
18402 {
18403 printf ("x86 feature needed: ");
18404 decode_x86_feature_2 (bitmask);
18405 }
18406 goto next;
18407
18408 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
18409 if (datasz != 4)
18410 printf (_("x86 ISA used: <corrupt length: %#x> "),
18411 datasz);
18412 else
18413 {
18414 printf ("x86 ISA used: ");
18415 decode_x86_compat_isa (bitmask);
18416 }
18417 goto next;
18418
18419 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
18420 if (datasz != 4)
18421 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18422 datasz);
18423 else
18424 {
18425 printf ("x86 ISA needed: ");
18426 decode_x86_compat_isa (bitmask);
aa7bca9b 18427 }
ee2fdd6f
L
18428 goto next;
18429
1fc87489
L
18430 default:
18431 break;
18432 }
18433 }
cd702818
SD
18434 else if (filedata->file_header.e_machine == EM_AARCH64)
18435 {
18436 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
18437 {
18438 printf ("AArch64 feature: ");
18439 if (datasz != 4)
18440 printf (_("<corrupt length: %#x> "), datasz);
18441 else
18442 decode_aarch64_feature_1_and (byte_get (ptr, 4));
18443 goto next;
18444 }
18445 }
1fc87489
L
18446 }
18447 else
18448 {
18449 switch (type)
9ef920e9 18450 {
1fc87489
L
18451 case GNU_PROPERTY_STACK_SIZE:
18452 printf (_("stack size: "));
18453 if (datasz != size)
18454 printf (_("<corrupt length: %#x> "), datasz);
18455 else
18456 printf ("%#lx", (unsigned long) byte_get (ptr, size));
18457 goto next;
18458
18459 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
18460 printf ("no copy on protected ");
18461 if (datasz)
18462 printf (_("<corrupt length: %#x> "), datasz);
18463 goto next;
18464
18465 default:
9ef920e9
NC
18466 break;
18467 }
9ef920e9
NC
18468 }
18469
1fc87489
L
18470 if (type < GNU_PROPERTY_LOPROC)
18471 printf (_("<unknown type %#x data: "), type);
18472 else if (type < GNU_PROPERTY_LOUSER)
18473 printf (_("<procesor-specific type %#x data: "), type);
18474 else
18475 printf (_("<application-specific type %#x data: "), type);
18476 for (j = 0; j < datasz; ++j)
18477 printf ("%02x ", ptr[j] & 0xff);
18478 printf (">");
18479
dc1e8a47 18480 next:
9ef920e9 18481 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
18482 if (ptr == ptr_end)
18483 break;
1fc87489 18484
6ab2c4ed
MC
18485 if (do_wide)
18486 printf (", ");
18487 else
18488 printf ("\n\t");
9ef920e9
NC
18489 }
18490
18491 printf ("\n");
18492}
18493
32ec8896 18494static bfd_boolean
dda8d76d 18495print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 18496{
1449284b 18497 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
18498 switch (pnote->type)
18499 {
18500 case NT_GNU_BUILD_ID:
18501 {
18502 unsigned long i;
18503
18504 printf (_(" Build ID: "));
18505 for (i = 0; i < pnote->descsz; ++i)
18506 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 18507 printf ("\n");
664f90a3
TT
18508 }
18509 break;
18510
18511 case NT_GNU_ABI_TAG:
18512 {
18513 unsigned long os, major, minor, subminor;
18514 const char *osname;
18515
3102e897
NC
18516 /* PR 17531: file: 030-599401-0.004. */
18517 if (pnote->descsz < 16)
18518 {
18519 printf (_(" <corrupt GNU_ABI_TAG>\n"));
18520 break;
18521 }
18522
664f90a3
TT
18523 os = byte_get ((unsigned char *) pnote->descdata, 4);
18524 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18525 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
18526 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
18527
18528 switch (os)
18529 {
18530 case GNU_ABI_TAG_LINUX:
18531 osname = "Linux";
18532 break;
18533 case GNU_ABI_TAG_HURD:
18534 osname = "Hurd";
18535 break;
18536 case GNU_ABI_TAG_SOLARIS:
18537 osname = "Solaris";
18538 break;
18539 case GNU_ABI_TAG_FREEBSD:
18540 osname = "FreeBSD";
18541 break;
18542 case GNU_ABI_TAG_NETBSD:
18543 osname = "NetBSD";
18544 break;
14ae95f2
RM
18545 case GNU_ABI_TAG_SYLLABLE:
18546 osname = "Syllable";
18547 break;
18548 case GNU_ABI_TAG_NACL:
18549 osname = "NaCl";
18550 break;
664f90a3
TT
18551 default:
18552 osname = "Unknown";
18553 break;
18554 }
18555
18556 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
18557 major, minor, subminor);
18558 }
18559 break;
926c5385
CC
18560
18561 case NT_GNU_GOLD_VERSION:
18562 {
18563 unsigned long i;
18564
18565 printf (_(" Version: "));
18566 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
18567 printf ("%c", pnote->descdata[i]);
18568 printf ("\n");
18569 }
18570 break;
1449284b
NC
18571
18572 case NT_GNU_HWCAP:
18573 {
18574 unsigned long num_entries, mask;
18575
18576 /* Hardware capabilities information. Word 0 is the number of entries.
18577 Word 1 is a bitmask of enabled entries. The rest of the descriptor
18578 is a series of entries, where each entry is a single byte followed
18579 by a nul terminated string. The byte gives the bit number to test
18580 if enabled in the bitmask. */
18581 printf (_(" Hardware Capabilities: "));
18582 if (pnote->descsz < 8)
18583 {
32ec8896
NC
18584 error (_("<corrupt GNU_HWCAP>\n"));
18585 return FALSE;
1449284b
NC
18586 }
18587 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
18588 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18589 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
18590 /* FIXME: Add code to display the entries... */
18591 }
18592 break;
18593
9ef920e9 18594 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 18595 print_gnu_property_note (filedata, pnote);
9ef920e9 18596 break;
9abca702 18597
1449284b
NC
18598 default:
18599 /* Handle unrecognised types. An error message should have already been
18600 created by get_gnu_elf_note_type(), so all that we need to do is to
18601 display the data. */
18602 {
18603 unsigned long i;
18604
18605 printf (_(" Description data: "));
18606 for (i = 0; i < pnote->descsz; ++i)
18607 printf ("%02x ", pnote->descdata[i] & 0xff);
18608 printf ("\n");
18609 }
18610 break;
664f90a3
TT
18611 }
18612
32ec8896 18613 return TRUE;
664f90a3
TT
18614}
18615
685080f2
NC
18616static const char *
18617get_v850_elf_note_type (enum v850_notes n_type)
18618{
18619 static char buff[64];
18620
18621 switch (n_type)
18622 {
18623 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
18624 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
18625 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
18626 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
18627 case V850_NOTE_CACHE_INFO: return _("Use of cache");
18628 case V850_NOTE_MMU_INFO: return _("Use of MMU");
18629 default:
18630 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
18631 return buff;
18632 }
18633}
18634
32ec8896 18635static bfd_boolean
685080f2
NC
18636print_v850_note (Elf_Internal_Note * pnote)
18637{
18638 unsigned int val;
18639
18640 if (pnote->descsz != 4)
32ec8896
NC
18641 return FALSE;
18642
685080f2
NC
18643 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
18644
18645 if (val == 0)
18646 {
18647 printf (_("not set\n"));
32ec8896 18648 return TRUE;
685080f2
NC
18649 }
18650
18651 switch (pnote->type)
18652 {
18653 case V850_NOTE_ALIGNMENT:
18654 switch (val)
18655 {
32ec8896
NC
18656 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
18657 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
18658 }
18659 break;
14ae95f2 18660
685080f2
NC
18661 case V850_NOTE_DATA_SIZE:
18662 switch (val)
18663 {
32ec8896
NC
18664 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
18665 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
18666 }
18667 break;
14ae95f2 18668
685080f2
NC
18669 case V850_NOTE_FPU_INFO:
18670 switch (val)
18671 {
32ec8896
NC
18672 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
18673 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
18674 }
18675 break;
14ae95f2 18676
685080f2
NC
18677 case V850_NOTE_MMU_INFO:
18678 case V850_NOTE_CACHE_INFO:
18679 case V850_NOTE_SIMD_INFO:
18680 if (val == EF_RH850_SIMD)
18681 {
18682 printf (_("yes\n"));
32ec8896 18683 return TRUE;
685080f2
NC
18684 }
18685 break;
18686
18687 default:
18688 /* An 'unknown note type' message will already have been displayed. */
18689 break;
18690 }
18691
18692 printf (_("unknown value: %x\n"), val);
32ec8896 18693 return FALSE;
685080f2
NC
18694}
18695
32ec8896 18696static bfd_boolean
c6056a74
SF
18697process_netbsd_elf_note (Elf_Internal_Note * pnote)
18698{
18699 unsigned int version;
18700
18701 switch (pnote->type)
18702 {
18703 case NT_NETBSD_IDENT:
b966f55f
AM
18704 if (pnote->descsz < 1)
18705 break;
c6056a74
SF
18706 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18707 if ((version / 10000) % 100)
b966f55f 18708 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
18709 version, version / 100000000, (version / 1000000) % 100,
18710 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 18711 'A' + (version / 10000) % 26);
c6056a74
SF
18712 else
18713 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 18714 version, version / 100000000, (version / 1000000) % 100,
15f205b1 18715 (version / 100) % 100);
32ec8896 18716 return TRUE;
c6056a74
SF
18717
18718 case NT_NETBSD_MARCH:
9abca702 18719 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 18720 pnote->descdata);
32ec8896 18721 return TRUE;
c6056a74 18722
9abca702
CZ
18723#ifdef NT_NETBSD_PAX
18724 case NT_NETBSD_PAX:
b966f55f
AM
18725 if (pnote->descsz < 1)
18726 break;
9abca702
CZ
18727 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18728 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
18729 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
18730 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
18731 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
18732 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
18733 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
18734 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
18735 return TRUE;
18736#endif
c6056a74 18737 }
b966f55f
AM
18738
18739 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
18740 pnote->descsz, pnote->type);
18741 return FALSE;
c6056a74
SF
18742}
18743
f4ddf30f 18744static const char *
dda8d76d 18745get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 18746{
f4ddf30f
JB
18747 switch (e_type)
18748 {
18749 case NT_FREEBSD_THRMISC:
18750 return _("NT_THRMISC (thrmisc structure)");
18751 case NT_FREEBSD_PROCSTAT_PROC:
18752 return _("NT_PROCSTAT_PROC (proc data)");
18753 case NT_FREEBSD_PROCSTAT_FILES:
18754 return _("NT_PROCSTAT_FILES (files data)");
18755 case NT_FREEBSD_PROCSTAT_VMMAP:
18756 return _("NT_PROCSTAT_VMMAP (vmmap data)");
18757 case NT_FREEBSD_PROCSTAT_GROUPS:
18758 return _("NT_PROCSTAT_GROUPS (groups data)");
18759 case NT_FREEBSD_PROCSTAT_UMASK:
18760 return _("NT_PROCSTAT_UMASK (umask data)");
18761 case NT_FREEBSD_PROCSTAT_RLIMIT:
18762 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
18763 case NT_FREEBSD_PROCSTAT_OSREL:
18764 return _("NT_PROCSTAT_OSREL (osreldate data)");
18765 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
18766 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
18767 case NT_FREEBSD_PROCSTAT_AUXV:
18768 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
18769 case NT_FREEBSD_PTLWPINFO:
18770 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 18771 }
dda8d76d 18772 return get_note_type (filedata, e_type);
f4ddf30f
JB
18773}
18774
9437c45b 18775static const char *
dda8d76d 18776get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
18777{
18778 static char buff[64];
18779
540e6170
CZ
18780 switch (e_type)
18781 {
18782 case NT_NETBSDCORE_PROCINFO:
18783 /* NetBSD core "procinfo" structure. */
18784 return _("NetBSD procinfo structure");
9437c45b 18785
540e6170
CZ
18786#ifdef NT_NETBSDCORE_AUXV
18787 case NT_NETBSDCORE_AUXV:
18788 return _("NetBSD ELF auxiliary vector data");
18789#endif
9437c45b 18790
06d949ec
KR
18791#ifdef NT_NETBSDCORE_LWPSTATUS
18792 case NT_NETBSDCORE_LWPSTATUS:
18793 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
18794#endif
18795
540e6170 18796 default:
06d949ec 18797 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
18798 defined for NetBSD core files. If the note type is less
18799 than the start of the machine-dependent note types, we don't
18800 understand it. */
18801
18802 if (e_type < NT_NETBSDCORE_FIRSTMACH)
18803 {
18804 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18805 return buff;
18806 }
18807 break;
9437c45b
JT
18808 }
18809
dda8d76d 18810 switch (filedata->file_header.e_machine)
9437c45b
JT
18811 {
18812 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
18813 and PT_GETFPREGS == mach+2. */
18814
18815 case EM_OLD_ALPHA:
18816 case EM_ALPHA:
18817 case EM_SPARC:
18818 case EM_SPARC32PLUS:
18819 case EM_SPARCV9:
18820 switch (e_type)
18821 {
2b692964 18822 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 18823 return _("PT_GETREGS (reg structure)");
2b692964 18824 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 18825 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18826 default:
18827 break;
18828 }
18829 break;
18830
c0d38b0e
CZ
18831 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
18832 There's also old PT___GETREGS40 == mach + 1 for old reg
18833 structure which lacks GBR. */
18834 case EM_SH:
18835 switch (e_type)
18836 {
18837 case NT_NETBSDCORE_FIRSTMACH + 1:
18838 return _("PT___GETREGS40 (old reg structure)");
18839 case NT_NETBSDCORE_FIRSTMACH + 3:
18840 return _("PT_GETREGS (reg structure)");
18841 case NT_NETBSDCORE_FIRSTMACH + 5:
18842 return _("PT_GETFPREGS (fpreg structure)");
18843 default:
18844 break;
18845 }
18846 break;
18847
9437c45b
JT
18848 /* On all other arch's, PT_GETREGS == mach+1 and
18849 PT_GETFPREGS == mach+3. */
18850 default:
18851 switch (e_type)
18852 {
2b692964 18853 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 18854 return _("PT_GETREGS (reg structure)");
2b692964 18855 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 18856 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18857 default:
18858 break;
18859 }
18860 }
18861
9cf03b7e 18862 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 18863 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
18864 return buff;
18865}
18866
70616151
TT
18867static const char *
18868get_stapsdt_note_type (unsigned e_type)
18869{
18870 static char buff[64];
18871
18872 switch (e_type)
18873 {
18874 case NT_STAPSDT:
18875 return _("NT_STAPSDT (SystemTap probe descriptors)");
18876
18877 default:
18878 break;
18879 }
18880
18881 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18882 return buff;
18883}
18884
32ec8896 18885static bfd_boolean
c6a9fc58
TT
18886print_stapsdt_note (Elf_Internal_Note *pnote)
18887{
3ca60c57
NC
18888 size_t len, maxlen;
18889 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
18890 char *data = pnote->descdata;
18891 char *data_end = pnote->descdata + pnote->descsz;
18892 bfd_vma pc, base_addr, semaphore;
18893 char *provider, *probe, *arg_fmt;
18894
3ca60c57
NC
18895 if (pnote->descsz < (addr_size * 3))
18896 goto stapdt_note_too_small;
18897
c6a9fc58
TT
18898 pc = byte_get ((unsigned char *) data, addr_size);
18899 data += addr_size;
3ca60c57 18900
c6a9fc58
TT
18901 base_addr = byte_get ((unsigned char *) data, addr_size);
18902 data += addr_size;
3ca60c57 18903
c6a9fc58
TT
18904 semaphore = byte_get ((unsigned char *) data, addr_size);
18905 data += addr_size;
18906
3ca60c57
NC
18907 if (data >= data_end)
18908 goto stapdt_note_too_small;
18909 maxlen = data_end - data;
18910 len = strnlen (data, maxlen);
18911 if (len < maxlen)
18912 {
18913 provider = data;
18914 data += len + 1;
18915 }
18916 else
18917 goto stapdt_note_too_small;
18918
18919 if (data >= data_end)
18920 goto stapdt_note_too_small;
18921 maxlen = data_end - data;
18922 len = strnlen (data, maxlen);
18923 if (len < maxlen)
18924 {
18925 probe = data;
18926 data += len + 1;
18927 }
18928 else
18929 goto stapdt_note_too_small;
9abca702 18930
3ca60c57
NC
18931 if (data >= data_end)
18932 goto stapdt_note_too_small;
18933 maxlen = data_end - data;
18934 len = strnlen (data, maxlen);
18935 if (len < maxlen)
18936 {
18937 arg_fmt = data;
18938 data += len + 1;
18939 }
18940 else
18941 goto stapdt_note_too_small;
c6a9fc58
TT
18942
18943 printf (_(" Provider: %s\n"), provider);
18944 printf (_(" Name: %s\n"), probe);
18945 printf (_(" Location: "));
18946 print_vma (pc, FULL_HEX);
18947 printf (_(", Base: "));
18948 print_vma (base_addr, FULL_HEX);
18949 printf (_(", Semaphore: "));
18950 print_vma (semaphore, FULL_HEX);
9cf03b7e 18951 printf ("\n");
c6a9fc58
TT
18952 printf (_(" Arguments: %s\n"), arg_fmt);
18953
18954 return data == data_end;
3ca60c57
NC
18955
18956 stapdt_note_too_small:
18957 printf (_(" <corrupt - note is too small>\n"));
18958 error (_("corrupt stapdt note - the data size is too small\n"));
18959 return FALSE;
c6a9fc58
TT
18960}
18961
00e98fc7
TG
18962static const char *
18963get_ia64_vms_note_type (unsigned e_type)
18964{
18965 static char buff[64];
18966
18967 switch (e_type)
18968 {
18969 case NT_VMS_MHD:
18970 return _("NT_VMS_MHD (module header)");
18971 case NT_VMS_LNM:
18972 return _("NT_VMS_LNM (language name)");
18973 case NT_VMS_SRC:
18974 return _("NT_VMS_SRC (source files)");
18975 case NT_VMS_TITLE:
9cf03b7e 18976 return "NT_VMS_TITLE";
00e98fc7
TG
18977 case NT_VMS_EIDC:
18978 return _("NT_VMS_EIDC (consistency check)");
18979 case NT_VMS_FPMODE:
18980 return _("NT_VMS_FPMODE (FP mode)");
18981 case NT_VMS_LINKTIME:
9cf03b7e 18982 return "NT_VMS_LINKTIME";
00e98fc7
TG
18983 case NT_VMS_IMGNAM:
18984 return _("NT_VMS_IMGNAM (image name)");
18985 case NT_VMS_IMGID:
18986 return _("NT_VMS_IMGID (image id)");
18987 case NT_VMS_LINKID:
18988 return _("NT_VMS_LINKID (link id)");
18989 case NT_VMS_IMGBID:
18990 return _("NT_VMS_IMGBID (build id)");
18991 case NT_VMS_GSTNAM:
18992 return _("NT_VMS_GSTNAM (sym table name)");
18993 case NT_VMS_ORIG_DYN:
9cf03b7e 18994 return "NT_VMS_ORIG_DYN";
00e98fc7 18995 case NT_VMS_PATCHTIME:
9cf03b7e 18996 return "NT_VMS_PATCHTIME";
00e98fc7
TG
18997 default:
18998 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18999 return buff;
19000 }
19001}
19002
32ec8896 19003static bfd_boolean
00e98fc7
TG
19004print_ia64_vms_note (Elf_Internal_Note * pnote)
19005{
8d18bf79
NC
19006 int maxlen = pnote->descsz;
19007
19008 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19009 goto desc_size_fail;
19010
00e98fc7
TG
19011 switch (pnote->type)
19012 {
19013 case NT_VMS_MHD:
8d18bf79
NC
19014 if (maxlen <= 36)
19015 goto desc_size_fail;
19016
19017 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19018
19019 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19020 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19021 if (l + 34 < maxlen)
19022 {
19023 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19024 if (l + 35 < maxlen)
19025 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19026 else
19027 printf (_(" Module version : <missing>\n"));
19028 }
00e98fc7 19029 else
8d18bf79
NC
19030 {
19031 printf (_(" Module name : <missing>\n"));
19032 printf (_(" Module version : <missing>\n"));
19033 }
00e98fc7 19034 break;
8d18bf79 19035
00e98fc7 19036 case NT_VMS_LNM:
8d18bf79 19037 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19038 break;
8d18bf79 19039
00e98fc7
TG
19040#ifdef BFD64
19041 case NT_VMS_FPMODE:
9cf03b7e 19042 printf (_(" Floating Point mode: "));
8d18bf79
NC
19043 if (maxlen < 8)
19044 goto desc_size_fail;
19045 /* FIXME: Generate an error if descsz > 8 ? */
19046
4a5cb34f 19047 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19048 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19049 break;
8d18bf79 19050
00e98fc7
TG
19051 case NT_VMS_LINKTIME:
19052 printf (_(" Link time: "));
8d18bf79
NC
19053 if (maxlen < 8)
19054 goto desc_size_fail;
19055 /* FIXME: Generate an error if descsz > 8 ? */
19056
00e98fc7 19057 print_vms_time
8d18bf79 19058 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19059 printf ("\n");
19060 break;
8d18bf79 19061
00e98fc7
TG
19062 case NT_VMS_PATCHTIME:
19063 printf (_(" Patch time: "));
8d18bf79
NC
19064 if (maxlen < 8)
19065 goto desc_size_fail;
19066 /* FIXME: Generate an error if descsz > 8 ? */
19067
00e98fc7 19068 print_vms_time
8d18bf79 19069 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19070 printf ("\n");
19071 break;
8d18bf79 19072
00e98fc7 19073 case NT_VMS_ORIG_DYN:
8d18bf79
NC
19074 if (maxlen < 34)
19075 goto desc_size_fail;
19076
00e98fc7
TG
19077 printf (_(" Major id: %u, minor id: %u\n"),
19078 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
19079 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 19080 printf (_(" Last modified : "));
00e98fc7
TG
19081 print_vms_time
19082 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 19083 printf (_("\n Link flags : "));
4a5cb34f 19084 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 19085 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 19086 printf (_(" Header flags: 0x%08x\n"),
948f632f 19087 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 19088 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
19089 break;
19090#endif
8d18bf79 19091
00e98fc7 19092 case NT_VMS_IMGNAM:
8d18bf79 19093 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19094 break;
8d18bf79 19095
00e98fc7 19096 case NT_VMS_GSTNAM:
8d18bf79 19097 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19098 break;
8d18bf79 19099
00e98fc7 19100 case NT_VMS_IMGID:
8d18bf79 19101 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19102 break;
8d18bf79 19103
00e98fc7 19104 case NT_VMS_LINKID:
8d18bf79 19105 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19106 break;
8d18bf79 19107
00e98fc7 19108 default:
32ec8896 19109 return FALSE;
00e98fc7 19110 }
8d18bf79 19111
32ec8896 19112 return TRUE;
8d18bf79
NC
19113
19114 desc_size_fail:
19115 printf (_(" <corrupt - data size is too small>\n"));
19116 error (_("corrupt IA64 note: data size is too small\n"));
19117 return FALSE;
00e98fc7
TG
19118}
19119
fd486f32
AM
19120struct build_attr_cache {
19121 Filedata *filedata;
19122 char *strtab;
19123 unsigned long strtablen;
19124 Elf_Internal_Sym *symtab;
19125 unsigned long nsyms;
19126} ba_cache;
19127
6f156d7a
NC
19128/* Find the symbol associated with a build attribute that is attached
19129 to address OFFSET. If PNAME is non-NULL then store the name of
19130 the symbol (if found) in the provided pointer, Returns NULL if a
19131 symbol could not be found. */
c799a79d 19132
6f156d7a
NC
19133static Elf_Internal_Sym *
19134get_symbol_for_build_attribute (Filedata * filedata,
19135 unsigned long offset,
19136 bfd_boolean is_open_attr,
19137 const char ** pname)
9ef920e9 19138{
fd486f32
AM
19139 Elf_Internal_Sym *saved_sym = NULL;
19140 Elf_Internal_Sym *sym;
9ef920e9 19141
dda8d76d 19142 if (filedata->section_headers != NULL
fd486f32 19143 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 19144 {
c799a79d 19145 Elf_Internal_Shdr * symsec;
9ef920e9 19146
fd486f32
AM
19147 free (ba_cache.strtab);
19148 ba_cache.strtab = NULL;
19149 free (ba_cache.symtab);
19150 ba_cache.symtab = NULL;
19151
c799a79d 19152 /* Load the symbol and string sections. */
dda8d76d
NC
19153 for (symsec = filedata->section_headers;
19154 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 19155 symsec ++)
9ef920e9 19156 {
28d13567
AM
19157 if (symsec->sh_type == SHT_SYMTAB
19158 && get_symtab (filedata, symsec,
19159 &ba_cache.symtab, &ba_cache.nsyms,
19160 &ba_cache.strtab, &ba_cache.strtablen))
19161 break;
9ef920e9 19162 }
fd486f32 19163 ba_cache.filedata = filedata;
9ef920e9
NC
19164 }
19165
fd486f32 19166 if (ba_cache.symtab == NULL)
6f156d7a 19167 return NULL;
9ef920e9 19168
c799a79d 19169 /* Find a symbol whose value matches offset. */
fd486f32 19170 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
19171 if (sym->st_value == offset)
19172 {
fd486f32 19173 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
19174 /* Huh ? This should not happen. */
19175 continue;
9ef920e9 19176
fd486f32 19177 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 19178 continue;
9ef920e9 19179
8fd75781
NC
19180 /* The AArch64 and ARM architectures define mapping symbols
19181 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
19182 if (ba_cache.strtab[sym->st_name] == '$'
19183 && ba_cache.strtab[sym->st_name + 1] != 0
19184 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
19185 continue;
19186
c799a79d
NC
19187 if (is_open_attr)
19188 {
19189 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
19190 and FILE or OBJECT symbols over NOTYPE symbols. We skip
19191 FUNC symbols entirely. */
19192 switch (ELF_ST_TYPE (sym->st_info))
19193 {
c799a79d 19194 case STT_OBJECT:
6f156d7a 19195 case STT_FILE:
c799a79d 19196 saved_sym = sym;
6f156d7a
NC
19197 if (sym->st_size)
19198 {
19199 /* If the symbol has a size associated
19200 with it then we can stop searching. */
fd486f32 19201 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 19202 }
c799a79d 19203 continue;
9ef920e9 19204
c799a79d
NC
19205 case STT_FUNC:
19206 /* Ignore function symbols. */
19207 continue;
19208
19209 default:
19210 break;
19211 }
19212
19213 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 19214 {
c799a79d
NC
19215 case STB_GLOBAL:
19216 if (saved_sym == NULL
19217 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
19218 saved_sym = sym;
19219 break;
c871dade 19220
c799a79d
NC
19221 case STB_LOCAL:
19222 if (saved_sym == NULL)
19223 saved_sym = sym;
19224 break;
19225
19226 default:
9ef920e9
NC
19227 break;
19228 }
19229 }
c799a79d
NC
19230 else
19231 {
19232 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
19233 continue;
19234
19235 saved_sym = sym;
19236 break;
19237 }
19238 }
19239
6f156d7a 19240 if (saved_sym && pname)
fd486f32 19241 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
19242
19243 return saved_sym;
c799a79d
NC
19244}
19245
d20e98ab
NC
19246/* Returns true iff addr1 and addr2 are in the same section. */
19247
19248static bfd_boolean
19249same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
19250{
19251 Elf_Internal_Shdr * a1;
19252 Elf_Internal_Shdr * a2;
19253
19254 a1 = find_section_by_address (filedata, addr1);
19255 a2 = find_section_by_address (filedata, addr2);
9abca702 19256
d20e98ab
NC
19257 return a1 == a2 && a1 != NULL;
19258}
19259
c799a79d 19260static bfd_boolean
dda8d76d
NC
19261print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
19262 Filedata * filedata)
c799a79d 19263{
6f156d7a
NC
19264 static unsigned long global_offset = 0;
19265 static unsigned long global_end = 0;
19266 static unsigned long func_offset = 0;
19267 static unsigned long func_end = 0;
c871dade 19268
6f156d7a
NC
19269 Elf_Internal_Sym * sym;
19270 const char * name;
19271 unsigned long start;
19272 unsigned long end;
19273 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
19274
19275 switch (pnote->descsz)
c799a79d 19276 {
6f156d7a
NC
19277 case 0:
19278 /* A zero-length description means that the range of
19279 the previous note of the same type should be used. */
c799a79d 19280 if (is_open_attr)
c871dade 19281 {
6f156d7a
NC
19282 if (global_end > global_offset)
19283 printf (_(" Applies to region from %#lx to %#lx\n"),
19284 global_offset, global_end);
19285 else
19286 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
19287 }
19288 else
19289 {
6f156d7a
NC
19290 if (func_end > func_offset)
19291 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
19292 else
19293 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 19294 }
6f156d7a 19295 return TRUE;
9ef920e9 19296
6f156d7a
NC
19297 case 4:
19298 start = byte_get ((unsigned char *) pnote->descdata, 4);
19299 end = 0;
19300 break;
19301
19302 case 8:
19303 if (is_32bit_elf)
19304 {
19305 /* FIXME: We should check that version 3+ notes are being used here... */
19306 start = byte_get ((unsigned char *) pnote->descdata, 4);
19307 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19308 }
19309 else
19310 {
19311 start = byte_get ((unsigned char *) pnote->descdata, 8);
19312 end = 0;
19313 }
19314 break;
19315
19316 case 16:
19317 start = byte_get ((unsigned char *) pnote->descdata, 8);
19318 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
19319 break;
9abca702 19320
6f156d7a 19321 default:
c799a79d
NC
19322 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
19323 printf (_(" <invalid descsz>"));
19324 return FALSE;
19325 }
19326
6f156d7a
NC
19327 name = NULL;
19328 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
19329 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
19330 in order to avoid them being confused with the start address of the
19331 first function in the file... */
19332 if (sym == NULL && is_open_attr)
19333 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
19334 & name);
6f156d7a
NC
19335
19336 if (end == 0 && sym != NULL && sym->st_size > 0)
19337 end = start + sym->st_size;
c799a79d
NC
19338
19339 if (is_open_attr)
19340 {
d20e98ab
NC
19341 /* FIXME: Need to properly allow for section alignment.
19342 16 is just the alignment used on x86_64. */
19343 if (global_end > 0
19344 && start > BFD_ALIGN (global_end, 16)
19345 /* Build notes are not guaranteed to be organised in order of
19346 increasing address, but we should find the all of the notes
19347 for one section in the same place. */
19348 && same_section (filedata, start, global_end))
6f156d7a
NC
19349 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
19350 global_end + 1, start - 1);
19351
19352 printf (_(" Applies to region from %#lx"), start);
19353 global_offset = start;
19354
19355 if (end)
19356 {
19357 printf (_(" to %#lx"), end);
19358 global_end = end;
19359 }
c799a79d
NC
19360 }
19361 else
19362 {
6f156d7a
NC
19363 printf (_(" Applies to region from %#lx"), start);
19364 func_offset = start;
19365
19366 if (end)
19367 {
19368 printf (_(" to %#lx"), end);
19369 func_end = end;
19370 }
c799a79d
NC
19371 }
19372
6f156d7a
NC
19373 if (sym && name)
19374 printf (_(" (%s)"), name);
19375
19376 printf ("\n");
19377 return TRUE;
9ef920e9
NC
19378}
19379
19380static bfd_boolean
19381print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
19382{
1d15e434
NC
19383 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
19384 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
19385 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
19386 char name_type;
19387 char name_attribute;
1d15e434 19388 const char * expected_types;
9ef920e9
NC
19389 const char * name = pnote->namedata;
19390 const char * text;
88305e1b 19391 signed int left;
9ef920e9
NC
19392
19393 if (name == NULL || pnote->namesz < 2)
19394 {
19395 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 19396 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
19397 return FALSE;
19398 }
19399
6f156d7a
NC
19400 if (do_wide)
19401 left = 28;
19402 else
19403 left = 20;
88305e1b
NC
19404
19405 /* Version 2 of the spec adds a "GA" prefix to the name field. */
19406 if (name[0] == 'G' && name[1] == 'A')
19407 {
6f156d7a
NC
19408 if (pnote->namesz < 4)
19409 {
19410 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
19411 print_symbol (-20, _(" <corrupt name>"));
19412 return FALSE;
19413 }
19414
88305e1b
NC
19415 printf ("GA");
19416 name += 2;
19417 left -= 2;
19418 }
19419
9ef920e9
NC
19420 switch ((name_type = * name))
19421 {
19422 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19423 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19424 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19425 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19426 printf ("%c", * name);
88305e1b 19427 left --;
9ef920e9
NC
19428 break;
19429 default:
19430 error (_("unrecognised attribute type in name field: %d\n"), name_type);
19431 print_symbol (-20, _("<unknown name type>"));
19432 return FALSE;
19433 }
19434
9ef920e9
NC
19435 ++ name;
19436 text = NULL;
19437
19438 switch ((name_attribute = * name))
19439 {
19440 case GNU_BUILD_ATTRIBUTE_VERSION:
19441 text = _("<version>");
1d15e434 19442 expected_types = string_expected;
9ef920e9
NC
19443 ++ name;
19444 break;
19445 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19446 text = _("<stack prot>");
75d7d298 19447 expected_types = "!+*";
9ef920e9
NC
19448 ++ name;
19449 break;
19450 case GNU_BUILD_ATTRIBUTE_RELRO:
19451 text = _("<relro>");
1d15e434 19452 expected_types = bool_expected;
9ef920e9
NC
19453 ++ name;
19454 break;
19455 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
19456 text = _("<stack size>");
1d15e434 19457 expected_types = number_expected;
9ef920e9
NC
19458 ++ name;
19459 break;
19460 case GNU_BUILD_ATTRIBUTE_TOOL:
19461 text = _("<tool>");
1d15e434 19462 expected_types = string_expected;
9ef920e9
NC
19463 ++ name;
19464 break;
19465 case GNU_BUILD_ATTRIBUTE_ABI:
19466 text = _("<ABI>");
19467 expected_types = "$*";
19468 ++ name;
19469 break;
19470 case GNU_BUILD_ATTRIBUTE_PIC:
19471 text = _("<PIC>");
1d15e434 19472 expected_types = number_expected;
9ef920e9
NC
19473 ++ name;
19474 break;
a8be5506
NC
19475 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
19476 text = _("<short enum>");
1d15e434 19477 expected_types = bool_expected;
a8be5506
NC
19478 ++ name;
19479 break;
9ef920e9
NC
19480 default:
19481 if (ISPRINT (* name))
19482 {
19483 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
19484
19485 if (len > left && ! do_wide)
19486 len = left;
75d7d298 19487 printf ("%.*s:", len, name);
9ef920e9 19488 left -= len;
0dd6ae21 19489 name += len;
9ef920e9
NC
19490 }
19491 else
19492 {
3e6b6445 19493 static char tmpbuf [128];
88305e1b 19494
3e6b6445
NC
19495 error (_("unrecognised byte in name field: %d\n"), * name);
19496 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
19497 text = tmpbuf;
19498 name ++;
9ef920e9
NC
19499 }
19500 expected_types = "*$!+";
19501 break;
19502 }
19503
19504 if (text)
88305e1b 19505 left -= printf ("%s", text);
9ef920e9
NC
19506
19507 if (strchr (expected_types, name_type) == NULL)
75d7d298 19508 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
19509
19510 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
19511 {
19512 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
19513 (unsigned long) pnote->namesz,
19514 (long) (name - pnote->namedata));
19515 return FALSE;
19516 }
19517
19518 if (left < 1 && ! do_wide)
19519 return TRUE;
19520
19521 switch (name_type)
19522 {
19523 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19524 {
b06b2c92 19525 unsigned int bytes;
ddef72cd
NC
19526 unsigned long long val = 0;
19527 unsigned int shift = 0;
19528 char * decoded = NULL;
19529
b06b2c92
NC
19530 bytes = pnote->namesz - (name - pnote->namedata);
19531 if (bytes > 0)
19532 /* The -1 is because the name field is always 0 terminated, and we
19533 want to be able to ensure that the shift in the while loop below
19534 will not overflow. */
19535 -- bytes;
19536
ddef72cd
NC
19537 if (bytes > sizeof (val))
19538 {
3e6b6445
NC
19539 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
19540 bytes);
19541 bytes = sizeof (val);
ddef72cd 19542 }
3e6b6445
NC
19543 /* We do not bother to warn if bytes == 0 as this can
19544 happen with some early versions of the gcc plugin. */
9ef920e9
NC
19545
19546 while (bytes --)
19547 {
79a964dc
NC
19548 unsigned long byte = (* name ++) & 0xff;
19549
19550 val |= byte << shift;
9ef920e9
NC
19551 shift += 8;
19552 }
19553
75d7d298 19554 switch (name_attribute)
9ef920e9 19555 {
75d7d298 19556 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
19557 switch (val)
19558 {
75d7d298
NC
19559 case 0: decoded = "static"; break;
19560 case 1: decoded = "pic"; break;
19561 case 2: decoded = "PIC"; break;
19562 case 3: decoded = "pie"; break;
19563 case 4: decoded = "PIE"; break;
19564 default: break;
9ef920e9 19565 }
75d7d298
NC
19566 break;
19567 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19568 switch (val)
9ef920e9 19569 {
75d7d298
NC
19570 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
19571 case 0: decoded = "off"; break;
19572 case 1: decoded = "on"; break;
19573 case 2: decoded = "all"; break;
19574 case 3: decoded = "strong"; break;
19575 case 4: decoded = "explicit"; break;
19576 default: break;
9ef920e9 19577 }
75d7d298
NC
19578 break;
19579 default:
19580 break;
9ef920e9
NC
19581 }
19582
75d7d298 19583 if (decoded != NULL)
3e6b6445
NC
19584 {
19585 print_symbol (-left, decoded);
19586 left = 0;
19587 }
19588 else if (val == 0)
19589 {
19590 printf ("0x0");
19591 left -= 3;
19592 }
9ef920e9 19593 else
75d7d298
NC
19594 {
19595 if (do_wide)
ddef72cd 19596 left -= printf ("0x%llx", val);
75d7d298 19597 else
ddef72cd 19598 left -= printf ("0x%-.*llx", left, val);
75d7d298 19599 }
9ef920e9
NC
19600 }
19601 break;
19602 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19603 left -= print_symbol (- left, name);
19604 break;
19605 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19606 left -= print_symbol (- left, "true");
19607 break;
19608 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19609 left -= print_symbol (- left, "false");
19610 break;
19611 }
19612
19613 if (do_wide && left > 0)
19614 printf ("%-*s", left, " ");
9abca702 19615
9ef920e9
NC
19616 return TRUE;
19617}
19618
6d118b09
NC
19619/* Note that by the ELF standard, the name field is already null byte
19620 terminated, and namesz includes the terminating null byte.
19621 I.E. the value of namesz for the name "FSF" is 4.
19622
e3c8793a 19623 If the value of namesz is zero, there is no name present. */
9ef920e9 19624
32ec8896 19625static bfd_boolean
9ef920e9 19626process_note (Elf_Internal_Note * pnote,
dda8d76d 19627 Filedata * filedata)
779fe533 19628{
2cf0635d
NC
19629 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
19630 const char * nt;
9437c45b
JT
19631
19632 if (pnote->namesz == 0)
1ec5cd37
NC
19633 /* If there is no note name, then use the default set of
19634 note type strings. */
dda8d76d 19635 nt = get_note_type (filedata, pnote->type);
1ec5cd37 19636
1118d252
RM
19637 else if (const_strneq (pnote->namedata, "GNU"))
19638 /* GNU-specific object file notes. */
19639 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
19640
19641 else if (const_strneq (pnote->namedata, "FreeBSD"))
19642 /* FreeBSD-specific core file notes. */
dda8d76d 19643 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 19644
0112cd26 19645 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 19646 /* NetBSD-specific core file notes. */
dda8d76d 19647 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 19648
c6056a74
SF
19649 else if (const_strneq (pnote->namedata, "NetBSD"))
19650 /* NetBSD-specific core file notes. */
19651 return process_netbsd_elf_note (pnote);
19652
9abca702
CZ
19653 else if (const_strneq (pnote->namedata, "PaX"))
19654 /* NetBSD-specific core file notes. */
19655 return process_netbsd_elf_note (pnote);
19656
b15fa79e
AM
19657 else if (strneq (pnote->namedata, "SPU/", 4))
19658 {
19659 /* SPU-specific core file notes. */
19660 nt = pnote->namedata + 4;
19661 name = "SPU";
19662 }
19663
00e98fc7
TG
19664 else if (const_strneq (pnote->namedata, "IPF/VMS"))
19665 /* VMS/ia64-specific file notes. */
19666 nt = get_ia64_vms_note_type (pnote->type);
19667
70616151
TT
19668 else if (const_strneq (pnote->namedata, "stapsdt"))
19669 nt = get_stapsdt_note_type (pnote->type);
19670
9437c45b 19671 else
1ec5cd37
NC
19672 /* Don't recognize this note name; just use the default set of
19673 note type strings. */
dda8d76d 19674 nt = get_note_type (filedata, pnote->type);
9437c45b 19675
1449284b 19676 printf (" ");
9ef920e9 19677
483767a3
AM
19678 if (((const_strneq (pnote->namedata, "GA")
19679 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19680 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19681 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19682 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
19683 print_gnu_build_attribute_name (pnote);
19684 else
19685 print_symbol (-20, name);
19686
19687 if (do_wide)
19688 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
19689 else
19690 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
19691
19692 if (const_strneq (pnote->namedata, "IPF/VMS"))
19693 return print_ia64_vms_note (pnote);
664f90a3 19694 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 19695 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
19696 else if (const_strneq (pnote->namedata, "stapsdt"))
19697 return print_stapsdt_note (pnote);
9ece1fa9
TT
19698 else if (const_strneq (pnote->namedata, "CORE"))
19699 return print_core_note (pnote);
483767a3
AM
19700 else if (((const_strneq (pnote->namedata, "GA")
19701 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19702 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19703 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19704 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 19705 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 19706
9ef920e9 19707 if (pnote->descsz)
1449284b
NC
19708 {
19709 unsigned long i;
19710
19711 printf (_(" description data: "));
19712 for (i = 0; i < pnote->descsz; i++)
178d8719 19713 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
19714 if (!do_wide)
19715 printf ("\n");
1449284b
NC
19716 }
19717
9ef920e9
NC
19718 if (do_wide)
19719 printf ("\n");
19720
32ec8896 19721 return TRUE;
1449284b 19722}
6d118b09 19723
32ec8896 19724static bfd_boolean
dda8d76d
NC
19725process_notes_at (Filedata * filedata,
19726 Elf_Internal_Shdr * section,
19727 bfd_vma offset,
82ed9683
L
19728 bfd_vma length,
19729 bfd_vma align)
779fe533 19730{
2cf0635d
NC
19731 Elf_External_Note * pnotes;
19732 Elf_External_Note * external;
4dff97b2
NC
19733 char * end;
19734 bfd_boolean res = TRUE;
103f02d3 19735
779fe533 19736 if (length <= 0)
32ec8896 19737 return FALSE;
103f02d3 19738
1449284b
NC
19739 if (section)
19740 {
dda8d76d 19741 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 19742 if (pnotes)
32ec8896 19743 {
dda8d76d 19744 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
19745 {
19746 free (pnotes);
19747 return FALSE;
19748 }
32ec8896 19749 }
1449284b
NC
19750 }
19751 else
82ed9683 19752 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 19753 _("notes"));
4dff97b2 19754
dd24e3da 19755 if (pnotes == NULL)
32ec8896 19756 return FALSE;
779fe533 19757
103f02d3 19758 external = pnotes;
103f02d3 19759
1449284b 19760 if (section)
dda8d76d 19761 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
19762 else
19763 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
19764 (unsigned long) offset, (unsigned long) length);
19765
82ed9683
L
19766 /* NB: Some note sections may have alignment value of 0 or 1. gABI
19767 specifies that notes should be aligned to 4 bytes in 32-bit
19768 objects and to 8 bytes in 64-bit objects. As a Linux extension,
19769 we also support 4 byte alignment in 64-bit objects. If section
19770 alignment is less than 4, we treate alignment as 4 bytes. */
19771 if (align < 4)
19772 align = 4;
19773 else if (align != 4 && align != 8)
19774 {
19775 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
19776 (long) align);
a788aedd 19777 free (pnotes);
82ed9683
L
19778 return FALSE;
19779 }
19780
dbe15e4e 19781 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 19782
c8071705
NC
19783 end = (char *) pnotes + length;
19784 while ((char *) external < end)
779fe533 19785 {
b34976b6 19786 Elf_Internal_Note inote;
15b42fb0 19787 size_t min_notesz;
4dff97b2 19788 char * next;
2cf0635d 19789 char * temp = NULL;
c8071705 19790 size_t data_remaining = end - (char *) external;
6d118b09 19791
dda8d76d 19792 if (!is_ia64_vms (filedata))
15b42fb0 19793 {
9dd3a467
NC
19794 /* PR binutils/15191
19795 Make sure that there is enough data to read. */
15b42fb0
AM
19796 min_notesz = offsetof (Elf_External_Note, name);
19797 if (data_remaining < min_notesz)
9dd3a467 19798 {
d3a49aa8
AM
19799 warn (ngettext ("Corrupt note: only %ld byte remains, "
19800 "not enough for a full note\n",
19801 "Corrupt note: only %ld bytes remain, "
19802 "not enough for a full note\n",
19803 data_remaining),
19804 (long) data_remaining);
9dd3a467
NC
19805 break;
19806 }
5396a86e
AM
19807 data_remaining -= min_notesz;
19808
15b42fb0
AM
19809 inote.type = BYTE_GET (external->type);
19810 inote.namesz = BYTE_GET (external->namesz);
19811 inote.namedata = external->name;
19812 inote.descsz = BYTE_GET (external->descsz);
276da9b3 19813 inote.descdata = ((char *) external
4dff97b2 19814 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 19815 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 19816 next = ((char *) external
4dff97b2 19817 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 19818 }
00e98fc7 19819 else
15b42fb0
AM
19820 {
19821 Elf64_External_VMS_Note *vms_external;
00e98fc7 19822
9dd3a467
NC
19823 /* PR binutils/15191
19824 Make sure that there is enough data to read. */
15b42fb0
AM
19825 min_notesz = offsetof (Elf64_External_VMS_Note, name);
19826 if (data_remaining < min_notesz)
9dd3a467 19827 {
d3a49aa8
AM
19828 warn (ngettext ("Corrupt note: only %ld byte remains, "
19829 "not enough for a full note\n",
19830 "Corrupt note: only %ld bytes remain, "
19831 "not enough for a full note\n",
19832 data_remaining),
19833 (long) data_remaining);
9dd3a467
NC
19834 break;
19835 }
5396a86e 19836 data_remaining -= min_notesz;
3e55a963 19837
15b42fb0
AM
19838 vms_external = (Elf64_External_VMS_Note *) external;
19839 inote.type = BYTE_GET (vms_external->type);
19840 inote.namesz = BYTE_GET (vms_external->namesz);
19841 inote.namedata = vms_external->name;
19842 inote.descsz = BYTE_GET (vms_external->descsz);
19843 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
19844 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19845 next = inote.descdata + align_power (inote.descsz, 3);
19846 }
19847
5396a86e
AM
19848 /* PR 17531: file: 3443835e. */
19849 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
19850 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
19851 || (size_t) (inote.descdata - inote.namedata) > data_remaining
19852 || (size_t) (next - inote.descdata) < inote.descsz
19853 || ((size_t) (next - inote.descdata)
19854 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 19855 {
15b42fb0 19856 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 19857 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
19858 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
19859 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
19860 break;
19861 }
19862
15b42fb0 19863 external = (Elf_External_Note *) next;
dd24e3da 19864
6d118b09
NC
19865 /* Verify that name is null terminated. It appears that at least
19866 one version of Linux (RedHat 6.0) generates corefiles that don't
19867 comply with the ELF spec by failing to include the null byte in
19868 namesz. */
18344509 19869 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 19870 {
5396a86e 19871 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 19872 {
5396a86e
AM
19873 temp = (char *) malloc (inote.namesz + 1);
19874 if (temp == NULL)
19875 {
19876 error (_("Out of memory allocating space for inote name\n"));
19877 res = FALSE;
19878 break;
19879 }
76da6bbe 19880
5396a86e
AM
19881 memcpy (temp, inote.namedata, inote.namesz);
19882 inote.namedata = temp;
19883 }
19884 inote.namedata[inote.namesz] = 0;
6d118b09
NC
19885 }
19886
dda8d76d 19887 if (! process_note (& inote, filedata))
6b4bf3bc 19888 res = FALSE;
103f02d3 19889
9db70fc3
AM
19890 free (temp);
19891 temp = NULL;
779fe533
NC
19892 }
19893
19894 free (pnotes);
103f02d3 19895
779fe533
NC
19896 return res;
19897}
19898
32ec8896 19899static bfd_boolean
dda8d76d 19900process_corefile_note_segments (Filedata * filedata)
779fe533 19901{
2cf0635d 19902 Elf_Internal_Phdr * segment;
b34976b6 19903 unsigned int i;
32ec8896 19904 bfd_boolean res = TRUE;
103f02d3 19905
dda8d76d 19906 if (! get_program_headers (filedata))
6b4bf3bc 19907 return TRUE;
103f02d3 19908
dda8d76d
NC
19909 for (i = 0, segment = filedata->program_headers;
19910 i < filedata->file_header.e_phnum;
b34976b6 19911 i++, segment++)
779fe533
NC
19912 {
19913 if (segment->p_type == PT_NOTE)
dda8d76d 19914 if (! process_notes_at (filedata, NULL,
32ec8896 19915 (bfd_vma) segment->p_offset,
82ed9683
L
19916 (bfd_vma) segment->p_filesz,
19917 (bfd_vma) segment->p_align))
32ec8896 19918 res = FALSE;
779fe533 19919 }
103f02d3 19920
779fe533
NC
19921 return res;
19922}
19923
32ec8896 19924static bfd_boolean
dda8d76d 19925process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
19926{
19927 Elf_External_Note * pnotes;
19928 Elf_External_Note * external;
c8071705 19929 char * end;
32ec8896 19930 bfd_boolean res = TRUE;
685080f2
NC
19931
19932 if (length <= 0)
32ec8896 19933 return FALSE;
685080f2 19934
dda8d76d 19935 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
19936 _("v850 notes"));
19937 if (pnotes == NULL)
32ec8896 19938 return FALSE;
685080f2
NC
19939
19940 external = pnotes;
c8071705 19941 end = (char*) pnotes + length;
685080f2
NC
19942
19943 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
19944 (unsigned long) offset, (unsigned long) length);
19945
c8071705 19946 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
19947 {
19948 Elf_External_Note * next;
19949 Elf_Internal_Note inote;
19950
19951 inote.type = BYTE_GET (external->type);
19952 inote.namesz = BYTE_GET (external->namesz);
19953 inote.namedata = external->name;
19954 inote.descsz = BYTE_GET (external->descsz);
19955 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
19956 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19957
c8071705
NC
19958 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
19959 {
19960 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
19961 inote.descdata = inote.namedata;
19962 inote.namesz = 0;
19963 }
19964
685080f2
NC
19965 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
19966
c8071705 19967 if ( ((char *) next > end)
685080f2
NC
19968 || ((char *) next < (char *) pnotes))
19969 {
19970 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
19971 (unsigned long) ((char *) external - (char *) pnotes));
19972 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19973 inote.type, inote.namesz, inote.descsz);
19974 break;
19975 }
19976
19977 external = next;
19978
19979 /* Prevent out-of-bounds indexing. */
c8071705 19980 if ( inote.namedata + inote.namesz > end
685080f2
NC
19981 || inote.namedata + inote.namesz < inote.namedata)
19982 {
19983 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
19984 (unsigned long) ((char *) external - (char *) pnotes));
19985 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19986 inote.type, inote.namesz, inote.descsz);
19987 break;
19988 }
19989
19990 printf (" %s: ", get_v850_elf_note_type (inote.type));
19991
19992 if (! print_v850_note (& inote))
19993 {
32ec8896 19994 res = FALSE;
685080f2
NC
19995 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
19996 inote.namesz, inote.descsz);
19997 }
19998 }
19999
20000 free (pnotes);
20001
20002 return res;
20003}
20004
32ec8896 20005static bfd_boolean
dda8d76d 20006process_note_sections (Filedata * filedata)
1ec5cd37 20007{
2cf0635d 20008 Elf_Internal_Shdr * section;
1ec5cd37 20009 unsigned long i;
32ec8896
NC
20010 unsigned int n = 0;
20011 bfd_boolean res = TRUE;
1ec5cd37 20012
dda8d76d
NC
20013 for (i = 0, section = filedata->section_headers;
20014 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20015 i++, section++)
685080f2
NC
20016 {
20017 if (section->sh_type == SHT_NOTE)
20018 {
dda8d76d 20019 if (! process_notes_at (filedata, section,
32ec8896 20020 (bfd_vma) section->sh_offset,
82ed9683
L
20021 (bfd_vma) section->sh_size,
20022 (bfd_vma) section->sh_addralign))
32ec8896 20023 res = FALSE;
685080f2
NC
20024 n++;
20025 }
20026
dda8d76d
NC
20027 if (( filedata->file_header.e_machine == EM_V800
20028 || filedata->file_header.e_machine == EM_V850
20029 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20030 && section->sh_type == SHT_RENESAS_INFO)
20031 {
dda8d76d 20032 if (! process_v850_notes (filedata,
32ec8896
NC
20033 (bfd_vma) section->sh_offset,
20034 (bfd_vma) section->sh_size))
20035 res = FALSE;
685080f2
NC
20036 n++;
20037 }
20038 }
df565f32
NC
20039
20040 if (n == 0)
20041 /* Try processing NOTE segments instead. */
dda8d76d 20042 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20043
20044 return res;
20045}
20046
32ec8896 20047static bfd_boolean
dda8d76d 20048process_notes (Filedata * filedata)
779fe533
NC
20049{
20050 /* If we have not been asked to display the notes then do nothing. */
20051 if (! do_notes)
32ec8896 20052 return TRUE;
103f02d3 20053
dda8d76d
NC
20054 if (filedata->file_header.e_type != ET_CORE)
20055 return process_note_sections (filedata);
103f02d3 20056
779fe533 20057 /* No program headers means no NOTE segment. */
dda8d76d
NC
20058 if (filedata->file_header.e_phnum > 0)
20059 return process_corefile_note_segments (filedata);
779fe533 20060
1ec5cd37 20061 printf (_("No note segments present in the core file.\n"));
32ec8896 20062 return TRUE;
779fe533
NC
20063}
20064
60abdbed
NC
20065static unsigned char *
20066display_public_gnu_attributes (unsigned char * start,
20067 const unsigned char * const end)
20068{
20069 printf (_(" Unknown GNU attribute: %s\n"), start);
20070
20071 start += strnlen ((char *) start, end - start);
20072 display_raw_attribute (start, end);
20073
20074 return (unsigned char *) end;
20075}
20076
20077static unsigned char *
20078display_generic_attribute (unsigned char * start,
20079 unsigned int tag,
20080 const unsigned char * const end)
20081{
20082 if (tag == 0)
20083 return (unsigned char *) end;
20084
20085 return display_tag_value (tag, start, end);
20086}
20087
32ec8896 20088static bfd_boolean
dda8d76d 20089process_arch_specific (Filedata * filedata)
252b5132 20090{
a952a375 20091 if (! do_arch)
32ec8896 20092 return TRUE;
a952a375 20093
dda8d76d 20094 switch (filedata->file_header.e_machine)
252b5132 20095 {
53a346d8
CZ
20096 case EM_ARC:
20097 case EM_ARC_COMPACT:
20098 case EM_ARC_COMPACT2:
dda8d76d 20099 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
20100 display_arc_attribute,
20101 display_generic_attribute);
11c1ff18 20102 case EM_ARM:
dda8d76d 20103 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
20104 display_arm_attribute,
20105 display_generic_attribute);
20106
252b5132 20107 case EM_MIPS:
4fe85591 20108 case EM_MIPS_RS3_LE:
dda8d76d 20109 return process_mips_specific (filedata);
60abdbed
NC
20110
20111 case EM_MSP430:
dda8d76d
NC
20112 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
20113 display_msp430x_attribute,
c0ea7c52 20114 display_msp430_gnu_attribute);
60abdbed 20115
2dc8dd17
JW
20116 case EM_RISCV:
20117 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
20118 display_riscv_attribute,
20119 display_generic_attribute);
20120
35c08157 20121 case EM_NDS32:
dda8d76d 20122 return process_nds32_specific (filedata);
60abdbed 20123
85f7484a
PB
20124 case EM_68K:
20125 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
20126 display_m68k_gnu_attribute);
20127
34c8bcba 20128 case EM_PPC:
b82317dd 20129 case EM_PPC64:
dda8d76d 20130 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20131 display_power_gnu_attribute);
20132
643f7afb
AK
20133 case EM_S390:
20134 case EM_S390_OLD:
dda8d76d 20135 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20136 display_s390_gnu_attribute);
20137
9e8c70f9
DM
20138 case EM_SPARC:
20139 case EM_SPARC32PLUS:
20140 case EM_SPARCV9:
dda8d76d 20141 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20142 display_sparc_gnu_attribute);
20143
59e6276b 20144 case EM_TI_C6000:
dda8d76d 20145 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
20146 display_tic6x_attribute,
20147 display_generic_attribute);
20148
252b5132 20149 default:
dda8d76d 20150 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
20151 display_public_gnu_attributes,
20152 display_generic_attribute);
252b5132 20153 }
252b5132
RH
20154}
20155
32ec8896 20156static bfd_boolean
dda8d76d 20157get_file_header (Filedata * filedata)
252b5132 20158{
9ea033b2 20159 /* Read in the identity array. */
dda8d76d 20160 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20161 return FALSE;
252b5132 20162
9ea033b2 20163 /* Determine how to read the rest of the header. */
dda8d76d 20164 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 20165 {
1a0670f3
AM
20166 default:
20167 case ELFDATANONE:
adab8cdc
AO
20168 case ELFDATA2LSB:
20169 byte_get = byte_get_little_endian;
20170 byte_put = byte_put_little_endian;
20171 break;
20172 case ELFDATA2MSB:
20173 byte_get = byte_get_big_endian;
20174 byte_put = byte_put_big_endian;
20175 break;
9ea033b2
NC
20176 }
20177
20178 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 20179 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
20180
20181 /* Read in the rest of the header. */
20182 if (is_32bit_elf)
20183 {
20184 Elf32_External_Ehdr ehdr32;
252b5132 20185
dda8d76d 20186 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20187 return FALSE;
103f02d3 20188
dda8d76d
NC
20189 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
20190 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
20191 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
20192 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
20193 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
20194 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
20195 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
20196 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
20197 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
20198 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
20199 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
20200 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
20201 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 20202 }
252b5132 20203 else
9ea033b2
NC
20204 {
20205 Elf64_External_Ehdr ehdr64;
a952a375
NC
20206
20207 /* If we have been compiled with sizeof (bfd_vma) == 4, then
20208 we will not be able to cope with the 64bit data found in
20209 64 ELF files. Detect this now and abort before we start
50c2245b 20210 overwriting things. */
a952a375
NC
20211 if (sizeof (bfd_vma) < 8)
20212 {
e3c8793a
NC
20213 error (_("This instance of readelf has been built without support for a\n\
2021464 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 20215 return FALSE;
a952a375 20216 }
103f02d3 20217
dda8d76d 20218 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20219 return FALSE;
103f02d3 20220
dda8d76d
NC
20221 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
20222 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
20223 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
20224 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
20225 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
20226 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
20227 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
20228 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
20229 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
20230 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
20231 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
20232 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
20233 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 20234 }
252b5132 20235
dda8d76d 20236 if (filedata->file_header.e_shoff)
7ece0d85
JJ
20237 {
20238 /* There may be some extensions in the first section header. Don't
20239 bomb if we can't read it. */
20240 if (is_32bit_elf)
dda8d76d 20241 get_32bit_section_headers (filedata, TRUE);
7ece0d85 20242 else
dda8d76d 20243 get_64bit_section_headers (filedata, TRUE);
7ece0d85 20244 }
560f3c1c 20245
32ec8896 20246 return TRUE;
252b5132
RH
20247}
20248
dda8d76d
NC
20249static void
20250close_file (Filedata * filedata)
20251{
20252 if (filedata)
20253 {
20254 if (filedata->handle)
20255 fclose (filedata->handle);
20256 free (filedata);
20257 }
20258}
20259
20260void
20261close_debug_file (void * data)
20262{
20263 close_file ((Filedata *) data);
20264}
20265
20266static Filedata *
20267open_file (const char * pathname)
20268{
20269 struct stat statbuf;
20270 Filedata * filedata = NULL;
20271
20272 if (stat (pathname, & statbuf) < 0
20273 || ! S_ISREG (statbuf.st_mode))
20274 goto fail;
20275
20276 filedata = calloc (1, sizeof * filedata);
20277 if (filedata == NULL)
20278 goto fail;
20279
20280 filedata->handle = fopen (pathname, "rb");
20281 if (filedata->handle == NULL)
20282 goto fail;
20283
20284 filedata->file_size = (bfd_size_type) statbuf.st_size;
20285 filedata->file_name = pathname;
20286
20287 if (! get_file_header (filedata))
20288 goto fail;
20289
20290 if (filedata->file_header.e_shoff)
20291 {
20292 bfd_boolean res;
20293
20294 /* Read the section headers again, this time for real. */
20295 if (is_32bit_elf)
20296 res = get_32bit_section_headers (filedata, FALSE);
20297 else
20298 res = get_64bit_section_headers (filedata, FALSE);
20299
20300 if (!res)
20301 goto fail;
20302 }
20303
20304 return filedata;
20305
20306 fail:
20307 if (filedata)
20308 {
20309 if (filedata->handle)
20310 fclose (filedata->handle);
20311 free (filedata);
20312 }
20313 return NULL;
20314}
20315
20316void *
20317open_debug_file (const char * pathname)
20318{
20319 return open_file (pathname);
20320}
20321
fb52b2f4
NC
20322/* Process one ELF object file according to the command line options.
20323 This file may actually be stored in an archive. The file is
32ec8896
NC
20324 positioned at the start of the ELF object. Returns TRUE if no
20325 problems were encountered, FALSE otherwise. */
fb52b2f4 20326
32ec8896 20327static bfd_boolean
dda8d76d 20328process_object (Filedata * filedata)
252b5132 20329{
24841daa 20330 bfd_boolean have_separate_files;
252b5132 20331 unsigned int i;
2482f306 20332 bfd_boolean res;
252b5132 20333
dda8d76d 20334 if (! get_file_header (filedata))
252b5132 20335 {
dda8d76d 20336 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 20337 return FALSE;
252b5132
RH
20338 }
20339
20340 /* Initialise per file variables. */
978c4450
AM
20341 for (i = ARRAY_SIZE (filedata->version_info); i--;)
20342 filedata->version_info[i] = 0;
252b5132 20343
978c4450
AM
20344 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
20345 filedata->dynamic_info[i] = 0;
20346 filedata->dynamic_info_DT_GNU_HASH = 0;
20347 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
20348
20349 /* Process the file. */
20350 if (show_name)
dda8d76d 20351 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 20352
18bd398b
NC
20353 /* Initialise the dump_sects array from the cmdline_dump_sects array.
20354 Note we do this even if cmdline_dump_sects is empty because we
20355 must make sure that the dump_sets array is zeroed out before each
20356 object file is processed. */
6431e409
AM
20357 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
20358 memset (filedata->dump.dump_sects, 0,
20359 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20360
dda8d76d 20361 if (cmdline.num_dump_sects > 0)
18bd398b 20362 {
6431e409 20363 if (filedata->dump.num_dump_sects == 0)
18bd398b 20364 /* A sneaky way of allocating the dump_sects array. */
6431e409 20365 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 20366
6431e409
AM
20367 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
20368 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
20369 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20370 }
d70c5fc7 20371
dda8d76d 20372 if (! process_file_header (filedata))
32ec8896 20373 return FALSE;
252b5132 20374
dda8d76d 20375 if (! process_section_headers (filedata))
2f62977e 20376 {
32ec8896
NC
20377 /* Without loaded section headers we cannot process lots of things. */
20378 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 20379
2f62977e 20380 if (! do_using_dynamic)
32ec8896 20381 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 20382 }
252b5132 20383
dda8d76d 20384 if (! process_section_groups (filedata))
32ec8896
NC
20385 /* Without loaded section groups we cannot process unwind. */
20386 do_unwind = FALSE;
d1f5c6e3 20387
2482f306
AM
20388 res = process_program_headers (filedata);
20389 if (res)
20390 res = process_dynamic_section (filedata);
252b5132 20391
dda8d76d 20392 if (! process_relocs (filedata))
32ec8896 20393 res = FALSE;
252b5132 20394
dda8d76d 20395 if (! process_unwind (filedata))
32ec8896 20396 res = FALSE;
4d6ed7c8 20397
dda8d76d 20398 if (! process_symbol_table (filedata))
32ec8896 20399 res = FALSE;
252b5132 20400
dda8d76d 20401 if (! process_syminfo (filedata))
32ec8896 20402 res = FALSE;
252b5132 20403
dda8d76d 20404 if (! process_version_sections (filedata))
32ec8896 20405 res = FALSE;
252b5132 20406
82ed9683 20407 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 20408 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 20409 else
24841daa 20410 have_separate_files = FALSE;
dda8d76d
NC
20411
20412 if (! process_section_contents (filedata))
32ec8896 20413 res = FALSE;
f5842774 20414
24841daa 20415 if (have_separate_files)
dda8d76d 20416 {
24841daa
NC
20417 separate_info * d;
20418
20419 for (d = first_separate_info; d != NULL; d = d->next)
20420 {
20421 if (! process_section_headers (d->handle))
20422 res = FALSE;
20423 else if (! process_section_contents (d->handle))
20424 res = FALSE;
20425 }
20426
20427 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
20428 }
20429
20430 if (! process_notes (filedata))
32ec8896 20431 res = FALSE;
103f02d3 20432
dda8d76d 20433 if (! process_gnu_liblist (filedata))
32ec8896 20434 res = FALSE;
047b2264 20435
dda8d76d 20436 if (! process_arch_specific (filedata))
32ec8896 20437 res = FALSE;
252b5132 20438
dda8d76d
NC
20439 free (filedata->program_headers);
20440 filedata->program_headers = NULL;
d93f0186 20441
dda8d76d
NC
20442 free (filedata->section_headers);
20443 filedata->section_headers = NULL;
252b5132 20444
dda8d76d
NC
20445 free (filedata->string_table);
20446 filedata->string_table = NULL;
20447 filedata->string_table_length = 0;
252b5132 20448
9db70fc3
AM
20449 free (filedata->dump.dump_sects);
20450 filedata->dump.dump_sects = NULL;
20451 filedata->dump.num_dump_sects = 0;
a788aedd 20452
9db70fc3
AM
20453 free (filedata->dynamic_strings);
20454 filedata->dynamic_strings = NULL;
20455 filedata->dynamic_strings_length = 0;
252b5132 20456
9db70fc3
AM
20457 free (filedata->dynamic_symbols);
20458 filedata->dynamic_symbols = NULL;
20459 filedata->num_dynamic_syms = 0;
252b5132 20460
9db70fc3
AM
20461 free (filedata->dynamic_syminfo);
20462 filedata->dynamic_syminfo = NULL;
ff78d6d6 20463
9db70fc3
AM
20464 free (filedata->dynamic_section);
20465 filedata->dynamic_section = NULL;
293c573e 20466
978c4450 20467 while (filedata->symtab_shndx_list != NULL)
8fb879cd 20468 {
978c4450
AM
20469 elf_section_list *next = filedata->symtab_shndx_list->next;
20470 free (filedata->symtab_shndx_list);
20471 filedata->symtab_shndx_list = next;
8fb879cd
AM
20472 }
20473
9db70fc3
AM
20474 free (filedata->section_headers_groups);
20475 filedata->section_headers_groups = NULL;
e4b17d5c 20476
978c4450 20477 if (filedata->section_groups)
e4b17d5c 20478 {
2cf0635d
NC
20479 struct group_list * g;
20480 struct group_list * next;
e4b17d5c 20481
978c4450 20482 for (i = 0; i < filedata->group_count; i++)
e4b17d5c 20483 {
978c4450 20484 for (g = filedata->section_groups [i].root; g != NULL; g = next)
e4b17d5c
L
20485 {
20486 next = g->next;
20487 free (g);
20488 }
20489 }
20490
978c4450
AM
20491 free (filedata->section_groups);
20492 filedata->section_groups = NULL;
e4b17d5c
L
20493 }
20494
19e6b90e 20495 free_debug_memory ();
18bd398b 20496
32ec8896 20497 return res;
252b5132
RH
20498}
20499
2cf0635d 20500/* Process an ELF archive.
32ec8896
NC
20501 On entry the file is positioned just after the ARMAG string.
20502 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 20503
32ec8896 20504static bfd_boolean
dda8d76d 20505process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
20506{
20507 struct archive_info arch;
20508 struct archive_info nested_arch;
20509 size_t got;
32ec8896 20510 bfd_boolean ret = TRUE;
2cf0635d 20511
32ec8896 20512 show_name = TRUE;
2cf0635d
NC
20513
20514 /* The ARCH structure is used to hold information about this archive. */
20515 arch.file_name = NULL;
20516 arch.file = NULL;
20517 arch.index_array = NULL;
20518 arch.sym_table = NULL;
20519 arch.longnames = NULL;
20520
20521 /* The NESTED_ARCH structure is used as a single-item cache of information
20522 about a nested archive (when members of a thin archive reside within
20523 another regular archive file). */
20524 nested_arch.file_name = NULL;
20525 nested_arch.file = NULL;
20526 nested_arch.index_array = NULL;
20527 nested_arch.sym_table = NULL;
20528 nested_arch.longnames = NULL;
20529
dda8d76d 20530 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
20531 filedata->file_size, is_thin_archive,
20532 do_archive_index) != 0)
2cf0635d 20533 {
32ec8896 20534 ret = FALSE;
2cf0635d 20535 goto out;
4145f1d5 20536 }
fb52b2f4 20537
4145f1d5
NC
20538 if (do_archive_index)
20539 {
2cf0635d 20540 if (arch.sym_table == NULL)
1cb7d8b1
AM
20541 error (_("%s: unable to dump the index as none was found\n"),
20542 filedata->file_name);
4145f1d5
NC
20543 else
20544 {
591f7597 20545 unsigned long i, l;
4145f1d5
NC
20546 unsigned long current_pos;
20547
1cb7d8b1
AM
20548 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
20549 "in the symbol table)\n"),
20550 filedata->file_name, (unsigned long) arch.index_num,
20551 arch.sym_size);
dda8d76d
NC
20552
20553 current_pos = ftell (filedata->handle);
4145f1d5 20554
2cf0635d 20555 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 20556 {
1cb7d8b1
AM
20557 if (i == 0
20558 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
20559 {
20560 char * member_name
20561 = get_archive_member_name_at (&arch, arch.index_array[i],
20562 &nested_arch);
2cf0635d 20563
1cb7d8b1
AM
20564 if (member_name != NULL)
20565 {
20566 char * qualified_name
20567 = make_qualified_name (&arch, &nested_arch,
20568 member_name);
2cf0635d 20569
1cb7d8b1
AM
20570 if (qualified_name != NULL)
20571 {
20572 printf (_("Contents of binary %s at offset "),
20573 qualified_name);
c2a7d3f5
NC
20574 (void) print_vma (arch.index_array[i], PREFIX_HEX);
20575 putchar ('\n');
1cb7d8b1
AM
20576 free (qualified_name);
20577 }
fd486f32 20578 free (member_name);
4145f1d5
NC
20579 }
20580 }
2cf0635d
NC
20581
20582 if (l >= arch.sym_size)
4145f1d5 20583 {
1cb7d8b1
AM
20584 error (_("%s: end of the symbol table reached "
20585 "before the end of the index\n"),
dda8d76d 20586 filedata->file_name);
32ec8896 20587 ret = FALSE;
cb8f3167 20588 break;
4145f1d5 20589 }
591f7597 20590 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
20591 printf ("\t%.*s\n",
20592 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 20593 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
20594 }
20595
67ce483b 20596 if (arch.uses_64bit_indices)
c2a7d3f5
NC
20597 l = (l + 7) & ~ 7;
20598 else
20599 l += l & 1;
20600
2cf0635d 20601 if (l < arch.sym_size)
32ec8896 20602 {
d3a49aa8
AM
20603 error (ngettext ("%s: %ld byte remains in the symbol table, "
20604 "but without corresponding entries in "
20605 "the index table\n",
20606 "%s: %ld bytes remain in the symbol table, "
20607 "but without corresponding entries in "
20608 "the index table\n",
20609 arch.sym_size - l),
dda8d76d 20610 filedata->file_name, arch.sym_size - l);
32ec8896
NC
20611 ret = FALSE;
20612 }
4145f1d5 20613
dda8d76d 20614 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 20615 {
1cb7d8b1
AM
20616 error (_("%s: failed to seek back to start of object files "
20617 "in the archive\n"),
dda8d76d 20618 filedata->file_name);
32ec8896 20619 ret = FALSE;
2cf0635d 20620 goto out;
4145f1d5 20621 }
fb52b2f4 20622 }
4145f1d5
NC
20623
20624 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
20625 && !do_segments && !do_header && !do_dump && !do_version
20626 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 20627 && !do_section_groups && !do_dyn_syms)
2cf0635d 20628 {
32ec8896 20629 ret = TRUE; /* Archive index only. */
2cf0635d
NC
20630 goto out;
20631 }
fb52b2f4
NC
20632 }
20633
fb52b2f4
NC
20634 while (1)
20635 {
2cf0635d
NC
20636 char * name;
20637 size_t namelen;
20638 char * qualified_name;
20639
20640 /* Read the next archive header. */
dda8d76d 20641 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
20642 {
20643 error (_("%s: failed to seek to next archive header\n"),
20644 arch.file_name);
20645 ret = FALSE;
20646 break;
20647 }
dda8d76d 20648 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 20649 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
20650 {
20651 if (got == 0)
2cf0635d 20652 break;
28e817cc
NC
20653 /* PR 24049 - we cannot use filedata->file_name as this will
20654 have already been freed. */
20655 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 20656
1cb7d8b1
AM
20657 ret = FALSE;
20658 break;
20659 }
2cf0635d 20660 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
20661 {
20662 error (_("%s: did not find a valid archive header\n"),
20663 arch.file_name);
20664 ret = FALSE;
20665 break;
20666 }
2cf0635d
NC
20667
20668 arch.next_arhdr_offset += sizeof arch.arhdr;
20669
978c4450
AM
20670 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
20671 if (filedata->archive_file_size & 01)
20672 ++filedata->archive_file_size;
2cf0635d
NC
20673
20674 name = get_archive_member_name (&arch, &nested_arch);
20675 if (name == NULL)
fb52b2f4 20676 {
28e817cc 20677 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 20678 ret = FALSE;
d989285c 20679 break;
fb52b2f4 20680 }
2cf0635d 20681 namelen = strlen (name);
fb52b2f4 20682
2cf0635d
NC
20683 qualified_name = make_qualified_name (&arch, &nested_arch, name);
20684 if (qualified_name == NULL)
fb52b2f4 20685 {
28e817cc 20686 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 20687 free (name);
32ec8896 20688 ret = FALSE;
d989285c 20689 break;
fb52b2f4
NC
20690 }
20691
2cf0635d 20692 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
20693 {
20694 /* This is a proxy for an external member of a thin archive. */
20695 Filedata * member_filedata;
20696 char * member_file_name = adjust_relative_path
dda8d76d 20697 (filedata->file_name, name, namelen);
32ec8896 20698
fd486f32 20699 free (name);
1cb7d8b1
AM
20700 if (member_file_name == NULL)
20701 {
fd486f32 20702 free (qualified_name);
1cb7d8b1
AM
20703 ret = FALSE;
20704 break;
20705 }
2cf0635d 20706
1cb7d8b1
AM
20707 member_filedata = open_file (member_file_name);
20708 if (member_filedata == NULL)
20709 {
20710 error (_("Input file '%s' is not readable.\n"), member_file_name);
20711 free (member_file_name);
fd486f32 20712 free (qualified_name);
1cb7d8b1
AM
20713 ret = FALSE;
20714 break;
20715 }
2cf0635d 20716
978c4450 20717 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 20718 member_filedata->file_name = qualified_name;
2cf0635d 20719
1cb7d8b1 20720 if (! process_object (member_filedata))
32ec8896 20721 ret = FALSE;
2cf0635d 20722
1cb7d8b1
AM
20723 close_file (member_filedata);
20724 free (member_file_name);
1cb7d8b1 20725 }
2cf0635d 20726 else if (is_thin_archive)
1cb7d8b1
AM
20727 {
20728 Filedata thin_filedata;
eb02c04d 20729
1cb7d8b1 20730 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 20731
a043396b
NC
20732 /* PR 15140: Allow for corrupt thin archives. */
20733 if (nested_arch.file == NULL)
20734 {
20735 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 20736 qualified_name, name);
fd486f32
AM
20737 free (qualified_name);
20738 free (name);
32ec8896 20739 ret = FALSE;
a043396b
NC
20740 break;
20741 }
fd486f32 20742 free (name);
a043396b 20743
1cb7d8b1 20744 /* This is a proxy for a member of a nested archive. */
978c4450
AM
20745 filedata->archive_file_offset
20746 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 20747
1cb7d8b1
AM
20748 /* The nested archive file will have been opened and setup by
20749 get_archive_member_name. */
978c4450
AM
20750 if (fseek (nested_arch.file, filedata->archive_file_offset,
20751 SEEK_SET) != 0)
1cb7d8b1
AM
20752 {
20753 error (_("%s: failed to seek to archive member.\n"),
20754 nested_arch.file_name);
fd486f32 20755 free (qualified_name);
1cb7d8b1
AM
20756 ret = FALSE;
20757 break;
20758 }
2cf0635d 20759
dda8d76d
NC
20760 thin_filedata.handle = nested_arch.file;
20761 thin_filedata.file_name = qualified_name;
9abca702 20762
1cb7d8b1 20763 if (! process_object (& thin_filedata))
32ec8896 20764 ret = FALSE;
1cb7d8b1 20765 }
2cf0635d 20766 else
1cb7d8b1 20767 {
fd486f32 20768 free (name);
978c4450 20769 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 20770 filedata->file_name = qualified_name;
1cb7d8b1 20771 if (! process_object (filedata))
32ec8896 20772 ret = FALSE;
978c4450 20773 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 20774 /* Stop looping with "negative" archive_file_size. */
978c4450 20775 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 20776 arch.next_arhdr_offset = -1ul;
1cb7d8b1 20777 }
fb52b2f4 20778
2cf0635d 20779 free (qualified_name);
fb52b2f4
NC
20780 }
20781
4145f1d5 20782 out:
2cf0635d
NC
20783 if (nested_arch.file != NULL)
20784 fclose (nested_arch.file);
20785 release_archive (&nested_arch);
20786 release_archive (&arch);
fb52b2f4 20787
d989285c 20788 return ret;
fb52b2f4
NC
20789}
20790
32ec8896 20791static bfd_boolean
2cf0635d 20792process_file (char * file_name)
fb52b2f4 20793{
dda8d76d 20794 Filedata * filedata = NULL;
fb52b2f4
NC
20795 struct stat statbuf;
20796 char armag[SARMAG];
32ec8896 20797 bfd_boolean ret = TRUE;
fb52b2f4
NC
20798
20799 if (stat (file_name, &statbuf) < 0)
20800 {
f24ddbdd
NC
20801 if (errno == ENOENT)
20802 error (_("'%s': No such file\n"), file_name);
20803 else
20804 error (_("Could not locate '%s'. System error message: %s\n"),
20805 file_name, strerror (errno));
32ec8896 20806 return FALSE;
f24ddbdd
NC
20807 }
20808
20809 if (! S_ISREG (statbuf.st_mode))
20810 {
20811 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 20812 return FALSE;
fb52b2f4
NC
20813 }
20814
dda8d76d
NC
20815 filedata = calloc (1, sizeof * filedata);
20816 if (filedata == NULL)
20817 {
20818 error (_("Out of memory allocating file data structure\n"));
20819 return FALSE;
20820 }
20821
20822 filedata->file_name = file_name;
20823 filedata->handle = fopen (file_name, "rb");
20824 if (filedata->handle == NULL)
fb52b2f4 20825 {
f24ddbdd 20826 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 20827 free (filedata);
32ec8896 20828 return FALSE;
fb52b2f4
NC
20829 }
20830
dda8d76d 20831 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 20832 {
4145f1d5 20833 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
20834 fclose (filedata->handle);
20835 free (filedata);
32ec8896 20836 return FALSE;
fb52b2f4
NC
20837 }
20838
dda8d76d 20839 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 20840
fb52b2f4 20841 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 20842 {
dda8d76d 20843 if (! process_archive (filedata, FALSE))
32ec8896
NC
20844 ret = FALSE;
20845 }
2cf0635d 20846 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 20847 {
dda8d76d 20848 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
20849 ret = FALSE;
20850 }
fb52b2f4
NC
20851 else
20852 {
1b513401 20853 if (do_archive_index && !check_all)
4145f1d5
NC
20854 error (_("File %s is not an archive so its index cannot be displayed.\n"),
20855 file_name);
20856
dda8d76d 20857 rewind (filedata->handle);
978c4450 20858 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 20859
dda8d76d 20860 if (! process_object (filedata))
32ec8896 20861 ret = FALSE;
fb52b2f4
NC
20862 }
20863
dda8d76d 20864 fclose (filedata->handle);
8fb879cd
AM
20865 free (filedata->section_headers);
20866 free (filedata->program_headers);
20867 free (filedata->string_table);
6431e409 20868 free (filedata->dump.dump_sects);
dda8d76d 20869 free (filedata);
32ec8896 20870
fd486f32 20871 free (ba_cache.strtab);
1bd6175a 20872 ba_cache.strtab = NULL;
fd486f32 20873 free (ba_cache.symtab);
1bd6175a 20874 ba_cache.symtab = NULL;
fd486f32
AM
20875 ba_cache.filedata = NULL;
20876
fb52b2f4
NC
20877 return ret;
20878}
20879
252b5132
RH
20880#ifdef SUPPORT_DISASSEMBLY
20881/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 20882 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 20883 symbols. */
252b5132
RH
20884
20885void
2cf0635d 20886print_address (unsigned int addr, FILE * outfile)
252b5132
RH
20887{
20888 fprintf (outfile,"0x%8.8x", addr);
20889}
20890
e3c8793a 20891/* Needed by the i386 disassembler. */
dda8d76d 20892
252b5132
RH
20893void
20894db_task_printsym (unsigned int addr)
20895{
20896 print_address (addr, stderr);
20897}
20898#endif
20899
20900int
2cf0635d 20901main (int argc, char ** argv)
252b5132 20902{
ff78d6d6
L
20903 int err;
20904
252b5132
RH
20905#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
20906 setlocale (LC_MESSAGES, "");
3882b010
L
20907#endif
20908#if defined (HAVE_SETLOCALE)
20909 setlocale (LC_CTYPE, "");
252b5132
RH
20910#endif
20911 bindtextdomain (PACKAGE, LOCALEDIR);
20912 textdomain (PACKAGE);
20913
869b9d07
MM
20914 expandargv (&argc, &argv);
20915
dda8d76d 20916 parse_args (& cmdline, argc, argv);
59f14fc0 20917
18bd398b 20918 if (optind < (argc - 1))
1b513401
NC
20919 /* When displaying information for more than one file,
20920 prefix the information with the file name. */
32ec8896 20921 show_name = TRUE;
5656ba2c
L
20922 else if (optind >= argc)
20923 {
1b513401
NC
20924 /* Ensure that the warning is always displayed. */
20925 do_checks = TRUE;
20926
5656ba2c
L
20927 warn (_("Nothing to do.\n"));
20928 usage (stderr);
20929 }
18bd398b 20930
32ec8896 20931 err = FALSE;
252b5132 20932 while (optind < argc)
32ec8896
NC
20933 if (! process_file (argv[optind++]))
20934 err = TRUE;
252b5132 20935
9db70fc3 20936 free (cmdline.dump_sects);
252b5132 20937
7d9813f1
NA
20938 free (dump_ctf_symtab_name);
20939 free (dump_ctf_strtab_name);
20940 free (dump_ctf_parent_name);
20941
32ec8896 20942 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 20943}