readelf: NULL dereference
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
b3adc24a 2 Copyright (C) 1998-2020 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
3bfcb652 47#ifdef HAVE_WCHAR_H
7bfd842d 48#include <wchar.h>
3bfcb652 49#endif
252b5132 50
a952a375 51#if __GNUC__ >= 2
19936277 52/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 53 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 54 Only do this if we believe that the compiler can support a 64 bit
a952a375 55 data type. For now we only rely on GCC being able to do this. */
19936277 56#define BFD64
a952a375
NC
57#endif
58
3db64b00
AM
59#include "bfd.h"
60#include "bucomm.h"
3284fe0c 61#include "elfcomm.h"
19e6b90e 62#include "dwarf.h"
7d9813f1 63#include "ctf-api.h"
252b5132
RH
64
65#include "elf/common.h"
66#include "elf/external.h"
67#include "elf/internal.h"
252b5132 68
4b78141a
NC
69
70/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
71 we can obtain the H8 reloc numbers. We need these for the
72 get_reloc_size() function. We include h8.h again after defining
73 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
74
75#include "elf/h8.h"
76#undef _ELF_H8_H
77
78/* Undo the effects of #including reloc-macros.h. */
79
80#undef START_RELOC_NUMBERS
81#undef RELOC_NUMBER
82#undef FAKE_RELOC
83#undef EMPTY_RELOC
84#undef END_RELOC_NUMBERS
85#undef _RELOC_MACROS_H
86
252b5132
RH
87/* The following headers use the elf/reloc-macros.h file to
88 automatically generate relocation recognition functions
89 such as elf_mips_reloc_type() */
90
91#define RELOC_MACROS_GEN_FUNC
92
a06ea964 93#include "elf/aarch64.h"
252b5132 94#include "elf/alpha.h"
3b16e843 95#include "elf/arc.h"
252b5132 96#include "elf/arm.h"
3b16e843 97#include "elf/avr.h"
1d65ded4 98#include "elf/bfin.h"
60bca95a 99#include "elf/cr16.h"
3b16e843 100#include "elf/cris.h"
1c0d3aa6 101#include "elf/crx.h"
b8891f8d 102#include "elf/csky.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
aca4efc7 106#include "elf/bpf.h"
cfb8c092 107#include "elf/epiphany.h"
252b5132 108#include "elf/fr30.h"
5c70f934 109#include "elf/frv.h"
3f8107ab 110#include "elf/ft32.h"
3b16e843
NC
111#include "elf/h8.h"
112#include "elf/hppa.h"
113#include "elf/i386.h"
f954747f
AM
114#include "elf/i370.h"
115#include "elf/i860.h"
116#include "elf/i960.h"
3b16e843 117#include "elf/ia64.h"
1e4cf259 118#include "elf/ip2k.h"
84e94c90 119#include "elf/lm32.h"
1c0d3aa6 120#include "elf/iq2000.h"
49f58d10 121#include "elf/m32c.h"
3b16e843
NC
122#include "elf/m32r.h"
123#include "elf/m68k.h"
75751cd9 124#include "elf/m68hc11.h"
7b4ae824 125#include "elf/s12z.h"
252b5132 126#include "elf/mcore.h"
15ab5209 127#include "elf/mep.h"
a3c62988 128#include "elf/metag.h"
7ba29e2a 129#include "elf/microblaze.h"
3b16e843 130#include "elf/mips.h"
3c3bdf30 131#include "elf/mmix.h"
3b16e843
NC
132#include "elf/mn10200.h"
133#include "elf/mn10300.h"
5506d11a 134#include "elf/moxie.h"
4970f871 135#include "elf/mt.h"
2469cfa2 136#include "elf/msp430.h"
35c08157 137#include "elf/nds32.h"
fe944acf 138#include "elf/nfp.h"
13761a11 139#include "elf/nios2.h"
73589c9d 140#include "elf/or1k.h"
7d466069 141#include "elf/pj.h"
3b16e843 142#include "elf/ppc.h"
c833c019 143#include "elf/ppc64.h"
2b100bb5 144#include "elf/pru.h"
03336641 145#include "elf/riscv.h"
99c513f6 146#include "elf/rl78.h"
c7927a3c 147#include "elf/rx.h"
a85d7ed0 148#include "elf/s390.h"
1c0d3aa6 149#include "elf/score.h"
3b16e843
NC
150#include "elf/sh.h"
151#include "elf/sparc.h"
e9f53129 152#include "elf/spu.h"
40b36596 153#include "elf/tic6x.h"
aa137e4d
NC
154#include "elf/tilegx.h"
155#include "elf/tilepro.h"
3b16e843 156#include "elf/v850.h"
179d3252 157#include "elf/vax.h"
619ed720 158#include "elf/visium.h"
f96bd6c2 159#include "elf/wasm32.h"
3b16e843 160#include "elf/x86-64.h"
c29aca4a 161#include "elf/xc16x.h"
f6c1a2d5 162#include "elf/xgate.h"
93fbbb04 163#include "elf/xstormy16.h"
88da6820 164#include "elf/xtensa.h"
6655dba2 165#include "elf/z80.h"
252b5132 166
252b5132 167#include "getopt.h"
566b0d53 168#include "libiberty.h"
09c11c86 169#include "safe-ctype.h"
2cf0635d 170#include "filenames.h"
252b5132 171
15b42fb0
AM
172#ifndef offsetof
173#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
174#endif
175
6a40cf0c
NC
176typedef struct elf_section_list
177{
dda8d76d
NC
178 Elf_Internal_Shdr * hdr;
179 struct elf_section_list * next;
6a40cf0c
NC
180} elf_section_list;
181
dda8d76d
NC
182/* Flag bits indicating particular types of dump. */
183#define HEX_DUMP (1 << 0) /* The -x command line switch. */
184#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
185#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
186#define STRING_DUMP (1 << 3) /* The -p command line switch. */
187#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 188#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
189
190typedef unsigned char dump_type;
191
192/* A linked list of the section names for which dumps were requested. */
193struct dump_list_entry
194{
195 char * name;
196 dump_type type;
197 struct dump_list_entry * next;
198};
199
6431e409
AM
200/* A dynamic array of flags indicating for which sections a dump
201 has been requested via command line switches. */
202struct dump_data {
203 dump_type * dump_sects;
204 unsigned int num_dump_sects;
205};
206
207static struct dump_data cmdline;
208
209static struct dump_list_entry * dump_sects_byname;
210
2cf0635d 211char * program_name = "readelf";
dda8d76d 212
32ec8896
NC
213static bfd_boolean show_name = FALSE;
214static bfd_boolean do_dynamic = FALSE;
215static bfd_boolean do_syms = FALSE;
216static bfd_boolean do_dyn_syms = FALSE;
217static bfd_boolean do_reloc = FALSE;
218static bfd_boolean do_sections = FALSE;
219static bfd_boolean do_section_groups = FALSE;
220static bfd_boolean do_section_details = FALSE;
221static bfd_boolean do_segments = FALSE;
222static bfd_boolean do_unwind = FALSE;
223static bfd_boolean do_using_dynamic = FALSE;
224static bfd_boolean do_header = FALSE;
225static bfd_boolean do_dump = FALSE;
226static bfd_boolean do_version = FALSE;
227static bfd_boolean do_histogram = FALSE;
228static bfd_boolean do_debugging = FALSE;
7d9813f1 229static bfd_boolean do_ctf = FALSE;
32ec8896
NC
230static bfd_boolean do_arch = FALSE;
231static bfd_boolean do_notes = FALSE;
232static bfd_boolean do_archive_index = FALSE;
233static bfd_boolean is_32bit_elf = FALSE;
234static bfd_boolean decompress_dumps = FALSE;
252b5132 235
7d9813f1
NA
236static char *dump_ctf_parent_name;
237static char *dump_ctf_symtab_name;
238static char *dump_ctf_strtab_name;
239
e4b17d5c
L
240struct group_list
241{
dda8d76d
NC
242 struct group_list * next;
243 unsigned int section_index;
e4b17d5c
L
244};
245
246struct group
247{
dda8d76d
NC
248 struct group_list * root;
249 unsigned int group_index;
e4b17d5c
L
250};
251
978c4450
AM
252typedef struct filedata
253{
254 const char * file_name;
255 FILE * handle;
256 bfd_size_type file_size;
257 Elf_Internal_Ehdr file_header;
258 Elf_Internal_Shdr * section_headers;
259 Elf_Internal_Phdr * program_headers;
260 char * string_table;
261 unsigned long string_table_length;
262 unsigned long archive_file_offset;
263 unsigned long archive_file_size;
264 unsigned long dynamic_addr;
265 bfd_size_type dynamic_size;
266 size_t dynamic_nent;
267 Elf_Internal_Dyn * dynamic_section;
268 char * dynamic_strings;
269 unsigned long dynamic_strings_length;
270 unsigned long num_dynamic_syms;
271 Elf_Internal_Sym * dynamic_symbols;
272 bfd_vma version_info[16];
273 unsigned int dynamic_syminfo_nent;
274 Elf_Internal_Syminfo * dynamic_syminfo;
275 unsigned long dynamic_syminfo_offset;
276 bfd_size_type nbuckets;
277 bfd_size_type nchains;
278 bfd_vma * buckets;
279 bfd_vma * chains;
280 bfd_size_type ngnubuckets;
281 bfd_size_type ngnuchains;
282 bfd_vma * gnubuckets;
283 bfd_vma * gnuchains;
284 bfd_vma * mipsxlat;
285 bfd_vma gnusymidx;
286 char program_interpreter[PATH_MAX];
287 bfd_vma dynamic_info[DT_ENCODING];
288 bfd_vma dynamic_info_DT_GNU_HASH;
289 bfd_vma dynamic_info_DT_MIPS_XHASH;
290 elf_section_list * symtab_shndx_list;
291 size_t group_count;
292 struct group * section_groups;
293 struct group ** section_headers_groups;
294 /* A dynamic array of flags indicating for which sections a dump of
295 some kind has been requested. It is reset on a per-object file
296 basis and then initialised from the cmdline_dump_sects array,
297 the results of interpreting the -w switch, and the
298 dump_sects_byname list. */
299 struct dump_data dump;
300} Filedata;
aef1f6d0 301
c256ffe7 302/* How to print a vma value. */
843dd992
NC
303typedef enum print_mode
304{
305 HEX,
306 DEC,
307 DEC_5,
308 UNSIGNED,
309 PREFIX_HEX,
310 FULL_HEX,
311 LONG_HEX
312}
313print_mode;
314
bb4d2ac2
L
315/* Versioned symbol info. */
316enum versioned_symbol_info
317{
318 symbol_undefined,
319 symbol_hidden,
320 symbol_public
321};
322
32ec8896 323static const char * get_symbol_version_string
dda8d76d 324 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 325 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 326
9c19a809
NC
327#define UNKNOWN -1
328
2b692964
NC
329#define SECTION_NAME(X) \
330 ((X) == NULL ? _("<none>") \
dda8d76d
NC
331 : filedata->string_table == NULL ? _("<no-strings>") \
332 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
333 : filedata->string_table + (X)->sh_name))
252b5132 334
ee42cf8c 335#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 336
ba5cdace
NC
337#define GET_ELF_SYMBOLS(file, section, sym_count) \
338 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
339 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 340
10ca4b04
L
341#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
342 (strtab != NULL && offset < strtab_size)
978c4450
AM
343#define VALID_DYNAMIC_NAME(filedata, offset) \
344 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
345 filedata->dynamic_strings_length, offset)
d79b3d50
NC
346/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
347 already been called and verified that the string exists. */
978c4450
AM
348#define GET_DYNAMIC_NAME(filedata, offset) \
349 (filedata->dynamic_strings + offset)
18bd398b 350
61865e30
NC
351#define REMOVE_ARCH_BITS(ADDR) \
352 do \
353 { \
dda8d76d 354 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
355 (ADDR) &= ~1; \
356 } \
357 while (0)
f16a9783
MS
358
359/* Get the correct GNU hash section name. */
978c4450
AM
360#define GNU_HASH_SECTION_NAME(filedata) \
361 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 362\f
66cfc0fd
AM
363/* Print a BFD_VMA to an internal buffer, for use in error messages.
364 BFD_FMA_FMT can't be used in translated strings. */
365
366static const char *
367bfd_vmatoa (char *fmtch, bfd_vma value)
368{
369 /* bfd_vmatoa is used more then once in a printf call for output.
370 Cycle through an array of buffers. */
371 static int buf_pos = 0;
372 static struct bfd_vmatoa_buf
373 {
374 char place[64];
375 } buf[4];
376 char *ret;
377 char fmt[32];
378
379 ret = buf[buf_pos++].place;
380 buf_pos %= ARRAY_SIZE (buf);
381
382 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
383 snprintf (ret, sizeof (buf[0].place), fmt, value);
384 return ret;
385}
386
dda8d76d
NC
387/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
388 OFFSET + the offset of the current archive member, if we are examining an
389 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
390 allocate a buffer using malloc and fill that. In either case return the
391 pointer to the start of the retrieved data or NULL if something went wrong.
392 If something does go wrong and REASON is not NULL then emit an error
393 message using REASON as part of the context. */
59245841 394
c256ffe7 395static void *
dda8d76d
NC
396get_data (void * var,
397 Filedata * filedata,
398 unsigned long offset,
399 bfd_size_type size,
400 bfd_size_type nmemb,
401 const char * reason)
a6e9f9df 402{
2cf0635d 403 void * mvar;
57028622 404 bfd_size_type amt = size * nmemb;
a6e9f9df 405
c256ffe7 406 if (size == 0 || nmemb == 0)
a6e9f9df
AM
407 return NULL;
408
57028622
NC
409 /* If the size_t type is smaller than the bfd_size_type, eg because
410 you are building a 32-bit tool on a 64-bit host, then make sure
411 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
412 if ((size_t) size != size
413 || (size_t) nmemb != nmemb
414 || (size_t) amt != amt)
57028622
NC
415 {
416 if (reason)
66cfc0fd
AM
417 error (_("Size truncation prevents reading %s"
418 " elements of size %s for %s\n"),
419 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
420 return NULL;
421 }
422
423 /* Check for size overflow. */
7c1c1904 424 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
425 {
426 if (reason)
66cfc0fd
AM
427 error (_("Size overflow prevents reading %s"
428 " elements of size %s for %s\n"),
429 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
430 return NULL;
431 }
432
c22b42ce 433 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 434 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
435 if (filedata->archive_file_offset > filedata->file_size
436 || offset > filedata->file_size - filedata->archive_file_offset
437 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 438 {
049b0c3a 439 if (reason)
66cfc0fd
AM
440 error (_("Reading %s bytes extends past end of file for %s\n"),
441 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
442 return NULL;
443 }
444
978c4450
AM
445 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
446 SEEK_SET))
071436c6
NC
447 {
448 if (reason)
c9c1d674 449 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 450 filedata->archive_file_offset + offset, reason);
071436c6
NC
451 return NULL;
452 }
453
a6e9f9df
AM
454 mvar = var;
455 if (mvar == NULL)
456 {
7c1c1904
AM
457 /* + 1 so that we can '\0' terminate invalid string table sections. */
458 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
459
460 if (mvar == NULL)
461 {
049b0c3a 462 if (reason)
66cfc0fd
AM
463 error (_("Out of memory allocating %s bytes for %s\n"),
464 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
465 return NULL;
466 }
c256ffe7 467
c9c1d674 468 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
469 }
470
dda8d76d 471 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 472 {
049b0c3a 473 if (reason)
66cfc0fd
AM
474 error (_("Unable to read in %s bytes of %s\n"),
475 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
476 if (mvar != var)
477 free (mvar);
478 return NULL;
479 }
480
481 return mvar;
482}
483
32ec8896
NC
484/* Print a VMA value in the MODE specified.
485 Returns the number of characters displayed. */
cb8f3167 486
32ec8896 487static unsigned int
14a91970 488print_vma (bfd_vma vma, print_mode mode)
66543521 489{
32ec8896 490 unsigned int nc = 0;
66543521 491
14a91970 492 switch (mode)
66543521 493 {
14a91970
AM
494 case FULL_HEX:
495 nc = printf ("0x");
1a0670f3 496 /* Fall through. */
14a91970 497 case LONG_HEX:
f7a99963 498#ifdef BFD64
14a91970 499 if (is_32bit_elf)
437c2fb7 500 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 501#endif
14a91970
AM
502 printf_vma (vma);
503 return nc + 16;
b19aac67 504
14a91970
AM
505 case DEC_5:
506 if (vma <= 99999)
507 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 508 /* Fall through. */
14a91970
AM
509 case PREFIX_HEX:
510 nc = printf ("0x");
1a0670f3 511 /* Fall through. */
14a91970
AM
512 case HEX:
513 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 514
14a91970
AM
515 case DEC:
516 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 517
14a91970
AM
518 case UNSIGNED:
519 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
520
521 default:
522 /* FIXME: Report unrecognised mode ? */
523 return 0;
f7a99963 524 }
f7a99963
NC
525}
526
7bfd842d 527/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 528 multibye characters (assuming the host environment supports them).
31104126 529
7bfd842d
NC
530 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
531
532 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
533 padding as necessary.
171191ba
NC
534
535 Returns the number of emitted characters. */
536
537static unsigned int
32ec8896 538print_symbol (signed int width, const char *symbol)
31104126 539{
171191ba 540 bfd_boolean extra_padding = FALSE;
32ec8896 541 signed int num_printed = 0;
3bfcb652 542#ifdef HAVE_MBSTATE_T
7bfd842d 543 mbstate_t state;
3bfcb652 544#endif
32ec8896 545 unsigned int width_remaining;
961c521f 546
7bfd842d 547 if (width < 0)
961c521f 548 {
88305e1b 549 /* Keep the width positive. This helps the code below. */
961c521f 550 width = - width;
171191ba 551 extra_padding = TRUE;
0b4362b0 552 }
56d8f8a9
NC
553 else if (width == 0)
554 return 0;
961c521f 555
7bfd842d
NC
556 if (do_wide)
557 /* Set the remaining width to a very large value.
558 This simplifies the code below. */
559 width_remaining = INT_MAX;
560 else
561 width_remaining = width;
cb8f3167 562
3bfcb652 563#ifdef HAVE_MBSTATE_T
7bfd842d
NC
564 /* Initialise the multibyte conversion state. */
565 memset (& state, 0, sizeof (state));
3bfcb652 566#endif
961c521f 567
7bfd842d
NC
568 while (width_remaining)
569 {
570 size_t n;
7bfd842d 571 const char c = *symbol++;
961c521f 572
7bfd842d 573 if (c == 0)
961c521f
NC
574 break;
575
7bfd842d
NC
576 /* Do not print control characters directly as they can affect terminal
577 settings. Such characters usually appear in the names generated
578 by the assembler for local labels. */
579 if (ISCNTRL (c))
961c521f 580 {
7bfd842d 581 if (width_remaining < 2)
961c521f
NC
582 break;
583
7bfd842d
NC
584 printf ("^%c", c + 0x40);
585 width_remaining -= 2;
171191ba 586 num_printed += 2;
961c521f 587 }
7bfd842d
NC
588 else if (ISPRINT (c))
589 {
590 putchar (c);
591 width_remaining --;
592 num_printed ++;
593 }
961c521f
NC
594 else
595 {
3bfcb652
NC
596#ifdef HAVE_MBSTATE_T
597 wchar_t w;
598#endif
7bfd842d
NC
599 /* Let printf do the hard work of displaying multibyte characters. */
600 printf ("%.1s", symbol - 1);
601 width_remaining --;
602 num_printed ++;
603
3bfcb652 604#ifdef HAVE_MBSTATE_T
7bfd842d
NC
605 /* Try to find out how many bytes made up the character that was
606 just printed. Advance the symbol pointer past the bytes that
607 were displayed. */
608 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
609#else
610 n = 1;
611#endif
7bfd842d
NC
612 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
613 symbol += (n - 1);
961c521f 614 }
961c521f 615 }
171191ba 616
7bfd842d 617 if (extra_padding && num_printed < width)
171191ba
NC
618 {
619 /* Fill in the remaining spaces. */
7bfd842d
NC
620 printf ("%-*s", width - num_printed, " ");
621 num_printed = width;
171191ba
NC
622 }
623
624 return num_printed;
31104126
NC
625}
626
1449284b 627/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
628 the given section's name. Like print_symbol, except that it does not try
629 to print multibyte characters, it just interprets them as hex values. */
630
631static const char *
dda8d76d 632printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
633{
634#define MAX_PRINT_SEC_NAME_LEN 128
635 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
636 const char * name = SECTION_NAME (sec);
637 char * buf = sec_name_buf;
638 char c;
639 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
640
641 while ((c = * name ++) != 0)
642 {
643 if (ISCNTRL (c))
644 {
645 if (remaining < 2)
646 break;
948f632f 647
74e1a04b
NC
648 * buf ++ = '^';
649 * buf ++ = c + 0x40;
650 remaining -= 2;
651 }
652 else if (ISPRINT (c))
653 {
654 * buf ++ = c;
655 remaining -= 1;
656 }
657 else
658 {
659 static char hex[17] = "0123456789ABCDEF";
660
661 if (remaining < 4)
662 break;
663 * buf ++ = '<';
664 * buf ++ = hex[(c & 0xf0) >> 4];
665 * buf ++ = hex[c & 0x0f];
666 * buf ++ = '>';
667 remaining -= 4;
668 }
669
670 if (remaining == 0)
671 break;
672 }
673
674 * buf = 0;
675 return sec_name_buf;
676}
677
678static const char *
dda8d76d 679printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 680{
dda8d76d 681 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
682 return _("<corrupt>");
683
dda8d76d 684 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
685}
686
89fac5e3
RS
687/* Return a pointer to section NAME, or NULL if no such section exists. */
688
689static Elf_Internal_Shdr *
dda8d76d 690find_section (Filedata * filedata, const char * name)
89fac5e3
RS
691{
692 unsigned int i;
693
68807c3c
NC
694 if (filedata->section_headers == NULL)
695 return NULL;
dda8d76d
NC
696
697 for (i = 0; i < filedata->file_header.e_shnum; i++)
698 if (streq (SECTION_NAME (filedata->section_headers + i), name))
699 return filedata->section_headers + i;
89fac5e3
RS
700
701 return NULL;
702}
703
0b6ae522
DJ
704/* Return a pointer to a section containing ADDR, or NULL if no such
705 section exists. */
706
707static Elf_Internal_Shdr *
dda8d76d 708find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
709{
710 unsigned int i;
711
68807c3c
NC
712 if (filedata->section_headers == NULL)
713 return NULL;
714
dda8d76d 715 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 716 {
dda8d76d
NC
717 Elf_Internal_Shdr *sec = filedata->section_headers + i;
718
0b6ae522
DJ
719 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
720 return sec;
721 }
722
723 return NULL;
724}
725
071436c6 726static Elf_Internal_Shdr *
dda8d76d 727find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
728{
729 unsigned int i;
730
68807c3c
NC
731 if (filedata->section_headers == NULL)
732 return NULL;
733
dda8d76d 734 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 735 {
dda8d76d
NC
736 Elf_Internal_Shdr *sec = filedata->section_headers + i;
737
071436c6
NC
738 if (sec->sh_type == type)
739 return sec;
740 }
741
742 return NULL;
743}
744
657d0d47
CC
745/* Return a pointer to section NAME, or NULL if no such section exists,
746 restricted to the list of sections given in SET. */
747
748static Elf_Internal_Shdr *
dda8d76d 749find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
750{
751 unsigned int i;
752
68807c3c
NC
753 if (filedata->section_headers == NULL)
754 return NULL;
755
657d0d47
CC
756 if (set != NULL)
757 {
758 while ((i = *set++) > 0)
b814a36d
NC
759 {
760 /* See PR 21156 for a reproducer. */
dda8d76d 761 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
762 continue; /* FIXME: Should we issue an error message ? */
763
dda8d76d
NC
764 if (streq (SECTION_NAME (filedata->section_headers + i), name))
765 return filedata->section_headers + i;
b814a36d 766 }
657d0d47
CC
767 }
768
dda8d76d 769 return find_section (filedata, name);
657d0d47
CC
770}
771
32ec8896 772/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
773 This OS has so many departures from the ELF standard that we test it at
774 many places. */
775
32ec8896 776static inline bfd_boolean
dda8d76d 777is_ia64_vms (Filedata * filedata)
28f997cf 778{
dda8d76d
NC
779 return filedata->file_header.e_machine == EM_IA_64
780 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
781}
782
bcedfee6 783/* Guess the relocation size commonly used by the specific machines. */
252b5132 784
32ec8896 785static bfd_boolean
2dc4cec1 786guess_is_rela (unsigned int e_machine)
252b5132 787{
9c19a809 788 switch (e_machine)
252b5132
RH
789 {
790 /* Targets that use REL relocations. */
252b5132 791 case EM_386:
22abe556 792 case EM_IAMCU:
f954747f 793 case EM_960:
e9f53129 794 case EM_ARM:
2b0337b0 795 case EM_D10V:
252b5132 796 case EM_CYGNUS_D10V:
e9f53129 797 case EM_DLX:
252b5132 798 case EM_MIPS:
4fe85591 799 case EM_MIPS_RS3_LE:
e9f53129 800 case EM_CYGNUS_M32R:
1c0d3aa6 801 case EM_SCORE:
f6c1a2d5 802 case EM_XGATE:
fe944acf 803 case EM_NFP:
aca4efc7 804 case EM_BPF:
9c19a809 805 return FALSE;
103f02d3 806
252b5132
RH
807 /* Targets that use RELA relocations. */
808 case EM_68K:
f954747f 809 case EM_860:
a06ea964 810 case EM_AARCH64:
cfb8c092 811 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
812 case EM_ALPHA:
813 case EM_ALTERA_NIOS2:
886a2506
NC
814 case EM_ARC:
815 case EM_ARC_COMPACT:
816 case EM_ARC_COMPACT2:
e9f53129
AM
817 case EM_AVR:
818 case EM_AVR_OLD:
819 case EM_BLACKFIN:
60bca95a 820 case EM_CR16:
e9f53129
AM
821 case EM_CRIS:
822 case EM_CRX:
b8891f8d 823 case EM_CSKY:
2b0337b0 824 case EM_D30V:
252b5132 825 case EM_CYGNUS_D30V:
2b0337b0 826 case EM_FR30:
3f8107ab 827 case EM_FT32:
252b5132 828 case EM_CYGNUS_FR30:
5c70f934 829 case EM_CYGNUS_FRV:
e9f53129
AM
830 case EM_H8S:
831 case EM_H8_300:
832 case EM_H8_300H:
800eeca4 833 case EM_IA_64:
1e4cf259
NC
834 case EM_IP2K:
835 case EM_IP2K_OLD:
3b36097d 836 case EM_IQ2000:
84e94c90 837 case EM_LATTICEMICO32:
ff7eeb89 838 case EM_M32C_OLD:
49f58d10 839 case EM_M32C:
e9f53129
AM
840 case EM_M32R:
841 case EM_MCORE:
15ab5209 842 case EM_CYGNUS_MEP:
a3c62988 843 case EM_METAG:
e9f53129
AM
844 case EM_MMIX:
845 case EM_MN10200:
846 case EM_CYGNUS_MN10200:
847 case EM_MN10300:
848 case EM_CYGNUS_MN10300:
5506d11a 849 case EM_MOXIE:
e9f53129
AM
850 case EM_MSP430:
851 case EM_MSP430_OLD:
d031aafb 852 case EM_MT:
35c08157 853 case EM_NDS32:
64fd6348 854 case EM_NIOS32:
73589c9d 855 case EM_OR1K:
e9f53129
AM
856 case EM_PPC64:
857 case EM_PPC:
2b100bb5 858 case EM_TI_PRU:
e23eba97 859 case EM_RISCV:
99c513f6 860 case EM_RL78:
c7927a3c 861 case EM_RX:
e9f53129
AM
862 case EM_S390:
863 case EM_S390_OLD:
864 case EM_SH:
865 case EM_SPARC:
866 case EM_SPARC32PLUS:
867 case EM_SPARCV9:
868 case EM_SPU:
40b36596 869 case EM_TI_C6000:
aa137e4d
NC
870 case EM_TILEGX:
871 case EM_TILEPRO:
708e2187 872 case EM_V800:
e9f53129
AM
873 case EM_V850:
874 case EM_CYGNUS_V850:
875 case EM_VAX:
619ed720 876 case EM_VISIUM:
e9f53129 877 case EM_X86_64:
8a9036a4 878 case EM_L1OM:
7a9068fe 879 case EM_K1OM:
e9f53129
AM
880 case EM_XSTORMY16:
881 case EM_XTENSA:
882 case EM_XTENSA_OLD:
7ba29e2a
NC
883 case EM_MICROBLAZE:
884 case EM_MICROBLAZE_OLD:
f96bd6c2 885 case EM_WEBASSEMBLY:
9c19a809 886 return TRUE;
103f02d3 887
e9f53129
AM
888 case EM_68HC05:
889 case EM_68HC08:
890 case EM_68HC11:
891 case EM_68HC16:
892 case EM_FX66:
893 case EM_ME16:
d1133906 894 case EM_MMA:
d1133906
NC
895 case EM_NCPU:
896 case EM_NDR1:
e9f53129 897 case EM_PCP:
d1133906 898 case EM_ST100:
e9f53129 899 case EM_ST19:
d1133906 900 case EM_ST7:
e9f53129
AM
901 case EM_ST9PLUS:
902 case EM_STARCORE:
d1133906 903 case EM_SVX:
e9f53129 904 case EM_TINYJ:
9c19a809
NC
905 default:
906 warn (_("Don't know about relocations on this machine architecture\n"));
907 return FALSE;
908 }
909}
252b5132 910
dda8d76d 911/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
912 Returns TRUE upon success, FALSE otherwise. If successful then a
913 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
914 and the number of relocs loaded is placed in *NRELASP. It is the caller's
915 responsibility to free the allocated buffer. */
916
917static bfd_boolean
dda8d76d
NC
918slurp_rela_relocs (Filedata * filedata,
919 unsigned long rel_offset,
920 unsigned long rel_size,
921 Elf_Internal_Rela ** relasp,
922 unsigned long * nrelasp)
9c19a809 923{
2cf0635d 924 Elf_Internal_Rela * relas;
8b73c356 925 size_t nrelas;
4d6ed7c8 926 unsigned int i;
252b5132 927
4d6ed7c8
NC
928 if (is_32bit_elf)
929 {
2cf0635d 930 Elf32_External_Rela * erelas;
103f02d3 931
dda8d76d 932 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 933 rel_size, _("32-bit relocation data"));
a6e9f9df 934 if (!erelas)
32ec8896 935 return FALSE;
252b5132 936
4d6ed7c8 937 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 938
3f5e193b
NC
939 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
940 sizeof (Elf_Internal_Rela));
103f02d3 941
4d6ed7c8
NC
942 if (relas == NULL)
943 {
c256ffe7 944 free (erelas);
591a748a 945 error (_("out of memory parsing relocs\n"));
32ec8896 946 return FALSE;
4d6ed7c8 947 }
103f02d3 948
4d6ed7c8
NC
949 for (i = 0; i < nrelas; i++)
950 {
951 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
952 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 953 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 954 }
103f02d3 955
4d6ed7c8
NC
956 free (erelas);
957 }
958 else
959 {
2cf0635d 960 Elf64_External_Rela * erelas;
103f02d3 961
dda8d76d 962 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 963 rel_size, _("64-bit relocation data"));
a6e9f9df 964 if (!erelas)
32ec8896 965 return FALSE;
4d6ed7c8
NC
966
967 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 968
3f5e193b
NC
969 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
970 sizeof (Elf_Internal_Rela));
103f02d3 971
4d6ed7c8
NC
972 if (relas == NULL)
973 {
c256ffe7 974 free (erelas);
591a748a 975 error (_("out of memory parsing relocs\n"));
32ec8896 976 return FALSE;
9c19a809 977 }
4d6ed7c8
NC
978
979 for (i = 0; i < nrelas; i++)
9c19a809 980 {
66543521
AM
981 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
982 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 983 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
984
985 /* The #ifdef BFD64 below is to prevent a compile time
986 warning. We know that if we do not have a 64 bit data
987 type that we will never execute this code anyway. */
988#ifdef BFD64
dda8d76d
NC
989 if (filedata->file_header.e_machine == EM_MIPS
990 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
991 {
992 /* In little-endian objects, r_info isn't really a
993 64-bit little-endian value: it has a 32-bit
994 little-endian symbol index followed by four
995 individual byte fields. Reorder INFO
996 accordingly. */
91d6fa6a
NC
997 bfd_vma inf = relas[i].r_info;
998 inf = (((inf & 0xffffffff) << 32)
999 | ((inf >> 56) & 0xff)
1000 | ((inf >> 40) & 0xff00)
1001 | ((inf >> 24) & 0xff0000)
1002 | ((inf >> 8) & 0xff000000));
1003 relas[i].r_info = inf;
861fb55a
DJ
1004 }
1005#endif /* BFD64 */
4d6ed7c8 1006 }
103f02d3 1007
4d6ed7c8
NC
1008 free (erelas);
1009 }
32ec8896 1010
4d6ed7c8
NC
1011 *relasp = relas;
1012 *nrelasp = nrelas;
32ec8896 1013 return TRUE;
4d6ed7c8 1014}
103f02d3 1015
dda8d76d 1016/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1017 Returns TRUE upon success, FALSE otherwise. If successful then a
1018 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1019 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1020 responsibility to free the allocated buffer. */
1021
1022static bfd_boolean
dda8d76d
NC
1023slurp_rel_relocs (Filedata * filedata,
1024 unsigned long rel_offset,
1025 unsigned long rel_size,
1026 Elf_Internal_Rela ** relsp,
1027 unsigned long * nrelsp)
4d6ed7c8 1028{
2cf0635d 1029 Elf_Internal_Rela * rels;
8b73c356 1030 size_t nrels;
4d6ed7c8 1031 unsigned int i;
103f02d3 1032
4d6ed7c8
NC
1033 if (is_32bit_elf)
1034 {
2cf0635d 1035 Elf32_External_Rel * erels;
103f02d3 1036
dda8d76d 1037 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1038 rel_size, _("32-bit relocation data"));
a6e9f9df 1039 if (!erels)
32ec8896 1040 return FALSE;
103f02d3 1041
4d6ed7c8 1042 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1043
3f5e193b 1044 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1045
4d6ed7c8
NC
1046 if (rels == NULL)
1047 {
c256ffe7 1048 free (erels);
591a748a 1049 error (_("out of memory parsing relocs\n"));
32ec8896 1050 return FALSE;
4d6ed7c8
NC
1051 }
1052
1053 for (i = 0; i < nrels; i++)
1054 {
1055 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1056 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1057 rels[i].r_addend = 0;
9ea033b2 1058 }
4d6ed7c8
NC
1059
1060 free (erels);
9c19a809
NC
1061 }
1062 else
1063 {
2cf0635d 1064 Elf64_External_Rel * erels;
9ea033b2 1065
dda8d76d 1066 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1067 rel_size, _("64-bit relocation data"));
a6e9f9df 1068 if (!erels)
32ec8896 1069 return FALSE;
103f02d3 1070
4d6ed7c8 1071 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1072
3f5e193b 1073 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1074
4d6ed7c8 1075 if (rels == NULL)
9c19a809 1076 {
c256ffe7 1077 free (erels);
591a748a 1078 error (_("out of memory parsing relocs\n"));
32ec8896 1079 return FALSE;
4d6ed7c8 1080 }
103f02d3 1081
4d6ed7c8
NC
1082 for (i = 0; i < nrels; i++)
1083 {
66543521
AM
1084 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1085 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1086 rels[i].r_addend = 0;
861fb55a
DJ
1087
1088 /* The #ifdef BFD64 below is to prevent a compile time
1089 warning. We know that if we do not have a 64 bit data
1090 type that we will never execute this code anyway. */
1091#ifdef BFD64
dda8d76d
NC
1092 if (filedata->file_header.e_machine == EM_MIPS
1093 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1094 {
1095 /* In little-endian objects, r_info isn't really a
1096 64-bit little-endian value: it has a 32-bit
1097 little-endian symbol index followed by four
1098 individual byte fields. Reorder INFO
1099 accordingly. */
91d6fa6a
NC
1100 bfd_vma inf = rels[i].r_info;
1101 inf = (((inf & 0xffffffff) << 32)
1102 | ((inf >> 56) & 0xff)
1103 | ((inf >> 40) & 0xff00)
1104 | ((inf >> 24) & 0xff0000)
1105 | ((inf >> 8) & 0xff000000));
1106 rels[i].r_info = inf;
861fb55a
DJ
1107 }
1108#endif /* BFD64 */
4d6ed7c8 1109 }
103f02d3 1110
4d6ed7c8
NC
1111 free (erels);
1112 }
32ec8896 1113
4d6ed7c8
NC
1114 *relsp = rels;
1115 *nrelsp = nrels;
32ec8896 1116 return TRUE;
4d6ed7c8 1117}
103f02d3 1118
aca88567
NC
1119/* Returns the reloc type extracted from the reloc info field. */
1120
1121static unsigned int
dda8d76d 1122get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1123{
1124 if (is_32bit_elf)
1125 return ELF32_R_TYPE (reloc_info);
1126
dda8d76d 1127 switch (filedata->file_header.e_machine)
aca88567
NC
1128 {
1129 case EM_MIPS:
1130 /* Note: We assume that reloc_info has already been adjusted for us. */
1131 return ELF64_MIPS_R_TYPE (reloc_info);
1132
1133 case EM_SPARCV9:
1134 return ELF64_R_TYPE_ID (reloc_info);
1135
1136 default:
1137 return ELF64_R_TYPE (reloc_info);
1138 }
1139}
1140
1141/* Return the symbol index extracted from the reloc info field. */
1142
1143static bfd_vma
1144get_reloc_symindex (bfd_vma reloc_info)
1145{
1146 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1147}
1148
13761a11 1149static inline bfd_boolean
dda8d76d 1150uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1151{
1152 return
dda8d76d 1153 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1154 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1155 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1156 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1157 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1158}
1159
d3ba0551
AM
1160/* Display the contents of the relocation data found at the specified
1161 offset. */
ee42cf8c 1162
32ec8896 1163static bfd_boolean
dda8d76d
NC
1164dump_relocations (Filedata * filedata,
1165 unsigned long rel_offset,
1166 unsigned long rel_size,
1167 Elf_Internal_Sym * symtab,
1168 unsigned long nsyms,
1169 char * strtab,
1170 unsigned long strtablen,
1171 int is_rela,
1172 bfd_boolean is_dynsym)
4d6ed7c8 1173{
32ec8896 1174 unsigned long i;
2cf0635d 1175 Elf_Internal_Rela * rels;
32ec8896 1176 bfd_boolean res = TRUE;
103f02d3 1177
4d6ed7c8 1178 if (is_rela == UNKNOWN)
dda8d76d 1179 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1180
4d6ed7c8
NC
1181 if (is_rela)
1182 {
dda8d76d 1183 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1184 return FALSE;
4d6ed7c8
NC
1185 }
1186 else
1187 {
dda8d76d 1188 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1189 return FALSE;
252b5132
RH
1190 }
1191
410f7a12
L
1192 if (is_32bit_elf)
1193 {
1194 if (is_rela)
2c71103e
NC
1195 {
1196 if (do_wide)
1197 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1198 else
1199 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1200 }
410f7a12 1201 else
2c71103e
NC
1202 {
1203 if (do_wide)
1204 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1205 else
1206 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1207 }
410f7a12 1208 }
252b5132 1209 else
410f7a12
L
1210 {
1211 if (is_rela)
2c71103e
NC
1212 {
1213 if (do_wide)
8beeaeb7 1214 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1215 else
1216 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1217 }
410f7a12 1218 else
2c71103e
NC
1219 {
1220 if (do_wide)
8beeaeb7 1221 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1222 else
1223 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1224 }
410f7a12 1225 }
252b5132
RH
1226
1227 for (i = 0; i < rel_size; i++)
1228 {
2cf0635d 1229 const char * rtype;
b34976b6 1230 bfd_vma offset;
91d6fa6a 1231 bfd_vma inf;
b34976b6
AM
1232 bfd_vma symtab_index;
1233 bfd_vma type;
103f02d3 1234
b34976b6 1235 offset = rels[i].r_offset;
91d6fa6a 1236 inf = rels[i].r_info;
103f02d3 1237
dda8d76d 1238 type = get_reloc_type (filedata, inf);
91d6fa6a 1239 symtab_index = get_reloc_symindex (inf);
252b5132 1240
410f7a12
L
1241 if (is_32bit_elf)
1242 {
39dbeff8
AM
1243 printf ("%8.8lx %8.8lx ",
1244 (unsigned long) offset & 0xffffffff,
91d6fa6a 1245 (unsigned long) inf & 0xffffffff);
410f7a12
L
1246 }
1247 else
1248 {
39dbeff8
AM
1249#if BFD_HOST_64BIT_LONG
1250 printf (do_wide
1251 ? "%16.16lx %16.16lx "
1252 : "%12.12lx %12.12lx ",
91d6fa6a 1253 offset, inf);
39dbeff8 1254#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1255#ifndef __MSVCRT__
39dbeff8
AM
1256 printf (do_wide
1257 ? "%16.16llx %16.16llx "
1258 : "%12.12llx %12.12llx ",
91d6fa6a 1259 offset, inf);
6e3d6dc1
NC
1260#else
1261 printf (do_wide
1262 ? "%16.16I64x %16.16I64x "
1263 : "%12.12I64x %12.12I64x ",
91d6fa6a 1264 offset, inf);
6e3d6dc1 1265#endif
39dbeff8 1266#else
2c71103e
NC
1267 printf (do_wide
1268 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1269 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1270 _bfd_int64_high (offset),
1271 _bfd_int64_low (offset),
91d6fa6a
NC
1272 _bfd_int64_high (inf),
1273 _bfd_int64_low (inf));
9ea033b2 1274#endif
410f7a12 1275 }
103f02d3 1276
dda8d76d 1277 switch (filedata->file_header.e_machine)
252b5132
RH
1278 {
1279 default:
1280 rtype = NULL;
1281 break;
1282
a06ea964
NC
1283 case EM_AARCH64:
1284 rtype = elf_aarch64_reloc_type (type);
1285 break;
1286
2b0337b0 1287 case EM_M32R:
252b5132 1288 case EM_CYGNUS_M32R:
9ea033b2 1289 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1290 break;
1291
1292 case EM_386:
22abe556 1293 case EM_IAMCU:
9ea033b2 1294 rtype = elf_i386_reloc_type (type);
252b5132
RH
1295 break;
1296
ba2685cc
AM
1297 case EM_68HC11:
1298 case EM_68HC12:
1299 rtype = elf_m68hc11_reloc_type (type);
1300 break;
75751cd9 1301
7b4ae824
JD
1302 case EM_S12Z:
1303 rtype = elf_s12z_reloc_type (type);
1304 break;
1305
252b5132 1306 case EM_68K:
9ea033b2 1307 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1308 break;
1309
f954747f
AM
1310 case EM_960:
1311 rtype = elf_i960_reloc_type (type);
1312 break;
1313
adde6300 1314 case EM_AVR:
2b0337b0 1315 case EM_AVR_OLD:
adde6300
AM
1316 rtype = elf_avr_reloc_type (type);
1317 break;
1318
9ea033b2
NC
1319 case EM_OLD_SPARCV9:
1320 case EM_SPARC32PLUS:
1321 case EM_SPARCV9:
252b5132 1322 case EM_SPARC:
9ea033b2 1323 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1324 break;
1325
e9f53129
AM
1326 case EM_SPU:
1327 rtype = elf_spu_reloc_type (type);
1328 break;
1329
708e2187
NC
1330 case EM_V800:
1331 rtype = v800_reloc_type (type);
1332 break;
2b0337b0 1333 case EM_V850:
252b5132 1334 case EM_CYGNUS_V850:
9ea033b2 1335 rtype = v850_reloc_type (type);
252b5132
RH
1336 break;
1337
2b0337b0 1338 case EM_D10V:
252b5132 1339 case EM_CYGNUS_D10V:
9ea033b2 1340 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1341 break;
1342
2b0337b0 1343 case EM_D30V:
252b5132 1344 case EM_CYGNUS_D30V:
9ea033b2 1345 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1346 break;
1347
d172d4ba
NC
1348 case EM_DLX:
1349 rtype = elf_dlx_reloc_type (type);
1350 break;
1351
252b5132 1352 case EM_SH:
9ea033b2 1353 rtype = elf_sh_reloc_type (type);
252b5132
RH
1354 break;
1355
2b0337b0 1356 case EM_MN10300:
252b5132 1357 case EM_CYGNUS_MN10300:
9ea033b2 1358 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1359 break;
1360
2b0337b0 1361 case EM_MN10200:
252b5132 1362 case EM_CYGNUS_MN10200:
9ea033b2 1363 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1364 break;
1365
2b0337b0 1366 case EM_FR30:
252b5132 1367 case EM_CYGNUS_FR30:
9ea033b2 1368 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1369 break;
1370
ba2685cc
AM
1371 case EM_CYGNUS_FRV:
1372 rtype = elf_frv_reloc_type (type);
1373 break;
5c70f934 1374
b8891f8d
AJ
1375 case EM_CSKY:
1376 rtype = elf_csky_reloc_type (type);
1377 break;
1378
3f8107ab
AM
1379 case EM_FT32:
1380 rtype = elf_ft32_reloc_type (type);
1381 break;
1382
252b5132 1383 case EM_MCORE:
9ea033b2 1384 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1385 break;
1386
3c3bdf30
NC
1387 case EM_MMIX:
1388 rtype = elf_mmix_reloc_type (type);
1389 break;
1390
5506d11a
AM
1391 case EM_MOXIE:
1392 rtype = elf_moxie_reloc_type (type);
1393 break;
1394
2469cfa2 1395 case EM_MSP430:
dda8d76d 1396 if (uses_msp430x_relocs (filedata))
13761a11
NC
1397 {
1398 rtype = elf_msp430x_reloc_type (type);
1399 break;
1400 }
1a0670f3 1401 /* Fall through. */
2469cfa2
NC
1402 case EM_MSP430_OLD:
1403 rtype = elf_msp430_reloc_type (type);
1404 break;
1405
35c08157
KLC
1406 case EM_NDS32:
1407 rtype = elf_nds32_reloc_type (type);
1408 break;
1409
252b5132 1410 case EM_PPC:
9ea033b2 1411 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1412 break;
1413
c833c019
AM
1414 case EM_PPC64:
1415 rtype = elf_ppc64_reloc_type (type);
1416 break;
1417
252b5132 1418 case EM_MIPS:
4fe85591 1419 case EM_MIPS_RS3_LE:
9ea033b2 1420 rtype = elf_mips_reloc_type (type);
252b5132
RH
1421 break;
1422
e23eba97
NC
1423 case EM_RISCV:
1424 rtype = elf_riscv_reloc_type (type);
1425 break;
1426
252b5132 1427 case EM_ALPHA:
9ea033b2 1428 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1429 break;
1430
1431 case EM_ARM:
9ea033b2 1432 rtype = elf_arm_reloc_type (type);
252b5132
RH
1433 break;
1434
584da044 1435 case EM_ARC:
886a2506
NC
1436 case EM_ARC_COMPACT:
1437 case EM_ARC_COMPACT2:
9ea033b2 1438 rtype = elf_arc_reloc_type (type);
252b5132
RH
1439 break;
1440
1441 case EM_PARISC:
69e617ca 1442 rtype = elf_hppa_reloc_type (type);
252b5132 1443 break;
7d466069 1444
b8720f9d
JL
1445 case EM_H8_300:
1446 case EM_H8_300H:
1447 case EM_H8S:
1448 rtype = elf_h8_reloc_type (type);
1449 break;
1450
73589c9d
CS
1451 case EM_OR1K:
1452 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1453 break;
1454
7d466069 1455 case EM_PJ:
2b0337b0 1456 case EM_PJ_OLD:
7d466069
ILT
1457 rtype = elf_pj_reloc_type (type);
1458 break;
800eeca4
JW
1459 case EM_IA_64:
1460 rtype = elf_ia64_reloc_type (type);
1461 break;
1b61cf92
HPN
1462
1463 case EM_CRIS:
1464 rtype = elf_cris_reloc_type (type);
1465 break;
535c37ff 1466
f954747f
AM
1467 case EM_860:
1468 rtype = elf_i860_reloc_type (type);
1469 break;
1470
bcedfee6 1471 case EM_X86_64:
8a9036a4 1472 case EM_L1OM:
7a9068fe 1473 case EM_K1OM:
bcedfee6
NC
1474 rtype = elf_x86_64_reloc_type (type);
1475 break;
a85d7ed0 1476
f954747f
AM
1477 case EM_S370:
1478 rtype = i370_reloc_type (type);
1479 break;
1480
53c7db4b
KH
1481 case EM_S390_OLD:
1482 case EM_S390:
1483 rtype = elf_s390_reloc_type (type);
1484 break;
93fbbb04 1485
1c0d3aa6
NC
1486 case EM_SCORE:
1487 rtype = elf_score_reloc_type (type);
1488 break;
1489
93fbbb04
GK
1490 case EM_XSTORMY16:
1491 rtype = elf_xstormy16_reloc_type (type);
1492 break;
179d3252 1493
1fe1f39c
NC
1494 case EM_CRX:
1495 rtype = elf_crx_reloc_type (type);
1496 break;
1497
179d3252
JT
1498 case EM_VAX:
1499 rtype = elf_vax_reloc_type (type);
1500 break;
1e4cf259 1501
619ed720
EB
1502 case EM_VISIUM:
1503 rtype = elf_visium_reloc_type (type);
1504 break;
1505
aca4efc7
JM
1506 case EM_BPF:
1507 rtype = elf_bpf_reloc_type (type);
1508 break;
1509
cfb8c092
NC
1510 case EM_ADAPTEVA_EPIPHANY:
1511 rtype = elf_epiphany_reloc_type (type);
1512 break;
1513
1e4cf259
NC
1514 case EM_IP2K:
1515 case EM_IP2K_OLD:
1516 rtype = elf_ip2k_reloc_type (type);
1517 break;
3b36097d
SC
1518
1519 case EM_IQ2000:
1520 rtype = elf_iq2000_reloc_type (type);
1521 break;
88da6820
NC
1522
1523 case EM_XTENSA_OLD:
1524 case EM_XTENSA:
1525 rtype = elf_xtensa_reloc_type (type);
1526 break;
a34e3ecb 1527
84e94c90
NC
1528 case EM_LATTICEMICO32:
1529 rtype = elf_lm32_reloc_type (type);
1530 break;
1531
ff7eeb89 1532 case EM_M32C_OLD:
49f58d10
JB
1533 case EM_M32C:
1534 rtype = elf_m32c_reloc_type (type);
1535 break;
1536
d031aafb
NS
1537 case EM_MT:
1538 rtype = elf_mt_reloc_type (type);
a34e3ecb 1539 break;
1d65ded4
CM
1540
1541 case EM_BLACKFIN:
1542 rtype = elf_bfin_reloc_type (type);
1543 break;
15ab5209
DB
1544
1545 case EM_CYGNUS_MEP:
1546 rtype = elf_mep_reloc_type (type);
1547 break;
60bca95a
NC
1548
1549 case EM_CR16:
1550 rtype = elf_cr16_reloc_type (type);
1551 break;
dd24e3da 1552
7ba29e2a
NC
1553 case EM_MICROBLAZE:
1554 case EM_MICROBLAZE_OLD:
1555 rtype = elf_microblaze_reloc_type (type);
1556 break;
c7927a3c 1557
99c513f6
DD
1558 case EM_RL78:
1559 rtype = elf_rl78_reloc_type (type);
1560 break;
1561
c7927a3c
NC
1562 case EM_RX:
1563 rtype = elf_rx_reloc_type (type);
1564 break;
c29aca4a 1565
a3c62988
NC
1566 case EM_METAG:
1567 rtype = elf_metag_reloc_type (type);
1568 break;
1569
c29aca4a
NC
1570 case EM_XC16X:
1571 case EM_C166:
1572 rtype = elf_xc16x_reloc_type (type);
1573 break;
40b36596
JM
1574
1575 case EM_TI_C6000:
1576 rtype = elf_tic6x_reloc_type (type);
1577 break;
aa137e4d
NC
1578
1579 case EM_TILEGX:
1580 rtype = elf_tilegx_reloc_type (type);
1581 break;
1582
1583 case EM_TILEPRO:
1584 rtype = elf_tilepro_reloc_type (type);
1585 break;
f6c1a2d5 1586
f96bd6c2
PC
1587 case EM_WEBASSEMBLY:
1588 rtype = elf_wasm32_reloc_type (type);
1589 break;
1590
f6c1a2d5
NC
1591 case EM_XGATE:
1592 rtype = elf_xgate_reloc_type (type);
1593 break;
36591ba1
SL
1594
1595 case EM_ALTERA_NIOS2:
1596 rtype = elf_nios2_reloc_type (type);
1597 break;
2b100bb5
DD
1598
1599 case EM_TI_PRU:
1600 rtype = elf_pru_reloc_type (type);
1601 break;
fe944acf
FT
1602
1603 case EM_NFP:
1604 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1605 rtype = elf_nfp3200_reloc_type (type);
1606 else
1607 rtype = elf_nfp_reloc_type (type);
1608 break;
6655dba2
SB
1609
1610 case EM_Z80:
1611 rtype = elf_z80_reloc_type (type);
1612 break;
252b5132
RH
1613 }
1614
1615 if (rtype == NULL)
39dbeff8 1616 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1617 else
5c144731 1618 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1619
dda8d76d 1620 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1621 && rtype != NULL
7ace3541
RH
1622 && streq (rtype, "R_ALPHA_LITUSE")
1623 && is_rela)
1624 {
1625 switch (rels[i].r_addend)
1626 {
1627 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1628 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1629 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1630 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1631 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1632 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1633 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1634 default: rtype = NULL;
1635 }
32ec8896 1636
7ace3541
RH
1637 if (rtype)
1638 printf (" (%s)", rtype);
1639 else
1640 {
1641 putchar (' ');
1642 printf (_("<unknown addend: %lx>"),
1643 (unsigned long) rels[i].r_addend);
32ec8896 1644 res = FALSE;
7ace3541
RH
1645 }
1646 }
1647 else if (symtab_index)
252b5132 1648 {
af3fc3bc 1649 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1650 {
27a45f42
AS
1651 error (_(" bad symbol index: %08lx in reloc\n"),
1652 (unsigned long) symtab_index);
32ec8896
NC
1653 res = FALSE;
1654 }
af3fc3bc 1655 else
19936277 1656 {
2cf0635d 1657 Elf_Internal_Sym * psym;
bb4d2ac2
L
1658 const char * version_string;
1659 enum versioned_symbol_info sym_info;
1660 unsigned short vna_other;
19936277 1661
af3fc3bc 1662 psym = symtab + symtab_index;
103f02d3 1663
bb4d2ac2 1664 version_string
dda8d76d 1665 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1666 strtab, strtablen,
1667 symtab_index,
1668 psym,
1669 &sym_info,
1670 &vna_other);
1671
af3fc3bc 1672 printf (" ");
171191ba 1673
d8045f23
NC
1674 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1675 {
1676 const char * name;
1677 unsigned int len;
1678 unsigned int width = is_32bit_elf ? 8 : 14;
1679
1680 /* Relocations against GNU_IFUNC symbols do not use the value
1681 of the symbol as the address to relocate against. Instead
1682 they invoke the function named by the symbol and use its
1683 result as the address for relocation.
1684
1685 To indicate this to the user, do not display the value of
1686 the symbol in the "Symbols's Value" field. Instead show
1687 its name followed by () as a hint that the symbol is
1688 invoked. */
1689
1690 if (strtab == NULL
1691 || psym->st_name == 0
1692 || psym->st_name >= strtablen)
1693 name = "??";
1694 else
1695 name = strtab + psym->st_name;
1696
1697 len = print_symbol (width, name);
bb4d2ac2
L
1698 if (version_string)
1699 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1700 version_string);
d8045f23
NC
1701 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1702 }
1703 else
1704 {
1705 print_vma (psym->st_value, LONG_HEX);
171191ba 1706
d8045f23
NC
1707 printf (is_32bit_elf ? " " : " ");
1708 }
103f02d3 1709
af3fc3bc 1710 if (psym->st_name == 0)
f1ef08cb 1711 {
2cf0635d 1712 const char * sec_name = "<null>";
f1ef08cb
AM
1713 char name_buf[40];
1714
1715 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1716 {
dda8d76d
NC
1717 if (psym->st_shndx < filedata->file_header.e_shnum)
1718 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1719 else if (psym->st_shndx == SHN_ABS)
1720 sec_name = "ABS";
1721 else if (psym->st_shndx == SHN_COMMON)
1722 sec_name = "COMMON";
dda8d76d 1723 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1724 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1725 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1726 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1727 sec_name = "SCOMMON";
dda8d76d 1728 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1729 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1730 sec_name = "SUNDEF";
dda8d76d
NC
1731 else if ((filedata->file_header.e_machine == EM_X86_64
1732 || filedata->file_header.e_machine == EM_L1OM
1733 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1734 && psym->st_shndx == SHN_X86_64_LCOMMON)
1735 sec_name = "LARGE_COMMON";
dda8d76d
NC
1736 else if (filedata->file_header.e_machine == EM_IA_64
1737 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1738 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1739 sec_name = "ANSI_COM";
dda8d76d 1740 else if (is_ia64_vms (filedata)
148b93f2
NC
1741 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1742 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1743 else
1744 {
1745 sprintf (name_buf, "<section 0x%x>",
1746 (unsigned int) psym->st_shndx);
1747 sec_name = name_buf;
1748 }
1749 }
1750 print_symbol (22, sec_name);
1751 }
af3fc3bc 1752 else if (strtab == NULL)
d79b3d50 1753 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1754 else if (psym->st_name >= strtablen)
32ec8896 1755 {
27a45f42
AS
1756 error (_("<corrupt string table index: %3ld>\n"),
1757 psym->st_name);
32ec8896
NC
1758 res = FALSE;
1759 }
af3fc3bc 1760 else
bb4d2ac2
L
1761 {
1762 print_symbol (22, strtab + psym->st_name);
1763 if (version_string)
1764 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1765 version_string);
1766 }
103f02d3 1767
af3fc3bc 1768 if (is_rela)
171191ba 1769 {
7360e63f 1770 bfd_vma off = rels[i].r_addend;
171191ba 1771
7360e63f 1772 if ((bfd_signed_vma) off < 0)
598aaa76 1773 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1774 else
598aaa76 1775 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1776 }
19936277 1777 }
252b5132 1778 }
1b228002 1779 else if (is_rela)
f7a99963 1780 {
7360e63f 1781 bfd_vma off = rels[i].r_addend;
e04d7088
L
1782
1783 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1784 if ((bfd_signed_vma) off < 0)
e04d7088
L
1785 printf ("-%" BFD_VMA_FMT "x", - off);
1786 else
1787 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1788 }
252b5132 1789
dda8d76d 1790 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1791 && rtype != NULL
1792 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1793 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1794
252b5132 1795 putchar ('\n');
2c71103e 1796
aca88567 1797#ifdef BFD64
dda8d76d 1798 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1799 {
91d6fa6a
NC
1800 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1801 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1802 const char * rtype2 = elf_mips_reloc_type (type2);
1803 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1804
2c71103e
NC
1805 printf (" Type2: ");
1806
1807 if (rtype2 == NULL)
39dbeff8
AM
1808 printf (_("unrecognized: %-7lx"),
1809 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1810 else
1811 printf ("%-17.17s", rtype2);
1812
18bd398b 1813 printf ("\n Type3: ");
2c71103e
NC
1814
1815 if (rtype3 == NULL)
39dbeff8
AM
1816 printf (_("unrecognized: %-7lx"),
1817 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1818 else
1819 printf ("%-17.17s", rtype3);
1820
53c7db4b 1821 putchar ('\n');
2c71103e 1822 }
aca88567 1823#endif /* BFD64 */
252b5132
RH
1824 }
1825
c8286bd1 1826 free (rels);
32ec8896
NC
1827
1828 return res;
252b5132
RH
1829}
1830
37c18eed
SD
1831static const char *
1832get_aarch64_dynamic_type (unsigned long type)
1833{
1834 switch (type)
1835 {
1836 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1837 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1838 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1839 default:
1840 return NULL;
1841 }
1842}
1843
252b5132 1844static const char *
d3ba0551 1845get_mips_dynamic_type (unsigned long type)
252b5132
RH
1846{
1847 switch (type)
1848 {
1849 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1850 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1851 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1852 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1853 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1854 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1855 case DT_MIPS_MSYM: return "MIPS_MSYM";
1856 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1857 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1858 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1859 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1860 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1861 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1862 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1863 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1864 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1865 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1866 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1867 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1868 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1869 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1870 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1871 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1872 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1873 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1874 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1875 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1876 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1877 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1878 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1879 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1880 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1881 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1882 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1883 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1884 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1885 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1886 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1887 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1888 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1889 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1890 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1891 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1892 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1893 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1894 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1895 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1896 default:
1897 return NULL;
1898 }
1899}
1900
9a097730 1901static const char *
d3ba0551 1902get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1903{
1904 switch (type)
1905 {
1906 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1907 default:
1908 return NULL;
1909 }
103f02d3
UD
1910}
1911
7490d522
AM
1912static const char *
1913get_ppc_dynamic_type (unsigned long type)
1914{
1915 switch (type)
1916 {
a7f2871e 1917 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1918 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1919 default:
1920 return NULL;
1921 }
1922}
1923
f1cb7e17 1924static const char *
d3ba0551 1925get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1926{
1927 switch (type)
1928 {
a7f2871e
AM
1929 case DT_PPC64_GLINK: return "PPC64_GLINK";
1930 case DT_PPC64_OPD: return "PPC64_OPD";
1931 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1932 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1933 default:
1934 return NULL;
1935 }
1936}
1937
103f02d3 1938static const char *
d3ba0551 1939get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1940{
1941 switch (type)
1942 {
1943 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1944 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1945 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1946 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1947 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1948 case DT_HP_PREINIT: return "HP_PREINIT";
1949 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1950 case DT_HP_NEEDED: return "HP_NEEDED";
1951 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1952 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1953 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1954 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1955 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1956 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1957 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1958 case DT_HP_FILTERED: return "HP_FILTERED";
1959 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1960 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1961 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1962 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1963 case DT_PLT: return "PLT";
1964 case DT_PLT_SIZE: return "PLT_SIZE";
1965 case DT_DLT: return "DLT";
1966 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1967 default:
1968 return NULL;
1969 }
1970}
9a097730 1971
ecc51f48 1972static const char *
d3ba0551 1973get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1974{
1975 switch (type)
1976 {
148b93f2
NC
1977 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1978 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1979 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1980 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1981 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1982 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1983 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1984 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1985 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1986 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1987 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1988 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1989 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1990 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1991 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1992 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1993 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1994 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1995 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1996 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1997 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1998 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1999 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2000 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2001 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2002 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2003 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2004 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2005 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2006 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2007 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2008 default:
2009 return NULL;
2010 }
2011}
2012
fd85a6a1
NC
2013static const char *
2014get_solaris_section_type (unsigned long type)
2015{
2016 switch (type)
2017 {
2018 case 0x6fffffee: return "SUNW_ancillary";
2019 case 0x6fffffef: return "SUNW_capchain";
2020 case 0x6ffffff0: return "SUNW_capinfo";
2021 case 0x6ffffff1: return "SUNW_symsort";
2022 case 0x6ffffff2: return "SUNW_tlssort";
2023 case 0x6ffffff3: return "SUNW_LDYNSYM";
2024 case 0x6ffffff4: return "SUNW_dof";
2025 case 0x6ffffff5: return "SUNW_cap";
2026 case 0x6ffffff6: return "SUNW_SIGNATURE";
2027 case 0x6ffffff7: return "SUNW_ANNOTATE";
2028 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2029 case 0x6ffffff9: return "SUNW_DEBUG";
2030 case 0x6ffffffa: return "SUNW_move";
2031 case 0x6ffffffb: return "SUNW_COMDAT";
2032 case 0x6ffffffc: return "SUNW_syminfo";
2033 case 0x6ffffffd: return "SUNW_verdef";
2034 case 0x6ffffffe: return "SUNW_verneed";
2035 case 0x6fffffff: return "SUNW_versym";
2036 case 0x70000000: return "SPARC_GOTDATA";
2037 default: return NULL;
2038 }
2039}
2040
fabcb361
RH
2041static const char *
2042get_alpha_dynamic_type (unsigned long type)
2043{
2044 switch (type)
2045 {
2046 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2047 default: return NULL;
fabcb361
RH
2048 }
2049}
2050
1c0d3aa6
NC
2051static const char *
2052get_score_dynamic_type (unsigned long type)
2053{
2054 switch (type)
2055 {
2056 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2057 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2058 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2059 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2060 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2061 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2062 default: return NULL;
1c0d3aa6
NC
2063 }
2064}
2065
40b36596
JM
2066static const char *
2067get_tic6x_dynamic_type (unsigned long type)
2068{
2069 switch (type)
2070 {
2071 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2072 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2073 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2074 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2075 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2076 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2077 default: return NULL;
40b36596
JM
2078 }
2079}
1c0d3aa6 2080
36591ba1
SL
2081static const char *
2082get_nios2_dynamic_type (unsigned long type)
2083{
2084 switch (type)
2085 {
2086 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2087 default: return NULL;
36591ba1
SL
2088 }
2089}
2090
fd85a6a1
NC
2091static const char *
2092get_solaris_dynamic_type (unsigned long type)
2093{
2094 switch (type)
2095 {
2096 case 0x6000000d: return "SUNW_AUXILIARY";
2097 case 0x6000000e: return "SUNW_RTLDINF";
2098 case 0x6000000f: return "SUNW_FILTER";
2099 case 0x60000010: return "SUNW_CAP";
2100 case 0x60000011: return "SUNW_SYMTAB";
2101 case 0x60000012: return "SUNW_SYMSZ";
2102 case 0x60000013: return "SUNW_SORTENT";
2103 case 0x60000014: return "SUNW_SYMSORT";
2104 case 0x60000015: return "SUNW_SYMSORTSZ";
2105 case 0x60000016: return "SUNW_TLSSORT";
2106 case 0x60000017: return "SUNW_TLSSORTSZ";
2107 case 0x60000018: return "SUNW_CAPINFO";
2108 case 0x60000019: return "SUNW_STRPAD";
2109 case 0x6000001a: return "SUNW_CAPCHAIN";
2110 case 0x6000001b: return "SUNW_LDMACH";
2111 case 0x6000001d: return "SUNW_CAPCHAINENT";
2112 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2113 case 0x60000021: return "SUNW_PARENT";
2114 case 0x60000023: return "SUNW_ASLR";
2115 case 0x60000025: return "SUNW_RELAX";
2116 case 0x60000029: return "SUNW_NXHEAP";
2117 case 0x6000002b: return "SUNW_NXSTACK";
2118
2119 case 0x70000001: return "SPARC_REGISTER";
2120 case 0x7ffffffd: return "AUXILIARY";
2121 case 0x7ffffffe: return "USED";
2122 case 0x7fffffff: return "FILTER";
2123
15f205b1 2124 default: return NULL;
fd85a6a1
NC
2125 }
2126}
2127
252b5132 2128static const char *
dda8d76d 2129get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2130{
e9e44622 2131 static char buff[64];
252b5132
RH
2132
2133 switch (type)
2134 {
2135 case DT_NULL: return "NULL";
2136 case DT_NEEDED: return "NEEDED";
2137 case DT_PLTRELSZ: return "PLTRELSZ";
2138 case DT_PLTGOT: return "PLTGOT";
2139 case DT_HASH: return "HASH";
2140 case DT_STRTAB: return "STRTAB";
2141 case DT_SYMTAB: return "SYMTAB";
2142 case DT_RELA: return "RELA";
2143 case DT_RELASZ: return "RELASZ";
2144 case DT_RELAENT: return "RELAENT";
2145 case DT_STRSZ: return "STRSZ";
2146 case DT_SYMENT: return "SYMENT";
2147 case DT_INIT: return "INIT";
2148 case DT_FINI: return "FINI";
2149 case DT_SONAME: return "SONAME";
2150 case DT_RPATH: return "RPATH";
2151 case DT_SYMBOLIC: return "SYMBOLIC";
2152 case DT_REL: return "REL";
2153 case DT_RELSZ: return "RELSZ";
2154 case DT_RELENT: return "RELENT";
2155 case DT_PLTREL: return "PLTREL";
2156 case DT_DEBUG: return "DEBUG";
2157 case DT_TEXTREL: return "TEXTREL";
2158 case DT_JMPREL: return "JMPREL";
2159 case DT_BIND_NOW: return "BIND_NOW";
2160 case DT_INIT_ARRAY: return "INIT_ARRAY";
2161 case DT_FINI_ARRAY: return "FINI_ARRAY";
2162 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2163 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2164 case DT_RUNPATH: return "RUNPATH";
2165 case DT_FLAGS: return "FLAGS";
2d0e6f43 2166
d1133906
NC
2167 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2168 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2169 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2170
05107a46 2171 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2172 case DT_PLTPADSZ: return "PLTPADSZ";
2173 case DT_MOVEENT: return "MOVEENT";
2174 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2175 case DT_FEATURE: return "FEATURE";
252b5132
RH
2176 case DT_POSFLAG_1: return "POSFLAG_1";
2177 case DT_SYMINSZ: return "SYMINSZ";
2178 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2179
252b5132 2180 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2181 case DT_CONFIG: return "CONFIG";
2182 case DT_DEPAUDIT: return "DEPAUDIT";
2183 case DT_AUDIT: return "AUDIT";
2184 case DT_PLTPAD: return "PLTPAD";
2185 case DT_MOVETAB: return "MOVETAB";
252b5132 2186 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2187
252b5132 2188 case DT_VERSYM: return "VERSYM";
103f02d3 2189
67a4f2b7
AO
2190 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2191 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2192 case DT_RELACOUNT: return "RELACOUNT";
2193 case DT_RELCOUNT: return "RELCOUNT";
2194 case DT_FLAGS_1: return "FLAGS_1";
2195 case DT_VERDEF: return "VERDEF";
2196 case DT_VERDEFNUM: return "VERDEFNUM";
2197 case DT_VERNEED: return "VERNEED";
2198 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2199
019148e4 2200 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2201 case DT_USED: return "USED";
2202 case DT_FILTER: return "FILTER";
103f02d3 2203
047b2264
JJ
2204 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2205 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2206 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2207 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2208 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2209 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2210
252b5132
RH
2211 default:
2212 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2213 {
2cf0635d 2214 const char * result;
103f02d3 2215
dda8d76d 2216 switch (filedata->file_header.e_machine)
252b5132 2217 {
37c18eed
SD
2218 case EM_AARCH64:
2219 result = get_aarch64_dynamic_type (type);
2220 break;
252b5132 2221 case EM_MIPS:
4fe85591 2222 case EM_MIPS_RS3_LE:
252b5132
RH
2223 result = get_mips_dynamic_type (type);
2224 break;
9a097730
RH
2225 case EM_SPARCV9:
2226 result = get_sparc64_dynamic_type (type);
2227 break;
7490d522
AM
2228 case EM_PPC:
2229 result = get_ppc_dynamic_type (type);
2230 break;
f1cb7e17
AM
2231 case EM_PPC64:
2232 result = get_ppc64_dynamic_type (type);
2233 break;
ecc51f48
NC
2234 case EM_IA_64:
2235 result = get_ia64_dynamic_type (type);
2236 break;
fabcb361
RH
2237 case EM_ALPHA:
2238 result = get_alpha_dynamic_type (type);
2239 break;
1c0d3aa6
NC
2240 case EM_SCORE:
2241 result = get_score_dynamic_type (type);
2242 break;
40b36596
JM
2243 case EM_TI_C6000:
2244 result = get_tic6x_dynamic_type (type);
2245 break;
36591ba1
SL
2246 case EM_ALTERA_NIOS2:
2247 result = get_nios2_dynamic_type (type);
2248 break;
252b5132 2249 default:
dda8d76d 2250 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2251 result = get_solaris_dynamic_type (type);
2252 else
2253 result = NULL;
252b5132
RH
2254 break;
2255 }
2256
2257 if (result != NULL)
2258 return result;
2259
e9e44622 2260 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2261 }
eec8f817 2262 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2263 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2264 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2265 {
2cf0635d 2266 const char * result;
103f02d3 2267
dda8d76d 2268 switch (filedata->file_header.e_machine)
103f02d3
UD
2269 {
2270 case EM_PARISC:
2271 result = get_parisc_dynamic_type (type);
2272 break;
148b93f2
NC
2273 case EM_IA_64:
2274 result = get_ia64_dynamic_type (type);
2275 break;
103f02d3 2276 default:
dda8d76d 2277 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2278 result = get_solaris_dynamic_type (type);
2279 else
2280 result = NULL;
103f02d3
UD
2281 break;
2282 }
2283
2284 if (result != NULL)
2285 return result;
2286
e9e44622
JJ
2287 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2288 type);
103f02d3 2289 }
252b5132 2290 else
e9e44622 2291 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2292
252b5132
RH
2293 return buff;
2294 }
2295}
2296
2297static char *
d3ba0551 2298get_file_type (unsigned e_type)
252b5132 2299{
89246a0e 2300 static char buff[64];
252b5132
RH
2301
2302 switch (e_type)
2303 {
32ec8896
NC
2304 case ET_NONE: return _("NONE (None)");
2305 case ET_REL: return _("REL (Relocatable file)");
2306 case ET_EXEC: return _("EXEC (Executable file)");
2307 case ET_DYN: return _("DYN (Shared object file)");
2308 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2309
2310 default:
2311 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2312 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2313 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2314 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2315 else
e9e44622 2316 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2317 return buff;
2318 }
2319}
2320
2321static char *
d3ba0551 2322get_machine_name (unsigned e_machine)
252b5132 2323{
b34976b6 2324 static char buff[64]; /* XXX */
252b5132
RH
2325
2326 switch (e_machine)
2327 {
55e22ca8
NC
2328 /* Please keep this switch table sorted by increasing EM_ value. */
2329 /* 0 */
c45021f2
NC
2330 case EM_NONE: return _("None");
2331 case EM_M32: return "WE32100";
2332 case EM_SPARC: return "Sparc";
2333 case EM_386: return "Intel 80386";
2334 case EM_68K: return "MC68000";
2335 case EM_88K: return "MC88000";
22abe556 2336 case EM_IAMCU: return "Intel MCU";
fb70ec17 2337 case EM_860: return "Intel 80860";
c45021f2
NC
2338 case EM_MIPS: return "MIPS R3000";
2339 case EM_S370: return "IBM System/370";
55e22ca8 2340 /* 10 */
7036c0e1 2341 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2342 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2343 case EM_PARISC: return "HPPA";
55e22ca8 2344 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2345 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2346 case EM_960: return "Intel 80960";
c45021f2 2347 case EM_PPC: return "PowerPC";
55e22ca8 2348 /* 20 */
285d1771 2349 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2350 case EM_S390_OLD:
2351 case EM_S390: return "IBM S/390";
2352 case EM_SPU: return "SPU";
2353 /* 30 */
2354 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2355 case EM_FR20: return "Fujitsu FR20";
2356 case EM_RH32: return "TRW RH32";
b34976b6 2357 case EM_MCORE: return "MCORE";
55e22ca8 2358 /* 40 */
7036c0e1
AJ
2359 case EM_ARM: return "ARM";
2360 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2361 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2362 case EM_SPARCV9: return "Sparc v9";
2363 case EM_TRICORE: return "Siemens Tricore";
584da044 2364 case EM_ARC: return "ARC";
c2dcd04e
NC
2365 case EM_H8_300: return "Renesas H8/300";
2366 case EM_H8_300H: return "Renesas H8/300H";
2367 case EM_H8S: return "Renesas H8S";
2368 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2369 /* 50 */
30800947 2370 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2371 case EM_MIPS_X: return "Stanford MIPS-X";
2372 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2373 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2374 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2375 case EM_PCP: return "Siemens PCP";
2376 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2377 case EM_NDR1: return "Denso NDR1 microprocesspr";
2378 case EM_STARCORE: return "Motorola Star*Core processor";
2379 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2380 /* 60 */
7036c0e1
AJ
2381 case EM_ST100: return "STMicroelectronics ST100 processor";
2382 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2383 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2384 case EM_PDSP: return "Sony DSP processor";
2385 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2386 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2387 case EM_FX66: return "Siemens FX66 microcontroller";
2388 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2389 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2390 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2391 /* 70 */
7036c0e1
AJ
2392 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2393 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2394 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2395 case EM_SVX: return "Silicon Graphics SVx";
2396 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2397 case EM_VAX: return "Digital VAX";
1b61cf92 2398 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2399 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2400 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2401 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2402 /* 80 */
b34976b6 2403 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2404 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2405 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2406 case EM_AVR_OLD:
2407 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2408 case EM_CYGNUS_FR30:
2409 case EM_FR30: return "Fujitsu FR30";
2410 case EM_CYGNUS_D10V:
2411 case EM_D10V: return "d10v";
2412 case EM_CYGNUS_D30V:
2413 case EM_D30V: return "d30v";
2414 case EM_CYGNUS_V850:
2415 case EM_V850: return "Renesas V850";
2416 case EM_CYGNUS_M32R:
2417 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2418 case EM_CYGNUS_MN10300:
2419 case EM_MN10300: return "mn10300";
2420 /* 90 */
2421 case EM_CYGNUS_MN10200:
2422 case EM_MN10200: return "mn10200";
2423 case EM_PJ: return "picoJava";
73589c9d 2424 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2425 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2426 case EM_XTENSA_OLD:
2427 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2428 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2429 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2430 case EM_NS32K: return "National Semiconductor 32000 series";
2431 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2432 case EM_SNP1K: return "Trebia SNP 1000 processor";
2433 /* 100 */
9abca702 2434 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2435 case EM_IP2K_OLD:
2436 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2437 case EM_MAX: return "MAX Processor";
2438 case EM_CR: return "National Semiconductor CompactRISC";
2439 case EM_F2MC16: return "Fujitsu F2MC16";
2440 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2441 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2442 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2443 case EM_SEP: return "Sharp embedded microprocessor";
2444 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2445 /* 110 */
11636f9e
JM
2446 case EM_UNICORE: return "Unicore";
2447 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2448 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2449 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2450 case EM_CRX: return "National Semiconductor CRX microprocessor";
2451 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2452 case EM_C166:
d70c5fc7 2453 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2454 case EM_M16C: return "Renesas M16C series microprocessors";
2455 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2456 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2457 /* 120 */
2458 case EM_M32C: return "Renesas M32c";
2459 /* 130 */
11636f9e
JM
2460 case EM_TSK3000: return "Altium TSK3000 core";
2461 case EM_RS08: return "Freescale RS08 embedded processor";
2462 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2463 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2464 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2465 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2466 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2467 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2468 /* 140 */
11636f9e
JM
2469 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2470 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2471 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2472 case EM_TI_PRU: return "TI PRU I/O processor";
2473 /* 160 */
11636f9e
JM
2474 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2475 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2476 case EM_R32C: return "Renesas R32C series microprocessors";
2477 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2478 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2479 case EM_8051: return "Intel 8051 and variants";
2480 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2481 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2482 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2483 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2484 /* 170 */
11636f9e
JM
2485 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2486 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2487 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2488 case EM_RX: return "Renesas RX";
a3c62988 2489 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2490 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2491 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2492 case EM_CR16:
2493 case EM_MICROBLAZE:
2494 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2495 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2496 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2497 /* 180 */
2498 case EM_L1OM: return "Intel L1OM";
2499 case EM_K1OM: return "Intel K1OM";
2500 case EM_INTEL182: return "Intel (reserved)";
2501 case EM_AARCH64: return "AArch64";
2502 case EM_ARM184: return "ARM (reserved)";
2503 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2504 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2505 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2506 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2507 /* 190 */
11636f9e 2508 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2509 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2510 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2511 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2512 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2513 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2514 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2515 case EM_RL78: return "Renesas RL78";
6d913794 2516 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2517 case EM_78K0R: return "Renesas 78K0R";
2518 /* 200 */
6d913794 2519 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2520 case EM_BA1: return "Beyond BA1 CPU architecture";
2521 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2522 case EM_XCORE: return "XMOS xCORE processor family";
2523 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2524 /* 210 */
6d913794
NC
2525 case EM_KM32: return "KM211 KM32 32-bit processor";
2526 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2527 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2528 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2529 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2530 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2531 case EM_COGE: return "Cognitive Smart Memory Processor";
2532 case EM_COOL: return "Bluechip Systems CoolEngine";
2533 case EM_NORC: return "Nanoradio Optimized RISC";
2534 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2535 /* 220 */
15f205b1 2536 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2537 case EM_VISIUM: return "CDS VISIUMcore processor";
2538 case EM_FT32: return "FTDI Chip FT32";
2539 case EM_MOXIE: return "Moxie";
2540 case EM_AMDGPU: return "AMD GPU";
2541 case EM_RISCV: return "RISC-V";
2542 case EM_LANAI: return "Lanai 32-bit processor";
2543 case EM_BPF: return "Linux BPF";
fe944acf 2544 case EM_NFP: return "Netronome Flow Processor";
55e22ca8
NC
2545
2546 /* Large numbers... */
2547 case EM_MT: return "Morpho Techologies MT processor";
2548 case EM_ALPHA: return "Alpha";
2549 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2550 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2551 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2552 case EM_IQ2000: return "Vitesse IQ2000";
2553 case EM_M32C_OLD:
2554 case EM_NIOS32: return "Altera Nios";
2555 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2556 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2557 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2558 case EM_S12Z: return "Freescale S12Z";
b8891f8d 2559 case EM_CSKY: return "C-SKY";
55e22ca8 2560
252b5132 2561 default:
35d9dd2f 2562 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2563 return buff;
2564 }
2565}
2566
a9522a21
AB
2567static void
2568decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2569{
2570 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2571 other compilers don't a specific architecture type in the e_flags, and
2572 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2573 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2574 architectures.
2575
2576 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2577 but also sets a specific architecture type in the e_flags field.
2578
2579 However, when decoding the flags we don't worry if we see an
2580 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2581 ARCEM architecture type. */
2582
2583 switch (e_flags & EF_ARC_MACH_MSK)
2584 {
2585 /* We only expect these to occur for EM_ARC_COMPACT2. */
2586 case EF_ARC_CPU_ARCV2EM:
2587 strcat (buf, ", ARC EM");
2588 break;
2589 case EF_ARC_CPU_ARCV2HS:
2590 strcat (buf, ", ARC HS");
2591 break;
2592
2593 /* We only expect these to occur for EM_ARC_COMPACT. */
2594 case E_ARC_MACH_ARC600:
2595 strcat (buf, ", ARC600");
2596 break;
2597 case E_ARC_MACH_ARC601:
2598 strcat (buf, ", ARC601");
2599 break;
2600 case E_ARC_MACH_ARC700:
2601 strcat (buf, ", ARC700");
2602 break;
2603
2604 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2605 new ELF with new architecture being read by an old version of
2606 readelf, or (c) An ELF built with non-GNU compiler that does not
2607 set the architecture in the e_flags. */
2608 default:
2609 if (e_machine == EM_ARC_COMPACT)
2610 strcat (buf, ", Unknown ARCompact");
2611 else
2612 strcat (buf, ", Unknown ARC");
2613 break;
2614 }
2615
2616 switch (e_flags & EF_ARC_OSABI_MSK)
2617 {
2618 case E_ARC_OSABI_ORIG:
2619 strcat (buf, ", (ABI:legacy)");
2620 break;
2621 case E_ARC_OSABI_V2:
2622 strcat (buf, ", (ABI:v2)");
2623 break;
2624 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2625 case E_ARC_OSABI_V3:
2626 strcat (buf, ", v3 no-legacy-syscalls ABI");
2627 break;
53a346d8
CZ
2628 case E_ARC_OSABI_V4:
2629 strcat (buf, ", v4 ABI");
2630 break;
a9522a21
AB
2631 default:
2632 strcat (buf, ", unrecognised ARC OSABI flag");
2633 break;
2634 }
2635}
2636
f3485b74 2637static void
d3ba0551 2638decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2639{
2640 unsigned eabi;
32ec8896 2641 bfd_boolean unknown = FALSE;
f3485b74
NC
2642
2643 eabi = EF_ARM_EABI_VERSION (e_flags);
2644 e_flags &= ~ EF_ARM_EABIMASK;
2645
2646 /* Handle "generic" ARM flags. */
2647 if (e_flags & EF_ARM_RELEXEC)
2648 {
2649 strcat (buf, ", relocatable executable");
2650 e_flags &= ~ EF_ARM_RELEXEC;
2651 }
76da6bbe 2652
18a20338
CL
2653 if (e_flags & EF_ARM_PIC)
2654 {
2655 strcat (buf, ", position independent");
2656 e_flags &= ~ EF_ARM_PIC;
2657 }
2658
f3485b74
NC
2659 /* Now handle EABI specific flags. */
2660 switch (eabi)
2661 {
2662 default:
2c71103e 2663 strcat (buf, ", <unrecognized EABI>");
f3485b74 2664 if (e_flags)
32ec8896 2665 unknown = TRUE;
f3485b74
NC
2666 break;
2667
2668 case EF_ARM_EABI_VER1:
a5bcd848 2669 strcat (buf, ", Version1 EABI");
f3485b74
NC
2670 while (e_flags)
2671 {
2672 unsigned flag;
76da6bbe 2673
f3485b74
NC
2674 /* Process flags one bit at a time. */
2675 flag = e_flags & - e_flags;
2676 e_flags &= ~ flag;
76da6bbe 2677
f3485b74
NC
2678 switch (flag)
2679 {
a5bcd848 2680 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2681 strcat (buf, ", sorted symbol tables");
2682 break;
76da6bbe 2683
f3485b74 2684 default:
32ec8896 2685 unknown = TRUE;
f3485b74
NC
2686 break;
2687 }
2688 }
2689 break;
76da6bbe 2690
a5bcd848
PB
2691 case EF_ARM_EABI_VER2:
2692 strcat (buf, ", Version2 EABI");
2693 while (e_flags)
2694 {
2695 unsigned flag;
2696
2697 /* Process flags one bit at a time. */
2698 flag = e_flags & - e_flags;
2699 e_flags &= ~ flag;
2700
2701 switch (flag)
2702 {
2703 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2704 strcat (buf, ", sorted symbol tables");
2705 break;
2706
2707 case EF_ARM_DYNSYMSUSESEGIDX:
2708 strcat (buf, ", dynamic symbols use segment index");
2709 break;
2710
2711 case EF_ARM_MAPSYMSFIRST:
2712 strcat (buf, ", mapping symbols precede others");
2713 break;
2714
2715 default:
32ec8896 2716 unknown = TRUE;
a5bcd848
PB
2717 break;
2718 }
2719 }
2720 break;
2721
d507cf36
PB
2722 case EF_ARM_EABI_VER3:
2723 strcat (buf, ", Version3 EABI");
8cb51566
PB
2724 break;
2725
2726 case EF_ARM_EABI_VER4:
2727 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2728 while (e_flags)
2729 {
2730 unsigned flag;
2731
2732 /* Process flags one bit at a time. */
2733 flag = e_flags & - e_flags;
2734 e_flags &= ~ flag;
2735
2736 switch (flag)
2737 {
2738 case EF_ARM_BE8:
2739 strcat (buf, ", BE8");
2740 break;
2741
2742 case EF_ARM_LE8:
2743 strcat (buf, ", LE8");
2744 break;
2745
2746 default:
32ec8896 2747 unknown = TRUE;
3bfcb652
NC
2748 break;
2749 }
3bfcb652
NC
2750 }
2751 break;
3a4a14e9
PB
2752
2753 case EF_ARM_EABI_VER5:
2754 strcat (buf, ", Version5 EABI");
d507cf36
PB
2755 while (e_flags)
2756 {
2757 unsigned flag;
2758
2759 /* Process flags one bit at a time. */
2760 flag = e_flags & - e_flags;
2761 e_flags &= ~ flag;
2762
2763 switch (flag)
2764 {
2765 case EF_ARM_BE8:
2766 strcat (buf, ", BE8");
2767 break;
2768
2769 case EF_ARM_LE8:
2770 strcat (buf, ", LE8");
2771 break;
2772
3bfcb652
NC
2773 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2774 strcat (buf, ", soft-float ABI");
2775 break;
2776
2777 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2778 strcat (buf, ", hard-float ABI");
2779 break;
2780
d507cf36 2781 default:
32ec8896 2782 unknown = TRUE;
d507cf36
PB
2783 break;
2784 }
2785 }
2786 break;
2787
f3485b74 2788 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2789 strcat (buf, ", GNU EABI");
f3485b74
NC
2790 while (e_flags)
2791 {
2792 unsigned flag;
76da6bbe 2793
f3485b74
NC
2794 /* Process flags one bit at a time. */
2795 flag = e_flags & - e_flags;
2796 e_flags &= ~ flag;
76da6bbe 2797
f3485b74
NC
2798 switch (flag)
2799 {
a5bcd848 2800 case EF_ARM_INTERWORK:
f3485b74
NC
2801 strcat (buf, ", interworking enabled");
2802 break;
76da6bbe 2803
a5bcd848 2804 case EF_ARM_APCS_26:
f3485b74
NC
2805 strcat (buf, ", uses APCS/26");
2806 break;
76da6bbe 2807
a5bcd848 2808 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2809 strcat (buf, ", uses APCS/float");
2810 break;
76da6bbe 2811
a5bcd848 2812 case EF_ARM_PIC:
f3485b74
NC
2813 strcat (buf, ", position independent");
2814 break;
76da6bbe 2815
a5bcd848 2816 case EF_ARM_ALIGN8:
f3485b74
NC
2817 strcat (buf, ", 8 bit structure alignment");
2818 break;
76da6bbe 2819
a5bcd848 2820 case EF_ARM_NEW_ABI:
f3485b74
NC
2821 strcat (buf, ", uses new ABI");
2822 break;
76da6bbe 2823
a5bcd848 2824 case EF_ARM_OLD_ABI:
f3485b74
NC
2825 strcat (buf, ", uses old ABI");
2826 break;
76da6bbe 2827
a5bcd848 2828 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2829 strcat (buf, ", software FP");
2830 break;
76da6bbe 2831
90e01f86
ILT
2832 case EF_ARM_VFP_FLOAT:
2833 strcat (buf, ", VFP");
2834 break;
2835
fde78edd
NC
2836 case EF_ARM_MAVERICK_FLOAT:
2837 strcat (buf, ", Maverick FP");
2838 break;
2839
f3485b74 2840 default:
32ec8896 2841 unknown = TRUE;
f3485b74
NC
2842 break;
2843 }
2844 }
2845 }
f3485b74
NC
2846
2847 if (unknown)
2b692964 2848 strcat (buf,_(", <unknown>"));
f3485b74
NC
2849}
2850
343433df
AB
2851static void
2852decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2853{
2854 --size; /* Leave space for null terminator. */
2855
2856 switch (e_flags & EF_AVR_MACH)
2857 {
2858 case E_AVR_MACH_AVR1:
2859 strncat (buf, ", avr:1", size);
2860 break;
2861 case E_AVR_MACH_AVR2:
2862 strncat (buf, ", avr:2", size);
2863 break;
2864 case E_AVR_MACH_AVR25:
2865 strncat (buf, ", avr:25", size);
2866 break;
2867 case E_AVR_MACH_AVR3:
2868 strncat (buf, ", avr:3", size);
2869 break;
2870 case E_AVR_MACH_AVR31:
2871 strncat (buf, ", avr:31", size);
2872 break;
2873 case E_AVR_MACH_AVR35:
2874 strncat (buf, ", avr:35", size);
2875 break;
2876 case E_AVR_MACH_AVR4:
2877 strncat (buf, ", avr:4", size);
2878 break;
2879 case E_AVR_MACH_AVR5:
2880 strncat (buf, ", avr:5", size);
2881 break;
2882 case E_AVR_MACH_AVR51:
2883 strncat (buf, ", avr:51", size);
2884 break;
2885 case E_AVR_MACH_AVR6:
2886 strncat (buf, ", avr:6", size);
2887 break;
2888 case E_AVR_MACH_AVRTINY:
2889 strncat (buf, ", avr:100", size);
2890 break;
2891 case E_AVR_MACH_XMEGA1:
2892 strncat (buf, ", avr:101", size);
2893 break;
2894 case E_AVR_MACH_XMEGA2:
2895 strncat (buf, ", avr:102", size);
2896 break;
2897 case E_AVR_MACH_XMEGA3:
2898 strncat (buf, ", avr:103", size);
2899 break;
2900 case E_AVR_MACH_XMEGA4:
2901 strncat (buf, ", avr:104", size);
2902 break;
2903 case E_AVR_MACH_XMEGA5:
2904 strncat (buf, ", avr:105", size);
2905 break;
2906 case E_AVR_MACH_XMEGA6:
2907 strncat (buf, ", avr:106", size);
2908 break;
2909 case E_AVR_MACH_XMEGA7:
2910 strncat (buf, ", avr:107", size);
2911 break;
2912 default:
2913 strncat (buf, ", avr:<unknown>", size);
2914 break;
2915 }
2916
2917 size -= strlen (buf);
2918 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2919 strncat (buf, ", link-relax", size);
2920}
2921
35c08157
KLC
2922static void
2923decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2924{
2925 unsigned abi;
2926 unsigned arch;
2927 unsigned config;
2928 unsigned version;
32ec8896
NC
2929 bfd_boolean has_fpu = FALSE;
2930 unsigned int r = 0;
35c08157
KLC
2931
2932 static const char *ABI_STRINGS[] =
2933 {
2934 "ABI v0", /* use r5 as return register; only used in N1213HC */
2935 "ABI v1", /* use r0 as return register */
2936 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2937 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2938 "AABI",
2939 "ABI2 FP+"
35c08157
KLC
2940 };
2941 static const char *VER_STRINGS[] =
2942 {
2943 "Andes ELF V1.3 or older",
2944 "Andes ELF V1.3.1",
2945 "Andes ELF V1.4"
2946 };
2947 static const char *ARCH_STRINGS[] =
2948 {
2949 "",
2950 "Andes Star v1.0",
2951 "Andes Star v2.0",
2952 "Andes Star v3.0",
2953 "Andes Star v3.0m"
2954 };
2955
2956 abi = EF_NDS_ABI & e_flags;
2957 arch = EF_NDS_ARCH & e_flags;
2958 config = EF_NDS_INST & e_flags;
2959 version = EF_NDS32_ELF_VERSION & e_flags;
2960
2961 memset (buf, 0, size);
2962
2963 switch (abi)
2964 {
2965 case E_NDS_ABI_V0:
2966 case E_NDS_ABI_V1:
2967 case E_NDS_ABI_V2:
2968 case E_NDS_ABI_V2FP:
2969 case E_NDS_ABI_AABI:
40c7a7cb 2970 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2971 /* In case there are holes in the array. */
2972 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2973 break;
2974
2975 default:
2976 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2977 break;
2978 }
2979
2980 switch (version)
2981 {
2982 case E_NDS32_ELF_VER_1_2:
2983 case E_NDS32_ELF_VER_1_3:
2984 case E_NDS32_ELF_VER_1_4:
2985 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2986 break;
2987
2988 default:
2989 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2990 break;
2991 }
2992
2993 if (E_NDS_ABI_V0 == abi)
2994 {
2995 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2996 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2997 if (arch == E_NDS_ARCH_STAR_V1_0)
2998 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2999 return;
3000 }
3001
3002 switch (arch)
3003 {
3004 case E_NDS_ARCH_STAR_V1_0:
3005 case E_NDS_ARCH_STAR_V2_0:
3006 case E_NDS_ARCH_STAR_V3_0:
3007 case E_NDS_ARCH_STAR_V3_M:
3008 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3009 break;
3010
3011 default:
3012 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3013 /* ARCH version determines how the e_flags are interpreted.
3014 If it is unknown, we cannot proceed. */
3015 return;
3016 }
3017
3018 /* Newer ABI; Now handle architecture specific flags. */
3019 if (arch == E_NDS_ARCH_STAR_V1_0)
3020 {
3021 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3022 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3023
3024 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3025 r += snprintf (buf + r, size -r, ", MAC");
3026
3027 if (config & E_NDS32_HAS_DIV_INST)
3028 r += snprintf (buf + r, size -r, ", DIV");
3029
3030 if (config & E_NDS32_HAS_16BIT_INST)
3031 r += snprintf (buf + r, size -r, ", 16b");
3032 }
3033 else
3034 {
3035 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3036 {
3037 if (version <= E_NDS32_ELF_VER_1_3)
3038 r += snprintf (buf + r, size -r, ", [B8]");
3039 else
3040 r += snprintf (buf + r, size -r, ", EX9");
3041 }
3042
3043 if (config & E_NDS32_HAS_MAC_DX_INST)
3044 r += snprintf (buf + r, size -r, ", MAC_DX");
3045
3046 if (config & E_NDS32_HAS_DIV_DX_INST)
3047 r += snprintf (buf + r, size -r, ", DIV_DX");
3048
3049 if (config & E_NDS32_HAS_16BIT_INST)
3050 {
3051 if (version <= E_NDS32_ELF_VER_1_3)
3052 r += snprintf (buf + r, size -r, ", 16b");
3053 else
3054 r += snprintf (buf + r, size -r, ", IFC");
3055 }
3056 }
3057
3058 if (config & E_NDS32_HAS_EXT_INST)
3059 r += snprintf (buf + r, size -r, ", PERF1");
3060
3061 if (config & E_NDS32_HAS_EXT2_INST)
3062 r += snprintf (buf + r, size -r, ", PERF2");
3063
3064 if (config & E_NDS32_HAS_FPU_INST)
3065 {
32ec8896 3066 has_fpu = TRUE;
35c08157
KLC
3067 r += snprintf (buf + r, size -r, ", FPU_SP");
3068 }
3069
3070 if (config & E_NDS32_HAS_FPU_DP_INST)
3071 {
32ec8896 3072 has_fpu = TRUE;
35c08157
KLC
3073 r += snprintf (buf + r, size -r, ", FPU_DP");
3074 }
3075
3076 if (config & E_NDS32_HAS_FPU_MAC_INST)
3077 {
32ec8896 3078 has_fpu = TRUE;
35c08157
KLC
3079 r += snprintf (buf + r, size -r, ", FPU_MAC");
3080 }
3081
3082 if (has_fpu)
3083 {
3084 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3085 {
3086 case E_NDS32_FPU_REG_8SP_4DP:
3087 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3088 break;
3089 case E_NDS32_FPU_REG_16SP_8DP:
3090 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3091 break;
3092 case E_NDS32_FPU_REG_32SP_16DP:
3093 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3094 break;
3095 case E_NDS32_FPU_REG_32SP_32DP:
3096 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3097 break;
3098 }
3099 }
3100
3101 if (config & E_NDS32_HAS_AUDIO_INST)
3102 r += snprintf (buf + r, size -r, ", AUDIO");
3103
3104 if (config & E_NDS32_HAS_STRING_INST)
3105 r += snprintf (buf + r, size -r, ", STR");
3106
3107 if (config & E_NDS32_HAS_REDUCED_REGS)
3108 r += snprintf (buf + r, size -r, ", 16REG");
3109
3110 if (config & E_NDS32_HAS_VIDEO_INST)
3111 {
3112 if (version <= E_NDS32_ELF_VER_1_3)
3113 r += snprintf (buf + r, size -r, ", VIDEO");
3114 else
3115 r += snprintf (buf + r, size -r, ", SATURATION");
3116 }
3117
3118 if (config & E_NDS32_HAS_ENCRIPT_INST)
3119 r += snprintf (buf + r, size -r, ", ENCRP");
3120
3121 if (config & E_NDS32_HAS_L2C_INST)
3122 r += snprintf (buf + r, size -r, ", L2C");
3123}
3124
252b5132 3125static char *
dda8d76d 3126get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3127{
b34976b6 3128 static char buf[1024];
252b5132
RH
3129
3130 buf[0] = '\0';
76da6bbe 3131
252b5132
RH
3132 if (e_flags)
3133 {
3134 switch (e_machine)
3135 {
3136 default:
3137 break;
3138
886a2506 3139 case EM_ARC_COMPACT2:
886a2506 3140 case EM_ARC_COMPACT:
a9522a21
AB
3141 decode_ARC_machine_flags (e_flags, e_machine, buf);
3142 break;
886a2506 3143
f3485b74
NC
3144 case EM_ARM:
3145 decode_ARM_machine_flags (e_flags, buf);
3146 break;
76da6bbe 3147
343433df
AB
3148 case EM_AVR:
3149 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3150 break;
3151
781303ce
MF
3152 case EM_BLACKFIN:
3153 if (e_flags & EF_BFIN_PIC)
3154 strcat (buf, ", PIC");
3155
3156 if (e_flags & EF_BFIN_FDPIC)
3157 strcat (buf, ", FDPIC");
3158
3159 if (e_flags & EF_BFIN_CODE_IN_L1)
3160 strcat (buf, ", code in L1");
3161
3162 if (e_flags & EF_BFIN_DATA_IN_L1)
3163 strcat (buf, ", data in L1");
3164
3165 break;
3166
ec2dfb42
AO
3167 case EM_CYGNUS_FRV:
3168 switch (e_flags & EF_FRV_CPU_MASK)
3169 {
3170 case EF_FRV_CPU_GENERIC:
3171 break;
3172
3173 default:
3174 strcat (buf, ", fr???");
3175 break;
57346661 3176
ec2dfb42
AO
3177 case EF_FRV_CPU_FR300:
3178 strcat (buf, ", fr300");
3179 break;
3180
3181 case EF_FRV_CPU_FR400:
3182 strcat (buf, ", fr400");
3183 break;
3184 case EF_FRV_CPU_FR405:
3185 strcat (buf, ", fr405");
3186 break;
3187
3188 case EF_FRV_CPU_FR450:
3189 strcat (buf, ", fr450");
3190 break;
3191
3192 case EF_FRV_CPU_FR500:
3193 strcat (buf, ", fr500");
3194 break;
3195 case EF_FRV_CPU_FR550:
3196 strcat (buf, ", fr550");
3197 break;
3198
3199 case EF_FRV_CPU_SIMPLE:
3200 strcat (buf, ", simple");
3201 break;
3202 case EF_FRV_CPU_TOMCAT:
3203 strcat (buf, ", tomcat");
3204 break;
3205 }
1c877e87 3206 break;
ec2dfb42 3207
53c7db4b 3208 case EM_68K:
425c6cb0 3209 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3210 strcat (buf, ", m68000");
425c6cb0 3211 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3212 strcat (buf, ", cpu32");
3213 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3214 strcat (buf, ", fido_a");
425c6cb0 3215 else
266abb8f 3216 {
2cf0635d
NC
3217 char const * isa = _("unknown");
3218 char const * mac = _("unknown mac");
3219 char const * additional = NULL;
0112cd26 3220
c694fd50 3221 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3222 {
c694fd50 3223 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3224 isa = "A";
3225 additional = ", nodiv";
3226 break;
c694fd50 3227 case EF_M68K_CF_ISA_A:
266abb8f
NS
3228 isa = "A";
3229 break;
c694fd50 3230 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3231 isa = "A+";
3232 break;
c694fd50 3233 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3234 isa = "B";
3235 additional = ", nousp";
3236 break;
c694fd50 3237 case EF_M68K_CF_ISA_B:
266abb8f
NS
3238 isa = "B";
3239 break;
f608cd77
NS
3240 case EF_M68K_CF_ISA_C:
3241 isa = "C";
3242 break;
3243 case EF_M68K_CF_ISA_C_NODIV:
3244 isa = "C";
3245 additional = ", nodiv";
3246 break;
266abb8f
NS
3247 }
3248 strcat (buf, ", cf, isa ");
3249 strcat (buf, isa);
0b2e31dc
NS
3250 if (additional)
3251 strcat (buf, additional);
c694fd50 3252 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3253 strcat (buf, ", float");
c694fd50 3254 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3255 {
3256 case 0:
3257 mac = NULL;
3258 break;
c694fd50 3259 case EF_M68K_CF_MAC:
266abb8f
NS
3260 mac = "mac";
3261 break;
c694fd50 3262 case EF_M68K_CF_EMAC:
266abb8f
NS
3263 mac = "emac";
3264 break;
f608cd77
NS
3265 case EF_M68K_CF_EMAC_B:
3266 mac = "emac_b";
3267 break;
266abb8f
NS
3268 }
3269 if (mac)
3270 {
3271 strcat (buf, ", ");
3272 strcat (buf, mac);
3273 }
266abb8f 3274 }
53c7db4b 3275 break;
33c63f9d 3276
153a2776
NC
3277 case EM_CYGNUS_MEP:
3278 switch (e_flags & EF_MEP_CPU_MASK)
3279 {
3280 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3281 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3282 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3283 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3284 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3285 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3286 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3287 }
3288
3289 switch (e_flags & EF_MEP_COP_MASK)
3290 {
3291 case EF_MEP_COP_NONE: break;
3292 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3293 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3294 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3295 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3296 default: strcat (buf, _("<unknown MeP copro type>")); break;
3297 }
3298
3299 if (e_flags & EF_MEP_LIBRARY)
3300 strcat (buf, ", Built for Library");
3301
3302 if (e_flags & EF_MEP_INDEX_MASK)
3303 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3304 e_flags & EF_MEP_INDEX_MASK);
3305
3306 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3307 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3308 e_flags & ~ EF_MEP_ALL_FLAGS);
3309 break;
3310
252b5132
RH
3311 case EM_PPC:
3312 if (e_flags & EF_PPC_EMB)
3313 strcat (buf, ", emb");
3314
3315 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3316 strcat (buf, _(", relocatable"));
252b5132
RH
3317
3318 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3319 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3320 break;
3321
ee67d69a
AM
3322 case EM_PPC64:
3323 if (e_flags & EF_PPC64_ABI)
3324 {
3325 char abi[] = ", abiv0";
3326
3327 abi[6] += e_flags & EF_PPC64_ABI;
3328 strcat (buf, abi);
3329 }
3330 break;
3331
708e2187
NC
3332 case EM_V800:
3333 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3334 strcat (buf, ", RH850 ABI");
0b4362b0 3335
708e2187
NC
3336 if (e_flags & EF_V800_850E3)
3337 strcat (buf, ", V3 architecture");
3338
3339 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3340 strcat (buf, ", FPU not used");
3341
3342 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3343 strcat (buf, ", regmode: COMMON");
3344
3345 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3346 strcat (buf, ", r4 not used");
3347
3348 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3349 strcat (buf, ", r30 not used");
3350
3351 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3352 strcat (buf, ", r5 not used");
3353
3354 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3355 strcat (buf, ", r2 not used");
3356
3357 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3358 {
3359 switch (e_flags & - e_flags)
3360 {
3361 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3362 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3363 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3364 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3365 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3366 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3367 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3368 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3369 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3370 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3371 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3372 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3373 default: break;
3374 }
3375 }
3376 break;
3377
2b0337b0 3378 case EM_V850:
252b5132
RH
3379 case EM_CYGNUS_V850:
3380 switch (e_flags & EF_V850_ARCH)
3381 {
78c8d46c
NC
3382 case E_V850E3V5_ARCH:
3383 strcat (buf, ", v850e3v5");
3384 break;
1cd986c5
NC
3385 case E_V850E2V3_ARCH:
3386 strcat (buf, ", v850e2v3");
3387 break;
3388 case E_V850E2_ARCH:
3389 strcat (buf, ", v850e2");
3390 break;
3391 case E_V850E1_ARCH:
3392 strcat (buf, ", v850e1");
8ad30312 3393 break;
252b5132
RH
3394 case E_V850E_ARCH:
3395 strcat (buf, ", v850e");
3396 break;
252b5132
RH
3397 case E_V850_ARCH:
3398 strcat (buf, ", v850");
3399 break;
3400 default:
2b692964 3401 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3402 break;
3403 }
3404 break;
3405
2b0337b0 3406 case EM_M32R:
252b5132
RH
3407 case EM_CYGNUS_M32R:
3408 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3409 strcat (buf, ", m32r");
252b5132
RH
3410 break;
3411
3412 case EM_MIPS:
4fe85591 3413 case EM_MIPS_RS3_LE:
252b5132
RH
3414 if (e_flags & EF_MIPS_NOREORDER)
3415 strcat (buf, ", noreorder");
3416
3417 if (e_flags & EF_MIPS_PIC)
3418 strcat (buf, ", pic");
3419
3420 if (e_flags & EF_MIPS_CPIC)
3421 strcat (buf, ", cpic");
3422
d1bdd336
TS
3423 if (e_flags & EF_MIPS_UCODE)
3424 strcat (buf, ", ugen_reserved");
3425
252b5132
RH
3426 if (e_flags & EF_MIPS_ABI2)
3427 strcat (buf, ", abi2");
3428
43521d43
TS
3429 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3430 strcat (buf, ", odk first");
3431
a5d22d2a
TS
3432 if (e_flags & EF_MIPS_32BITMODE)
3433 strcat (buf, ", 32bitmode");
3434
ba92f887
MR
3435 if (e_flags & EF_MIPS_NAN2008)
3436 strcat (buf, ", nan2008");
3437
fef1b0b3
SE
3438 if (e_flags & EF_MIPS_FP64)
3439 strcat (buf, ", fp64");
3440
156c2f8b
NC
3441 switch ((e_flags & EF_MIPS_MACH))
3442 {
3443 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3444 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3445 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3446 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3447 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3448 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3449 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3450 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3451 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3452 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3453 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3454 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3455 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3456 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3457 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3458 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3459 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3460 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3461 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3462 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3463 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3464 case 0:
3465 /* We simply ignore the field in this case to avoid confusion:
3466 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3467 extension. */
3468 break;
2b692964 3469 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3470 }
43521d43
TS
3471
3472 switch ((e_flags & EF_MIPS_ABI))
3473 {
3474 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3475 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3476 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3477 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3478 case 0:
3479 /* We simply ignore the field in this case to avoid confusion:
3480 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3481 This means it is likely to be an o32 file, but not for
3482 sure. */
3483 break;
2b692964 3484 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3485 }
3486
3487 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3488 strcat (buf, ", mdmx");
3489
3490 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3491 strcat (buf, ", mips16");
3492
df58fc94
RS
3493 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3494 strcat (buf, ", micromips");
3495
43521d43
TS
3496 switch ((e_flags & EF_MIPS_ARCH))
3497 {
3498 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3499 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3500 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3501 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3502 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3503 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3504 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3505 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3506 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3507 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3508 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3509 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3510 }
252b5132 3511 break;
351b4b40 3512
35c08157
KLC
3513 case EM_NDS32:
3514 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3515 break;
3516
fe944acf
FT
3517 case EM_NFP:
3518 switch (EF_NFP_MACH (e_flags))
3519 {
3520 case E_NFP_MACH_3200:
3521 strcat (buf, ", NFP-32xx");
3522 break;
3523 case E_NFP_MACH_6000:
3524 strcat (buf, ", NFP-6xxx");
3525 break;
3526 }
3527 break;
3528
e23eba97
NC
3529 case EM_RISCV:
3530 if (e_flags & EF_RISCV_RVC)
3531 strcat (buf, ", RVC");
2922d21d 3532
7f999549
JW
3533 if (e_flags & EF_RISCV_RVE)
3534 strcat (buf, ", RVE");
3535
2922d21d
AW
3536 switch (e_flags & EF_RISCV_FLOAT_ABI)
3537 {
3538 case EF_RISCV_FLOAT_ABI_SOFT:
3539 strcat (buf, ", soft-float ABI");
3540 break;
3541
3542 case EF_RISCV_FLOAT_ABI_SINGLE:
3543 strcat (buf, ", single-float ABI");
3544 break;
3545
3546 case EF_RISCV_FLOAT_ABI_DOUBLE:
3547 strcat (buf, ", double-float ABI");
3548 break;
3549
3550 case EF_RISCV_FLOAT_ABI_QUAD:
3551 strcat (buf, ", quad-float ABI");
3552 break;
3553 }
e23eba97
NC
3554 break;
3555
ccde1100
AO
3556 case EM_SH:
3557 switch ((e_flags & EF_SH_MACH_MASK))
3558 {
3559 case EF_SH1: strcat (buf, ", sh1"); break;
3560 case EF_SH2: strcat (buf, ", sh2"); break;
3561 case EF_SH3: strcat (buf, ", sh3"); break;
3562 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3563 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3564 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3565 case EF_SH3E: strcat (buf, ", sh3e"); break;
3566 case EF_SH4: strcat (buf, ", sh4"); break;
3567 case EF_SH5: strcat (buf, ", sh5"); break;
3568 case EF_SH2E: strcat (buf, ", sh2e"); break;
3569 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3570 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3571 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3572 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3573 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3574 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3575 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3576 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3577 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3578 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3579 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3580 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3581 }
3582
cec6a5b8
MR
3583 if (e_flags & EF_SH_PIC)
3584 strcat (buf, ", pic");
3585
3586 if (e_flags & EF_SH_FDPIC)
3587 strcat (buf, ", fdpic");
ccde1100 3588 break;
948f632f 3589
73589c9d
CS
3590 case EM_OR1K:
3591 if (e_flags & EF_OR1K_NODELAY)
3592 strcat (buf, ", no delay");
3593 break;
57346661 3594
351b4b40
RH
3595 case EM_SPARCV9:
3596 if (e_flags & EF_SPARC_32PLUS)
3597 strcat (buf, ", v8+");
3598
3599 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3600 strcat (buf, ", ultrasparcI");
3601
3602 if (e_flags & EF_SPARC_SUN_US3)
3603 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3604
3605 if (e_flags & EF_SPARC_HAL_R1)
3606 strcat (buf, ", halr1");
3607
3608 if (e_flags & EF_SPARC_LEDATA)
3609 strcat (buf, ", ledata");
3610
3611 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3612 strcat (buf, ", tso");
3613
3614 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3615 strcat (buf, ", pso");
3616
3617 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3618 strcat (buf, ", rmo");
3619 break;
7d466069 3620
103f02d3
UD
3621 case EM_PARISC:
3622 switch (e_flags & EF_PARISC_ARCH)
3623 {
3624 case EFA_PARISC_1_0:
3625 strcpy (buf, ", PA-RISC 1.0");
3626 break;
3627 case EFA_PARISC_1_1:
3628 strcpy (buf, ", PA-RISC 1.1");
3629 break;
3630 case EFA_PARISC_2_0:
3631 strcpy (buf, ", PA-RISC 2.0");
3632 break;
3633 default:
3634 break;
3635 }
3636 if (e_flags & EF_PARISC_TRAPNIL)
3637 strcat (buf, ", trapnil");
3638 if (e_flags & EF_PARISC_EXT)
3639 strcat (buf, ", ext");
3640 if (e_flags & EF_PARISC_LSB)
3641 strcat (buf, ", lsb");
3642 if (e_flags & EF_PARISC_WIDE)
3643 strcat (buf, ", wide");
3644 if (e_flags & EF_PARISC_NO_KABP)
3645 strcat (buf, ", no kabp");
3646 if (e_flags & EF_PARISC_LAZYSWAP)
3647 strcat (buf, ", lazyswap");
30800947 3648 break;
76da6bbe 3649
7d466069 3650 case EM_PJ:
2b0337b0 3651 case EM_PJ_OLD:
7d466069
ILT
3652 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3653 strcat (buf, ", new calling convention");
3654
3655 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3656 strcat (buf, ", gnu calling convention");
3657 break;
4d6ed7c8
NC
3658
3659 case EM_IA_64:
3660 if ((e_flags & EF_IA_64_ABI64))
3661 strcat (buf, ", 64-bit");
3662 else
3663 strcat (buf, ", 32-bit");
3664 if ((e_flags & EF_IA_64_REDUCEDFP))
3665 strcat (buf, ", reduced fp model");
3666 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3667 strcat (buf, ", no function descriptors, constant gp");
3668 else if ((e_flags & EF_IA_64_CONS_GP))
3669 strcat (buf, ", constant gp");
3670 if ((e_flags & EF_IA_64_ABSOLUTE))
3671 strcat (buf, ", absolute");
dda8d76d 3672 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3673 {
3674 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3675 strcat (buf, ", vms_linkages");
3676 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3677 {
3678 case EF_IA_64_VMS_COMCOD_SUCCESS:
3679 break;
3680 case EF_IA_64_VMS_COMCOD_WARNING:
3681 strcat (buf, ", warning");
3682 break;
3683 case EF_IA_64_VMS_COMCOD_ERROR:
3684 strcat (buf, ", error");
3685 break;
3686 case EF_IA_64_VMS_COMCOD_ABORT:
3687 strcat (buf, ", abort");
3688 break;
3689 default:
bee0ee85
NC
3690 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3691 e_flags & EF_IA_64_VMS_COMCOD);
3692 strcat (buf, ", <unknown>");
28f997cf
TG
3693 }
3694 }
4d6ed7c8 3695 break;
179d3252
JT
3696
3697 case EM_VAX:
3698 if ((e_flags & EF_VAX_NONPIC))
3699 strcat (buf, ", non-PIC");
3700 if ((e_flags & EF_VAX_DFLOAT))
3701 strcat (buf, ", D-Float");
3702 if ((e_flags & EF_VAX_GFLOAT))
3703 strcat (buf, ", G-Float");
3704 break;
c7927a3c 3705
619ed720
EB
3706 case EM_VISIUM:
3707 if (e_flags & EF_VISIUM_ARCH_MCM)
3708 strcat (buf, ", mcm");
3709 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3710 strcat (buf, ", mcm24");
3711 if (e_flags & EF_VISIUM_ARCH_GR6)
3712 strcat (buf, ", gr6");
3713 break;
3714
4046d87a 3715 case EM_RL78:
1740ba0c
NC
3716 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3717 {
3718 case E_FLAG_RL78_ANY_CPU: break;
3719 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3720 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3721 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3722 }
856ea05c
KP
3723 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3724 strcat (buf, ", 64-bit doubles");
4046d87a 3725 break;
0b4362b0 3726
c7927a3c
NC
3727 case EM_RX:
3728 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3729 strcat (buf, ", 64-bit doubles");
3730 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3731 strcat (buf, ", dsp");
d4cb0ea0 3732 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3733 strcat (buf, ", pid");
708e2187
NC
3734 if (e_flags & E_FLAG_RX_ABI)
3735 strcat (buf, ", RX ABI");
3525236c
NC
3736 if (e_flags & E_FLAG_RX_SINSNS_SET)
3737 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3738 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3739 if (e_flags & E_FLAG_RX_V2)
3740 strcat (buf, ", V2");
f87673e0
YS
3741 if (e_flags & E_FLAG_RX_V3)
3742 strcat (buf, ", V3");
d4cb0ea0 3743 break;
55786da2
AK
3744
3745 case EM_S390:
3746 if (e_flags & EF_S390_HIGH_GPRS)
3747 strcat (buf, ", highgprs");
d4cb0ea0 3748 break;
40b36596
JM
3749
3750 case EM_TI_C6000:
3751 if ((e_flags & EF_C6000_REL))
3752 strcat (buf, ", relocatable module");
d4cb0ea0 3753 break;
13761a11
NC
3754
3755 case EM_MSP430:
3756 strcat (buf, _(": architecture variant: "));
3757 switch (e_flags & EF_MSP430_MACH)
3758 {
3759 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3760 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3761 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3762 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3763 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3764 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3765 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3766 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3767 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3768 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3769 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3770 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3771 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3772 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3773 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3774 default:
3775 strcat (buf, _(": unknown")); break;
3776 }
3777
3778 if (e_flags & ~ EF_MSP430_MACH)
3779 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3780 break;
3781
3782 case EM_Z80:
3783 switch (e_flags & EF_Z80_MACH_MSK)
3784 {
3785 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3786 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3787 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3788 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3789 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3790 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3791 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3792 default:
3793 strcat (buf, _(", unknown")); break;
3794 }
3795 break;
252b5132
RH
3796 }
3797 }
3798
3799 return buf;
3800}
3801
252b5132 3802static const char *
dda8d76d 3803get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3804{
3805 static char buff[32];
3806
3807 switch (osabi)
3808 {
3809 case ELFOSABI_NONE: return "UNIX - System V";
3810 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3811 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3812 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3813 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3814 case ELFOSABI_AIX: return "UNIX - AIX";
3815 case ELFOSABI_IRIX: return "UNIX - IRIX";
3816 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3817 case ELFOSABI_TRU64: return "UNIX - TRU64";
3818 case ELFOSABI_MODESTO: return "Novell - Modesto";
3819 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3820 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3821 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3822 case ELFOSABI_AROS: return "AROS";
11636f9e 3823 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3824 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3825 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3826 default:
40b36596 3827 if (osabi >= 64)
dda8d76d 3828 switch (filedata->file_header.e_machine)
40b36596
JM
3829 {
3830 case EM_ARM:
3831 switch (osabi)
3832 {
3833 case ELFOSABI_ARM: return "ARM";
18a20338 3834 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3835 default:
3836 break;
3837 }
3838 break;
3839
3840 case EM_MSP430:
3841 case EM_MSP430_OLD:
619ed720 3842 case EM_VISIUM:
40b36596
JM
3843 switch (osabi)
3844 {
3845 case ELFOSABI_STANDALONE: return _("Standalone App");
3846 default:
3847 break;
3848 }
3849 break;
3850
3851 case EM_TI_C6000:
3852 switch (osabi)
3853 {
3854 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3855 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3856 default:
3857 break;
3858 }
3859 break;
3860
3861 default:
3862 break;
3863 }
e9e44622 3864 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3865 return buff;
3866 }
3867}
3868
a06ea964
NC
3869static const char *
3870get_aarch64_segment_type (unsigned long type)
3871{
3872 switch (type)
3873 {
32ec8896
NC
3874 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3875 default: return NULL;
a06ea964 3876 }
a06ea964
NC
3877}
3878
b294bdf8
MM
3879static const char *
3880get_arm_segment_type (unsigned long type)
3881{
3882 switch (type)
3883 {
32ec8896
NC
3884 case PT_ARM_EXIDX: return "EXIDX";
3885 default: return NULL;
b294bdf8 3886 }
b294bdf8
MM
3887}
3888
b4cbbe8f
AK
3889static const char *
3890get_s390_segment_type (unsigned long type)
3891{
3892 switch (type)
3893 {
3894 case PT_S390_PGSTE: return "S390_PGSTE";
3895 default: return NULL;
3896 }
3897}
3898
d3ba0551
AM
3899static const char *
3900get_mips_segment_type (unsigned long type)
252b5132
RH
3901{
3902 switch (type)
3903 {
32ec8896
NC
3904 case PT_MIPS_REGINFO: return "REGINFO";
3905 case PT_MIPS_RTPROC: return "RTPROC";
3906 case PT_MIPS_OPTIONS: return "OPTIONS";
3907 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3908 default: return NULL;
252b5132 3909 }
252b5132
RH
3910}
3911
103f02d3 3912static const char *
d3ba0551 3913get_parisc_segment_type (unsigned long type)
103f02d3
UD
3914{
3915 switch (type)
3916 {
103f02d3
UD
3917 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3918 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3919 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3920 default: return NULL;
103f02d3 3921 }
103f02d3
UD
3922}
3923
4d6ed7c8 3924static const char *
d3ba0551 3925get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3926{
3927 switch (type)
3928 {
3929 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3930 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3931 default: return NULL;
4d6ed7c8 3932 }
4d6ed7c8
NC
3933}
3934
40b36596
JM
3935static const char *
3936get_tic6x_segment_type (unsigned long type)
3937{
3938 switch (type)
3939 {
32ec8896
NC
3940 case PT_C6000_PHATTR: return "C6000_PHATTR";
3941 default: return NULL;
40b36596 3942 }
40b36596
JM
3943}
3944
df3a023b
AM
3945static const char *
3946get_hpux_segment_type (unsigned long type, unsigned e_machine)
3947{
3948 if (e_machine == EM_PARISC)
3949 switch (type)
3950 {
3951 case PT_HP_TLS: return "HP_TLS";
3952 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3953 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3954 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3955 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3956 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3957 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3958 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3959 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3960 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3961 case PT_HP_PARALLEL: return "HP_PARALLEL";
3962 case PT_HP_FASTBIND: return "HP_FASTBIND";
3963 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3964 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3965 case PT_HP_STACK: return "HP_STACK";
3966 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
3967 default: return NULL;
3968 }
3969
3970 if (e_machine == EM_IA_64)
3971 switch (type)
3972 {
3973 case PT_HP_TLS: return "HP_TLS";
3974 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3975 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3976 case PT_IA_64_HP_STACK: return "HP_STACK";
3977 default: return NULL;
3978 }
3979
3980 return NULL;
3981}
3982
5522f910
NC
3983static const char *
3984get_solaris_segment_type (unsigned long type)
3985{
3986 switch (type)
3987 {
3988 case 0x6464e550: return "PT_SUNW_UNWIND";
3989 case 0x6474e550: return "PT_SUNW_EH_FRAME";
3990 case 0x6ffffff7: return "PT_LOSUNW";
3991 case 0x6ffffffa: return "PT_SUNWBSS";
3992 case 0x6ffffffb: return "PT_SUNWSTACK";
3993 case 0x6ffffffc: return "PT_SUNWDTRACE";
3994 case 0x6ffffffd: return "PT_SUNWCAP";
3995 case 0x6fffffff: return "PT_HISUNW";
32ec8896 3996 default: return NULL;
5522f910
NC
3997 }
3998}
3999
252b5132 4000static const char *
dda8d76d 4001get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4002{
b34976b6 4003 static char buff[32];
252b5132
RH
4004
4005 switch (p_type)
4006 {
b34976b6
AM
4007 case PT_NULL: return "NULL";
4008 case PT_LOAD: return "LOAD";
252b5132 4009 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4010 case PT_INTERP: return "INTERP";
4011 case PT_NOTE: return "NOTE";
4012 case PT_SHLIB: return "SHLIB";
4013 case PT_PHDR: return "PHDR";
13ae64f3 4014 case PT_TLS: return "TLS";
32ec8896 4015 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4016 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4017 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4018 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4019
252b5132 4020 default:
df3a023b 4021 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4022 {
2cf0635d 4023 const char * result;
103f02d3 4024
dda8d76d 4025 switch (filedata->file_header.e_machine)
252b5132 4026 {
a06ea964
NC
4027 case EM_AARCH64:
4028 result = get_aarch64_segment_type (p_type);
4029 break;
b294bdf8
MM
4030 case EM_ARM:
4031 result = get_arm_segment_type (p_type);
4032 break;
252b5132 4033 case EM_MIPS:
4fe85591 4034 case EM_MIPS_RS3_LE:
252b5132
RH
4035 result = get_mips_segment_type (p_type);
4036 break;
103f02d3
UD
4037 case EM_PARISC:
4038 result = get_parisc_segment_type (p_type);
4039 break;
4d6ed7c8
NC
4040 case EM_IA_64:
4041 result = get_ia64_segment_type (p_type);
4042 break;
40b36596
JM
4043 case EM_TI_C6000:
4044 result = get_tic6x_segment_type (p_type);
4045 break;
b4cbbe8f
AK
4046 case EM_S390:
4047 case EM_S390_OLD:
4048 result = get_s390_segment_type (p_type);
4049 break;
252b5132
RH
4050 default:
4051 result = NULL;
4052 break;
4053 }
103f02d3 4054
252b5132
RH
4055 if (result != NULL)
4056 return result;
103f02d3 4057
1a9ccd70 4058 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4059 }
4060 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4061 {
df3a023b 4062 const char * result = NULL;
103f02d3 4063
df3a023b 4064 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4065 {
df3a023b
AM
4066 case ELFOSABI_GNU:
4067 case ELFOSABI_FREEBSD:
4068 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4069 {
4070 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4071 result = buff;
4072 }
103f02d3 4073 break;
df3a023b
AM
4074 case ELFOSABI_HPUX:
4075 result = get_hpux_segment_type (p_type,
4076 filedata->file_header.e_machine);
4077 break;
4078 case ELFOSABI_SOLARIS:
4079 result = get_solaris_segment_type (p_type);
00428cca 4080 break;
103f02d3 4081 default:
103f02d3
UD
4082 break;
4083 }
103f02d3
UD
4084 if (result != NULL)
4085 return result;
4086
1a9ccd70 4087 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4088 }
252b5132 4089 else
e9e44622 4090 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4091
4092 return buff;
4093 }
4094}
4095
53a346d8
CZ
4096static const char *
4097get_arc_section_type_name (unsigned int sh_type)
4098{
4099 switch (sh_type)
4100 {
4101 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4102 default:
4103 break;
4104 }
4105 return NULL;
4106}
4107
252b5132 4108static const char *
d3ba0551 4109get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4110{
4111 switch (sh_type)
4112 {
b34976b6
AM
4113 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4114 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4115 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4116 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4117 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4118 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4119 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4120 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4121 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4122 case SHT_MIPS_RELD: return "MIPS_RELD";
4123 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4124 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4125 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4126 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4127 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4128 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4129 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4130 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4131 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4132 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4133 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4134 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4135 case SHT_MIPS_LINE: return "MIPS_LINE";
4136 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4137 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4138 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4139 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4140 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4141 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4142 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4143 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4144 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4145 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4146 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4147 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4148 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4149 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4150 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4151 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4152 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4153 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4154 default:
4155 break;
4156 }
4157 return NULL;
4158}
4159
103f02d3 4160static const char *
d3ba0551 4161get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4162{
4163 switch (sh_type)
4164 {
4165 case SHT_PARISC_EXT: return "PARISC_EXT";
4166 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4167 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4168 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4169 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4170 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4171 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4172 default: return NULL;
103f02d3 4173 }
103f02d3
UD
4174}
4175
4d6ed7c8 4176static const char *
dda8d76d 4177get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4178{
18bd398b 4179 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4180 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4181 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4182
4d6ed7c8
NC
4183 switch (sh_type)
4184 {
148b93f2
NC
4185 case SHT_IA_64_EXT: return "IA_64_EXT";
4186 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4187 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4188 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4189 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4190 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4191 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4192 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4193 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4194 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4195 default:
4196 break;
4197 }
4198 return NULL;
4199}
4200
d2b2c203
DJ
4201static const char *
4202get_x86_64_section_type_name (unsigned int sh_type)
4203{
4204 switch (sh_type)
4205 {
4206 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4207 default: return NULL;
d2b2c203 4208 }
d2b2c203
DJ
4209}
4210
a06ea964
NC
4211static const char *
4212get_aarch64_section_type_name (unsigned int sh_type)
4213{
4214 switch (sh_type)
4215 {
32ec8896
NC
4216 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4217 default: return NULL;
a06ea964 4218 }
a06ea964
NC
4219}
4220
40a18ebd
NC
4221static const char *
4222get_arm_section_type_name (unsigned int sh_type)
4223{
4224 switch (sh_type)
4225 {
7f6fed87
NC
4226 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4227 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4228 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4229 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4230 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4231 default: return NULL;
40a18ebd 4232 }
40a18ebd
NC
4233}
4234
40b36596
JM
4235static const char *
4236get_tic6x_section_type_name (unsigned int sh_type)
4237{
4238 switch (sh_type)
4239 {
32ec8896
NC
4240 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4241 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4242 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4243 case SHT_TI_ICODE: return "TI_ICODE";
4244 case SHT_TI_XREF: return "TI_XREF";
4245 case SHT_TI_HANDLER: return "TI_HANDLER";
4246 case SHT_TI_INITINFO: return "TI_INITINFO";
4247 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4248 default: return NULL;
40b36596 4249 }
40b36596
JM
4250}
4251
13761a11
NC
4252static const char *
4253get_msp430x_section_type_name (unsigned int sh_type)
4254{
4255 switch (sh_type)
4256 {
32ec8896
NC
4257 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4258 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4259 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4260 default: return NULL;
13761a11
NC
4261 }
4262}
4263
fe944acf
FT
4264static const char *
4265get_nfp_section_type_name (unsigned int sh_type)
4266{
4267 switch (sh_type)
4268 {
4269 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4270 case SHT_NFP_INITREG: return "NFP_INITREG";
4271 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4272 default: return NULL;
4273 }
4274}
4275
685080f2
NC
4276static const char *
4277get_v850_section_type_name (unsigned int sh_type)
4278{
4279 switch (sh_type)
4280 {
32ec8896
NC
4281 case SHT_V850_SCOMMON: return "V850 Small Common";
4282 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4283 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4284 case SHT_RENESAS_IOP: return "RENESAS IOP";
4285 case SHT_RENESAS_INFO: return "RENESAS INFO";
4286 default: return NULL;
685080f2
NC
4287 }
4288}
4289
2dc8dd17
JW
4290static const char *
4291get_riscv_section_type_name (unsigned int sh_type)
4292{
4293 switch (sh_type)
4294 {
4295 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4296 default: return NULL;
4297 }
4298}
4299
252b5132 4300static const char *
dda8d76d 4301get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4302{
b34976b6 4303 static char buff[32];
9fb71ee4 4304 const char * result;
252b5132
RH
4305
4306 switch (sh_type)
4307 {
4308 case SHT_NULL: return "NULL";
4309 case SHT_PROGBITS: return "PROGBITS";
4310 case SHT_SYMTAB: return "SYMTAB";
4311 case SHT_STRTAB: return "STRTAB";
4312 case SHT_RELA: return "RELA";
4313 case SHT_HASH: return "HASH";
4314 case SHT_DYNAMIC: return "DYNAMIC";
4315 case SHT_NOTE: return "NOTE";
4316 case SHT_NOBITS: return "NOBITS";
4317 case SHT_REL: return "REL";
4318 case SHT_SHLIB: return "SHLIB";
4319 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4320 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4321 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4322 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4323 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4324 case SHT_GROUP: return "GROUP";
67ce483b 4325 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4326 case SHT_GNU_verdef: return "VERDEF";
4327 case SHT_GNU_verneed: return "VERNEED";
4328 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4329 case 0x6ffffff0: return "VERSYM";
4330 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4331 case 0x7ffffffd: return "AUXILIARY";
4332 case 0x7fffffff: return "FILTER";
047b2264 4333 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4334
4335 default:
4336 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4337 {
dda8d76d 4338 switch (filedata->file_header.e_machine)
252b5132 4339 {
53a346d8
CZ
4340 case EM_ARC:
4341 case EM_ARC_COMPACT:
4342 case EM_ARC_COMPACT2:
4343 result = get_arc_section_type_name (sh_type);
4344 break;
252b5132 4345 case EM_MIPS:
4fe85591 4346 case EM_MIPS_RS3_LE:
252b5132
RH
4347 result = get_mips_section_type_name (sh_type);
4348 break;
103f02d3
UD
4349 case EM_PARISC:
4350 result = get_parisc_section_type_name (sh_type);
4351 break;
4d6ed7c8 4352 case EM_IA_64:
dda8d76d 4353 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4354 break;
d2b2c203 4355 case EM_X86_64:
8a9036a4 4356 case EM_L1OM:
7a9068fe 4357 case EM_K1OM:
d2b2c203
DJ
4358 result = get_x86_64_section_type_name (sh_type);
4359 break;
a06ea964
NC
4360 case EM_AARCH64:
4361 result = get_aarch64_section_type_name (sh_type);
4362 break;
40a18ebd
NC
4363 case EM_ARM:
4364 result = get_arm_section_type_name (sh_type);
4365 break;
40b36596
JM
4366 case EM_TI_C6000:
4367 result = get_tic6x_section_type_name (sh_type);
4368 break;
13761a11
NC
4369 case EM_MSP430:
4370 result = get_msp430x_section_type_name (sh_type);
4371 break;
fe944acf
FT
4372 case EM_NFP:
4373 result = get_nfp_section_type_name (sh_type);
4374 break;
685080f2
NC
4375 case EM_V800:
4376 case EM_V850:
4377 case EM_CYGNUS_V850:
4378 result = get_v850_section_type_name (sh_type);
4379 break;
2dc8dd17
JW
4380 case EM_RISCV:
4381 result = get_riscv_section_type_name (sh_type);
4382 break;
252b5132
RH
4383 default:
4384 result = NULL;
4385 break;
4386 }
4387
4388 if (result != NULL)
4389 return result;
4390
9fb71ee4 4391 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4392 }
4393 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4394 {
dda8d76d 4395 switch (filedata->file_header.e_machine)
148b93f2
NC
4396 {
4397 case EM_IA_64:
dda8d76d 4398 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4399 break;
4400 default:
dda8d76d 4401 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4402 result = get_solaris_section_type (sh_type);
4403 else
1b4b80bf
NC
4404 {
4405 switch (sh_type)
4406 {
4407 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4408 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4409 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4410 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4411 default:
4412 result = NULL;
4413 break;
4414 }
4415 }
148b93f2
NC
4416 break;
4417 }
4418
4419 if (result != NULL)
4420 return result;
4421
9fb71ee4 4422 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4423 }
252b5132 4424 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4425 {
dda8d76d 4426 switch (filedata->file_header.e_machine)
685080f2
NC
4427 {
4428 case EM_V800:
4429 case EM_V850:
4430 case EM_CYGNUS_V850:
9fb71ee4 4431 result = get_v850_section_type_name (sh_type);
a9fb83be 4432 break;
685080f2 4433 default:
9fb71ee4 4434 result = NULL;
685080f2
NC
4435 break;
4436 }
4437
9fb71ee4
NC
4438 if (result != NULL)
4439 return result;
4440
4441 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4442 }
252b5132 4443 else
a7dbfd1c
NC
4444 /* This message is probably going to be displayed in a 15
4445 character wide field, so put the hex value first. */
4446 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4447
252b5132
RH
4448 return buff;
4449 }
4450}
4451
2979dc34 4452#define OPTION_DEBUG_DUMP 512
2c610e4b 4453#define OPTION_DYN_SYMS 513
fd2f0033
TT
4454#define OPTION_DWARF_DEPTH 514
4455#define OPTION_DWARF_START 515
4723351a 4456#define OPTION_DWARF_CHECK 516
7d9813f1
NA
4457#define OPTION_CTF_DUMP 517
4458#define OPTION_CTF_PARENT 518
4459#define OPTION_CTF_SYMBOLS 519
4460#define OPTION_CTF_STRINGS 520
2979dc34 4461
85b1c36d 4462static struct option options[] =
252b5132 4463{
b34976b6 4464 {"all", no_argument, 0, 'a'},
252b5132
RH
4465 {"file-header", no_argument, 0, 'h'},
4466 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4467 {"headers", no_argument, 0, 'e'},
4468 {"histogram", no_argument, 0, 'I'},
4469 {"segments", no_argument, 0, 'l'},
4470 {"sections", no_argument, 0, 'S'},
252b5132 4471 {"section-headers", no_argument, 0, 'S'},
f5842774 4472 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4473 {"section-details", no_argument, 0, 't'},
595cf52e 4474 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4475 {"symbols", no_argument, 0, 's'},
4476 {"syms", no_argument, 0, 's'},
2c610e4b 4477 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4478 {"relocs", no_argument, 0, 'r'},
4479 {"notes", no_argument, 0, 'n'},
4480 {"dynamic", no_argument, 0, 'd'},
a952a375 4481 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4482 {"version-info", no_argument, 0, 'V'},
4483 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4484 {"unwind", no_argument, 0, 'u'},
4145f1d5 4485 {"archive-index", no_argument, 0, 'c'},
b34976b6 4486 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4487 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4488 {"string-dump", required_argument, 0, 'p'},
0e602686 4489 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4490#ifdef SUPPORT_DISASSEMBLY
4491 {"instruction-dump", required_argument, 0, 'i'},
4492#endif
cf13d699 4493 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4494
fd2f0033
TT
4495 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4496 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4497 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4498
d344b407 4499 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4500
4501 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4502 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4503 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
4504
b34976b6
AM
4505 {"version", no_argument, 0, 'v'},
4506 {"wide", no_argument, 0, 'W'},
4507 {"help", no_argument, 0, 'H'},
4508 {0, no_argument, 0, 0}
252b5132
RH
4509};
4510
4511static void
2cf0635d 4512usage (FILE * stream)
252b5132 4513{
92f01d61
JM
4514 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4515 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4516 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4517 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4518 -h --file-header Display the ELF file header\n\
4519 -l --program-headers Display the program headers\n\
4520 --segments An alias for --program-headers\n\
4521 -S --section-headers Display the sections' header\n\
4522 --sections An alias for --section-headers\n\
f5842774 4523 -g --section-groups Display the section groups\n\
5477e8a0 4524 -t --section-details Display the section details\n\
8b53311e
NC
4525 -e --headers Equivalent to: -h -l -S\n\
4526 -s --syms Display the symbol table\n\
3f08eb35 4527 --symbols An alias for --syms\n\
2c610e4b 4528 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4529 -n --notes Display the core notes (if present)\n\
4530 -r --relocs Display the relocations (if present)\n\
4531 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4532 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4533 -V --version-info Display the version sections (if present)\n\
1b31d05e 4534 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4535 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4536 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
4537 -x --hex-dump=<number|name>\n\
4538 Dump the contents of section <number|name> as bytes\n\
4539 -p --string-dump=<number|name>\n\
4540 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4541 -R --relocated-dump=<number|name>\n\
4542 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4543 -z --decompress Decompress section before dumping it\n\
dda8d76d 4544 -w[lLiaprmfFsoRtUuTgAckK] or\n\
1ed06042 4545 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4546 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47 4547 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4548 =addr,=cu_index,=links,=follow-links]\n\
4549 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4550 fprintf (stream, _("\
4551 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4552 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4553 or deeper\n"));
7d9813f1
NA
4554 fprintf (stream, _("\
4555 --ctf=<number|name> Display CTF info from section <number|name>\n\
4556 --ctf-parent=<number|name>\n\
4557 Use section <number|name> as the CTF parent\n\n\
4558 --ctf-symbols=<number|name>\n\
4559 Use section <number|name> as the CTF external symtab\n\n\
4560 --ctf-strings=<number|name>\n\
4561 Use section <number|name> as the CTF external strtab\n\n"));
4562
252b5132 4563#ifdef SUPPORT_DISASSEMBLY
92f01d61 4564 fprintf (stream, _("\
09c11c86
NC
4565 -i --instruction-dump=<number|name>\n\
4566 Disassemble the contents of section <number|name>\n"));
252b5132 4567#endif
92f01d61 4568 fprintf (stream, _("\
8b53311e
NC
4569 -I --histogram Display histogram of bucket list lengths\n\
4570 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4571 @<file> Read options from <file>\n\
8b53311e
NC
4572 -H --help Display this information\n\
4573 -v --version Display the version number of readelf\n"));
1118d252 4574
92f01d61
JM
4575 if (REPORT_BUGS_TO[0] && stream == stdout)
4576 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4577
92f01d61 4578 exit (stream == stdout ? 0 : 1);
252b5132
RH
4579}
4580
18bd398b
NC
4581/* Record the fact that the user wants the contents of section number
4582 SECTION to be displayed using the method(s) encoded as flags bits
4583 in TYPE. Note, TYPE can be zero if we are creating the array for
4584 the first time. */
4585
252b5132 4586static void
6431e409
AM
4587request_dump_bynumber (struct dump_data *dumpdata,
4588 unsigned int section, dump_type type)
252b5132 4589{
6431e409 4590 if (section >= dumpdata->num_dump_sects)
252b5132 4591 {
2cf0635d 4592 dump_type * new_dump_sects;
252b5132 4593
3f5e193b 4594 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4595 sizeof (* new_dump_sects));
252b5132
RH
4596
4597 if (new_dump_sects == NULL)
591a748a 4598 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4599 else
4600 {
6431e409 4601 if (dumpdata->dump_sects)
21b65bac
NC
4602 {
4603 /* Copy current flag settings. */
6431e409
AM
4604 memcpy (new_dump_sects, dumpdata->dump_sects,
4605 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4606
6431e409 4607 free (dumpdata->dump_sects);
21b65bac 4608 }
252b5132 4609
6431e409
AM
4610 dumpdata->dump_sects = new_dump_sects;
4611 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4612 }
4613 }
4614
6431e409
AM
4615 if (dumpdata->dump_sects)
4616 dumpdata->dump_sects[section] |= type;
252b5132
RH
4617}
4618
aef1f6d0
DJ
4619/* Request a dump by section name. */
4620
4621static void
2cf0635d 4622request_dump_byname (const char * section, dump_type type)
aef1f6d0 4623{
2cf0635d 4624 struct dump_list_entry * new_request;
aef1f6d0 4625
3f5e193b
NC
4626 new_request = (struct dump_list_entry *)
4627 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4628 if (!new_request)
591a748a 4629 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4630
4631 new_request->name = strdup (section);
4632 if (!new_request->name)
591a748a 4633 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4634
4635 new_request->type = type;
4636
4637 new_request->next = dump_sects_byname;
4638 dump_sects_byname = new_request;
4639}
4640
cf13d699 4641static inline void
6431e409 4642request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4643{
4644 int section;
4645 char * cp;
4646
4647 do_dump++;
4648 section = strtoul (optarg, & cp, 0);
4649
4650 if (! *cp && section >= 0)
6431e409 4651 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4652 else
4653 request_dump_byname (optarg, type);
4654}
4655
252b5132 4656static void
6431e409 4657parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4658{
4659 int c;
4660
4661 if (argc < 2)
92f01d61 4662 usage (stderr);
252b5132
RH
4663
4664 while ((c = getopt_long
0e602686 4665 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4666 {
252b5132
RH
4667 switch (c)
4668 {
4669 case 0:
4670 /* Long options. */
4671 break;
4672 case 'H':
92f01d61 4673 usage (stdout);
252b5132
RH
4674 break;
4675
4676 case 'a':
32ec8896
NC
4677 do_syms = TRUE;
4678 do_reloc = TRUE;
4679 do_unwind = TRUE;
4680 do_dynamic = TRUE;
4681 do_header = TRUE;
4682 do_sections = TRUE;
4683 do_section_groups = TRUE;
4684 do_segments = TRUE;
4685 do_version = TRUE;
4686 do_histogram = TRUE;
4687 do_arch = TRUE;
4688 do_notes = TRUE;
252b5132 4689 break;
f5842774 4690 case 'g':
32ec8896 4691 do_section_groups = TRUE;
f5842774 4692 break;
5477e8a0 4693 case 't':
595cf52e 4694 case 'N':
32ec8896
NC
4695 do_sections = TRUE;
4696 do_section_details = TRUE;
595cf52e 4697 break;
252b5132 4698 case 'e':
32ec8896
NC
4699 do_header = TRUE;
4700 do_sections = TRUE;
4701 do_segments = TRUE;
252b5132 4702 break;
a952a375 4703 case 'A':
32ec8896 4704 do_arch = TRUE;
a952a375 4705 break;
252b5132 4706 case 'D':
32ec8896 4707 do_using_dynamic = TRUE;
252b5132
RH
4708 break;
4709 case 'r':
32ec8896 4710 do_reloc = TRUE;
252b5132 4711 break;
4d6ed7c8 4712 case 'u':
32ec8896 4713 do_unwind = TRUE;
4d6ed7c8 4714 break;
252b5132 4715 case 'h':
32ec8896 4716 do_header = TRUE;
252b5132
RH
4717 break;
4718 case 'l':
32ec8896 4719 do_segments = TRUE;
252b5132
RH
4720 break;
4721 case 's':
32ec8896 4722 do_syms = TRUE;
252b5132
RH
4723 break;
4724 case 'S':
32ec8896 4725 do_sections = TRUE;
252b5132
RH
4726 break;
4727 case 'd':
32ec8896 4728 do_dynamic = TRUE;
252b5132 4729 break;
a952a375 4730 case 'I':
32ec8896 4731 do_histogram = TRUE;
a952a375 4732 break;
779fe533 4733 case 'n':
32ec8896 4734 do_notes = TRUE;
779fe533 4735 break;
4145f1d5 4736 case 'c':
32ec8896 4737 do_archive_index = TRUE;
4145f1d5 4738 break;
252b5132 4739 case 'x':
6431e409 4740 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4741 break;
09c11c86 4742 case 'p':
6431e409 4743 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4744 break;
4745 case 'R':
6431e409 4746 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4747 break;
0e602686 4748 case 'z':
32ec8896 4749 decompress_dumps = TRUE;
0e602686 4750 break;
252b5132 4751 case 'w':
32ec8896 4752 do_dump = TRUE;
252b5132 4753 if (optarg == 0)
613ff48b 4754 {
32ec8896 4755 do_debugging = TRUE;
613ff48b
CC
4756 dwarf_select_sections_all ();
4757 }
252b5132
RH
4758 else
4759 {
32ec8896 4760 do_debugging = FALSE;
4cb93e3b 4761 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4762 }
4763 break;
2979dc34 4764 case OPTION_DEBUG_DUMP:
32ec8896 4765 do_dump = TRUE;
2979dc34 4766 if (optarg == 0)
32ec8896 4767 do_debugging = TRUE;
2979dc34
JJ
4768 else
4769 {
32ec8896 4770 do_debugging = FALSE;
4cb93e3b 4771 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4772 }
4773 break;
fd2f0033
TT
4774 case OPTION_DWARF_DEPTH:
4775 {
4776 char *cp;
4777
4778 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4779 }
4780 break;
4781 case OPTION_DWARF_START:
4782 {
4783 char *cp;
4784
4785 dwarf_start_die = strtoul (optarg, & cp, 0);
4786 }
4787 break;
4723351a 4788 case OPTION_DWARF_CHECK:
32ec8896 4789 dwarf_check = TRUE;
4723351a 4790 break;
7d9813f1
NA
4791 case OPTION_CTF_DUMP:
4792 do_ctf = TRUE;
6431e409 4793 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4794 break;
4795 case OPTION_CTF_SYMBOLS:
4796 dump_ctf_symtab_name = strdup (optarg);
4797 break;
4798 case OPTION_CTF_STRINGS:
4799 dump_ctf_strtab_name = strdup (optarg);
4800 break;
4801 case OPTION_CTF_PARENT:
4802 dump_ctf_parent_name = strdup (optarg);
4803 break;
2c610e4b 4804 case OPTION_DYN_SYMS:
32ec8896 4805 do_dyn_syms = TRUE;
2c610e4b 4806 break;
252b5132
RH
4807#ifdef SUPPORT_DISASSEMBLY
4808 case 'i':
6431e409 4809 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4810 break;
252b5132
RH
4811#endif
4812 case 'v':
4813 print_version (program_name);
4814 break;
4815 case 'V':
32ec8896 4816 do_version = TRUE;
252b5132 4817 break;
d974e256 4818 case 'W':
32ec8896 4819 do_wide = TRUE;
d974e256 4820 break;
252b5132 4821 default:
252b5132
RH
4822 /* xgettext:c-format */
4823 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4824 /* Fall through. */
252b5132 4825 case '?':
92f01d61 4826 usage (stderr);
252b5132
RH
4827 }
4828 }
4829
4d6ed7c8 4830 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4831 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4832 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4833 && !do_section_groups && !do_archive_index
4834 && !do_dyn_syms)
92f01d61 4835 usage (stderr);
252b5132
RH
4836}
4837
4838static const char *
d3ba0551 4839get_elf_class (unsigned int elf_class)
252b5132 4840{
b34976b6 4841 static char buff[32];
103f02d3 4842
252b5132
RH
4843 switch (elf_class)
4844 {
4845 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4846 case ELFCLASS32: return "ELF32";
4847 case ELFCLASS64: return "ELF64";
ab5e7794 4848 default:
e9e44622 4849 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4850 return buff;
252b5132
RH
4851 }
4852}
4853
4854static const char *
d3ba0551 4855get_data_encoding (unsigned int encoding)
252b5132 4856{
b34976b6 4857 static char buff[32];
103f02d3 4858
252b5132
RH
4859 switch (encoding)
4860 {
4861 case ELFDATANONE: return _("none");
33c63f9d
CM
4862 case ELFDATA2LSB: return _("2's complement, little endian");
4863 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4864 default:
e9e44622 4865 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4866 return buff;
252b5132
RH
4867 }
4868}
4869
dda8d76d 4870/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4871
32ec8896 4872static bfd_boolean
dda8d76d 4873process_file_header (Filedata * filedata)
252b5132 4874{
dda8d76d
NC
4875 Elf_Internal_Ehdr * header = & filedata->file_header;
4876
4877 if ( header->e_ident[EI_MAG0] != ELFMAG0
4878 || header->e_ident[EI_MAG1] != ELFMAG1
4879 || header->e_ident[EI_MAG2] != ELFMAG2
4880 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4881 {
4882 error
4883 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4884 return FALSE;
252b5132
RH
4885 }
4886
955ff7fc 4887 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 4888
252b5132
RH
4889 if (do_header)
4890 {
32ec8896 4891 unsigned i;
252b5132
RH
4892
4893 printf (_("ELF Header:\n"));
4894 printf (_(" Magic: "));
b34976b6 4895 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4896 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4897 printf ("\n");
4898 printf (_(" Class: %s\n"),
dda8d76d 4899 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4900 printf (_(" Data: %s\n"),
dda8d76d 4901 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 4902 printf (_(" Version: %d%s\n"),
dda8d76d
NC
4903 header->e_ident[EI_VERSION],
4904 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 4905 ? _(" (current)")
dda8d76d 4906 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 4907 ? _(" <unknown>")
789be9f7 4908 : "")));
252b5132 4909 printf (_(" OS/ABI: %s\n"),
dda8d76d 4910 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 4911 printf (_(" ABI Version: %d\n"),
dda8d76d 4912 header->e_ident[EI_ABIVERSION]);
252b5132 4913 printf (_(" Type: %s\n"),
dda8d76d 4914 get_file_type (header->e_type));
252b5132 4915 printf (_(" Machine: %s\n"),
dda8d76d 4916 get_machine_name (header->e_machine));
252b5132 4917 printf (_(" Version: 0x%lx\n"),
e8a64888 4918 header->e_version);
76da6bbe 4919
f7a99963 4920 printf (_(" Entry point address: "));
e8a64888 4921 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 4922 printf (_("\n Start of program headers: "));
e8a64888 4923 print_vma (header->e_phoff, DEC);
f7a99963 4924 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 4925 print_vma (header->e_shoff, DEC);
f7a99963 4926 printf (_(" (bytes into file)\n"));
76da6bbe 4927
252b5132 4928 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 4929 header->e_flags,
dda8d76d 4930 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
4931 printf (_(" Size of this header: %u (bytes)\n"),
4932 header->e_ehsize);
4933 printf (_(" Size of program headers: %u (bytes)\n"),
4934 header->e_phentsize);
4935 printf (_(" Number of program headers: %u"),
4936 header->e_phnum);
dda8d76d
NC
4937 if (filedata->section_headers != NULL
4938 && header->e_phnum == PN_XNUM
4939 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
4940 {
4941 header->e_phnum = filedata->section_headers[0].sh_info;
4942 printf (" (%u)", header->e_phnum);
4943 }
2046a35d 4944 putc ('\n', stdout);
e8a64888
AM
4945 printf (_(" Size of section headers: %u (bytes)\n"),
4946 header->e_shentsize);
4947 printf (_(" Number of section headers: %u"),
4948 header->e_shnum);
dda8d76d 4949 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
4950 {
4951 header->e_shnum = filedata->section_headers[0].sh_size;
4952 printf (" (%u)", header->e_shnum);
4953 }
560f3c1c 4954 putc ('\n', stdout);
e8a64888
AM
4955 printf (_(" Section header string table index: %u"),
4956 header->e_shstrndx);
dda8d76d
NC
4957 if (filedata->section_headers != NULL
4958 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
4959 {
4960 header->e_shstrndx = filedata->section_headers[0].sh_link;
4961 printf (" (%u)", header->e_shstrndx);
4962 }
4963 if (header->e_shstrndx != SHN_UNDEF
4964 && header->e_shstrndx >= header->e_shnum)
4965 {
4966 header->e_shstrndx = SHN_UNDEF;
4967 printf (_(" <corrupt: out of range>"));
4968 }
560f3c1c
AM
4969 putc ('\n', stdout);
4970 }
4971
dda8d76d 4972 if (filedata->section_headers != NULL)
560f3c1c 4973 {
dda8d76d
NC
4974 if (header->e_phnum == PN_XNUM
4975 && filedata->section_headers[0].sh_info != 0)
4976 header->e_phnum = filedata->section_headers[0].sh_info;
4977 if (header->e_shnum == SHN_UNDEF)
4978 header->e_shnum = filedata->section_headers[0].sh_size;
4979 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
4980 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 4981 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
4982 header->e_shstrndx = SHN_UNDEF;
4983 free (filedata->section_headers);
4984 filedata->section_headers = NULL;
252b5132 4985 }
103f02d3 4986
32ec8896 4987 return TRUE;
9ea033b2
NC
4988}
4989
dda8d76d
NC
4990/* Read in the program headers from FILEDATA and store them in PHEADERS.
4991 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
4992
e0a31db1 4993static bfd_boolean
dda8d76d 4994get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4995{
2cf0635d
NC
4996 Elf32_External_Phdr * phdrs;
4997 Elf32_External_Phdr * external;
4998 Elf_Internal_Phdr * internal;
b34976b6 4999 unsigned int i;
dda8d76d
NC
5000 unsigned int size = filedata->file_header.e_phentsize;
5001 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5002
5003 /* PR binutils/17531: Cope with unexpected section header sizes. */
5004 if (size == 0 || num == 0)
5005 return FALSE;
5006 if (size < sizeof * phdrs)
5007 {
5008 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5009 return FALSE;
5010 }
5011 if (size > sizeof * phdrs)
5012 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5013
dda8d76d 5014 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5015 size, num, _("program headers"));
5016 if (phdrs == NULL)
5017 return FALSE;
9ea033b2 5018
91d6fa6a 5019 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5020 i < filedata->file_header.e_phnum;
b34976b6 5021 i++, internal++, external++)
252b5132 5022 {
9ea033b2
NC
5023 internal->p_type = BYTE_GET (external->p_type);
5024 internal->p_offset = BYTE_GET (external->p_offset);
5025 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5026 internal->p_paddr = BYTE_GET (external->p_paddr);
5027 internal->p_filesz = BYTE_GET (external->p_filesz);
5028 internal->p_memsz = BYTE_GET (external->p_memsz);
5029 internal->p_flags = BYTE_GET (external->p_flags);
5030 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5031 }
5032
9ea033b2 5033 free (phdrs);
e0a31db1 5034 return TRUE;
252b5132
RH
5035}
5036
dda8d76d
NC
5037/* Read in the program headers from FILEDATA and store them in PHEADERS.
5038 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5039
e0a31db1 5040static bfd_boolean
dda8d76d 5041get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5042{
2cf0635d
NC
5043 Elf64_External_Phdr * phdrs;
5044 Elf64_External_Phdr * external;
5045 Elf_Internal_Phdr * internal;
b34976b6 5046 unsigned int i;
dda8d76d
NC
5047 unsigned int size = filedata->file_header.e_phentsize;
5048 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5049
5050 /* PR binutils/17531: Cope with unexpected section header sizes. */
5051 if (size == 0 || num == 0)
5052 return FALSE;
5053 if (size < sizeof * phdrs)
5054 {
5055 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5056 return FALSE;
5057 }
5058 if (size > sizeof * phdrs)
5059 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5060
dda8d76d 5061 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5062 size, num, _("program headers"));
a6e9f9df 5063 if (!phdrs)
e0a31db1 5064 return FALSE;
9ea033b2 5065
91d6fa6a 5066 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5067 i < filedata->file_header.e_phnum;
b34976b6 5068 i++, internal++, external++)
9ea033b2
NC
5069 {
5070 internal->p_type = BYTE_GET (external->p_type);
5071 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5072 internal->p_offset = BYTE_GET (external->p_offset);
5073 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5074 internal->p_paddr = BYTE_GET (external->p_paddr);
5075 internal->p_filesz = BYTE_GET (external->p_filesz);
5076 internal->p_memsz = BYTE_GET (external->p_memsz);
5077 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5078 }
5079
5080 free (phdrs);
e0a31db1 5081 return TRUE;
9ea033b2 5082}
252b5132 5083
32ec8896 5084/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5085
32ec8896 5086static bfd_boolean
dda8d76d 5087get_program_headers (Filedata * filedata)
d93f0186 5088{
2cf0635d 5089 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5090
5091 /* Check cache of prior read. */
dda8d76d 5092 if (filedata->program_headers != NULL)
32ec8896 5093 return TRUE;
d93f0186 5094
82156ab7
NC
5095 /* Be kind to memory checkers by looking for
5096 e_phnum values which we know must be invalid. */
dda8d76d 5097 if (filedata->file_header.e_phnum
82156ab7 5098 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5099 >= filedata->file_size)
82156ab7
NC
5100 {
5101 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5102 filedata->file_header.e_phnum);
82156ab7
NC
5103 return FALSE;
5104 }
d93f0186 5105
dda8d76d 5106 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5107 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5108 if (phdrs == NULL)
5109 {
8b73c356 5110 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5111 filedata->file_header.e_phnum);
32ec8896 5112 return FALSE;
d93f0186
NC
5113 }
5114
5115 if (is_32bit_elf
dda8d76d
NC
5116 ? get_32bit_program_headers (filedata, phdrs)
5117 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5118 {
dda8d76d 5119 filedata->program_headers = phdrs;
32ec8896 5120 return TRUE;
d93f0186
NC
5121 }
5122
5123 free (phdrs);
32ec8896 5124 return FALSE;
d93f0186
NC
5125}
5126
32ec8896 5127/* Returns TRUE if the program headers were loaded. */
2f62977e 5128
32ec8896 5129static bfd_boolean
dda8d76d 5130process_program_headers (Filedata * filedata)
252b5132 5131{
2cf0635d 5132 Elf_Internal_Phdr * segment;
b34976b6 5133 unsigned int i;
1a9ccd70 5134 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5135
978c4450
AM
5136 filedata->dynamic_addr = 0;
5137 filedata->dynamic_size = 0;
663f67df 5138
dda8d76d 5139 if (filedata->file_header.e_phnum == 0)
252b5132 5140 {
82f2dbf7 5141 /* PR binutils/12467. */
dda8d76d 5142 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5143 {
5144 warn (_("possibly corrupt ELF header - it has a non-zero program"
5145 " header offset, but no program headers\n"));
5146 return FALSE;
5147 }
82f2dbf7 5148 else if (do_segments)
252b5132 5149 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5150 return TRUE;
252b5132
RH
5151 }
5152
5153 if (do_segments && !do_header)
5154 {
dda8d76d
NC
5155 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5156 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5157 printf (ngettext ("There is %d program header, starting at offset %s\n",
5158 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5159 filedata->file_header.e_phnum),
5160 filedata->file_header.e_phnum,
5161 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5162 }
5163
dda8d76d 5164 if (! get_program_headers (filedata))
6b4bf3bc 5165 return TRUE;
103f02d3 5166
252b5132
RH
5167 if (do_segments)
5168 {
dda8d76d 5169 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5170 printf (_("\nProgram Headers:\n"));
5171 else
5172 printf (_("\nProgram Headers:\n"));
76da6bbe 5173
f7a99963
NC
5174 if (is_32bit_elf)
5175 printf
5176 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5177 else if (do_wide)
5178 printf
5179 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5180 else
5181 {
5182 printf
5183 (_(" Type Offset VirtAddr PhysAddr\n"));
5184 printf
5185 (_(" FileSiz MemSiz Flags Align\n"));
5186 }
252b5132
RH
5187 }
5188
dda8d76d
NC
5189 for (i = 0, segment = filedata->program_headers;
5190 i < filedata->file_header.e_phnum;
b34976b6 5191 i++, segment++)
252b5132
RH
5192 {
5193 if (do_segments)
5194 {
dda8d76d 5195 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5196
5197 if (is_32bit_elf)
5198 {
5199 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5200 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5201 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5202 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5203 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5204 printf ("%c%c%c ",
5205 (segment->p_flags & PF_R ? 'R' : ' '),
5206 (segment->p_flags & PF_W ? 'W' : ' '),
5207 (segment->p_flags & PF_X ? 'E' : ' '));
5208 printf ("%#lx", (unsigned long) segment->p_align);
5209 }
d974e256
JJ
5210 else if (do_wide)
5211 {
5212 if ((unsigned long) segment->p_offset == segment->p_offset)
5213 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5214 else
5215 {
5216 print_vma (segment->p_offset, FULL_HEX);
5217 putchar (' ');
5218 }
5219
5220 print_vma (segment->p_vaddr, FULL_HEX);
5221 putchar (' ');
5222 print_vma (segment->p_paddr, FULL_HEX);
5223 putchar (' ');
5224
5225 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5226 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5227 else
5228 {
5229 print_vma (segment->p_filesz, FULL_HEX);
5230 putchar (' ');
5231 }
5232
5233 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5234 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5235 else
5236 {
f48e6c45 5237 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5238 }
5239
5240 printf (" %c%c%c ",
5241 (segment->p_flags & PF_R ? 'R' : ' '),
5242 (segment->p_flags & PF_W ? 'W' : ' '),
5243 (segment->p_flags & PF_X ? 'E' : ' '));
5244
5245 if ((unsigned long) segment->p_align == segment->p_align)
5246 printf ("%#lx", (unsigned long) segment->p_align);
5247 else
5248 {
5249 print_vma (segment->p_align, PREFIX_HEX);
5250 }
5251 }
f7a99963
NC
5252 else
5253 {
5254 print_vma (segment->p_offset, FULL_HEX);
5255 putchar (' ');
5256 print_vma (segment->p_vaddr, FULL_HEX);
5257 putchar (' ');
5258 print_vma (segment->p_paddr, FULL_HEX);
5259 printf ("\n ");
5260 print_vma (segment->p_filesz, FULL_HEX);
5261 putchar (' ');
5262 print_vma (segment->p_memsz, FULL_HEX);
5263 printf (" %c%c%c ",
5264 (segment->p_flags & PF_R ? 'R' : ' '),
5265 (segment->p_flags & PF_W ? 'W' : ' '),
5266 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5267 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5268 }
252b5132 5269
1a9ccd70
NC
5270 putc ('\n', stdout);
5271 }
f54498b4 5272
252b5132
RH
5273 switch (segment->p_type)
5274 {
1a9ccd70 5275 case PT_LOAD:
502d895c
NC
5276#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5277 required by the ELF standard, several programs, including the Linux
5278 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5279 if (previous_load
5280 && previous_load->p_vaddr > segment->p_vaddr)
5281 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5282#endif
1a9ccd70
NC
5283 if (segment->p_memsz < segment->p_filesz)
5284 error (_("the segment's file size is larger than its memory size\n"));
5285 previous_load = segment;
5286 break;
5287
5288 case PT_PHDR:
5289 /* PR 20815 - Verify that the program header is loaded into memory. */
5290 if (i > 0 && previous_load != NULL)
5291 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5292 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5293 {
5294 unsigned int j;
5295
dda8d76d 5296 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5297 {
5298 Elf_Internal_Phdr *load = filedata->program_headers + j;
5299 if (load->p_type == PT_LOAD
5300 && load->p_offset <= segment->p_offset
5301 && (load->p_offset + load->p_filesz
5302 >= segment->p_offset + segment->p_filesz)
5303 && load->p_vaddr <= segment->p_vaddr
5304 && (load->p_vaddr + load->p_filesz
5305 >= segment->p_vaddr + segment->p_filesz))
5306 break;
5307 }
dda8d76d 5308 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5309 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5310 }
5311 break;
5312
252b5132 5313 case PT_DYNAMIC:
978c4450 5314 if (filedata->dynamic_addr)
252b5132
RH
5315 error (_("more than one dynamic segment\n"));
5316
20737c13
AM
5317 /* By default, assume that the .dynamic section is the first
5318 section in the DYNAMIC segment. */
978c4450
AM
5319 filedata->dynamic_addr = segment->p_offset;
5320 filedata->dynamic_size = segment->p_filesz;
20737c13 5321
b2d38a17
NC
5322 /* Try to locate the .dynamic section. If there is
5323 a section header table, we can easily locate it. */
dda8d76d 5324 if (filedata->section_headers != NULL)
b2d38a17 5325 {
2cf0635d 5326 Elf_Internal_Shdr * sec;
b2d38a17 5327
dda8d76d 5328 sec = find_section (filedata, ".dynamic");
89fac5e3 5329 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5330 {
28f997cf
TG
5331 /* A corresponding .dynamic section is expected, but on
5332 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5333 if (!is_ia64_vms (filedata))
28f997cf 5334 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5335 break;
5336 }
5337
42bb2e33 5338 if (sec->sh_type == SHT_NOBITS)
20737c13 5339 {
978c4450 5340 filedata->dynamic_size = 0;
20737c13
AM
5341 break;
5342 }
42bb2e33 5343
978c4450
AM
5344 filedata->dynamic_addr = sec->sh_offset;
5345 filedata->dynamic_size = sec->sh_size;
b2d38a17 5346
978c4450
AM
5347 if (filedata->dynamic_addr < segment->p_offset
5348 || filedata->dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
5349 warn (_("the .dynamic section is not contained"
5350 " within the dynamic segment\n"));
978c4450 5351 else if (filedata->dynamic_addr > segment->p_offset)
20737c13
AM
5352 warn (_("the .dynamic section is not the first section"
5353 " in the dynamic segment.\n"));
b2d38a17 5354 }
39e224f6
MW
5355
5356 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5357 segment. Check this after matching against the section headers
5358 so we don't warn on debuginfo file (which have NOBITS .dynamic
5359 sections). */
978c4450
AM
5360 if (filedata->dynamic_addr > filedata->file_size
5361 || (filedata->dynamic_size
5362 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5363 {
5364 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5365 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5366 }
252b5132
RH
5367 break;
5368
5369 case PT_INTERP:
978c4450
AM
5370 if (fseek (filedata->handle,
5371 filedata->archive_file_offset + (long) segment->p_offset,
fb52b2f4 5372 SEEK_SET))
252b5132
RH
5373 error (_("Unable to find program interpreter name\n"));
5374 else
5375 {
f8eae8b2 5376 char fmt [32];
9495b2e6 5377 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5378
5379 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5380 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5381
978c4450
AM
5382 filedata->program_interpreter[0] = 0;
5383 if (fscanf (filedata->handle, fmt,
5384 filedata->program_interpreter) <= 0)
7bd7b3ef 5385 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5386
5387 if (do_segments)
f54498b4 5388 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5389 filedata->program_interpreter);
252b5132
RH
5390 }
5391 break;
5392 }
252b5132
RH
5393 }
5394
dda8d76d
NC
5395 if (do_segments
5396 && filedata->section_headers != NULL
5397 && filedata->string_table != NULL)
252b5132
RH
5398 {
5399 printf (_("\n Section to Segment mapping:\n"));
5400 printf (_(" Segment Sections...\n"));
5401
dda8d76d 5402 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5403 {
9ad5cbcf 5404 unsigned int j;
2cf0635d 5405 Elf_Internal_Shdr * section;
252b5132 5406
dda8d76d
NC
5407 segment = filedata->program_headers + i;
5408 section = filedata->section_headers + 1;
252b5132
RH
5409
5410 printf (" %2.2d ", i);
5411
dda8d76d 5412 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5413 {
f4638467
AM
5414 if (!ELF_TBSS_SPECIAL (section, segment)
5415 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5416 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5417 }
5418
5419 putc ('\n',stdout);
5420 }
5421 }
5422
32ec8896 5423 return TRUE;
252b5132
RH
5424}
5425
5426
d93f0186
NC
5427/* Find the file offset corresponding to VMA by using the program headers. */
5428
5429static long
dda8d76d 5430offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5431{
2cf0635d 5432 Elf_Internal_Phdr * seg;
d93f0186 5433
dda8d76d 5434 if (! get_program_headers (filedata))
d93f0186
NC
5435 {
5436 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5437 return (long) vma;
5438 }
5439
dda8d76d
NC
5440 for (seg = filedata->program_headers;
5441 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5442 ++seg)
5443 {
5444 if (seg->p_type != PT_LOAD)
5445 continue;
5446
5447 if (vma >= (seg->p_vaddr & -seg->p_align)
5448 && vma + size <= seg->p_vaddr + seg->p_filesz)
5449 return vma - seg->p_vaddr + seg->p_offset;
5450 }
5451
5452 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5453 (unsigned long) vma);
d93f0186
NC
5454 return (long) vma;
5455}
5456
5457
dda8d76d
NC
5458/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5459 If PROBE is true, this is just a probe and we do not generate any error
5460 messages if the load fails. */
049b0c3a
NC
5461
5462static bfd_boolean
dda8d76d 5463get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5464{
2cf0635d
NC
5465 Elf32_External_Shdr * shdrs;
5466 Elf_Internal_Shdr * internal;
dda8d76d
NC
5467 unsigned int i;
5468 unsigned int size = filedata->file_header.e_shentsize;
5469 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5470
5471 /* PR binutils/17531: Cope with unexpected section header sizes. */
5472 if (size == 0 || num == 0)
5473 return FALSE;
5474 if (size < sizeof * shdrs)
5475 {
5476 if (! probe)
5477 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5478 return FALSE;
5479 }
5480 if (!probe && size > sizeof * shdrs)
5481 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5482
dda8d76d 5483 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5484 size, num,
5485 probe ? NULL : _("section headers"));
5486 if (shdrs == NULL)
5487 return FALSE;
252b5132 5488
dda8d76d
NC
5489 free (filedata->section_headers);
5490 filedata->section_headers = (Elf_Internal_Shdr *)
5491 cmalloc (num, sizeof (Elf_Internal_Shdr));
5492 if (filedata->section_headers == NULL)
252b5132 5493 {
049b0c3a 5494 if (!probe)
8b73c356 5495 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5496 free (shdrs);
049b0c3a 5497 return FALSE;
252b5132
RH
5498 }
5499
dda8d76d 5500 for (i = 0, internal = filedata->section_headers;
560f3c1c 5501 i < num;
b34976b6 5502 i++, internal++)
252b5132
RH
5503 {
5504 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5505 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5506 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5507 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5508 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5509 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5510 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5511 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5512 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5513 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5514 if (!probe && internal->sh_link > num)
5515 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5516 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5517 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5518 }
5519
5520 free (shdrs);
049b0c3a 5521 return TRUE;
252b5132
RH
5522}
5523
dda8d76d
NC
5524/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5525
049b0c3a 5526static bfd_boolean
dda8d76d 5527get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5528{
dda8d76d
NC
5529 Elf64_External_Shdr * shdrs;
5530 Elf_Internal_Shdr * internal;
5531 unsigned int i;
5532 unsigned int size = filedata->file_header.e_shentsize;
5533 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5534
5535 /* PR binutils/17531: Cope with unexpected section header sizes. */
5536 if (size == 0 || num == 0)
5537 return FALSE;
dda8d76d 5538
049b0c3a
NC
5539 if (size < sizeof * shdrs)
5540 {
5541 if (! probe)
5542 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5543 return FALSE;
5544 }
dda8d76d 5545
049b0c3a
NC
5546 if (! probe && size > sizeof * shdrs)
5547 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5548
dda8d76d
NC
5549 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5550 filedata->file_header.e_shoff,
049b0c3a
NC
5551 size, num,
5552 probe ? NULL : _("section headers"));
5553 if (shdrs == NULL)
5554 return FALSE;
9ea033b2 5555
dda8d76d
NC
5556 free (filedata->section_headers);
5557 filedata->section_headers = (Elf_Internal_Shdr *)
5558 cmalloc (num, sizeof (Elf_Internal_Shdr));
5559 if (filedata->section_headers == NULL)
9ea033b2 5560 {
049b0c3a 5561 if (! probe)
8b73c356 5562 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5563 free (shdrs);
049b0c3a 5564 return FALSE;
9ea033b2
NC
5565 }
5566
dda8d76d 5567 for (i = 0, internal = filedata->section_headers;
560f3c1c 5568 i < num;
b34976b6 5569 i++, internal++)
9ea033b2
NC
5570 {
5571 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5572 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5573 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5574 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5575 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5576 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5577 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5578 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5579 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5580 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5581 if (!probe && internal->sh_link > num)
5582 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5583 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5584 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5585 }
5586
5587 free (shdrs);
049b0c3a 5588 return TRUE;
9ea033b2
NC
5589}
5590
252b5132 5591static Elf_Internal_Sym *
dda8d76d
NC
5592get_32bit_elf_symbols (Filedata * filedata,
5593 Elf_Internal_Shdr * section,
5594 unsigned long * num_syms_return)
252b5132 5595{
ba5cdace 5596 unsigned long number = 0;
dd24e3da 5597 Elf32_External_Sym * esyms = NULL;
ba5cdace 5598 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5599 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5600 Elf_Internal_Sym * psym;
b34976b6 5601 unsigned int j;
e3d39609 5602 elf_section_list * entry;
252b5132 5603
c9c1d674
EG
5604 if (section->sh_size == 0)
5605 {
5606 if (num_syms_return != NULL)
5607 * num_syms_return = 0;
5608 return NULL;
5609 }
5610
dd24e3da 5611 /* Run some sanity checks first. */
c9c1d674 5612 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5613 {
c9c1d674 5614 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5615 printable_section_name (filedata, section),
5616 (unsigned long) section->sh_entsize);
ba5cdace 5617 goto exit_point;
dd24e3da
NC
5618 }
5619
dda8d76d 5620 if (section->sh_size > filedata->file_size)
f54498b4
NC
5621 {
5622 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5623 printable_section_name (filedata, section),
5624 (unsigned long) section->sh_size);
f54498b4
NC
5625 goto exit_point;
5626 }
5627
dd24e3da
NC
5628 number = section->sh_size / section->sh_entsize;
5629
5630 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5631 {
c9c1d674 5632 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5633 (unsigned long) section->sh_size,
dda8d76d 5634 printable_section_name (filedata, section),
8066deb1 5635 (unsigned long) section->sh_entsize);
ba5cdace 5636 goto exit_point;
dd24e3da
NC
5637 }
5638
dda8d76d 5639 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5640 section->sh_size, _("symbols"));
dd24e3da 5641 if (esyms == NULL)
ba5cdace 5642 goto exit_point;
252b5132 5643
e3d39609 5644 shndx = NULL;
978c4450 5645 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5646 {
5647 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5648 continue;
5649
5650 if (shndx != NULL)
5651 {
5652 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5653 free (shndx);
5654 }
5655
5656 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5657 entry->hdr->sh_offset,
5658 1, entry->hdr->sh_size,
5659 _("symbol table section indices"));
5660 if (shndx == NULL)
5661 goto exit_point;
5662
5663 /* PR17531: file: heap-buffer-overflow */
5664 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5665 {
5666 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5667 printable_section_name (filedata, entry->hdr),
5668 (unsigned long) entry->hdr->sh_size,
5669 (unsigned long) section->sh_size);
5670 goto exit_point;
c9c1d674 5671 }
e3d39609 5672 }
9ad5cbcf 5673
3f5e193b 5674 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5675
5676 if (isyms == NULL)
5677 {
8b73c356
NC
5678 error (_("Out of memory reading %lu symbols\n"),
5679 (unsigned long) number);
dd24e3da 5680 goto exit_point;
252b5132
RH
5681 }
5682
dd24e3da 5683 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5684 {
5685 psym->st_name = BYTE_GET (esyms[j].st_name);
5686 psym->st_value = BYTE_GET (esyms[j].st_value);
5687 psym->st_size = BYTE_GET (esyms[j].st_size);
5688 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5689 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5690 psym->st_shndx
5691 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5692 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5693 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5694 psym->st_info = BYTE_GET (esyms[j].st_info);
5695 psym->st_other = BYTE_GET (esyms[j].st_other);
5696 }
5697
dd24e3da 5698 exit_point:
e3d39609
NC
5699 free (shndx);
5700 free (esyms);
252b5132 5701
ba5cdace
NC
5702 if (num_syms_return != NULL)
5703 * num_syms_return = isyms == NULL ? 0 : number;
5704
252b5132
RH
5705 return isyms;
5706}
5707
9ea033b2 5708static Elf_Internal_Sym *
dda8d76d
NC
5709get_64bit_elf_symbols (Filedata * filedata,
5710 Elf_Internal_Shdr * section,
5711 unsigned long * num_syms_return)
9ea033b2 5712{
ba5cdace
NC
5713 unsigned long number = 0;
5714 Elf64_External_Sym * esyms = NULL;
5715 Elf_External_Sym_Shndx * shndx = NULL;
5716 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5717 Elf_Internal_Sym * psym;
b34976b6 5718 unsigned int j;
e3d39609 5719 elf_section_list * entry;
9ea033b2 5720
c9c1d674
EG
5721 if (section->sh_size == 0)
5722 {
5723 if (num_syms_return != NULL)
5724 * num_syms_return = 0;
5725 return NULL;
5726 }
5727
dd24e3da 5728 /* Run some sanity checks first. */
c9c1d674 5729 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5730 {
c9c1d674 5731 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5732 printable_section_name (filedata, section),
8066deb1 5733 (unsigned long) section->sh_entsize);
ba5cdace 5734 goto exit_point;
dd24e3da
NC
5735 }
5736
dda8d76d 5737 if (section->sh_size > filedata->file_size)
f54498b4
NC
5738 {
5739 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5740 printable_section_name (filedata, section),
8066deb1 5741 (unsigned long) section->sh_size);
f54498b4
NC
5742 goto exit_point;
5743 }
5744
dd24e3da
NC
5745 number = section->sh_size / section->sh_entsize;
5746
5747 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5748 {
c9c1d674 5749 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5750 (unsigned long) section->sh_size,
dda8d76d 5751 printable_section_name (filedata, section),
8066deb1 5752 (unsigned long) section->sh_entsize);
ba5cdace 5753 goto exit_point;
dd24e3da
NC
5754 }
5755
dda8d76d 5756 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5757 section->sh_size, _("symbols"));
a6e9f9df 5758 if (!esyms)
ba5cdace 5759 goto exit_point;
9ea033b2 5760
e3d39609 5761 shndx = NULL;
978c4450 5762 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5763 {
5764 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5765 continue;
5766
5767 if (shndx != NULL)
5768 {
5769 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5770 free (shndx);
c9c1d674 5771 }
e3d39609
NC
5772
5773 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5774 entry->hdr->sh_offset,
5775 1, entry->hdr->sh_size,
5776 _("symbol table section indices"));
5777 if (shndx == NULL)
5778 goto exit_point;
5779
5780 /* PR17531: file: heap-buffer-overflow */
5781 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5782 {
5783 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5784 printable_section_name (filedata, entry->hdr),
5785 (unsigned long) entry->hdr->sh_size,
5786 (unsigned long) section->sh_size);
5787 goto exit_point;
5788 }
5789 }
9ad5cbcf 5790
3f5e193b 5791 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5792
5793 if (isyms == NULL)
5794 {
8b73c356
NC
5795 error (_("Out of memory reading %lu symbols\n"),
5796 (unsigned long) number);
ba5cdace 5797 goto exit_point;
9ea033b2
NC
5798 }
5799
ba5cdace 5800 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5801 {
5802 psym->st_name = BYTE_GET (esyms[j].st_name);
5803 psym->st_info = BYTE_GET (esyms[j].st_info);
5804 psym->st_other = BYTE_GET (esyms[j].st_other);
5805 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5806
4fbb74a6 5807 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5808 psym->st_shndx
5809 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5810 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5811 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5812
66543521
AM
5813 psym->st_value = BYTE_GET (esyms[j].st_value);
5814 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5815 }
5816
ba5cdace 5817 exit_point:
e3d39609
NC
5818 free (shndx);
5819 free (esyms);
ba5cdace
NC
5820
5821 if (num_syms_return != NULL)
5822 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5823
5824 return isyms;
5825}
5826
d1133906 5827static const char *
dda8d76d 5828get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5829{
5477e8a0 5830 static char buff[1024];
2cf0635d 5831 char * p = buff;
32ec8896
NC
5832 unsigned int field_size = is_32bit_elf ? 8 : 16;
5833 signed int sindex;
5834 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5835 bfd_vma os_flags = 0;
5836 bfd_vma proc_flags = 0;
5837 bfd_vma unknown_flags = 0;
148b93f2 5838 static const struct
5477e8a0 5839 {
2cf0635d 5840 const char * str;
32ec8896 5841 unsigned int len;
5477e8a0
L
5842 }
5843 flags [] =
5844 {
cfcac11d
NC
5845 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5846 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5847 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5848 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5849 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5850 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5851 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5852 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5853 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5854 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5855 /* IA-64 specific. */
5856 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5857 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5858 /* IA-64 OpenVMS specific. */
5859 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5860 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5861 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5862 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5863 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5864 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5865 /* Generic. */
cfcac11d 5866 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5867 /* SPARC specific. */
77115a4a 5868 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5869 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5870 /* ARM specific. */
5871 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5872 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5873 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5874 /* GNU specific. */
5875 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5876 /* VLE specific. */
5877 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5878 };
5879
5880 if (do_section_details)
5881 {
8d5ff12c
L
5882 sprintf (buff, "[%*.*lx]: ",
5883 field_size, field_size, (unsigned long) sh_flags);
5884 p += field_size + 4;
5477e8a0 5885 }
76da6bbe 5886
d1133906
NC
5887 while (sh_flags)
5888 {
5889 bfd_vma flag;
5890
5891 flag = sh_flags & - sh_flags;
5892 sh_flags &= ~ flag;
76da6bbe 5893
5477e8a0 5894 if (do_section_details)
d1133906 5895 {
5477e8a0
L
5896 switch (flag)
5897 {
91d6fa6a
NC
5898 case SHF_WRITE: sindex = 0; break;
5899 case SHF_ALLOC: sindex = 1; break;
5900 case SHF_EXECINSTR: sindex = 2; break;
5901 case SHF_MERGE: sindex = 3; break;
5902 case SHF_STRINGS: sindex = 4; break;
5903 case SHF_INFO_LINK: sindex = 5; break;
5904 case SHF_LINK_ORDER: sindex = 6; break;
5905 case SHF_OS_NONCONFORMING: sindex = 7; break;
5906 case SHF_GROUP: sindex = 8; break;
5907 case SHF_TLS: sindex = 9; break;
18ae9cc1 5908 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5909 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5910 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 5911
5477e8a0 5912 default:
91d6fa6a 5913 sindex = -1;
dda8d76d 5914 switch (filedata->file_header.e_machine)
148b93f2 5915 {
cfcac11d 5916 case EM_IA_64:
148b93f2 5917 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5918 sindex = 10;
148b93f2 5919 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5920 sindex = 11;
148b93f2 5921#ifdef BFD64
dda8d76d 5922 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
5923 switch (flag)
5924 {
91d6fa6a
NC
5925 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5926 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5927 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5928 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5929 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5930 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5931 default: break;
5932 }
5933#endif
cfcac11d
NC
5934 break;
5935
caa83f8b 5936 case EM_386:
22abe556 5937 case EM_IAMCU:
caa83f8b 5938 case EM_X86_64:
7f502d6c 5939 case EM_L1OM:
7a9068fe 5940 case EM_K1OM:
cfcac11d
NC
5941 case EM_OLD_SPARCV9:
5942 case EM_SPARC32PLUS:
5943 case EM_SPARCV9:
5944 case EM_SPARC:
18ae9cc1 5945 if (flag == SHF_ORDERED)
91d6fa6a 5946 sindex = 19;
cfcac11d 5947 break;
ac4c9b04
MG
5948
5949 case EM_ARM:
5950 switch (flag)
5951 {
5952 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5953 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5954 case SHF_COMDEF: sindex = 23; break;
5955 default: break;
5956 }
5957 break;
83eef883
AFB
5958 case EM_PPC:
5959 if (flag == SHF_PPC_VLE)
5960 sindex = 25;
5961 break;
ac4c9b04 5962
cfcac11d
NC
5963 default:
5964 break;
148b93f2 5965 }
5477e8a0
L
5966 }
5967
91d6fa6a 5968 if (sindex != -1)
5477e8a0 5969 {
8d5ff12c
L
5970 if (p != buff + field_size + 4)
5971 {
5972 if (size < (10 + 2))
bee0ee85
NC
5973 {
5974 warn (_("Internal error: not enough buffer room for section flag info"));
5975 return _("<unknown>");
5976 }
8d5ff12c
L
5977 size -= 2;
5978 *p++ = ',';
5979 *p++ = ' ';
5980 }
5981
91d6fa6a
NC
5982 size -= flags [sindex].len;
5983 p = stpcpy (p, flags [sindex].str);
5477e8a0 5984 }
3b22753a 5985 else if (flag & SHF_MASKOS)
8d5ff12c 5986 os_flags |= flag;
d1133906 5987 else if (flag & SHF_MASKPROC)
8d5ff12c 5988 proc_flags |= flag;
d1133906 5989 else
8d5ff12c 5990 unknown_flags |= flag;
5477e8a0
L
5991 }
5992 else
5993 {
5994 switch (flag)
5995 {
5996 case SHF_WRITE: *p = 'W'; break;
5997 case SHF_ALLOC: *p = 'A'; break;
5998 case SHF_EXECINSTR: *p = 'X'; break;
5999 case SHF_MERGE: *p = 'M'; break;
6000 case SHF_STRINGS: *p = 'S'; break;
6001 case SHF_INFO_LINK: *p = 'I'; break;
6002 case SHF_LINK_ORDER: *p = 'L'; break;
6003 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6004 case SHF_GROUP: *p = 'G'; break;
6005 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6006 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6007 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 6008 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
6009
6010 default:
dda8d76d
NC
6011 if ((filedata->file_header.e_machine == EM_X86_64
6012 || filedata->file_header.e_machine == EM_L1OM
6013 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6014 && flag == SHF_X86_64_LARGE)
6015 *p = 'l';
dda8d76d 6016 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6017 && flag == SHF_ARM_PURECODE)
91f68a68 6018 *p = 'y';
dda8d76d 6019 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
6020 && flag == SHF_PPC_VLE)
6021 *p = 'v';
5477e8a0
L
6022 else if (flag & SHF_MASKOS)
6023 {
6024 *p = 'o';
6025 sh_flags &= ~ SHF_MASKOS;
6026 }
6027 else if (flag & SHF_MASKPROC)
6028 {
6029 *p = 'p';
6030 sh_flags &= ~ SHF_MASKPROC;
6031 }
6032 else
6033 *p = 'x';
6034 break;
6035 }
6036 p++;
d1133906
NC
6037 }
6038 }
76da6bbe 6039
8d5ff12c
L
6040 if (do_section_details)
6041 {
6042 if (os_flags)
6043 {
6044 size -= 5 + field_size;
6045 if (p != buff + field_size + 4)
6046 {
6047 if (size < (2 + 1))
bee0ee85
NC
6048 {
6049 warn (_("Internal error: not enough buffer room for section flag info"));
6050 return _("<unknown>");
6051 }
8d5ff12c
L
6052 size -= 2;
6053 *p++ = ',';
6054 *p++ = ' ';
6055 }
6056 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6057 (unsigned long) os_flags);
6058 p += 5 + field_size;
6059 }
6060 if (proc_flags)
6061 {
6062 size -= 7 + field_size;
6063 if (p != buff + field_size + 4)
6064 {
6065 if (size < (2 + 1))
bee0ee85
NC
6066 {
6067 warn (_("Internal error: not enough buffer room for section flag info"));
6068 return _("<unknown>");
6069 }
8d5ff12c
L
6070 size -= 2;
6071 *p++ = ',';
6072 *p++ = ' ';
6073 }
6074 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6075 (unsigned long) proc_flags);
6076 p += 7 + field_size;
6077 }
6078 if (unknown_flags)
6079 {
6080 size -= 10 + field_size;
6081 if (p != buff + field_size + 4)
6082 {
6083 if (size < (2 + 1))
bee0ee85
NC
6084 {
6085 warn (_("Internal error: not enough buffer room for section flag info"));
6086 return _("<unknown>");
6087 }
8d5ff12c
L
6088 size -= 2;
6089 *p++ = ',';
6090 *p++ = ' ';
6091 }
2b692964 6092 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6093 (unsigned long) unknown_flags);
6094 p += 10 + field_size;
6095 }
6096 }
6097
e9e44622 6098 *p = '\0';
d1133906
NC
6099 return buff;
6100}
6101
5844b465 6102static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6103get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6104{
6105 if (is_32bit_elf)
6106 {
6107 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6108
ebdf1ebf
NC
6109 if (size < sizeof (* echdr))
6110 {
6111 error (_("Compressed section is too small even for a compression header\n"));
6112 return 0;
6113 }
6114
77115a4a
L
6115 chdr->ch_type = BYTE_GET (echdr->ch_type);
6116 chdr->ch_size = BYTE_GET (echdr->ch_size);
6117 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6118 return sizeof (*echdr);
6119 }
6120 else
6121 {
6122 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6123
ebdf1ebf
NC
6124 if (size < sizeof (* echdr))
6125 {
6126 error (_("Compressed section is too small even for a compression header\n"));
6127 return 0;
6128 }
6129
77115a4a
L
6130 chdr->ch_type = BYTE_GET (echdr->ch_type);
6131 chdr->ch_size = BYTE_GET (echdr->ch_size);
6132 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6133 return sizeof (*echdr);
6134 }
6135}
6136
32ec8896 6137static bfd_boolean
dda8d76d 6138process_section_headers (Filedata * filedata)
252b5132 6139{
2cf0635d 6140 Elf_Internal_Shdr * section;
b34976b6 6141 unsigned int i;
252b5132 6142
8fb879cd 6143 free (filedata->section_headers);
dda8d76d 6144 filedata->section_headers = NULL;
978c4450
AM
6145 free (filedata->dynamic_symbols);
6146 filedata->dynamic_symbols = NULL;
6147 filedata->num_dynamic_syms = 0;
6148 free (filedata->dynamic_strings);
6149 filedata->dynamic_strings = NULL;
6150 filedata->dynamic_strings_length = 0;
6151 free (filedata->dynamic_syminfo);
6152 filedata->dynamic_syminfo = NULL;
6153 while (filedata->symtab_shndx_list != NULL)
8ff66993 6154 {
978c4450
AM
6155 elf_section_list *next = filedata->symtab_shndx_list->next;
6156 free (filedata->symtab_shndx_list);
6157 filedata->symtab_shndx_list = next;
8ff66993 6158 }
252b5132 6159
dda8d76d 6160 if (filedata->file_header.e_shnum == 0)
252b5132 6161 {
82f2dbf7 6162 /* PR binutils/12467. */
dda8d76d 6163 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6164 {
6165 warn (_("possibly corrupt ELF file header - it has a non-zero"
6166 " section header offset, but no section headers\n"));
6167 return FALSE;
6168 }
82f2dbf7 6169 else if (do_sections)
252b5132
RH
6170 printf (_("\nThere are no sections in this file.\n"));
6171
32ec8896 6172 return TRUE;
252b5132
RH
6173 }
6174
6175 if (do_sections && !do_header)
d3a49aa8
AM
6176 printf (ngettext ("There is %d section header, "
6177 "starting at offset 0x%lx:\n",
6178 "There are %d section headers, "
6179 "starting at offset 0x%lx:\n",
dda8d76d
NC
6180 filedata->file_header.e_shnum),
6181 filedata->file_header.e_shnum,
6182 (unsigned long) filedata->file_header.e_shoff);
252b5132 6183
9ea033b2
NC
6184 if (is_32bit_elf)
6185 {
dda8d76d 6186 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6187 return FALSE;
6188 }
6189 else
6190 {
dda8d76d 6191 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6192 return FALSE;
9ea033b2 6193 }
252b5132
RH
6194
6195 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6196 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6197 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6198 {
dda8d76d 6199 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6200
c256ffe7
JJ
6201 if (section->sh_size != 0)
6202 {
dda8d76d
NC
6203 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6204 1, section->sh_size,
6205 _("string table"));
0de14b54 6206
dda8d76d 6207 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6208 }
252b5132
RH
6209 }
6210
6211 /* Scan the sections for the dynamic symbol table
e3c8793a 6212 and dynamic string table and debug sections. */
89fac5e3 6213 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6214 switch (filedata->file_header.e_machine)
89fac5e3
RS
6215 {
6216 case EM_MIPS:
6217 case EM_MIPS_RS3_LE:
6218 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6219 FDE addresses. However, the ABI also has a semi-official ILP32
6220 variant for which the normal FDE address size rules apply.
6221
6222 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6223 section, where XX is the size of longs in bits. Unfortunately,
6224 earlier compilers provided no way of distinguishing ILP32 objects
6225 from LP64 objects, so if there's any doubt, we should assume that
6226 the official LP64 form is being used. */
dda8d76d
NC
6227 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6228 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6229 eh_addr_size = 8;
6230 break;
0f56a26a
DD
6231
6232 case EM_H8_300:
6233 case EM_H8_300H:
dda8d76d 6234 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6235 {
6236 case E_H8_MACH_H8300:
6237 case E_H8_MACH_H8300HN:
6238 case E_H8_MACH_H8300SN:
6239 case E_H8_MACH_H8300SXN:
6240 eh_addr_size = 2;
6241 break;
6242 case E_H8_MACH_H8300H:
6243 case E_H8_MACH_H8300S:
6244 case E_H8_MACH_H8300SX:
6245 eh_addr_size = 4;
6246 break;
6247 }
f4236fe4
DD
6248 break;
6249
ff7eeb89 6250 case EM_M32C_OLD:
f4236fe4 6251 case EM_M32C:
dda8d76d 6252 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6253 {
6254 case EF_M32C_CPU_M16C:
6255 eh_addr_size = 2;
6256 break;
6257 }
6258 break;
89fac5e3
RS
6259 }
6260
76ca31c0
NC
6261#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6262 do \
6263 { \
6264 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6265 if (section->sh_entsize != expected_entsize) \
9dd3a467 6266 { \
76ca31c0
NC
6267 char buf[40]; \
6268 sprintf_vma (buf, section->sh_entsize); \
6269 /* Note: coded this way so that there is a single string for \
6270 translation. */ \
6271 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6272 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6273 (unsigned) expected_entsize); \
9dd3a467 6274 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6275 } \
6276 } \
08d8fa11 6277 while (0)
9dd3a467
NC
6278
6279#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
6280 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
6281 sizeof (Elf64_External_##type))
6282
dda8d76d
NC
6283 for (i = 0, section = filedata->section_headers;
6284 i < filedata->file_header.e_shnum;
b34976b6 6285 i++, section++)
252b5132 6286 {
2cf0635d 6287 char * name = SECTION_NAME (section);
252b5132
RH
6288
6289 if (section->sh_type == SHT_DYNSYM)
6290 {
978c4450 6291 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6292 {
6293 error (_("File contains multiple dynamic symbol tables\n"));
6294 continue;
6295 }
6296
08d8fa11 6297 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6298 filedata->dynamic_symbols
6299 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
252b5132
RH
6300 }
6301 else if (section->sh_type == SHT_STRTAB
18bd398b 6302 && streq (name, ".dynstr"))
252b5132 6303 {
978c4450 6304 if (filedata->dynamic_strings != NULL)
252b5132
RH
6305 {
6306 error (_("File contains multiple dynamic string tables\n"));
6307 continue;
6308 }
6309
978c4450
AM
6310 filedata->dynamic_strings
6311 = (char *) get_data (NULL, filedata, section->sh_offset,
6312 1, section->sh_size, _("dynamic strings"));
6313 filedata->dynamic_strings_length
6314 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 6315 }
9ad5cbcf
AM
6316 else if (section->sh_type == SHT_SYMTAB_SHNDX)
6317 {
6a40cf0c 6318 elf_section_list * entry = xmalloc (sizeof * entry);
dda8d76d 6319
6a40cf0c 6320 entry->hdr = section;
978c4450
AM
6321 entry->next = filedata->symtab_shndx_list;
6322 filedata->symtab_shndx_list = entry;
9ad5cbcf 6323 }
08d8fa11
JJ
6324 else if (section->sh_type == SHT_SYMTAB)
6325 CHECK_ENTSIZE (section, i, Sym);
6326 else if (section->sh_type == SHT_GROUP)
6327 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6328 else if (section->sh_type == SHT_REL)
6329 CHECK_ENTSIZE (section, i, Rel);
6330 else if (section->sh_type == SHT_RELA)
6331 CHECK_ENTSIZE (section, i, Rela);
252b5132 6332 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 6333 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 6334 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47 6335 || do_debug_str || do_debug_loc || do_debug_ranges
d85bf2ba 6336 || do_debug_addr || do_debug_cu_index || do_debug_links)
1b315056
CS
6337 && (const_strneq (name, ".debug_")
6338 || const_strneq (name, ".zdebug_")))
252b5132 6339 {
1b315056
CS
6340 if (name[1] == 'z')
6341 name += sizeof (".zdebug_") - 1;
6342 else
6343 name += sizeof (".debug_") - 1;
252b5132
RH
6344
6345 if (do_debugging
4723351a
CC
6346 || (do_debug_info && const_strneq (name, "info"))
6347 || (do_debug_info && const_strneq (name, "types"))
6348 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6349 || (do_debug_lines && strcmp (name, "line") == 0)
6350 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6351 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6352 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6353 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6354 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6355 || (do_debug_aranges && const_strneq (name, "aranges"))
6356 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6357 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6358 || (do_debug_frames && const_strneq (name, "frame"))
6359 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6360 || (do_debug_macinfo && const_strneq (name, "macro"))
6361 || (do_debug_str && const_strneq (name, "str"))
6362 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6363 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6364 || (do_debug_addr && const_strneq (name, "addr"))
6365 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6366 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6367 )
6431e409 6368 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6369 }
a262ae96 6370 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6371 else if ((do_debugging || do_debug_info)
0112cd26 6372 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6373 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6374 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6375 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6376 else if (do_gdb_index && (streq (name, ".gdb_index")
6377 || streq (name, ".debug_names")))
6431e409 6378 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6379 /* Trace sections for Itanium VMS. */
6380 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6381 || do_trace_aranges)
6382 && const_strneq (name, ".trace_"))
6383 {
6384 name += sizeof (".trace_") - 1;
6385
6386 if (do_debugging
6387 || (do_trace_info && streq (name, "info"))
6388 || (do_trace_abbrevs && streq (name, "abbrev"))
6389 || (do_trace_aranges && streq (name, "aranges"))
6390 )
6431e409 6391 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6392 }
dda8d76d
NC
6393 else if ((do_debugging || do_debug_links)
6394 && (const_strneq (name, ".gnu_debuglink")
6395 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6396 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6397 }
6398
6399 if (! do_sections)
32ec8896 6400 return TRUE;
252b5132 6401
dda8d76d 6402 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6403 printf (_("\nSection Headers:\n"));
6404 else
6405 printf (_("\nSection Header:\n"));
76da6bbe 6406
f7a99963 6407 if (is_32bit_elf)
595cf52e 6408 {
5477e8a0 6409 if (do_section_details)
595cf52e
L
6410 {
6411 printf (_(" [Nr] Name\n"));
5477e8a0 6412 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6413 }
6414 else
6415 printf
6416 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6417 }
d974e256 6418 else if (do_wide)
595cf52e 6419 {
5477e8a0 6420 if (do_section_details)
595cf52e
L
6421 {
6422 printf (_(" [Nr] Name\n"));
5477e8a0 6423 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6424 }
6425 else
6426 printf
6427 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6428 }
f7a99963
NC
6429 else
6430 {
5477e8a0 6431 if (do_section_details)
595cf52e
L
6432 {
6433 printf (_(" [Nr] Name\n"));
5477e8a0
L
6434 printf (_(" Type Address Offset Link\n"));
6435 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6436 }
6437 else
6438 {
6439 printf (_(" [Nr] Name Type Address Offset\n"));
6440 printf (_(" Size EntSize Flags Link Info Align\n"));
6441 }
f7a99963 6442 }
252b5132 6443
5477e8a0
L
6444 if (do_section_details)
6445 printf (_(" Flags\n"));
6446
dda8d76d
NC
6447 for (i = 0, section = filedata->section_headers;
6448 i < filedata->file_header.e_shnum;
b34976b6 6449 i++, section++)
252b5132 6450 {
dd905818
NC
6451 /* Run some sanity checks on the section header. */
6452
6453 /* Check the sh_link field. */
6454 switch (section->sh_type)
6455 {
285e3f99
AM
6456 case SHT_REL:
6457 case SHT_RELA:
6458 if (section->sh_link == 0
6459 && (filedata->file_header.e_type == ET_EXEC
6460 || filedata->file_header.e_type == ET_DYN))
6461 /* A dynamic relocation section where all entries use a
6462 zero symbol index need not specify a symtab section. */
6463 break;
6464 /* Fall through. */
dd905818
NC
6465 case SHT_SYMTAB_SHNDX:
6466 case SHT_GROUP:
6467 case SHT_HASH:
6468 case SHT_GNU_HASH:
6469 case SHT_GNU_versym:
285e3f99 6470 if (section->sh_link == 0
dda8d76d
NC
6471 || section->sh_link >= filedata->file_header.e_shnum
6472 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6473 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6474 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6475 i, section->sh_link);
6476 break;
6477
6478 case SHT_DYNAMIC:
6479 case SHT_SYMTAB:
6480 case SHT_DYNSYM:
6481 case SHT_GNU_verneed:
6482 case SHT_GNU_verdef:
6483 case SHT_GNU_LIBLIST:
285e3f99 6484 if (section->sh_link == 0
dda8d76d
NC
6485 || section->sh_link >= filedata->file_header.e_shnum
6486 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6487 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6488 i, section->sh_link);
6489 break;
6490
6491 case SHT_INIT_ARRAY:
6492 case SHT_FINI_ARRAY:
6493 case SHT_PREINIT_ARRAY:
6494 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6495 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6496 i, section->sh_link);
6497 break;
6498
6499 default:
6500 /* FIXME: Add support for target specific section types. */
6501#if 0 /* Currently we do not check other section types as there are too
6502 many special cases. Stab sections for example have a type
6503 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6504 section. */
6505 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6506 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6507 i, section->sh_link);
6508#endif
6509 break;
6510 }
6511
6512 /* Check the sh_info field. */
6513 switch (section->sh_type)
6514 {
6515 case SHT_REL:
6516 case SHT_RELA:
285e3f99
AM
6517 if (section->sh_info == 0
6518 && (filedata->file_header.e_type == ET_EXEC
6519 || filedata->file_header.e_type == ET_DYN))
6520 /* Dynamic relocations apply to segments, so they do not
6521 need to specify the section they relocate. */
6522 break;
6523 if (section->sh_info == 0
dda8d76d
NC
6524 || section->sh_info >= filedata->file_header.e_shnum
6525 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6526 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6527 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6528 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6529 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6530 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6531 /* FIXME: Are other section types valid ? */
dda8d76d 6532 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6533 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6534 i, section->sh_info);
dd905818
NC
6535 break;
6536
6537 case SHT_DYNAMIC:
6538 case SHT_HASH:
6539 case SHT_SYMTAB_SHNDX:
6540 case SHT_INIT_ARRAY:
6541 case SHT_FINI_ARRAY:
6542 case SHT_PREINIT_ARRAY:
6543 if (section->sh_info != 0)
6544 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6545 i, section->sh_info);
6546 break;
6547
6548 case SHT_GROUP:
6549 case SHT_SYMTAB:
6550 case SHT_DYNSYM:
6551 /* A symbol index - we assume that it is valid. */
6552 break;
6553
6554 default:
6555 /* FIXME: Add support for target specific section types. */
6556 if (section->sh_type == SHT_NOBITS)
6557 /* NOBITS section headers with non-zero sh_info fields can be
6558 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6559 information. The stripped sections have their headers
6560 preserved but their types set to SHT_NOBITS. So do not check
6561 this type of section. */
dd905818
NC
6562 ;
6563 else if (section->sh_flags & SHF_INFO_LINK)
6564 {
dda8d76d 6565 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6566 warn (_("[%2u]: Expected link to another section in info field"), i);
6567 }
a91e1603
L
6568 else if (section->sh_type < SHT_LOOS
6569 && (section->sh_flags & SHF_GNU_MBIND) == 0
6570 && section->sh_info != 0)
dd905818
NC
6571 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6572 i, section->sh_info);
6573 break;
6574 }
6575
3e6b6445 6576 /* Check the sh_size field. */
dda8d76d 6577 if (section->sh_size > filedata->file_size
3e6b6445
NC
6578 && section->sh_type != SHT_NOBITS
6579 && section->sh_type != SHT_NULL
6580 && section->sh_type < SHT_LOOS)
6581 warn (_("Size of section %u is larger than the entire file!\n"), i);
6582
7bfd842d 6583 printf (" [%2u] ", i);
5477e8a0 6584 if (do_section_details)
dda8d76d 6585 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6586 else
74e1a04b 6587 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6588
ea52a088 6589 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6590 get_section_type_name (filedata, section->sh_type));
0b4362b0 6591
f7a99963
NC
6592 if (is_32bit_elf)
6593 {
cfcac11d
NC
6594 const char * link_too_big = NULL;
6595
f7a99963 6596 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6597
f7a99963
NC
6598 printf ( " %6.6lx %6.6lx %2.2lx",
6599 (unsigned long) section->sh_offset,
6600 (unsigned long) section->sh_size,
6601 (unsigned long) section->sh_entsize);
d1133906 6602
5477e8a0
L
6603 if (do_section_details)
6604 fputs (" ", stdout);
6605 else
dda8d76d 6606 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6607
dda8d76d 6608 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6609 {
6610 link_too_big = "";
6611 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6612 an error but it can have special values in Solaris binaries. */
dda8d76d 6613 switch (filedata->file_header.e_machine)
cfcac11d 6614 {
caa83f8b 6615 case EM_386:
22abe556 6616 case EM_IAMCU:
caa83f8b 6617 case EM_X86_64:
7f502d6c 6618 case EM_L1OM:
7a9068fe 6619 case EM_K1OM:
cfcac11d
NC
6620 case EM_OLD_SPARCV9:
6621 case EM_SPARC32PLUS:
6622 case EM_SPARCV9:
6623 case EM_SPARC:
6624 if (section->sh_link == (SHN_BEFORE & 0xffff))
6625 link_too_big = "BEFORE";
6626 else if (section->sh_link == (SHN_AFTER & 0xffff))
6627 link_too_big = "AFTER";
6628 break;
6629 default:
6630 break;
6631 }
6632 }
6633
6634 if (do_section_details)
6635 {
6636 if (link_too_big != NULL && * link_too_big)
6637 printf ("<%s> ", link_too_big);
6638 else
6639 printf ("%2u ", section->sh_link);
6640 printf ("%3u %2lu\n", section->sh_info,
6641 (unsigned long) section->sh_addralign);
6642 }
6643 else
6644 printf ("%2u %3u %2lu\n",
6645 section->sh_link,
6646 section->sh_info,
6647 (unsigned long) section->sh_addralign);
6648
6649 if (link_too_big && ! * link_too_big)
6650 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6651 i, section->sh_link);
f7a99963 6652 }
d974e256
JJ
6653 else if (do_wide)
6654 {
6655 print_vma (section->sh_addr, LONG_HEX);
6656
6657 if ((long) section->sh_offset == section->sh_offset)
6658 printf (" %6.6lx", (unsigned long) section->sh_offset);
6659 else
6660 {
6661 putchar (' ');
6662 print_vma (section->sh_offset, LONG_HEX);
6663 }
6664
6665 if ((unsigned long) section->sh_size == section->sh_size)
6666 printf (" %6.6lx", (unsigned long) section->sh_size);
6667 else
6668 {
6669 putchar (' ');
6670 print_vma (section->sh_size, LONG_HEX);
6671 }
6672
6673 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6674 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6675 else
6676 {
6677 putchar (' ');
6678 print_vma (section->sh_entsize, LONG_HEX);
6679 }
6680
5477e8a0
L
6681 if (do_section_details)
6682 fputs (" ", stdout);
6683 else
dda8d76d 6684 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6685
72de5009 6686 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6687
6688 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6689 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6690 else
6691 {
6692 print_vma (section->sh_addralign, DEC);
6693 putchar ('\n');
6694 }
6695 }
5477e8a0 6696 else if (do_section_details)
595cf52e 6697 {
55cc53e9 6698 putchar (' ');
595cf52e
L
6699 print_vma (section->sh_addr, LONG_HEX);
6700 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6701 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6702 else
6703 {
6704 printf (" ");
6705 print_vma (section->sh_offset, LONG_HEX);
6706 }
72de5009 6707 printf (" %u\n ", section->sh_link);
595cf52e 6708 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6709 putchar (' ');
595cf52e
L
6710 print_vma (section->sh_entsize, LONG_HEX);
6711
72de5009
AM
6712 printf (" %-16u %lu\n",
6713 section->sh_info,
595cf52e
L
6714 (unsigned long) section->sh_addralign);
6715 }
f7a99963
NC
6716 else
6717 {
6718 putchar (' ');
6719 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6720 if ((long) section->sh_offset == section->sh_offset)
6721 printf (" %8.8lx", (unsigned long) section->sh_offset);
6722 else
6723 {
6724 printf (" ");
6725 print_vma (section->sh_offset, LONG_HEX);
6726 }
f7a99963
NC
6727 printf ("\n ");
6728 print_vma (section->sh_size, LONG_HEX);
6729 printf (" ");
6730 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6731
dda8d76d 6732 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6733
72de5009
AM
6734 printf (" %2u %3u %lu\n",
6735 section->sh_link,
6736 section->sh_info,
f7a99963
NC
6737 (unsigned long) section->sh_addralign);
6738 }
5477e8a0
L
6739
6740 if (do_section_details)
77115a4a 6741 {
dda8d76d 6742 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6743 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6744 {
6745 /* Minimum section size is 12 bytes for 32-bit compression
6746 header + 12 bytes for compressed data header. */
6747 unsigned char buf[24];
d8024a91 6748
77115a4a 6749 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6750 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6751 sizeof (buf), _("compression header")))
6752 {
6753 Elf_Internal_Chdr chdr;
d8024a91 6754
5844b465
NC
6755 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
6756 printf (_(" [<corrupt>]\n"));
77115a4a 6757 else
5844b465
NC
6758 {
6759 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6760 printf (" ZLIB, ");
6761 else
6762 printf (_(" [<unknown>: 0x%x], "),
6763 chdr.ch_type);
6764 print_vma (chdr.ch_size, LONG_HEX);
6765 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6766 }
77115a4a
L
6767 }
6768 }
6769 }
252b5132
RH
6770 }
6771
5477e8a0 6772 if (!do_section_details)
3dbcc61d 6773 {
9fb71ee4
NC
6774 /* The ordering of the letters shown here matches the ordering of the
6775 corresponding SHF_xxx values, and hence the order in which these
6776 letters will be displayed to the user. */
6777 printf (_("Key to Flags:\n\
6778 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6779 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6780 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6781 if (filedata->file_header.e_machine == EM_X86_64
6782 || filedata->file_header.e_machine == EM_L1OM
6783 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6784 printf (_("l (large), "));
dda8d76d 6785 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6786 printf (_("y (purecode), "));
dda8d76d 6787 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6788 printf (_("v (VLE), "));
9fb71ee4 6789 printf ("p (processor specific)\n");
0b4362b0 6790 }
d1133906 6791
32ec8896 6792 return TRUE;
252b5132
RH
6793}
6794
28d13567
AM
6795static bfd_boolean
6796get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
6797 Elf_Internal_Sym **symtab, unsigned long *nsyms,
6798 char **strtab, unsigned long *strtablen)
6799{
6800 *strtab = NULL;
6801 *strtablen = 0;
6802 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
6803
6804 if (*symtab == NULL)
6805 return FALSE;
6806
6807 if (symsec->sh_link != 0)
6808 {
6809 Elf_Internal_Shdr *strsec;
6810
6811 if (symsec->sh_link >= filedata->file_header.e_shnum)
6812 {
6813 error (_("Bad sh_link in symbol table section\n"));
6814 free (*symtab);
6815 *symtab = NULL;
6816 *nsyms = 0;
6817 return FALSE;
6818 }
6819
6820 strsec = filedata->section_headers + symsec->sh_link;
6821
6822 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
6823 1, strsec->sh_size, _("string table"));
6824 if (*strtab == NULL)
6825 {
6826 free (*symtab);
6827 *symtab = NULL;
6828 *nsyms = 0;
6829 return FALSE;
6830 }
6831 *strtablen = strsec->sh_size;
6832 }
6833 return TRUE;
6834}
6835
f5842774
L
6836static const char *
6837get_group_flags (unsigned int flags)
6838{
1449284b 6839 static char buff[128];
220453ec 6840
6d913794
NC
6841 if (flags == 0)
6842 return "";
6843 else if (flags == GRP_COMDAT)
6844 return "COMDAT ";
f5842774 6845
89246a0e
AM
6846 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
6847 flags,
6848 flags & GRP_MASKOS ? _("<OS specific>") : "",
6849 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
6850 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
6851 ? _("<unknown>") : ""));
6d913794 6852
f5842774
L
6853 return buff;
6854}
6855
32ec8896 6856static bfd_boolean
dda8d76d 6857process_section_groups (Filedata * filedata)
f5842774 6858{
2cf0635d 6859 Elf_Internal_Shdr * section;
f5842774 6860 unsigned int i;
2cf0635d
NC
6861 struct group * group;
6862 Elf_Internal_Shdr * symtab_sec;
6863 Elf_Internal_Shdr * strtab_sec;
6864 Elf_Internal_Sym * symtab;
ba5cdace 6865 unsigned long num_syms;
2cf0635d 6866 char * strtab;
c256ffe7 6867 size_t strtab_size;
d1f5c6e3
L
6868
6869 /* Don't process section groups unless needed. */
6870 if (!do_unwind && !do_section_groups)
32ec8896 6871 return TRUE;
f5842774 6872
dda8d76d 6873 if (filedata->file_header.e_shnum == 0)
f5842774
L
6874 {
6875 if (do_section_groups)
82f2dbf7 6876 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 6877
32ec8896 6878 return TRUE;
f5842774
L
6879 }
6880
dda8d76d 6881 if (filedata->section_headers == NULL)
f5842774
L
6882 {
6883 error (_("Section headers are not available!\n"));
fa1908fd 6884 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 6885 return FALSE;
f5842774
L
6886 }
6887
978c4450
AM
6888 filedata->section_headers_groups
6889 = (struct group **) calloc (filedata->file_header.e_shnum,
6890 sizeof (struct group *));
e4b17d5c 6891
978c4450 6892 if (filedata->section_headers_groups == NULL)
e4b17d5c 6893 {
8b73c356 6894 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 6895 filedata->file_header.e_shnum);
32ec8896 6896 return FALSE;
e4b17d5c
L
6897 }
6898
f5842774 6899 /* Scan the sections for the group section. */
978c4450 6900 filedata->group_count = 0;
dda8d76d
NC
6901 for (i = 0, section = filedata->section_headers;
6902 i < filedata->file_header.e_shnum;
f5842774 6903 i++, section++)
e4b17d5c 6904 if (section->sh_type == SHT_GROUP)
978c4450 6905 filedata->group_count++;
e4b17d5c 6906
978c4450 6907 if (filedata->group_count == 0)
d1f5c6e3
L
6908 {
6909 if (do_section_groups)
6910 printf (_("\nThere are no section groups in this file.\n"));
6911
32ec8896 6912 return TRUE;
d1f5c6e3
L
6913 }
6914
978c4450
AM
6915 filedata->section_groups = (struct group *) calloc (filedata->group_count,
6916 sizeof (struct group));
e4b17d5c 6917
978c4450 6918 if (filedata->section_groups == NULL)
e4b17d5c 6919 {
8b73c356 6920 error (_("Out of memory reading %lu groups\n"),
978c4450 6921 (unsigned long) filedata->group_count);
32ec8896 6922 return FALSE;
e4b17d5c
L
6923 }
6924
d1f5c6e3
L
6925 symtab_sec = NULL;
6926 strtab_sec = NULL;
6927 symtab = NULL;
ba5cdace 6928 num_syms = 0;
d1f5c6e3 6929 strtab = NULL;
c256ffe7 6930 strtab_size = 0;
978c4450 6931 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 6932 i < filedata->file_header.e_shnum;
e4b17d5c 6933 i++, section++)
f5842774
L
6934 {
6935 if (section->sh_type == SHT_GROUP)
6936 {
dda8d76d 6937 const char * name = printable_section_name (filedata, section);
74e1a04b 6938 const char * group_name;
2cf0635d
NC
6939 unsigned char * start;
6940 unsigned char * indices;
f5842774 6941 unsigned int entry, j, size;
2cf0635d
NC
6942 Elf_Internal_Shdr * sec;
6943 Elf_Internal_Sym * sym;
f5842774
L
6944
6945 /* Get the symbol table. */
dda8d76d
NC
6946 if (section->sh_link >= filedata->file_header.e_shnum
6947 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 6948 != SHT_SYMTAB))
f5842774
L
6949 {
6950 error (_("Bad sh_link in group section `%s'\n"), name);
6951 continue;
6952 }
d1f5c6e3
L
6953
6954 if (symtab_sec != sec)
6955 {
6956 symtab_sec = sec;
6957 if (symtab)
6958 free (symtab);
dda8d76d 6959 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 6960 }
f5842774 6961
dd24e3da
NC
6962 if (symtab == NULL)
6963 {
6964 error (_("Corrupt header in group section `%s'\n"), name);
6965 continue;
6966 }
6967
ba5cdace
NC
6968 if (section->sh_info >= num_syms)
6969 {
6970 error (_("Bad sh_info in group section `%s'\n"), name);
6971 continue;
6972 }
6973
f5842774
L
6974 sym = symtab + section->sh_info;
6975
6976 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6977 {
4fbb74a6 6978 if (sym->st_shndx == 0
dda8d76d 6979 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
6980 {
6981 error (_("Bad sh_info in group section `%s'\n"), name);
6982 continue;
6983 }
ba2685cc 6984
dda8d76d 6985 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7
JJ
6986 strtab_sec = NULL;
6987 if (strtab)
6988 free (strtab);
f5842774 6989 strtab = NULL;
c256ffe7 6990 strtab_size = 0;
f5842774
L
6991 }
6992 else
6993 {
6994 /* Get the string table. */
dda8d76d 6995 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
6996 {
6997 strtab_sec = NULL;
6998 if (strtab)
6999 free (strtab);
7000 strtab = NULL;
7001 strtab_size = 0;
7002 }
7003 else if (strtab_sec
dda8d76d 7004 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7005 {
7006 strtab_sec = sec;
7007 if (strtab)
7008 free (strtab);
071436c6 7009
dda8d76d 7010 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7011 1, strtab_sec->sh_size,
7012 _("string table"));
c256ffe7 7013 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7014 }
c256ffe7 7015 group_name = sym->st_name < strtab_size
2b692964 7016 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7017 }
7018
c9c1d674
EG
7019 /* PR 17531: file: loop. */
7020 if (section->sh_entsize > section->sh_size)
7021 {
7022 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7023 printable_section_name (filedata, section),
8066deb1
AM
7024 (unsigned long) section->sh_entsize,
7025 (unsigned long) section->sh_size);
61dd8e19 7026 continue;
c9c1d674
EG
7027 }
7028
dda8d76d 7029 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7030 1, section->sh_size,
7031 _("section data"));
59245841
NC
7032 if (start == NULL)
7033 continue;
f5842774
L
7034
7035 indices = start;
7036 size = (section->sh_size / section->sh_entsize) - 1;
7037 entry = byte_get (indices, 4);
7038 indices += 4;
e4b17d5c
L
7039
7040 if (do_section_groups)
7041 {
2b692964 7042 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7043 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7044
e4b17d5c
L
7045 printf (_(" [Index] Name\n"));
7046 }
7047
7048 group->group_index = i;
7049
f5842774
L
7050 for (j = 0; j < size; j++)
7051 {
2cf0635d 7052 struct group_list * g;
e4b17d5c 7053
f5842774
L
7054 entry = byte_get (indices, 4);
7055 indices += 4;
7056
dda8d76d 7057 if (entry >= filedata->file_header.e_shnum)
391cb864 7058 {
57028622
NC
7059 static unsigned num_group_errors = 0;
7060
7061 if (num_group_errors ++ < 10)
7062 {
7063 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7064 entry, i, filedata->file_header.e_shnum - 1);
57028622 7065 if (num_group_errors == 10)
67ce483b 7066 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7067 }
391cb864
L
7068 continue;
7069 }
391cb864 7070
978c4450 7071 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7072 {
d1f5c6e3
L
7073 if (entry)
7074 {
57028622
NC
7075 static unsigned num_errs = 0;
7076
7077 if (num_errs ++ < 10)
7078 {
7079 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7080 entry, i,
978c4450 7081 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7082 if (num_errs == 10)
7083 warn (_("Further error messages about already contained group sections suppressed\n"));
7084 }
d1f5c6e3
L
7085 continue;
7086 }
7087 else
7088 {
7089 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7090 section group. We just warn it the first time
d1f5c6e3 7091 and ignore it afterwards. */
32ec8896 7092 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7093 if (!warned)
7094 {
7095 error (_("section 0 in group section [%5u]\n"),
978c4450 7096 filedata->section_headers_groups [entry]->group_index);
32ec8896 7097 warned = TRUE;
d1f5c6e3
L
7098 }
7099 }
e4b17d5c
L
7100 }
7101
978c4450 7102 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7103
7104 if (do_section_groups)
7105 {
dda8d76d
NC
7106 sec = filedata->section_headers + entry;
7107 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7108 }
7109
3f5e193b 7110 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7111 g->section_index = entry;
7112 g->next = group->root;
7113 group->root = g;
f5842774
L
7114 }
7115
f5842774
L
7116 if (start)
7117 free (start);
e4b17d5c
L
7118
7119 group++;
f5842774
L
7120 }
7121 }
7122
d1f5c6e3
L
7123 if (symtab)
7124 free (symtab);
7125 if (strtab)
7126 free (strtab);
32ec8896 7127 return TRUE;
f5842774
L
7128}
7129
28f997cf
TG
7130/* Data used to display dynamic fixups. */
7131
7132struct ia64_vms_dynfixup
7133{
7134 bfd_vma needed_ident; /* Library ident number. */
7135 bfd_vma needed; /* Index in the dstrtab of the library name. */
7136 bfd_vma fixup_needed; /* Index of the library. */
7137 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7138 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7139};
7140
7141/* Data used to display dynamic relocations. */
7142
7143struct ia64_vms_dynimgrela
7144{
7145 bfd_vma img_rela_cnt; /* Number of relocations. */
7146 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7147};
7148
7149/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7150 library). */
7151
32ec8896 7152static bfd_boolean
dda8d76d
NC
7153dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7154 struct ia64_vms_dynfixup * fixup,
7155 const char * strtab,
7156 unsigned int strtab_sz)
28f997cf 7157{
32ec8896 7158 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7159 long i;
32ec8896 7160 const char * lib_name;
28f997cf 7161
978c4450
AM
7162 imfs = get_data (NULL, filedata,
7163 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7164 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7165 _("dynamic section image fixups"));
7166 if (!imfs)
32ec8896 7167 return FALSE;
28f997cf
TG
7168
7169 if (fixup->needed < strtab_sz)
7170 lib_name = strtab + fixup->needed;
7171 else
7172 {
32ec8896 7173 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7174 (unsigned long) fixup->needed);
28f997cf
TG
7175 lib_name = "???";
7176 }
736990c4 7177
28f997cf
TG
7178 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7179 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7180 printf
7181 (_("Seg Offset Type SymVec DataType\n"));
7182
7183 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7184 {
7185 unsigned int type;
7186 const char *rtype;
7187
7188 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7189 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7190 type = BYTE_GET (imfs [i].type);
7191 rtype = elf_ia64_reloc_type (type);
7192 if (rtype == NULL)
7193 printf (" 0x%08x ", type);
7194 else
7195 printf (" %-32s ", rtype);
7196 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7197 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7198 }
7199
7200 free (imfs);
32ec8896 7201 return TRUE;
28f997cf
TG
7202}
7203
7204/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7205
32ec8896 7206static bfd_boolean
dda8d76d 7207dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7208{
7209 Elf64_External_VMS_IMAGE_RELA *imrs;
7210 long i;
7211
978c4450
AM
7212 imrs = get_data (NULL, filedata,
7213 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7214 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7215 _("dynamic section image relocations"));
28f997cf 7216 if (!imrs)
32ec8896 7217 return FALSE;
28f997cf
TG
7218
7219 printf (_("\nImage relocs\n"));
7220 printf
7221 (_("Seg Offset Type Addend Seg Sym Off\n"));
7222
7223 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7224 {
7225 unsigned int type;
7226 const char *rtype;
7227
7228 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7229 printf ("%08" BFD_VMA_FMT "x ",
7230 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7231 type = BYTE_GET (imrs [i].type);
7232 rtype = elf_ia64_reloc_type (type);
7233 if (rtype == NULL)
7234 printf ("0x%08x ", type);
7235 else
7236 printf ("%-31s ", rtype);
7237 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7238 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7239 printf ("%08" BFD_VMA_FMT "x\n",
7240 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7241 }
7242
7243 free (imrs);
32ec8896 7244 return TRUE;
28f997cf
TG
7245}
7246
7247/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7248
32ec8896 7249static bfd_boolean
dda8d76d 7250process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7251{
7252 struct ia64_vms_dynfixup fixup;
7253 struct ia64_vms_dynimgrela imgrela;
7254 Elf_Internal_Dyn *entry;
28f997cf
TG
7255 bfd_vma strtab_off = 0;
7256 bfd_vma strtab_sz = 0;
7257 char *strtab = NULL;
32ec8896 7258 bfd_boolean res = TRUE;
28f997cf
TG
7259
7260 memset (&fixup, 0, sizeof (fixup));
7261 memset (&imgrela, 0, sizeof (imgrela));
7262
7263 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7264 for (entry = filedata->dynamic_section;
7265 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7266 entry++)
7267 {
7268 switch (entry->d_tag)
7269 {
7270 case DT_IA_64_VMS_STRTAB_OFFSET:
7271 strtab_off = entry->d_un.d_val;
7272 break;
7273 case DT_STRSZ:
7274 strtab_sz = entry->d_un.d_val;
7275 if (strtab == NULL)
978c4450
AM
7276 strtab = get_data (NULL, filedata,
7277 filedata->dynamic_addr + strtab_off,
28f997cf 7278 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7279 if (strtab == NULL)
7280 strtab_sz = 0;
28f997cf
TG
7281 break;
7282
7283 case DT_IA_64_VMS_NEEDED_IDENT:
7284 fixup.needed_ident = entry->d_un.d_val;
7285 break;
7286 case DT_NEEDED:
7287 fixup.needed = entry->d_un.d_val;
7288 break;
7289 case DT_IA_64_VMS_FIXUP_NEEDED:
7290 fixup.fixup_needed = entry->d_un.d_val;
7291 break;
7292 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7293 fixup.fixup_rela_cnt = entry->d_un.d_val;
7294 break;
7295 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7296 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7297 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7298 res = FALSE;
28f997cf 7299 break;
28f997cf
TG
7300 case DT_IA_64_VMS_IMG_RELA_CNT:
7301 imgrela.img_rela_cnt = entry->d_un.d_val;
7302 break;
7303 case DT_IA_64_VMS_IMG_RELA_OFF:
7304 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7305 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7306 res = FALSE;
28f997cf
TG
7307 break;
7308
7309 default:
7310 break;
7311 }
7312 }
7313
7314 if (strtab != NULL)
7315 free (strtab);
7316
7317 return res;
7318}
7319
85b1c36d 7320static struct
566b0d53 7321{
2cf0635d 7322 const char * name;
566b0d53
L
7323 int reloc;
7324 int size;
7325 int rela;
32ec8896
NC
7326}
7327 dynamic_relocations [] =
566b0d53 7328{
32ec8896
NC
7329 { "REL", DT_REL, DT_RELSZ, FALSE },
7330 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7331 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7332};
7333
252b5132 7334/* Process the reloc section. */
18bd398b 7335
32ec8896 7336static bfd_boolean
dda8d76d 7337process_relocs (Filedata * filedata)
252b5132 7338{
b34976b6
AM
7339 unsigned long rel_size;
7340 unsigned long rel_offset;
252b5132 7341
252b5132 7342 if (!do_reloc)
32ec8896 7343 return TRUE;
252b5132
RH
7344
7345 if (do_using_dynamic)
7346 {
32ec8896 7347 int is_rela;
2cf0635d 7348 const char * name;
32ec8896 7349 bfd_boolean has_dynamic_reloc;
566b0d53 7350 unsigned int i;
0de14b54 7351
32ec8896 7352 has_dynamic_reloc = FALSE;
252b5132 7353
566b0d53 7354 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7355 {
566b0d53
L
7356 is_rela = dynamic_relocations [i].rela;
7357 name = dynamic_relocations [i].name;
978c4450
AM
7358 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7359 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7360
32ec8896
NC
7361 if (rel_size)
7362 has_dynamic_reloc = TRUE;
566b0d53
L
7363
7364 if (is_rela == UNKNOWN)
aa903cfb 7365 {
566b0d53 7366 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7367 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7368 {
7369 case DT_REL:
7370 is_rela = FALSE;
7371 break;
7372 case DT_RELA:
7373 is_rela = TRUE;
7374 break;
7375 }
aa903cfb 7376 }
252b5132 7377
566b0d53
L
7378 if (rel_size)
7379 {
7380 printf
7381 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7382 name, rel_offset, rel_size);
252b5132 7383
dda8d76d
NC
7384 dump_relocations (filedata,
7385 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7386 rel_size,
978c4450
AM
7387 filedata->dynamic_symbols,
7388 filedata->num_dynamic_syms,
7389 filedata->dynamic_strings,
7390 filedata->dynamic_strings_length,
32ec8896 7391 is_rela, TRUE /* is_dynamic */);
566b0d53 7392 }
252b5132 7393 }
566b0d53 7394
dda8d76d
NC
7395 if (is_ia64_vms (filedata))
7396 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7397 has_dynamic_reloc = TRUE;
28f997cf 7398
566b0d53 7399 if (! has_dynamic_reloc)
252b5132
RH
7400 printf (_("\nThere are no dynamic relocations in this file.\n"));
7401 }
7402 else
7403 {
2cf0635d 7404 Elf_Internal_Shdr * section;
b34976b6 7405 unsigned long i;
32ec8896 7406 bfd_boolean found = FALSE;
252b5132 7407
dda8d76d
NC
7408 for (i = 0, section = filedata->section_headers;
7409 i < filedata->file_header.e_shnum;
b34976b6 7410 i++, section++)
252b5132
RH
7411 {
7412 if ( section->sh_type != SHT_RELA
7413 && section->sh_type != SHT_REL)
7414 continue;
7415
7416 rel_offset = section->sh_offset;
7417 rel_size = section->sh_size;
7418
7419 if (rel_size)
7420 {
b34976b6 7421 int is_rela;
d3a49aa8 7422 unsigned long num_rela;
103f02d3 7423
252b5132
RH
7424 printf (_("\nRelocation section "));
7425
dda8d76d 7426 if (filedata->string_table == NULL)
19936277 7427 printf ("%d", section->sh_name);
252b5132 7428 else
dda8d76d 7429 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7430
d3a49aa8
AM
7431 num_rela = rel_size / section->sh_entsize;
7432 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7433 " at offset 0x%lx contains %lu entries:\n",
7434 num_rela),
7435 rel_offset, num_rela);
252b5132 7436
d79b3d50
NC
7437 is_rela = section->sh_type == SHT_RELA;
7438
4fbb74a6 7439 if (section->sh_link != 0
dda8d76d 7440 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7441 {
2cf0635d
NC
7442 Elf_Internal_Shdr * symsec;
7443 Elf_Internal_Sym * symtab;
d79b3d50 7444 unsigned long nsyms;
c256ffe7 7445 unsigned long strtablen = 0;
2cf0635d 7446 char * strtab = NULL;
57346661 7447
dda8d76d 7448 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7449 if (symsec->sh_type != SHT_SYMTAB
7450 && symsec->sh_type != SHT_DYNSYM)
7451 continue;
7452
28d13567
AM
7453 if (!get_symtab (filedata, symsec,
7454 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7455 continue;
252b5132 7456
dda8d76d 7457 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7458 symtab, nsyms, strtab, strtablen,
7459 is_rela,
7460 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
7461 if (strtab)
7462 free (strtab);
7463 free (symtab);
7464 }
7465 else
dda8d76d 7466 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7467 NULL, 0, NULL, 0, is_rela,
7468 FALSE /* is_dynamic */);
252b5132 7469
32ec8896 7470 found = TRUE;
252b5132
RH
7471 }
7472 }
7473
7474 if (! found)
45ac8f4f
NC
7475 {
7476 /* Users sometimes forget the -D option, so try to be helpful. */
7477 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7478 {
978c4450 7479 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f
NC
7480 {
7481 printf (_("\nThere are no static relocations in this file."));
7482 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7483
7484 break;
7485 }
7486 }
7487 if (i == ARRAY_SIZE (dynamic_relocations))
7488 printf (_("\nThere are no relocations in this file.\n"));
7489 }
252b5132
RH
7490 }
7491
32ec8896 7492 return TRUE;
252b5132
RH
7493}
7494
4d6ed7c8
NC
7495/* An absolute address consists of a section and an offset. If the
7496 section is NULL, the offset itself is the address, otherwise, the
7497 address equals to LOAD_ADDRESS(section) + offset. */
7498
7499struct absaddr
948f632f
DA
7500{
7501 unsigned short section;
7502 bfd_vma offset;
7503};
4d6ed7c8 7504
948f632f
DA
7505/* Find the nearest symbol at or below ADDR. Returns the symbol
7506 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7507
4d6ed7c8 7508static void
dda8d76d
NC
7509find_symbol_for_address (Filedata * filedata,
7510 Elf_Internal_Sym * symtab,
7511 unsigned long nsyms,
7512 const char * strtab,
7513 unsigned long strtab_size,
7514 struct absaddr addr,
7515 const char ** symname,
7516 bfd_vma * offset)
4d6ed7c8 7517{
d3ba0551 7518 bfd_vma dist = 0x100000;
2cf0635d 7519 Elf_Internal_Sym * sym;
948f632f
DA
7520 Elf_Internal_Sym * beg;
7521 Elf_Internal_Sym * end;
2cf0635d 7522 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7523
0b6ae522 7524 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7525 beg = symtab;
7526 end = symtab + nsyms;
0b6ae522 7527
948f632f 7528 while (beg < end)
4d6ed7c8 7529 {
948f632f
DA
7530 bfd_vma value;
7531
7532 sym = beg + (end - beg) / 2;
0b6ae522 7533
948f632f 7534 value = sym->st_value;
0b6ae522
DJ
7535 REMOVE_ARCH_BITS (value);
7536
948f632f 7537 if (sym->st_name != 0
4d6ed7c8 7538 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7539 && addr.offset >= value
7540 && addr.offset - value < dist)
4d6ed7c8
NC
7541 {
7542 best = sym;
0b6ae522 7543 dist = addr.offset - value;
4d6ed7c8
NC
7544 if (!dist)
7545 break;
7546 }
948f632f
DA
7547
7548 if (addr.offset < value)
7549 end = sym;
7550 else
7551 beg = sym + 1;
4d6ed7c8 7552 }
1b31d05e 7553
4d6ed7c8
NC
7554 if (best)
7555 {
57346661 7556 *symname = (best->st_name >= strtab_size
2b692964 7557 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7558 *offset = dist;
7559 return;
7560 }
1b31d05e 7561
4d6ed7c8
NC
7562 *symname = NULL;
7563 *offset = addr.offset;
7564}
7565
32ec8896 7566static /* signed */ int
948f632f
DA
7567symcmp (const void *p, const void *q)
7568{
7569 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7570 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7571
7572 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7573}
7574
7575/* Process the unwind section. */
7576
7577#include "unwind-ia64.h"
7578
7579struct ia64_unw_table_entry
7580{
7581 struct absaddr start;
7582 struct absaddr end;
7583 struct absaddr info;
7584};
7585
7586struct ia64_unw_aux_info
7587{
32ec8896
NC
7588 struct ia64_unw_table_entry * table; /* Unwind table. */
7589 unsigned long table_len; /* Length of unwind table. */
7590 unsigned char * info; /* Unwind info. */
7591 unsigned long info_size; /* Size of unwind info. */
7592 bfd_vma info_addr; /* Starting address of unwind info. */
7593 bfd_vma seg_base; /* Starting address of segment. */
7594 Elf_Internal_Sym * symtab; /* The symbol table. */
7595 unsigned long nsyms; /* Number of symbols. */
7596 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7597 unsigned long nfuns; /* Number of entries in funtab. */
7598 char * strtab; /* The string table. */
7599 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7600};
7601
32ec8896 7602static bfd_boolean
dda8d76d 7603dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7604{
2cf0635d 7605 struct ia64_unw_table_entry * tp;
948f632f 7606 unsigned long j, nfuns;
4d6ed7c8 7607 int in_body;
32ec8896 7608 bfd_boolean res = TRUE;
7036c0e1 7609
948f632f
DA
7610 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7611 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7612 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7613 aux->funtab[nfuns++] = aux->symtab[j];
7614 aux->nfuns = nfuns;
7615 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7616
4d6ed7c8
NC
7617 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7618 {
7619 bfd_vma stamp;
7620 bfd_vma offset;
2cf0635d
NC
7621 const unsigned char * dp;
7622 const unsigned char * head;
53774b7e 7623 const unsigned char * end;
2cf0635d 7624 const char * procname;
4d6ed7c8 7625
dda8d76d 7626 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7627 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7628
7629 fputs ("\n<", stdout);
7630
7631 if (procname)
7632 {
7633 fputs (procname, stdout);
7634
7635 if (offset)
7636 printf ("+%lx", (unsigned long) offset);
7637 }
7638
7639 fputs (">: [", stdout);
7640 print_vma (tp->start.offset, PREFIX_HEX);
7641 fputc ('-', stdout);
7642 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7643 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7644 (unsigned long) (tp->info.offset - aux->seg_base));
7645
53774b7e
NC
7646 /* PR 17531: file: 86232b32. */
7647 if (aux->info == NULL)
7648 continue;
7649
97c0a079
AM
7650 offset = tp->info.offset;
7651 if (tp->info.section)
7652 {
7653 if (tp->info.section >= filedata->file_header.e_shnum)
7654 {
7655 warn (_("Invalid section %u in table entry %ld\n"),
7656 tp->info.section, (long) (tp - aux->table));
7657 res = FALSE;
7658 continue;
7659 }
7660 offset += filedata->section_headers[tp->info.section].sh_addr;
7661 }
7662 offset -= aux->info_addr;
53774b7e 7663 /* PR 17531: file: 0997b4d1. */
90679903
AM
7664 if (offset >= aux->info_size
7665 || aux->info_size - offset < 8)
53774b7e
NC
7666 {
7667 warn (_("Invalid offset %lx in table entry %ld\n"),
7668 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7669 res = FALSE;
53774b7e
NC
7670 continue;
7671 }
7672
97c0a079 7673 head = aux->info + offset;
a4a00738 7674 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7675
86f55779 7676 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7677 (unsigned) UNW_VER (stamp),
7678 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7679 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7680 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7681 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7682
7683 if (UNW_VER (stamp) != 1)
7684 {
2b692964 7685 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7686 continue;
7687 }
7688
7689 in_body = 0;
53774b7e
NC
7690 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7691 /* PR 17531: file: 16ceda89. */
7692 if (end > aux->info + aux->info_size)
7693 end = aux->info + aux->info_size;
7694 for (dp = head + 8; dp < end;)
b4477bc8 7695 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7696 }
948f632f
DA
7697
7698 free (aux->funtab);
32ec8896
NC
7699
7700 return res;
4d6ed7c8
NC
7701}
7702
53774b7e 7703static bfd_boolean
dda8d76d
NC
7704slurp_ia64_unwind_table (Filedata * filedata,
7705 struct ia64_unw_aux_info * aux,
7706 Elf_Internal_Shdr * sec)
4d6ed7c8 7707{
89fac5e3 7708 unsigned long size, nrelas, i;
2cf0635d
NC
7709 Elf_Internal_Phdr * seg;
7710 struct ia64_unw_table_entry * tep;
7711 Elf_Internal_Shdr * relsec;
7712 Elf_Internal_Rela * rela;
7713 Elf_Internal_Rela * rp;
7714 unsigned char * table;
7715 unsigned char * tp;
7716 Elf_Internal_Sym * sym;
7717 const char * relname;
4d6ed7c8 7718
53774b7e
NC
7719 aux->table_len = 0;
7720
4d6ed7c8
NC
7721 /* First, find the starting address of the segment that includes
7722 this section: */
7723
dda8d76d 7724 if (filedata->file_header.e_phnum)
4d6ed7c8 7725 {
dda8d76d 7726 if (! get_program_headers (filedata))
53774b7e 7727 return FALSE;
4d6ed7c8 7728
dda8d76d
NC
7729 for (seg = filedata->program_headers;
7730 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7731 ++seg)
4d6ed7c8
NC
7732 {
7733 if (seg->p_type != PT_LOAD)
7734 continue;
7735
7736 if (sec->sh_addr >= seg->p_vaddr
7737 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7738 {
7739 aux->seg_base = seg->p_vaddr;
7740 break;
7741 }
7742 }
4d6ed7c8
NC
7743 }
7744
7745 /* Second, build the unwind table from the contents of the unwind section: */
7746 size = sec->sh_size;
dda8d76d 7747 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7748 _("unwind table"));
a6e9f9df 7749 if (!table)
53774b7e 7750 return FALSE;
4d6ed7c8 7751
53774b7e 7752 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7753 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7754 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7755 tep = aux->table;
53774b7e
NC
7756
7757 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7758 {
7759 tep->start.section = SHN_UNDEF;
7760 tep->end.section = SHN_UNDEF;
7761 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7762 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7763 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7764 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7765 tep->start.offset += aux->seg_base;
7766 tep->end.offset += aux->seg_base;
7767 tep->info.offset += aux->seg_base;
7768 }
7769 free (table);
7770
41e92641 7771 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7772 for (relsec = filedata->section_headers;
7773 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7774 ++relsec)
7775 {
7776 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7777 || relsec->sh_info >= filedata->file_header.e_shnum
7778 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7779 continue;
7780
dda8d76d 7781 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7782 & rela, & nrelas))
53774b7e
NC
7783 {
7784 free (aux->table);
7785 aux->table = NULL;
7786 aux->table_len = 0;
7787 return FALSE;
7788 }
4d6ed7c8
NC
7789
7790 for (rp = rela; rp < rela + nrelas; ++rp)
7791 {
4770fb94 7792 unsigned int sym_ndx;
726bd37d
AM
7793 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
7794 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 7795
82b1b41b
NC
7796 /* PR 17531: file: 9fa67536. */
7797 if (relname == NULL)
7798 {
726bd37d 7799 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
7800 continue;
7801 }
948f632f 7802
0112cd26 7803 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7804 {
82b1b41b 7805 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7806 continue;
7807 }
7808
89fac5e3 7809 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7810
53774b7e
NC
7811 /* PR 17531: file: 5bc8d9bf. */
7812 if (i >= aux->table_len)
7813 {
7814 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7815 continue;
7816 }
7817
4770fb94
AM
7818 sym_ndx = get_reloc_symindex (rp->r_info);
7819 if (sym_ndx >= aux->nsyms)
7820 {
7821 warn (_("Skipping reloc with invalid symbol index: %u\n"),
7822 sym_ndx);
7823 continue;
7824 }
7825 sym = aux->symtab + sym_ndx;
7826
53774b7e 7827 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7828 {
7829 case 0:
7830 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7831 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7832 break;
7833 case 1:
7834 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7835 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7836 break;
7837 case 2:
7838 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7839 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7840 break;
7841 default:
7842 break;
7843 }
7844 }
7845
7846 free (rela);
7847 }
7848
53774b7e 7849 return TRUE;
4d6ed7c8
NC
7850}
7851
32ec8896 7852static bfd_boolean
dda8d76d 7853ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7854{
2cf0635d
NC
7855 Elf_Internal_Shdr * sec;
7856 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 7857 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7858 struct ia64_unw_aux_info aux;
32ec8896 7859 bfd_boolean res = TRUE;
f1467e33 7860
4d6ed7c8
NC
7861 memset (& aux, 0, sizeof (aux));
7862
dda8d76d 7863 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7864 {
28d13567 7865 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 7866 {
28d13567 7867 if (aux.symtab)
4082ef84 7868 {
28d13567
AM
7869 error (_("Multiple symbol tables encountered\n"));
7870 free (aux.symtab);
7871 aux.symtab = NULL;
4082ef84 7872 free (aux.strtab);
28d13567 7873 aux.strtab = NULL;
4082ef84 7874 }
28d13567
AM
7875 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
7876 &aux.strtab, &aux.strtab_size))
7877 return FALSE;
4d6ed7c8
NC
7878 }
7879 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7880 unwcount++;
7881 }
7882
7883 if (!unwcount)
7884 printf (_("\nThere are no unwind sections in this file.\n"));
7885
7886 while (unwcount-- > 0)
7887 {
2cf0635d 7888 char * suffix;
579f31ac
JJ
7889 size_t len, len2;
7890
dda8d76d
NC
7891 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
7892 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
7893 if (sec->sh_type == SHT_IA_64_UNWIND)
7894 {
7895 unwsec = sec;
7896 break;
7897 }
4082ef84
NC
7898 /* We have already counted the number of SHT_IA64_UNWIND
7899 sections so the loop above should never fail. */
7900 assert (unwsec != NULL);
579f31ac
JJ
7901
7902 unwstart = i + 1;
7903 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7904
e4b17d5c
L
7905 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7906 {
7907 /* We need to find which section group it is in. */
4082ef84 7908 struct group_list * g;
e4b17d5c 7909
978c4450
AM
7910 if (filedata->section_headers_groups == NULL
7911 || filedata->section_headers_groups[i] == NULL)
dda8d76d 7912 i = filedata->file_header.e_shnum;
4082ef84 7913 else
e4b17d5c 7914 {
978c4450 7915 g = filedata->section_headers_groups[i]->root;
18bd398b 7916
4082ef84
NC
7917 for (; g != NULL; g = g->next)
7918 {
dda8d76d 7919 sec = filedata->section_headers + g->section_index;
e4b17d5c 7920
4082ef84
NC
7921 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7922 break;
7923 }
7924
7925 if (g == NULL)
dda8d76d 7926 i = filedata->file_header.e_shnum;
4082ef84 7927 }
e4b17d5c 7928 }
18bd398b 7929 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7930 {
18bd398b 7931 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7932 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7933 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7934 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7935 ++i, ++sec)
18bd398b
NC
7936 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7937 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7938 break;
7939 }
7940 else
7941 {
7942 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7943 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7944 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7945 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7946 suffix = "";
18bd398b 7947 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 7948 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7949 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7950 ++i, ++sec)
18bd398b
NC
7951 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
7952 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7953 break;
7954 }
7955
dda8d76d 7956 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
7957 {
7958 printf (_("\nCould not find unwind info section for "));
7959
dda8d76d 7960 if (filedata->string_table == NULL)
579f31ac
JJ
7961 printf ("%d", unwsec->sh_name);
7962 else
dda8d76d 7963 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
7964 }
7965 else
4d6ed7c8 7966 {
4d6ed7c8 7967 aux.info_addr = sec->sh_addr;
dda8d76d 7968 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
7969 sec->sh_size,
7970 _("unwind info"));
59245841 7971 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 7972
579f31ac 7973 printf (_("\nUnwind section "));
4d6ed7c8 7974
dda8d76d 7975 if (filedata->string_table == NULL)
579f31ac
JJ
7976 printf ("%d", unwsec->sh_name);
7977 else
dda8d76d 7978 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 7979
579f31ac 7980 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 7981 (unsigned long) unwsec->sh_offset,
89fac5e3 7982 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 7983
dda8d76d 7984 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 7985 && aux.table_len > 0)
dda8d76d 7986 dump_ia64_unwind (filedata, & aux);
579f31ac
JJ
7987
7988 if (aux.table)
7989 free ((char *) aux.table);
7990 if (aux.info)
7991 free ((char *) aux.info);
7992 aux.table = NULL;
7993 aux.info = NULL;
7994 }
4d6ed7c8 7995 }
4d6ed7c8 7996
4d6ed7c8
NC
7997 if (aux.symtab)
7998 free (aux.symtab);
7999 if (aux.strtab)
8000 free ((char *) aux.strtab);
32ec8896
NC
8001
8002 return res;
4d6ed7c8
NC
8003}
8004
3f5e193b 8005struct hppa_unw_table_entry
32ec8896
NC
8006{
8007 struct absaddr start;
8008 struct absaddr end;
8009 unsigned int Cannot_unwind:1; /* 0 */
8010 unsigned int Millicode:1; /* 1 */
8011 unsigned int Millicode_save_sr0:1; /* 2 */
8012 unsigned int Region_description:2; /* 3..4 */
8013 unsigned int reserved1:1; /* 5 */
8014 unsigned int Entry_SR:1; /* 6 */
8015 unsigned int Entry_FR:4; /* Number saved 7..10 */
8016 unsigned int Entry_GR:5; /* Number saved 11..15 */
8017 unsigned int Args_stored:1; /* 16 */
8018 unsigned int Variable_Frame:1; /* 17 */
8019 unsigned int Separate_Package_Body:1; /* 18 */
8020 unsigned int Frame_Extension_Millicode:1; /* 19 */
8021 unsigned int Stack_Overflow_Check:1; /* 20 */
8022 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8023 unsigned int Ada_Region:1; /* 22 */
8024 unsigned int cxx_info:1; /* 23 */
8025 unsigned int cxx_try_catch:1; /* 24 */
8026 unsigned int sched_entry_seq:1; /* 25 */
8027 unsigned int reserved2:1; /* 26 */
8028 unsigned int Save_SP:1; /* 27 */
8029 unsigned int Save_RP:1; /* 28 */
8030 unsigned int Save_MRP_in_frame:1; /* 29 */
8031 unsigned int extn_ptr_defined:1; /* 30 */
8032 unsigned int Cleanup_defined:1; /* 31 */
8033
8034 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8035 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8036 unsigned int Large_frame:1; /* 2 */
8037 unsigned int Pseudo_SP_Set:1; /* 3 */
8038 unsigned int reserved4:1; /* 4 */
8039 unsigned int Total_frame_size:27; /* 5..31 */
8040};
3f5e193b 8041
57346661 8042struct hppa_unw_aux_info
948f632f 8043{
32ec8896
NC
8044 struct hppa_unw_table_entry * table; /* Unwind table. */
8045 unsigned long table_len; /* Length of unwind table. */
8046 bfd_vma seg_base; /* Starting address of segment. */
8047 Elf_Internal_Sym * symtab; /* The symbol table. */
8048 unsigned long nsyms; /* Number of symbols. */
8049 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8050 unsigned long nfuns; /* Number of entries in funtab. */
8051 char * strtab; /* The string table. */
8052 unsigned long strtab_size; /* Size of string table. */
948f632f 8053};
57346661 8054
32ec8896 8055static bfd_boolean
dda8d76d 8056dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8057{
2cf0635d 8058 struct hppa_unw_table_entry * tp;
948f632f 8059 unsigned long j, nfuns;
32ec8896 8060 bfd_boolean res = TRUE;
948f632f
DA
8061
8062 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8063 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8064 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8065 aux->funtab[nfuns++] = aux->symtab[j];
8066 aux->nfuns = nfuns;
8067 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8068
57346661
AM
8069 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8070 {
8071 bfd_vma offset;
2cf0635d 8072 const char * procname;
57346661 8073
dda8d76d 8074 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8075 aux->strtab_size, tp->start, &procname,
8076 &offset);
8077
8078 fputs ("\n<", stdout);
8079
8080 if (procname)
8081 {
8082 fputs (procname, stdout);
8083
8084 if (offset)
8085 printf ("+%lx", (unsigned long) offset);
8086 }
8087
8088 fputs (">: [", stdout);
8089 print_vma (tp->start.offset, PREFIX_HEX);
8090 fputc ('-', stdout);
8091 print_vma (tp->end.offset, PREFIX_HEX);
8092 printf ("]\n\t");
8093
18bd398b
NC
8094#define PF(_m) if (tp->_m) printf (#_m " ");
8095#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8096 PF(Cannot_unwind);
8097 PF(Millicode);
8098 PF(Millicode_save_sr0);
18bd398b 8099 /* PV(Region_description); */
57346661
AM
8100 PF(Entry_SR);
8101 PV(Entry_FR);
8102 PV(Entry_GR);
8103 PF(Args_stored);
8104 PF(Variable_Frame);
8105 PF(Separate_Package_Body);
8106 PF(Frame_Extension_Millicode);
8107 PF(Stack_Overflow_Check);
8108 PF(Two_Instruction_SP_Increment);
8109 PF(Ada_Region);
8110 PF(cxx_info);
8111 PF(cxx_try_catch);
8112 PF(sched_entry_seq);
8113 PF(Save_SP);
8114 PF(Save_RP);
8115 PF(Save_MRP_in_frame);
8116 PF(extn_ptr_defined);
8117 PF(Cleanup_defined);
8118 PF(MPE_XL_interrupt_marker);
8119 PF(HP_UX_interrupt_marker);
8120 PF(Large_frame);
8121 PF(Pseudo_SP_Set);
8122 PV(Total_frame_size);
8123#undef PF
8124#undef PV
8125 }
8126
18bd398b 8127 printf ("\n");
948f632f
DA
8128
8129 free (aux->funtab);
32ec8896
NC
8130
8131 return res;
57346661
AM
8132}
8133
32ec8896 8134static bfd_boolean
dda8d76d
NC
8135slurp_hppa_unwind_table (Filedata * filedata,
8136 struct hppa_unw_aux_info * aux,
8137 Elf_Internal_Shdr * sec)
57346661 8138{
1c0751b2 8139 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8140 Elf_Internal_Phdr * seg;
8141 struct hppa_unw_table_entry * tep;
8142 Elf_Internal_Shdr * relsec;
8143 Elf_Internal_Rela * rela;
8144 Elf_Internal_Rela * rp;
8145 unsigned char * table;
8146 unsigned char * tp;
8147 Elf_Internal_Sym * sym;
8148 const char * relname;
57346661 8149
57346661
AM
8150 /* First, find the starting address of the segment that includes
8151 this section. */
dda8d76d 8152 if (filedata->file_header.e_phnum)
57346661 8153 {
dda8d76d 8154 if (! get_program_headers (filedata))
32ec8896 8155 return FALSE;
57346661 8156
dda8d76d
NC
8157 for (seg = filedata->program_headers;
8158 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8159 ++seg)
8160 {
8161 if (seg->p_type != PT_LOAD)
8162 continue;
8163
8164 if (sec->sh_addr >= seg->p_vaddr
8165 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8166 {
8167 aux->seg_base = seg->p_vaddr;
8168 break;
8169 }
8170 }
8171 }
8172
8173 /* Second, build the unwind table from the contents of the unwind
8174 section. */
8175 size = sec->sh_size;
dda8d76d 8176 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8177 _("unwind table"));
57346661 8178 if (!table)
32ec8896 8179 return FALSE;
57346661 8180
1c0751b2
DA
8181 unw_ent_size = 16;
8182 nentries = size / unw_ent_size;
8183 size = unw_ent_size * nentries;
57346661 8184
3f5e193b
NC
8185 tep = aux->table = (struct hppa_unw_table_entry *)
8186 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8187
1c0751b2 8188 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8189 {
8190 unsigned int tmp1, tmp2;
8191
8192 tep->start.section = SHN_UNDEF;
8193 tep->end.section = SHN_UNDEF;
8194
1c0751b2
DA
8195 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8196 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8197 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8198 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8199
8200 tep->start.offset += aux->seg_base;
8201 tep->end.offset += aux->seg_base;
57346661
AM
8202
8203 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8204 tep->Millicode = (tmp1 >> 30) & 0x1;
8205 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8206 tep->Region_description = (tmp1 >> 27) & 0x3;
8207 tep->reserved1 = (tmp1 >> 26) & 0x1;
8208 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8209 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8210 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8211 tep->Args_stored = (tmp1 >> 15) & 0x1;
8212 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8213 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8214 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8215 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8216 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8217 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8218 tep->cxx_info = (tmp1 >> 8) & 0x1;
8219 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8220 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8221 tep->reserved2 = (tmp1 >> 5) & 0x1;
8222 tep->Save_SP = (tmp1 >> 4) & 0x1;
8223 tep->Save_RP = (tmp1 >> 3) & 0x1;
8224 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8225 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8226 tep->Cleanup_defined = tmp1 & 0x1;
8227
8228 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8229 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8230 tep->Large_frame = (tmp2 >> 29) & 0x1;
8231 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8232 tep->reserved4 = (tmp2 >> 27) & 0x1;
8233 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8234 }
8235 free (table);
8236
8237 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8238 for (relsec = filedata->section_headers;
8239 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8240 ++relsec)
8241 {
8242 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8243 || relsec->sh_info >= filedata->file_header.e_shnum
8244 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8245 continue;
8246
dda8d76d 8247 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8248 & rela, & nrelas))
32ec8896 8249 return FALSE;
57346661
AM
8250
8251 for (rp = rela; rp < rela + nrelas; ++rp)
8252 {
4770fb94 8253 unsigned int sym_ndx;
726bd37d
AM
8254 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8255 relname = elf_hppa_reloc_type (r_type);
57346661 8256
726bd37d
AM
8257 if (relname == NULL)
8258 {
8259 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8260 continue;
8261 }
8262
57346661 8263 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8264 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8265 {
726bd37d 8266 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8267 continue;
8268 }
8269
8270 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8271 if (i >= aux->table_len)
8272 {
8273 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8274 continue;
8275 }
57346661 8276
4770fb94
AM
8277 sym_ndx = get_reloc_symindex (rp->r_info);
8278 if (sym_ndx >= aux->nsyms)
8279 {
8280 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8281 sym_ndx);
8282 continue;
8283 }
8284 sym = aux->symtab + sym_ndx;
8285
43f6cd05 8286 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8287 {
8288 case 0:
8289 aux->table[i].start.section = sym->st_shndx;
1e456d54 8290 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8291 break;
8292 case 1:
8293 aux->table[i].end.section = sym->st_shndx;
1e456d54 8294 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8295 break;
8296 default:
8297 break;
8298 }
8299 }
8300
8301 free (rela);
8302 }
8303
1c0751b2 8304 aux->table_len = nentries;
57346661 8305
32ec8896 8306 return TRUE;
57346661
AM
8307}
8308
32ec8896 8309static bfd_boolean
dda8d76d 8310hppa_process_unwind (Filedata * filedata)
57346661 8311{
57346661 8312 struct hppa_unw_aux_info aux;
2cf0635d 8313 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8314 Elf_Internal_Shdr * sec;
18bd398b 8315 unsigned long i;
32ec8896 8316 bfd_boolean res = TRUE;
57346661 8317
dda8d76d 8318 if (filedata->string_table == NULL)
32ec8896 8319 return FALSE;
1b31d05e
NC
8320
8321 memset (& aux, 0, sizeof (aux));
57346661 8322
dda8d76d 8323 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8324 {
28d13567 8325 if (sec->sh_type == SHT_SYMTAB)
57346661 8326 {
28d13567 8327 if (aux.symtab)
4082ef84 8328 {
28d13567
AM
8329 error (_("Multiple symbol tables encountered\n"));
8330 free (aux.symtab);
8331 aux.symtab = NULL;
4082ef84 8332 free (aux.strtab);
28d13567 8333 aux.strtab = NULL;
4082ef84 8334 }
28d13567
AM
8335 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8336 &aux.strtab, &aux.strtab_size))
8337 return FALSE;
57346661 8338 }
18bd398b 8339 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8340 unwsec = sec;
8341 }
8342
8343 if (!unwsec)
8344 printf (_("\nThere are no unwind sections in this file.\n"));
8345
dda8d76d 8346 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8347 {
18bd398b 8348 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8349 {
43f6cd05 8350 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8351
d3a49aa8
AM
8352 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8353 "contains %lu entry:\n",
8354 "\nUnwind section '%s' at offset 0x%lx "
8355 "contains %lu entries:\n",
8356 num_unwind),
dda8d76d 8357 printable_section_name (filedata, sec),
57346661 8358 (unsigned long) sec->sh_offset,
d3a49aa8 8359 num_unwind);
57346661 8360
dda8d76d 8361 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8362 res = FALSE;
66b09c7e
S
8363
8364 if (res && aux.table_len > 0)
32ec8896 8365 {
dda8d76d 8366 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8367 res = FALSE;
8368 }
57346661
AM
8369
8370 if (aux.table)
8371 free ((char *) aux.table);
8372 aux.table = NULL;
8373 }
8374 }
8375
8376 if (aux.symtab)
8377 free (aux.symtab);
8378 if (aux.strtab)
8379 free ((char *) aux.strtab);
32ec8896
NC
8380
8381 return res;
57346661
AM
8382}
8383
0b6ae522
DJ
8384struct arm_section
8385{
a734115a
NC
8386 unsigned char * data; /* The unwind data. */
8387 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8388 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8389 unsigned long nrelas; /* The number of relocations. */
8390 unsigned int rel_type; /* REL or RELA ? */
8391 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8392};
8393
8394struct arm_unw_aux_info
8395{
dda8d76d 8396 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8397 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8398 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8399 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8400 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8401 char * strtab; /* The file's string table. */
8402 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8403};
8404
8405static const char *
dda8d76d
NC
8406arm_print_vma_and_name (Filedata * filedata,
8407 struct arm_unw_aux_info * aux,
8408 bfd_vma fn,
8409 struct absaddr addr)
0b6ae522
DJ
8410{
8411 const char *procname;
8412 bfd_vma sym_offset;
8413
8414 if (addr.section == SHN_UNDEF)
8415 addr.offset = fn;
8416
dda8d76d 8417 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8418 aux->strtab_size, addr, &procname,
8419 &sym_offset);
8420
8421 print_vma (fn, PREFIX_HEX);
8422
8423 if (procname)
8424 {
8425 fputs (" <", stdout);
8426 fputs (procname, stdout);
8427
8428 if (sym_offset)
8429 printf ("+0x%lx", (unsigned long) sym_offset);
8430 fputc ('>', stdout);
8431 }
8432
8433 return procname;
8434}
8435
8436static void
8437arm_free_section (struct arm_section *arm_sec)
8438{
8439 if (arm_sec->data != NULL)
8440 free (arm_sec->data);
8441
8442 if (arm_sec->rela != NULL)
8443 free (arm_sec->rela);
8444}
8445
a734115a
NC
8446/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8447 cached section and install SEC instead.
8448 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8449 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8450 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8451 relocation's offset in ADDR.
1b31d05e
NC
8452 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8453 into the string table of the symbol associated with the reloc. If no
8454 reloc was applied store -1 there.
8455 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8456
8457static bfd_boolean
dda8d76d
NC
8458get_unwind_section_word (Filedata * filedata,
8459 struct arm_unw_aux_info * aux,
1b31d05e
NC
8460 struct arm_section * arm_sec,
8461 Elf_Internal_Shdr * sec,
8462 bfd_vma word_offset,
8463 unsigned int * wordp,
8464 struct absaddr * addr,
8465 bfd_vma * sym_name)
0b6ae522
DJ
8466{
8467 Elf_Internal_Rela *rp;
8468 Elf_Internal_Sym *sym;
8469 const char * relname;
8470 unsigned int word;
8471 bfd_boolean wrapped;
8472
e0a31db1
NC
8473 if (sec == NULL || arm_sec == NULL)
8474 return FALSE;
8475
0b6ae522
DJ
8476 addr->section = SHN_UNDEF;
8477 addr->offset = 0;
8478
1b31d05e
NC
8479 if (sym_name != NULL)
8480 *sym_name = (bfd_vma) -1;
8481
a734115a 8482 /* If necessary, update the section cache. */
0b6ae522
DJ
8483 if (sec != arm_sec->sec)
8484 {
8485 Elf_Internal_Shdr *relsec;
8486
8487 arm_free_section (arm_sec);
8488
8489 arm_sec->sec = sec;
dda8d76d 8490 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8491 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8492 arm_sec->rela = NULL;
8493 arm_sec->nrelas = 0;
8494
dda8d76d
NC
8495 for (relsec = filedata->section_headers;
8496 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8497 ++relsec)
8498 {
dda8d76d
NC
8499 if (relsec->sh_info >= filedata->file_header.e_shnum
8500 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8501 /* PR 15745: Check the section type as well. */
8502 || (relsec->sh_type != SHT_REL
8503 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8504 continue;
8505
a734115a 8506 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8507 if (relsec->sh_type == SHT_REL)
8508 {
dda8d76d 8509 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8510 relsec->sh_size,
8511 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8512 return FALSE;
0b6ae522 8513 }
1ae40aa4 8514 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8515 {
dda8d76d 8516 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8517 relsec->sh_size,
8518 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8519 return FALSE;
0b6ae522 8520 }
1ae40aa4 8521 break;
0b6ae522
DJ
8522 }
8523
8524 arm_sec->next_rela = arm_sec->rela;
8525 }
8526
a734115a 8527 /* If there is no unwind data we can do nothing. */
0b6ae522 8528 if (arm_sec->data == NULL)
a734115a 8529 return FALSE;
0b6ae522 8530
e0a31db1 8531 /* If the offset is invalid then fail. */
f32ba729
NC
8532 if (/* PR 21343 *//* PR 18879 */
8533 sec->sh_size < 4
8534 || word_offset > (sec->sh_size - 4)
1a915552 8535 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8536 return FALSE;
8537
a734115a 8538 /* Get the word at the required offset. */
0b6ae522
DJ
8539 word = byte_get (arm_sec->data + word_offset, 4);
8540
0eff7165
NC
8541 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8542 if (arm_sec->rela == NULL)
8543 {
8544 * wordp = word;
8545 return TRUE;
8546 }
8547
a734115a 8548 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8549 wrapped = FALSE;
8550 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8551 {
8552 bfd_vma prelval, offset;
8553
8554 if (rp->r_offset > word_offset && !wrapped)
8555 {
8556 rp = arm_sec->rela;
8557 wrapped = TRUE;
8558 }
8559 if (rp->r_offset > word_offset)
8560 break;
8561
8562 if (rp->r_offset & 3)
8563 {
8564 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8565 (unsigned long) rp->r_offset);
8566 continue;
8567 }
8568
8569 if (rp->r_offset < word_offset)
8570 continue;
8571
74e1a04b
NC
8572 /* PR 17531: file: 027-161405-0.004 */
8573 if (aux->symtab == NULL)
8574 continue;
8575
0b6ae522
DJ
8576 if (arm_sec->rel_type == SHT_REL)
8577 {
8578 offset = word & 0x7fffffff;
8579 if (offset & 0x40000000)
8580 offset |= ~ (bfd_vma) 0x7fffffff;
8581 }
a734115a 8582 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8583 offset = rp->r_addend;
a734115a 8584 else
74e1a04b
NC
8585 {
8586 error (_("Unknown section relocation type %d encountered\n"),
8587 arm_sec->rel_type);
8588 break;
8589 }
0b6ae522 8590
071436c6
NC
8591 /* PR 17531 file: 027-1241568-0.004. */
8592 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8593 {
8594 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8595 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8596 break;
8597 }
8598
8599 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8600 offset += sym->st_value;
8601 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8602
a734115a 8603 /* Check that we are processing the expected reloc type. */
dda8d76d 8604 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8605 {
8606 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8607 if (relname == NULL)
8608 {
8609 warn (_("Skipping unknown ARM relocation type: %d\n"),
8610 (int) ELF32_R_TYPE (rp->r_info));
8611 continue;
8612 }
a734115a
NC
8613
8614 if (streq (relname, "R_ARM_NONE"))
8615 continue;
0b4362b0 8616
a734115a
NC
8617 if (! streq (relname, "R_ARM_PREL31"))
8618 {
071436c6 8619 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8620 continue;
8621 }
8622 }
dda8d76d 8623 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8624 {
8625 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8626 if (relname == NULL)
8627 {
8628 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8629 (int) ELF32_R_TYPE (rp->r_info));
8630 continue;
8631 }
0b4362b0 8632
a734115a
NC
8633 if (streq (relname, "R_C6000_NONE"))
8634 continue;
8635
8636 if (! streq (relname, "R_C6000_PREL31"))
8637 {
071436c6 8638 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8639 continue;
8640 }
8641
8642 prelval >>= 1;
8643 }
8644 else
74e1a04b
NC
8645 {
8646 /* This function currently only supports ARM and TI unwinders. */
8647 warn (_("Only TI and ARM unwinders are currently supported\n"));
8648 break;
8649 }
fa197c1c 8650
0b6ae522
DJ
8651 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8652 addr->section = sym->st_shndx;
8653 addr->offset = offset;
74e1a04b 8654
1b31d05e
NC
8655 if (sym_name)
8656 * sym_name = sym->st_name;
0b6ae522
DJ
8657 break;
8658 }
8659
8660 *wordp = word;
8661 arm_sec->next_rela = rp;
8662
a734115a 8663 return TRUE;
0b6ae522
DJ
8664}
8665
a734115a
NC
8666static const char *tic6x_unwind_regnames[16] =
8667{
0b4362b0
RM
8668 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8669 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8670 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8671};
fa197c1c 8672
0b6ae522 8673static void
fa197c1c 8674decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8675{
fa197c1c
PB
8676 int i;
8677
8678 for (i = 12; mask; mask >>= 1, i--)
8679 {
8680 if (mask & 1)
8681 {
8682 fputs (tic6x_unwind_regnames[i], stdout);
8683 if (mask > 1)
8684 fputs (", ", stdout);
8685 }
8686 }
8687}
0b6ae522
DJ
8688
8689#define ADVANCE \
8690 if (remaining == 0 && more_words) \
8691 { \
8692 data_offset += 4; \
dda8d76d 8693 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8694 data_offset, & word, & addr, NULL)) \
32ec8896 8695 return FALSE; \
0b6ae522
DJ
8696 remaining = 4; \
8697 more_words--; \
8698 } \
8699
8700#define GET_OP(OP) \
8701 ADVANCE; \
8702 if (remaining) \
8703 { \
8704 remaining--; \
8705 (OP) = word >> 24; \
8706 word <<= 8; \
8707 } \
8708 else \
8709 { \
2b692964 8710 printf (_("[Truncated opcode]\n")); \
32ec8896 8711 return FALSE; \
0b6ae522 8712 } \
cc5914eb 8713 printf ("0x%02x ", OP)
0b6ae522 8714
32ec8896 8715static bfd_boolean
dda8d76d
NC
8716decode_arm_unwind_bytecode (Filedata * filedata,
8717 struct arm_unw_aux_info * aux,
948f632f
DA
8718 unsigned int word,
8719 unsigned int remaining,
8720 unsigned int more_words,
8721 bfd_vma data_offset,
8722 Elf_Internal_Shdr * data_sec,
8723 struct arm_section * data_arm_sec)
fa197c1c
PB
8724{
8725 struct absaddr addr;
32ec8896 8726 bfd_boolean res = TRUE;
0b6ae522
DJ
8727
8728 /* Decode the unwinding instructions. */
8729 while (1)
8730 {
8731 unsigned int op, op2;
8732
8733 ADVANCE;
8734 if (remaining == 0)
8735 break;
8736 remaining--;
8737 op = word >> 24;
8738 word <<= 8;
8739
cc5914eb 8740 printf (" 0x%02x ", op);
0b6ae522
DJ
8741
8742 if ((op & 0xc0) == 0x00)
8743 {
8744 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8745
cc5914eb 8746 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8747 }
8748 else if ((op & 0xc0) == 0x40)
8749 {
8750 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8751
cc5914eb 8752 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8753 }
8754 else if ((op & 0xf0) == 0x80)
8755 {
8756 GET_OP (op2);
8757 if (op == 0x80 && op2 == 0)
8758 printf (_("Refuse to unwind"));
8759 else
8760 {
8761 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8762 bfd_boolean first = TRUE;
0b6ae522 8763 int i;
2b692964 8764
0b6ae522
DJ
8765 printf ("pop {");
8766 for (i = 0; i < 12; i++)
8767 if (mask & (1 << i))
8768 {
8769 if (first)
32ec8896 8770 first = FALSE;
0b6ae522
DJ
8771 else
8772 printf (", ");
8773 printf ("r%d", 4 + i);
8774 }
8775 printf ("}");
8776 }
8777 }
8778 else if ((op & 0xf0) == 0x90)
8779 {
8780 if (op == 0x9d || op == 0x9f)
8781 printf (_(" [Reserved]"));
8782 else
cc5914eb 8783 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8784 }
8785 else if ((op & 0xf0) == 0xa0)
8786 {
8787 int end = 4 + (op & 0x07);
32ec8896 8788 bfd_boolean first = TRUE;
0b6ae522 8789 int i;
61865e30 8790
0b6ae522
DJ
8791 printf (" pop {");
8792 for (i = 4; i <= end; i++)
8793 {
8794 if (first)
32ec8896 8795 first = FALSE;
0b6ae522
DJ
8796 else
8797 printf (", ");
8798 printf ("r%d", i);
8799 }
8800 if (op & 0x08)
8801 {
1b31d05e 8802 if (!first)
0b6ae522
DJ
8803 printf (", ");
8804 printf ("r14");
8805 }
8806 printf ("}");
8807 }
8808 else if (op == 0xb0)
8809 printf (_(" finish"));
8810 else if (op == 0xb1)
8811 {
8812 GET_OP (op2);
8813 if (op2 == 0 || (op2 & 0xf0) != 0)
8814 printf (_("[Spare]"));
8815 else
8816 {
8817 unsigned int mask = op2 & 0x0f;
32ec8896 8818 bfd_boolean first = TRUE;
0b6ae522 8819 int i;
61865e30 8820
0b6ae522
DJ
8821 printf ("pop {");
8822 for (i = 0; i < 12; i++)
8823 if (mask & (1 << i))
8824 {
8825 if (first)
32ec8896 8826 first = FALSE;
0b6ae522
DJ
8827 else
8828 printf (", ");
8829 printf ("r%d", i);
8830 }
8831 printf ("}");
8832 }
8833 }
8834 else if (op == 0xb2)
8835 {
b115cf96 8836 unsigned char buf[9];
0b6ae522
DJ
8837 unsigned int i, len;
8838 unsigned long offset;
61865e30 8839
b115cf96 8840 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8841 {
8842 GET_OP (buf[i]);
8843 if ((buf[i] & 0x80) == 0)
8844 break;
8845 }
4082ef84 8846 if (i == sizeof (buf))
32ec8896 8847 {
27a45f42 8848 error (_("corrupt change to vsp\n"));
32ec8896
NC
8849 res = FALSE;
8850 }
4082ef84
NC
8851 else
8852 {
cd30bcef 8853 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
8854 assert (len == i + 1);
8855 offset = offset * 4 + 0x204;
8856 printf ("vsp = vsp + %ld", offset);
8857 }
0b6ae522 8858 }
61865e30 8859 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8860 {
61865e30
NC
8861 unsigned int first, last;
8862
8863 GET_OP (op2);
8864 first = op2 >> 4;
8865 last = op2 & 0x0f;
8866 if (op == 0xc8)
8867 first = first + 16;
8868 printf ("pop {D%d", first);
8869 if (last)
8870 printf ("-D%d", first + last);
8871 printf ("}");
8872 }
8873 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8874 {
8875 unsigned int count = op & 0x07;
8876
8877 printf ("pop {D8");
8878 if (count)
8879 printf ("-D%d", 8 + count);
8880 printf ("}");
8881 }
8882 else if (op >= 0xc0 && op <= 0xc5)
8883 {
8884 unsigned int count = op & 0x07;
8885
8886 printf (" pop {wR10");
8887 if (count)
8888 printf ("-wR%d", 10 + count);
8889 printf ("}");
8890 }
8891 else if (op == 0xc6)
8892 {
8893 unsigned int first, last;
8894
8895 GET_OP (op2);
8896 first = op2 >> 4;
8897 last = op2 & 0x0f;
8898 printf ("pop {wR%d", first);
8899 if (last)
8900 printf ("-wR%d", first + last);
8901 printf ("}");
8902 }
8903 else if (op == 0xc7)
8904 {
8905 GET_OP (op2);
8906 if (op2 == 0 || (op2 & 0xf0) != 0)
8907 printf (_("[Spare]"));
0b6ae522
DJ
8908 else
8909 {
61865e30 8910 unsigned int mask = op2 & 0x0f;
32ec8896 8911 bfd_boolean first = TRUE;
61865e30
NC
8912 int i;
8913
8914 printf ("pop {");
8915 for (i = 0; i < 4; i++)
8916 if (mask & (1 << i))
8917 {
8918 if (first)
32ec8896 8919 first = FALSE;
61865e30
NC
8920 else
8921 printf (", ");
8922 printf ("wCGR%d", i);
8923 }
8924 printf ("}");
0b6ae522
DJ
8925 }
8926 }
61865e30 8927 else
32ec8896
NC
8928 {
8929 printf (_(" [unsupported opcode]"));
8930 res = FALSE;
8931 }
8932
0b6ae522
DJ
8933 printf ("\n");
8934 }
32ec8896
NC
8935
8936 return res;
fa197c1c
PB
8937}
8938
32ec8896 8939static bfd_boolean
dda8d76d
NC
8940decode_tic6x_unwind_bytecode (Filedata * filedata,
8941 struct arm_unw_aux_info * aux,
948f632f
DA
8942 unsigned int word,
8943 unsigned int remaining,
8944 unsigned int more_words,
8945 bfd_vma data_offset,
8946 Elf_Internal_Shdr * data_sec,
8947 struct arm_section * data_arm_sec)
fa197c1c
PB
8948{
8949 struct absaddr addr;
8950
8951 /* Decode the unwinding instructions. */
8952 while (1)
8953 {
8954 unsigned int op, op2;
8955
8956 ADVANCE;
8957 if (remaining == 0)
8958 break;
8959 remaining--;
8960 op = word >> 24;
8961 word <<= 8;
8962
9cf03b7e 8963 printf (" 0x%02x ", op);
fa197c1c
PB
8964
8965 if ((op & 0xc0) == 0x00)
8966 {
8967 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 8968 printf (" sp = sp + %d", offset);
fa197c1c
PB
8969 }
8970 else if ((op & 0xc0) == 0x80)
8971 {
8972 GET_OP (op2);
8973 if (op == 0x80 && op2 == 0)
8974 printf (_("Refuse to unwind"));
8975 else
8976 {
8977 unsigned int mask = ((op & 0x1f) << 8) | op2;
8978 if (op & 0x20)
8979 printf ("pop compact {");
8980 else
8981 printf ("pop {");
8982
8983 decode_tic6x_unwind_regmask (mask);
8984 printf("}");
8985 }
8986 }
8987 else if ((op & 0xf0) == 0xc0)
8988 {
8989 unsigned int reg;
8990 unsigned int nregs;
8991 unsigned int i;
8992 const char *name;
a734115a
NC
8993 struct
8994 {
32ec8896
NC
8995 unsigned int offset;
8996 unsigned int reg;
fa197c1c
PB
8997 } regpos[16];
8998
8999 /* Scan entire instruction first so that GET_OP output is not
9000 interleaved with disassembly. */
9001 nregs = 0;
9002 for (i = 0; nregs < (op & 0xf); i++)
9003 {
9004 GET_OP (op2);
9005 reg = op2 >> 4;
9006 if (reg != 0xf)
9007 {
9008 regpos[nregs].offset = i * 2;
9009 regpos[nregs].reg = reg;
9010 nregs++;
9011 }
9012
9013 reg = op2 & 0xf;
9014 if (reg != 0xf)
9015 {
9016 regpos[nregs].offset = i * 2 + 1;
9017 regpos[nregs].reg = reg;
9018 nregs++;
9019 }
9020 }
9021
9022 printf (_("pop frame {"));
18344509 9023 if (nregs == 0)
fa197c1c 9024 {
18344509
NC
9025 printf (_("*corrupt* - no registers specified"));
9026 }
9027 else
9028 {
9029 reg = nregs - 1;
9030 for (i = i * 2; i > 0; i--)
fa197c1c 9031 {
18344509
NC
9032 if (regpos[reg].offset == i - 1)
9033 {
9034 name = tic6x_unwind_regnames[regpos[reg].reg];
9035 if (reg > 0)
9036 reg--;
9037 }
9038 else
9039 name = _("[pad]");
fa197c1c 9040
18344509
NC
9041 fputs (name, stdout);
9042 if (i > 1)
9043 printf (", ");
9044 }
fa197c1c
PB
9045 }
9046
9047 printf ("}");
9048 }
9049 else if (op == 0xd0)
9050 printf (" MOV FP, SP");
9051 else if (op == 0xd1)
9052 printf (" __c6xabi_pop_rts");
9053 else if (op == 0xd2)
9054 {
9055 unsigned char buf[9];
9056 unsigned int i, len;
9057 unsigned long offset;
a734115a 9058
fa197c1c
PB
9059 for (i = 0; i < sizeof (buf); i++)
9060 {
9061 GET_OP (buf[i]);
9062 if ((buf[i] & 0x80) == 0)
9063 break;
9064 }
0eff7165
NC
9065 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9066 if (i == sizeof (buf))
9067 {
0eff7165 9068 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9069 return FALSE;
0eff7165 9070 }
948f632f 9071
cd30bcef 9072 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9073 assert (len == i + 1);
9074 offset = offset * 8 + 0x408;
9075 printf (_("sp = sp + %ld"), offset);
9076 }
9077 else if ((op & 0xf0) == 0xe0)
9078 {
9079 if ((op & 0x0f) == 7)
9080 printf (" RETURN");
9081 else
9082 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9083 }
9084 else
9085 {
9086 printf (_(" [unsupported opcode]"));
9087 }
9088 putchar ('\n');
9089 }
32ec8896
NC
9090
9091 return TRUE;
fa197c1c
PB
9092}
9093
9094static bfd_vma
dda8d76d 9095arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9096{
9097 bfd_vma offset;
9098
9099 offset = word & 0x7fffffff;
9100 if (offset & 0x40000000)
9101 offset |= ~ (bfd_vma) 0x7fffffff;
9102
dda8d76d 9103 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9104 offset <<= 1;
9105
9106 return offset + where;
9107}
9108
32ec8896 9109static bfd_boolean
dda8d76d
NC
9110decode_arm_unwind (Filedata * filedata,
9111 struct arm_unw_aux_info * aux,
1b31d05e
NC
9112 unsigned int word,
9113 unsigned int remaining,
9114 bfd_vma data_offset,
9115 Elf_Internal_Shdr * data_sec,
9116 struct arm_section * data_arm_sec)
fa197c1c
PB
9117{
9118 int per_index;
9119 unsigned int more_words = 0;
37e14bc3 9120 struct absaddr addr;
1b31d05e 9121 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9122 bfd_boolean res = TRUE;
fa197c1c
PB
9123
9124 if (remaining == 0)
9125 {
1b31d05e
NC
9126 /* Fetch the first word.
9127 Note - when decoding an object file the address extracted
9128 here will always be 0. So we also pass in the sym_name
9129 parameter so that we can find the symbol associated with
9130 the personality routine. */
dda8d76d 9131 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9132 & word, & addr, & sym_name))
32ec8896 9133 return FALSE;
1b31d05e 9134
fa197c1c
PB
9135 remaining = 4;
9136 }
c93dbb25
CZ
9137 else
9138 {
9139 addr.section = SHN_UNDEF;
9140 addr.offset = 0;
9141 }
fa197c1c
PB
9142
9143 if ((word & 0x80000000) == 0)
9144 {
9145 /* Expand prel31 for personality routine. */
9146 bfd_vma fn;
9147 const char *procname;
9148
dda8d76d 9149 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9150 printf (_(" Personality routine: "));
1b31d05e
NC
9151 if (fn == 0
9152 && addr.section == SHN_UNDEF && addr.offset == 0
9153 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9154 {
9155 procname = aux->strtab + sym_name;
9156 print_vma (fn, PREFIX_HEX);
9157 if (procname)
9158 {
9159 fputs (" <", stdout);
9160 fputs (procname, stdout);
9161 fputc ('>', stdout);
9162 }
9163 }
9164 else
dda8d76d 9165 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9166 fputc ('\n', stdout);
9167
9168 /* The GCC personality routines use the standard compact
9169 encoding, starting with one byte giving the number of
9170 words. */
9171 if (procname != NULL
9172 && (const_strneq (procname, "__gcc_personality_v0")
9173 || const_strneq (procname, "__gxx_personality_v0")
9174 || const_strneq (procname, "__gcj_personality_v0")
9175 || const_strneq (procname, "__gnu_objc_personality_v0")))
9176 {
9177 remaining = 0;
9178 more_words = 1;
9179 ADVANCE;
9180 if (!remaining)
9181 {
9182 printf (_(" [Truncated data]\n"));
32ec8896 9183 return FALSE;
fa197c1c
PB
9184 }
9185 more_words = word >> 24;
9186 word <<= 8;
9187 remaining--;
9188 per_index = -1;
9189 }
9190 else
32ec8896 9191 return TRUE;
fa197c1c
PB
9192 }
9193 else
9194 {
1b31d05e 9195 /* ARM EHABI Section 6.3:
0b4362b0 9196
1b31d05e 9197 An exception-handling table entry for the compact model looks like:
0b4362b0 9198
1b31d05e
NC
9199 31 30-28 27-24 23-0
9200 -- ----- ----- ----
9201 1 0 index Data for personalityRoutine[index] */
9202
dda8d76d 9203 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9204 && (word & 0x70000000))
32ec8896
NC
9205 {
9206 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9207 res = FALSE;
9208 }
1b31d05e 9209
fa197c1c 9210 per_index = (word >> 24) & 0x7f;
1b31d05e 9211 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9212 if (per_index == 0)
9213 {
9214 more_words = 0;
9215 word <<= 8;
9216 remaining--;
9217 }
9218 else if (per_index < 3)
9219 {
9220 more_words = (word >> 16) & 0xff;
9221 word <<= 16;
9222 remaining -= 2;
9223 }
9224 }
9225
dda8d76d 9226 switch (filedata->file_header.e_machine)
fa197c1c
PB
9227 {
9228 case EM_ARM:
9229 if (per_index < 3)
9230 {
dda8d76d 9231 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9232 data_offset, data_sec, data_arm_sec))
9233 res = FALSE;
fa197c1c
PB
9234 }
9235 else
1b31d05e
NC
9236 {
9237 warn (_("Unknown ARM compact model index encountered\n"));
9238 printf (_(" [reserved]\n"));
32ec8896 9239 res = FALSE;
1b31d05e 9240 }
fa197c1c
PB
9241 break;
9242
9243 case EM_TI_C6000:
9244 if (per_index < 3)
9245 {
dda8d76d 9246 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9247 data_offset, data_sec, data_arm_sec))
9248 res = FALSE;
fa197c1c
PB
9249 }
9250 else if (per_index < 5)
9251 {
9252 if (((word >> 17) & 0x7f) == 0x7f)
9253 printf (_(" Restore stack from frame pointer\n"));
9254 else
9255 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9256 printf (_(" Registers restored: "));
9257 if (per_index == 4)
9258 printf (" (compact) ");
9259 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9260 putchar ('\n');
9261 printf (_(" Return register: %s\n"),
9262 tic6x_unwind_regnames[word & 0xf]);
9263 }
9264 else
1b31d05e 9265 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9266 break;
9267
9268 default:
74e1a04b 9269 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9270 filedata->file_header.e_machine);
32ec8896 9271 res = FALSE;
fa197c1c 9272 }
0b6ae522
DJ
9273
9274 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9275
9276 return res;
0b6ae522
DJ
9277}
9278
32ec8896 9279static bfd_boolean
dda8d76d
NC
9280dump_arm_unwind (Filedata * filedata,
9281 struct arm_unw_aux_info * aux,
9282 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9283{
9284 struct arm_section exidx_arm_sec, extab_arm_sec;
9285 unsigned int i, exidx_len;
948f632f 9286 unsigned long j, nfuns;
32ec8896 9287 bfd_boolean res = TRUE;
0b6ae522
DJ
9288
9289 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9290 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9291 exidx_len = exidx_sec->sh_size / 8;
9292
948f632f
DA
9293 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9294 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9295 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9296 aux->funtab[nfuns++] = aux->symtab[j];
9297 aux->nfuns = nfuns;
9298 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9299
0b6ae522
DJ
9300 for (i = 0; i < exidx_len; i++)
9301 {
9302 unsigned int exidx_fn, exidx_entry;
9303 struct absaddr fn_addr, entry_addr;
9304 bfd_vma fn;
9305
9306 fputc ('\n', stdout);
9307
dda8d76d 9308 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9309 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9310 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9311 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9312 {
948f632f 9313 free (aux->funtab);
1b31d05e
NC
9314 arm_free_section (& exidx_arm_sec);
9315 arm_free_section (& extab_arm_sec);
32ec8896 9316 return FALSE;
0b6ae522
DJ
9317 }
9318
83c257ca
NC
9319 /* ARM EHABI, Section 5:
9320 An index table entry consists of 2 words.
9321 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9322 if (exidx_fn & 0x80000000)
32ec8896
NC
9323 {
9324 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9325 res = FALSE;
9326 }
83c257ca 9327
dda8d76d 9328 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9329
dda8d76d 9330 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9331 fputs (": ", stdout);
9332
9333 if (exidx_entry == 1)
9334 {
9335 print_vma (exidx_entry, PREFIX_HEX);
9336 fputs (" [cantunwind]\n", stdout);
9337 }
9338 else if (exidx_entry & 0x80000000)
9339 {
9340 print_vma (exidx_entry, PREFIX_HEX);
9341 fputc ('\n', stdout);
dda8d76d 9342 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9343 }
9344 else
9345 {
8f73510c 9346 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9347 Elf_Internal_Shdr *table_sec;
9348
9349 fputs ("@", stdout);
dda8d76d 9350 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9351 print_vma (table, PREFIX_HEX);
9352 printf ("\n");
9353
9354 /* Locate the matching .ARM.extab. */
9355 if (entry_addr.section != SHN_UNDEF
dda8d76d 9356 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9357 {
dda8d76d 9358 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9359 table_offset = entry_addr.offset;
1a915552
NC
9360 /* PR 18879 */
9361 if (table_offset > table_sec->sh_size
9362 || ((bfd_signed_vma) table_offset) < 0)
9363 {
9364 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9365 (unsigned long) table_offset,
dda8d76d 9366 printable_section_name (filedata, table_sec));
32ec8896 9367 res = FALSE;
1a915552
NC
9368 continue;
9369 }
0b6ae522
DJ
9370 }
9371 else
9372 {
dda8d76d 9373 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9374 if (table_sec != NULL)
9375 table_offset = table - table_sec->sh_addr;
9376 }
32ec8896 9377
0b6ae522
DJ
9378 if (table_sec == NULL)
9379 {
9380 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9381 (unsigned long) table);
32ec8896 9382 res = FALSE;
0b6ae522
DJ
9383 continue;
9384 }
32ec8896 9385
dda8d76d 9386 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9387 &extab_arm_sec))
9388 res = FALSE;
0b6ae522
DJ
9389 }
9390 }
9391
9392 printf ("\n");
9393
948f632f 9394 free (aux->funtab);
0b6ae522
DJ
9395 arm_free_section (&exidx_arm_sec);
9396 arm_free_section (&extab_arm_sec);
32ec8896
NC
9397
9398 return res;
0b6ae522
DJ
9399}
9400
fa197c1c 9401/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9402
32ec8896 9403static bfd_boolean
dda8d76d 9404arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9405{
9406 struct arm_unw_aux_info aux;
9407 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9408 Elf_Internal_Shdr *sec;
9409 unsigned long i;
fa197c1c 9410 unsigned int sec_type;
32ec8896 9411 bfd_boolean res = TRUE;
0b6ae522 9412
dda8d76d 9413 switch (filedata->file_header.e_machine)
fa197c1c
PB
9414 {
9415 case EM_ARM:
9416 sec_type = SHT_ARM_EXIDX;
9417 break;
9418
9419 case EM_TI_C6000:
9420 sec_type = SHT_C6000_UNWIND;
9421 break;
9422
0b4362b0 9423 default:
74e1a04b 9424 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9425 filedata->file_header.e_machine);
32ec8896 9426 return FALSE;
fa197c1c
PB
9427 }
9428
dda8d76d 9429 if (filedata->string_table == NULL)
32ec8896 9430 return FALSE;
1b31d05e
NC
9431
9432 memset (& aux, 0, sizeof (aux));
dda8d76d 9433 aux.filedata = filedata;
0b6ae522 9434
dda8d76d 9435 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9436 {
28d13567 9437 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9438 {
28d13567 9439 if (aux.symtab)
74e1a04b 9440 {
28d13567
AM
9441 error (_("Multiple symbol tables encountered\n"));
9442 free (aux.symtab);
9443 aux.symtab = NULL;
74e1a04b 9444 free (aux.strtab);
28d13567 9445 aux.strtab = NULL;
74e1a04b 9446 }
28d13567
AM
9447 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9448 &aux.strtab, &aux.strtab_size))
9449 return FALSE;
0b6ae522 9450 }
fa197c1c 9451 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9452 unwsec = sec;
9453 }
9454
1b31d05e 9455 if (unwsec == NULL)
0b6ae522 9456 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9457 else
dda8d76d 9458 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9459 {
9460 if (sec->sh_type == sec_type)
9461 {
d3a49aa8
AM
9462 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9463 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9464 "contains %lu entry:\n",
9465 "\nUnwind section '%s' at offset 0x%lx "
9466 "contains %lu entries:\n",
9467 num_unwind),
dda8d76d 9468 printable_section_name (filedata, sec),
1b31d05e 9469 (unsigned long) sec->sh_offset,
d3a49aa8 9470 num_unwind);
0b6ae522 9471
dda8d76d 9472 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9473 res = FALSE;
1b31d05e
NC
9474 }
9475 }
0b6ae522
DJ
9476
9477 if (aux.symtab)
9478 free (aux.symtab);
9479 if (aux.strtab)
9480 free ((char *) aux.strtab);
32ec8896
NC
9481
9482 return res;
0b6ae522
DJ
9483}
9484
32ec8896 9485static bfd_boolean
dda8d76d 9486process_unwind (Filedata * filedata)
57346661 9487{
2cf0635d
NC
9488 struct unwind_handler
9489 {
32ec8896 9490 unsigned int machtype;
dda8d76d 9491 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9492 } handlers[] =
9493 {
0b6ae522 9494 { EM_ARM, arm_process_unwind },
57346661
AM
9495 { EM_IA_64, ia64_process_unwind },
9496 { EM_PARISC, hppa_process_unwind },
fa197c1c 9497 { EM_TI_C6000, arm_process_unwind },
32ec8896 9498 { 0, NULL }
57346661
AM
9499 };
9500 int i;
9501
9502 if (!do_unwind)
32ec8896 9503 return TRUE;
57346661
AM
9504
9505 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9506 if (filedata->file_header.e_machine == handlers[i].machtype)
9507 return handlers[i].handler (filedata);
57346661 9508
1b31d05e 9509 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9510 get_machine_name (filedata->file_header.e_machine));
32ec8896 9511 return TRUE;
57346661
AM
9512}
9513
37c18eed
SD
9514static void
9515dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9516{
9517 switch (entry->d_tag)
9518 {
9519 case DT_AARCH64_BTI_PLT:
1dbade74 9520 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9521 break;
9522 default:
9523 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9524 break;
9525 }
9526 putchar ('\n');
9527}
9528
252b5132 9529static void
978c4450 9530dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9531{
9532 switch (entry->d_tag)
9533 {
9534 case DT_MIPS_FLAGS:
9535 if (entry->d_un.d_val == 0)
4b68bca3 9536 printf (_("NONE"));
252b5132
RH
9537 else
9538 {
9539 static const char * opts[] =
9540 {
9541 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9542 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9543 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9544 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9545 "RLD_ORDER_SAFE"
9546 };
9547 unsigned int cnt;
32ec8896 9548 bfd_boolean first = TRUE;
2b692964 9549
60bca95a 9550 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9551 if (entry->d_un.d_val & (1 << cnt))
9552 {
9553 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9554 first = FALSE;
252b5132 9555 }
252b5132
RH
9556 }
9557 break;
103f02d3 9558
252b5132 9559 case DT_MIPS_IVERSION:
978c4450
AM
9560 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9561 printf (_("Interface Version: %s"),
9562 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9563 else
76ca31c0
NC
9564 {
9565 char buf[40];
9566 sprintf_vma (buf, entry->d_un.d_ptr);
9567 /* Note: coded this way so that there is a single string for translation. */
9568 printf (_("<corrupt: %s>"), buf);
9569 }
252b5132 9570 break;
103f02d3 9571
252b5132
RH
9572 case DT_MIPS_TIME_STAMP:
9573 {
d5b07ef4 9574 char timebuf[128];
2cf0635d 9575 struct tm * tmp;
91d6fa6a 9576 time_t atime = entry->d_un.d_val;
82b1b41b 9577
91d6fa6a 9578 tmp = gmtime (&atime);
82b1b41b
NC
9579 /* PR 17531: file: 6accc532. */
9580 if (tmp == NULL)
9581 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9582 else
9583 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9584 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9585 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9586 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9587 }
9588 break;
103f02d3 9589
252b5132
RH
9590 case DT_MIPS_RLD_VERSION:
9591 case DT_MIPS_LOCAL_GOTNO:
9592 case DT_MIPS_CONFLICTNO:
9593 case DT_MIPS_LIBLISTNO:
9594 case DT_MIPS_SYMTABNO:
9595 case DT_MIPS_UNREFEXTNO:
9596 case DT_MIPS_HIPAGENO:
9597 case DT_MIPS_DELTA_CLASS_NO:
9598 case DT_MIPS_DELTA_INSTANCE_NO:
9599 case DT_MIPS_DELTA_RELOC_NO:
9600 case DT_MIPS_DELTA_SYM_NO:
9601 case DT_MIPS_DELTA_CLASSSYM_NO:
9602 case DT_MIPS_COMPACT_SIZE:
c69075ac 9603 print_vma (entry->d_un.d_val, DEC);
252b5132 9604 break;
103f02d3 9605
f16a9783 9606 case DT_MIPS_XHASH:
978c4450
AM
9607 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9608 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9609 /* Falls through. */
9610
103f02d3 9611 default:
4b68bca3 9612 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9613 }
4b68bca3 9614 putchar ('\n');
103f02d3
UD
9615}
9616
103f02d3 9617static void
2cf0635d 9618dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9619{
9620 switch (entry->d_tag)
9621 {
9622 case DT_HP_DLD_FLAGS:
9623 {
9624 static struct
9625 {
9626 long int bit;
2cf0635d 9627 const char * str;
5e220199
NC
9628 }
9629 flags[] =
9630 {
9631 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9632 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9633 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9634 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9635 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9636 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9637 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9638 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9639 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9640 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9641 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9642 { DT_HP_GST, "HP_GST" },
9643 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9644 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9645 { DT_HP_NODELETE, "HP_NODELETE" },
9646 { DT_HP_GROUP, "HP_GROUP" },
9647 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9648 };
32ec8896 9649 bfd_boolean first = TRUE;
5e220199 9650 size_t cnt;
f7a99963 9651 bfd_vma val = entry->d_un.d_val;
103f02d3 9652
60bca95a 9653 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9654 if (val & flags[cnt].bit)
30800947
NC
9655 {
9656 if (! first)
9657 putchar (' ');
9658 fputs (flags[cnt].str, stdout);
32ec8896 9659 first = FALSE;
30800947
NC
9660 val ^= flags[cnt].bit;
9661 }
76da6bbe 9662
103f02d3 9663 if (val != 0 || first)
f7a99963
NC
9664 {
9665 if (! first)
9666 putchar (' ');
9667 print_vma (val, HEX);
9668 }
103f02d3
UD
9669 }
9670 break;
76da6bbe 9671
252b5132 9672 default:
f7a99963
NC
9673 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9674 break;
252b5132 9675 }
35b1837e 9676 putchar ('\n');
252b5132
RH
9677}
9678
28f997cf
TG
9679#ifdef BFD64
9680
9681/* VMS vs Unix time offset and factor. */
9682
9683#define VMS_EPOCH_OFFSET 35067168000000000LL
9684#define VMS_GRANULARITY_FACTOR 10000000
9685
9686/* Display a VMS time in a human readable format. */
9687
9688static void
9689print_vms_time (bfd_int64_t vmstime)
9690{
9691 struct tm *tm;
9692 time_t unxtime;
9693
9694 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9695 tm = gmtime (&unxtime);
9696 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9697 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9698 tm->tm_hour, tm->tm_min, tm->tm_sec);
9699}
9700#endif /* BFD64 */
9701
ecc51f48 9702static void
2cf0635d 9703dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9704{
9705 switch (entry->d_tag)
9706 {
0de14b54 9707 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9708 /* First 3 slots reserved. */
ecc51f48
NC
9709 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9710 printf (" -- ");
9711 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9712 break;
9713
28f997cf
TG
9714 case DT_IA_64_VMS_LINKTIME:
9715#ifdef BFD64
9716 print_vms_time (entry->d_un.d_val);
9717#endif
9718 break;
9719
9720 case DT_IA_64_VMS_LNKFLAGS:
9721 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9722 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9723 printf (" CALL_DEBUG");
9724 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9725 printf (" NOP0BUFS");
9726 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9727 printf (" P0IMAGE");
9728 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9729 printf (" MKTHREADS");
9730 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9731 printf (" UPCALLS");
9732 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9733 printf (" IMGSTA");
9734 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9735 printf (" INITIALIZE");
9736 if (entry->d_un.d_val & VMS_LF_MAIN)
9737 printf (" MAIN");
9738 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9739 printf (" EXE_INIT");
9740 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9741 printf (" TBK_IN_IMG");
9742 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9743 printf (" DBG_IN_IMG");
9744 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9745 printf (" TBK_IN_DSF");
9746 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9747 printf (" DBG_IN_DSF");
9748 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9749 printf (" SIGNATURES");
9750 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9751 printf (" REL_SEG_OFF");
9752 break;
9753
bdf4d63a
JJ
9754 default:
9755 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9756 break;
ecc51f48 9757 }
bdf4d63a 9758 putchar ('\n');
ecc51f48
NC
9759}
9760
32ec8896 9761static bfd_boolean
dda8d76d 9762get_32bit_dynamic_section (Filedata * filedata)
252b5132 9763{
2cf0635d
NC
9764 Elf32_External_Dyn * edyn;
9765 Elf32_External_Dyn * ext;
9766 Elf_Internal_Dyn * entry;
103f02d3 9767
978c4450
AM
9768 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
9769 filedata->dynamic_addr, 1,
9770 filedata->dynamic_size,
9771 _("dynamic section"));
a6e9f9df 9772 if (!edyn)
32ec8896 9773 return FALSE;
103f02d3 9774
071436c6
NC
9775 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9776 might not have the luxury of section headers. Look for the DT_NULL
9777 terminator to determine the number of entries. */
978c4450
AM
9778 for (ext = edyn, filedata->dynamic_nent = 0;
9779 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9780 ext++)
9781 {
978c4450 9782 filedata->dynamic_nent++;
ba2685cc
AM
9783 if (BYTE_GET (ext->d_tag) == DT_NULL)
9784 break;
9785 }
252b5132 9786
978c4450
AM
9787 filedata->dynamic_section
9788 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9789 if (filedata->dynamic_section == NULL)
252b5132 9790 {
8b73c356 9791 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9792 (unsigned long) filedata->dynamic_nent);
9ea033b2 9793 free (edyn);
32ec8896 9794 return FALSE;
9ea033b2 9795 }
252b5132 9796
978c4450
AM
9797 for (ext = edyn, entry = filedata->dynamic_section;
9798 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9799 ext++, entry++)
9ea033b2 9800 {
fb514b26
AM
9801 entry->d_tag = BYTE_GET (ext->d_tag);
9802 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9803 }
9804
9ea033b2
NC
9805 free (edyn);
9806
32ec8896 9807 return TRUE;
9ea033b2
NC
9808}
9809
32ec8896 9810static bfd_boolean
dda8d76d 9811get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9812{
2cf0635d
NC
9813 Elf64_External_Dyn * edyn;
9814 Elf64_External_Dyn * ext;
9815 Elf_Internal_Dyn * entry;
103f02d3 9816
071436c6 9817 /* Read in the data. */
978c4450
AM
9818 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
9819 filedata->dynamic_addr, 1,
9820 filedata->dynamic_size,
9821 _("dynamic section"));
a6e9f9df 9822 if (!edyn)
32ec8896 9823 return FALSE;
103f02d3 9824
071436c6
NC
9825 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9826 might not have the luxury of section headers. Look for the DT_NULL
9827 terminator to determine the number of entries. */
978c4450 9828 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 9829 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 9830 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9831 ext++)
9832 {
978c4450 9833 filedata->dynamic_nent++;
66543521 9834 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9835 break;
9836 }
252b5132 9837
978c4450
AM
9838 filedata->dynamic_section
9839 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9840 if (filedata->dynamic_section == NULL)
252b5132 9841 {
8b73c356 9842 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9843 (unsigned long) filedata->dynamic_nent);
252b5132 9844 free (edyn);
32ec8896 9845 return FALSE;
252b5132
RH
9846 }
9847
071436c6 9848 /* Convert from external to internal formats. */
978c4450
AM
9849 for (ext = edyn, entry = filedata->dynamic_section;
9850 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9851 ext++, entry++)
252b5132 9852 {
66543521
AM
9853 entry->d_tag = BYTE_GET (ext->d_tag);
9854 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9855 }
9856
9857 free (edyn);
9858
32ec8896 9859 return TRUE;
9ea033b2
NC
9860}
9861
e9e44622
JJ
9862static void
9863print_dynamic_flags (bfd_vma flags)
d1133906 9864{
32ec8896 9865 bfd_boolean first = TRUE;
13ae64f3 9866
d1133906
NC
9867 while (flags)
9868 {
9869 bfd_vma flag;
9870
9871 flag = flags & - flags;
9872 flags &= ~ flag;
9873
e9e44622 9874 if (first)
32ec8896 9875 first = FALSE;
e9e44622
JJ
9876 else
9877 putc (' ', stdout);
13ae64f3 9878
d1133906
NC
9879 switch (flag)
9880 {
e9e44622
JJ
9881 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9882 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9883 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9884 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9885 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9886 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9887 }
9888 }
e9e44622 9889 puts ("");
d1133906
NC
9890}
9891
10ca4b04
L
9892static bfd_vma *
9893get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
9894{
9895 unsigned char * e_data;
9896 bfd_vma * i_data;
9897
9898 /* If the size_t type is smaller than the bfd_size_type, eg because
9899 you are building a 32-bit tool on a 64-bit host, then make sure
9900 that when (number) is cast to (size_t) no information is lost. */
9901 if (sizeof (size_t) < sizeof (bfd_size_type)
9902 && (bfd_size_type) ((size_t) number) != number)
9903 {
9904 error (_("Size truncation prevents reading %s elements of size %u\n"),
9905 bfd_vmatoa ("u", number), ent_size);
9906 return NULL;
9907 }
9908
9909 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
9910 attempting to allocate memory when the read is bound to fail. */
9911 if (ent_size * number > filedata->file_size)
9912 {
9913 error (_("Invalid number of dynamic entries: %s\n"),
9914 bfd_vmatoa ("u", number));
9915 return NULL;
9916 }
9917
9918 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
9919 if (e_data == NULL)
9920 {
9921 error (_("Out of memory reading %s dynamic entries\n"),
9922 bfd_vmatoa ("u", number));
9923 return NULL;
9924 }
9925
9926 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
9927 {
9928 error (_("Unable to read in %s bytes of dynamic data\n"),
9929 bfd_vmatoa ("u", number * ent_size));
9930 free (e_data);
9931 return NULL;
9932 }
9933
9934 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
9935 if (i_data == NULL)
9936 {
9937 error (_("Out of memory allocating space for %s dynamic entries\n"),
9938 bfd_vmatoa ("u", number));
9939 free (e_data);
9940 return NULL;
9941 }
9942
9943 while (number--)
9944 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
9945
9946 free (e_data);
9947
9948 return i_data;
9949}
9950
9951static unsigned long
9952get_num_dynamic_syms (Filedata * filedata)
9953{
9954 unsigned long num_of_syms = 0;
9955
9956 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
9957 return num_of_syms;
9958
978c4450 9959 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
9960 {
9961 unsigned char nb[8];
9962 unsigned char nc[8];
9963 unsigned int hash_ent_size = 4;
9964
9965 if ((filedata->file_header.e_machine == EM_ALPHA
9966 || filedata->file_header.e_machine == EM_S390
9967 || filedata->file_header.e_machine == EM_S390_OLD)
9968 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
9969 hash_ent_size = 8;
9970
9971 if (fseek (filedata->handle,
978c4450
AM
9972 (filedata->archive_file_offset
9973 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
9974 sizeof nb + sizeof nc)),
9975 SEEK_SET))
9976 {
9977 error (_("Unable to seek to start of dynamic information\n"));
9978 goto no_hash;
9979 }
9980
9981 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
9982 {
9983 error (_("Failed to read in number of buckets\n"));
9984 goto no_hash;
9985 }
9986
9987 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
9988 {
9989 error (_("Failed to read in number of chains\n"));
9990 goto no_hash;
9991 }
9992
978c4450
AM
9993 filedata->nbuckets = byte_get (nb, hash_ent_size);
9994 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 9995
2482f306
AM
9996 if (filedata->nbuckets != 0 && filedata->nchains != 0)
9997 {
9998 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
9999 hash_ent_size);
10000 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10001 hash_ent_size);
001890e1 10002
2482f306
AM
10003 if (filedata->buckets != NULL && filedata->chains != NULL)
10004 num_of_syms = filedata->nchains;
10005 }
ceb9bf11 10006 no_hash:
10ca4b04
L
10007 if (num_of_syms == 0)
10008 {
978c4450 10009 if (filedata->buckets)
10ca4b04 10010 {
978c4450
AM
10011 free (filedata->buckets);
10012 filedata->buckets = NULL;
10ca4b04 10013 }
978c4450 10014 if (filedata->chains)
10ca4b04 10015 {
978c4450
AM
10016 free (filedata->chains);
10017 filedata->chains = NULL;
10ca4b04 10018 }
978c4450 10019 filedata->nbuckets = 0;
10ca4b04
L
10020 }
10021 }
10022
978c4450 10023 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10024 {
10025 unsigned char nb[16];
10026 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10027 bfd_vma buckets_vma;
10028 unsigned long hn;
10ca4b04
L
10029
10030 if (fseek (filedata->handle,
978c4450
AM
10031 (filedata->archive_file_offset
10032 + offset_from_vma (filedata,
10033 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10034 sizeof nb)),
10035 SEEK_SET))
10036 {
10037 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10038 goto no_gnu_hash;
10039 }
10040
10041 if (fread (nb, 16, 1, filedata->handle) != 1)
10042 {
10043 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10044 goto no_gnu_hash;
10045 }
10046
978c4450
AM
10047 filedata->ngnubuckets = byte_get (nb, 4);
10048 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10049 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10050 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10051 if (is_32bit_elf)
10052 buckets_vma += bitmaskwords * 4;
10053 else
10054 buckets_vma += bitmaskwords * 8;
10055
10056 if (fseek (filedata->handle,
978c4450 10057 (filedata->archive_file_offset
10ca4b04
L
10058 + offset_from_vma (filedata, buckets_vma, 4)),
10059 SEEK_SET))
10060 {
10061 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10062 goto no_gnu_hash;
10063 }
10064
978c4450
AM
10065 filedata->gnubuckets
10066 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10067
978c4450 10068 if (filedata->gnubuckets == NULL)
90837ea7 10069 goto no_gnu_hash;
10ca4b04 10070
978c4450
AM
10071 for (i = 0; i < filedata->ngnubuckets; i++)
10072 if (filedata->gnubuckets[i] != 0)
10ca4b04 10073 {
978c4450 10074 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10075 goto no_gnu_hash;
10ca4b04 10076
978c4450
AM
10077 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10078 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10079 }
10080
10081 if (maxchain == 0xffffffff)
90837ea7 10082 goto no_gnu_hash;
10ca4b04 10083
978c4450 10084 maxchain -= filedata->gnusymidx;
10ca4b04
L
10085
10086 if (fseek (filedata->handle,
978c4450
AM
10087 (filedata->archive_file_offset
10088 + offset_from_vma (filedata,
10089 buckets_vma + 4 * (filedata->ngnubuckets
10090 + maxchain),
10091 4)),
10ca4b04
L
10092 SEEK_SET))
10093 {
10094 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10095 goto no_gnu_hash;
10096 }
10097
10098 do
10099 {
10100 if (fread (nb, 4, 1, filedata->handle) != 1)
10101 {
10102 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10103 goto no_gnu_hash;
10104 }
10105
10106 if (maxchain + 1 == 0)
90837ea7 10107 goto no_gnu_hash;
10ca4b04
L
10108
10109 ++maxchain;
10110 }
10111 while ((byte_get (nb, 4) & 1) == 0);
10112
10113 if (fseek (filedata->handle,
978c4450
AM
10114 (filedata->archive_file_offset
10115 + offset_from_vma (filedata, (buckets_vma
10116 + 4 * filedata->ngnubuckets),
10117 4)),
10ca4b04
L
10118 SEEK_SET))
10119 {
10120 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10121 goto no_gnu_hash;
10122 }
10123
978c4450
AM
10124 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10125 filedata->ngnuchains = maxchain;
10ca4b04 10126
978c4450 10127 if (filedata->gnuchains == NULL)
90837ea7 10128 goto no_gnu_hash;
10ca4b04 10129
978c4450 10130 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10131 {
10132 if (fseek (filedata->handle,
978c4450 10133 (filedata->archive_file_offset
10ca4b04 10134 + offset_from_vma (filedata, (buckets_vma
978c4450 10135 + 4 * (filedata->ngnubuckets
10ca4b04
L
10136 + maxchain)), 4)),
10137 SEEK_SET))
10138 {
10139 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10140 goto no_gnu_hash;
10141 }
10142
978c4450 10143 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10144 if (filedata->mipsxlat == NULL)
10145 goto no_gnu_hash;
10ca4b04
L
10146 }
10147
978c4450
AM
10148 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10149 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10150 {
978c4450
AM
10151 bfd_vma si = filedata->gnubuckets[hn];
10152 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10153
10154 do
10155 {
978c4450 10156 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10157 {
978c4450
AM
10158 if (filedata->mipsxlat[off] >= num_of_syms)
10159 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10160 }
10161 else
10162 {
10163 if (si >= num_of_syms)
10164 num_of_syms = si + 1;
10165 }
10166 si++;
10167 }
978c4450
AM
10168 while (off < filedata->ngnuchains
10169 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10170 }
10171
90837ea7 10172 if (num_of_syms == 0)
10ca4b04 10173 {
90837ea7 10174 no_gnu_hash:
978c4450 10175 if (filedata->mipsxlat)
10ca4b04 10176 {
978c4450
AM
10177 free (filedata->mipsxlat);
10178 filedata->mipsxlat = NULL;
10ca4b04 10179 }
978c4450 10180 if (filedata->gnuchains)
10ca4b04 10181 {
978c4450
AM
10182 free (filedata->gnuchains);
10183 filedata->gnuchains = NULL;
10ca4b04 10184 }
978c4450 10185 if (filedata->gnubuckets)
10ca4b04 10186 {
978c4450
AM
10187 free (filedata->gnubuckets);
10188 filedata->gnubuckets = NULL;
10ca4b04 10189 }
978c4450
AM
10190 filedata->ngnubuckets = 0;
10191 filedata->ngnuchains = 0;
10ca4b04
L
10192 }
10193 }
10194
10195 return num_of_syms;
10196}
10197
b2d38a17
NC
10198/* Parse and display the contents of the dynamic section. */
10199
32ec8896 10200static bfd_boolean
dda8d76d 10201process_dynamic_section (Filedata * filedata)
9ea033b2 10202{
2cf0635d 10203 Elf_Internal_Dyn * entry;
9ea033b2 10204
978c4450 10205 if (filedata->dynamic_size == 0)
9ea033b2
NC
10206 {
10207 if (do_dynamic)
b2d38a17 10208 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 10209
32ec8896 10210 return TRUE;
9ea033b2
NC
10211 }
10212
10213 if (is_32bit_elf)
10214 {
dda8d76d 10215 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10216 return FALSE;
10217 }
10218 else
10219 {
dda8d76d 10220 if (! get_64bit_dynamic_section (filedata))
32ec8896 10221 return FALSE;
9ea033b2 10222 }
9ea033b2 10223
252b5132 10224 /* Find the appropriate symbol table. */
978c4450 10225 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10226 {
2482f306
AM
10227 unsigned long num_of_syms;
10228
978c4450
AM
10229 for (entry = filedata->dynamic_section;
10230 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10231 ++entry)
10ca4b04 10232 if (entry->d_tag == DT_SYMTAB)
978c4450 10233 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10234 else if (entry->d_tag == DT_SYMENT)
978c4450 10235 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10236 else if (entry->d_tag == DT_HASH)
978c4450 10237 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10238 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10239 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10240 else if ((filedata->file_header.e_machine == EM_MIPS
10241 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10242 && entry->d_tag == DT_MIPS_XHASH)
10243 {
978c4450
AM
10244 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10245 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10246 }
252b5132 10247
2482f306
AM
10248 num_of_syms = get_num_dynamic_syms (filedata);
10249
10250 if (num_of_syms != 0
10251 && filedata->dynamic_symbols == NULL
10252 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10253 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10254 {
10255 Elf_Internal_Phdr *seg;
2482f306 10256 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10257
2482f306
AM
10258 if (! get_program_headers (filedata))
10259 {
10260 error (_("Cannot interpret virtual addresses "
10261 "without program headers.\n"));
10262 return FALSE;
10263 }
252b5132 10264
2482f306
AM
10265 for (seg = filedata->program_headers;
10266 seg < filedata->program_headers + filedata->file_header.e_phnum;
10267 ++seg)
10268 {
10269 if (seg->p_type != PT_LOAD)
10270 continue;
252b5132 10271
2482f306
AM
10272 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10273 {
10274 /* See PR 21379 for a reproducer. */
10275 error (_("Invalid PT_LOAD entry\n"));
10276 return FALSE;
10277 }
252b5132 10278
2482f306
AM
10279 if (vma >= (seg->p_vaddr & -seg->p_align)
10280 && vma < seg->p_vaddr + seg->p_filesz)
10281 {
10282 /* Since we do not know how big the symbol table is,
10283 we default to reading in up to the end of PT_LOAD
10284 segment and processing that. This is overkill, I
10285 know, but it should work. */
10286 Elf_Internal_Shdr section;
10287 section.sh_offset = (vma - seg->p_vaddr
10288 + seg->p_offset);
10289 section.sh_size = (num_of_syms
10290 * filedata->dynamic_info[DT_SYMENT]);
10291 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
10292 section.sh_name = filedata->string_table_length;
10293 filedata->dynamic_symbols
10294 = GET_ELF_SYMBOLS (filedata, &section,
10295 &filedata->num_dynamic_syms);
10296 if (filedata->dynamic_symbols == NULL
10297 || filedata->num_dynamic_syms != num_of_syms)
10298 {
10299 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10300 return FALSE;
10301 }
10302 break;
10303 }
10304 }
10305 }
10306 }
252b5132
RH
10307
10308 /* Similarly find a string table. */
978c4450
AM
10309 if (filedata->dynamic_strings == NULL)
10310 for (entry = filedata->dynamic_section;
10311 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10312 ++entry)
10313 {
10314 if (entry->d_tag == DT_STRTAB)
978c4450 10315 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10316
10ca4b04 10317 if (entry->d_tag == DT_STRSZ)
978c4450 10318 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10319
978c4450
AM
10320 if (filedata->dynamic_info[DT_STRTAB]
10321 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10322 {
10323 unsigned long offset;
978c4450 10324 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10325
10326 offset = offset_from_vma (filedata,
978c4450 10327 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10328 str_tab_len);
978c4450
AM
10329 filedata->dynamic_strings
10330 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10331 _("dynamic string table"));
10332 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10333 {
10334 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10335 break;
10336 }
e3d39609 10337
978c4450 10338 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10339 break;
10340 }
10341 }
252b5132
RH
10342
10343 /* And find the syminfo section if available. */
978c4450 10344 if (filedata->dynamic_syminfo == NULL)
252b5132 10345 {
3e8bba36 10346 unsigned long syminsz = 0;
252b5132 10347
978c4450
AM
10348 for (entry = filedata->dynamic_section;
10349 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10350 ++entry)
252b5132
RH
10351 {
10352 if (entry->d_tag == DT_SYMINENT)
10353 {
10354 /* Note: these braces are necessary to avoid a syntax
10355 error from the SunOS4 C compiler. */
049b0c3a
NC
10356 /* PR binutils/17531: A corrupt file can trigger this test.
10357 So do not use an assert, instead generate an error message. */
10358 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10359 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10360 (int) entry->d_un.d_val);
252b5132
RH
10361 }
10362 else if (entry->d_tag == DT_SYMINSZ)
10363 syminsz = entry->d_un.d_val;
10364 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10365 filedata->dynamic_syminfo_offset
10366 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10367 }
10368
978c4450 10369 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10370 {
2cf0635d
NC
10371 Elf_External_Syminfo * extsyminfo;
10372 Elf_External_Syminfo * extsym;
10373 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10374
10375 /* There is a syminfo section. Read the data. */
3f5e193b 10376 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10377 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10378 1, syminsz, _("symbol information"));
a6e9f9df 10379 if (!extsyminfo)
32ec8896 10380 return FALSE;
252b5132 10381
978c4450 10382 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10383 {
10384 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10385 free (filedata->dynamic_syminfo);
e3d39609 10386 }
978c4450
AM
10387 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10388 if (filedata->dynamic_syminfo == NULL)
252b5132 10389 {
2482f306
AM
10390 error (_("Out of memory allocating %lu bytes "
10391 "for dynamic symbol info\n"),
8b73c356 10392 (unsigned long) syminsz);
32ec8896 10393 return FALSE;
252b5132
RH
10394 }
10395
2482f306
AM
10396 filedata->dynamic_syminfo_nent
10397 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10398 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10399 syminfo < (filedata->dynamic_syminfo
10400 + filedata->dynamic_syminfo_nent);
86dba8ee 10401 ++syminfo, ++extsym)
252b5132 10402 {
86dba8ee
AM
10403 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10404 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10405 }
10406
10407 free (extsyminfo);
10408 }
10409 }
10410
978c4450 10411 if (do_dynamic && filedata->dynamic_addr)
d3a49aa8
AM
10412 printf (ngettext ("\nDynamic section at offset 0x%lx "
10413 "contains %lu entry:\n",
10414 "\nDynamic section at offset 0x%lx "
10415 "contains %lu entries:\n",
978c4450
AM
10416 filedata->dynamic_nent),
10417 filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent);
252b5132
RH
10418 if (do_dynamic)
10419 printf (_(" Tag Type Name/Value\n"));
10420
978c4450
AM
10421 for (entry = filedata->dynamic_section;
10422 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10423 entry++)
252b5132
RH
10424 {
10425 if (do_dynamic)
f7a99963 10426 {
2cf0635d 10427 const char * dtype;
e699b9ff 10428
f7a99963
NC
10429 putchar (' ');
10430 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10431 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10432 printf (" (%s)%*s", dtype,
32ec8896 10433 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10434 }
252b5132
RH
10435
10436 switch (entry->d_tag)
10437 {
d1133906
NC
10438 case DT_FLAGS:
10439 if (do_dynamic)
e9e44622 10440 print_dynamic_flags (entry->d_un.d_val);
d1133906 10441 break;
76da6bbe 10442
252b5132
RH
10443 case DT_AUXILIARY:
10444 case DT_FILTER:
019148e4
L
10445 case DT_CONFIG:
10446 case DT_DEPAUDIT:
10447 case DT_AUDIT:
252b5132
RH
10448 if (do_dynamic)
10449 {
019148e4 10450 switch (entry->d_tag)
b34976b6 10451 {
019148e4
L
10452 case DT_AUXILIARY:
10453 printf (_("Auxiliary library"));
10454 break;
10455
10456 case DT_FILTER:
10457 printf (_("Filter library"));
10458 break;
10459
b34976b6 10460 case DT_CONFIG:
019148e4
L
10461 printf (_("Configuration file"));
10462 break;
10463
10464 case DT_DEPAUDIT:
10465 printf (_("Dependency audit library"));
10466 break;
10467
10468 case DT_AUDIT:
10469 printf (_("Audit library"));
10470 break;
10471 }
252b5132 10472
978c4450
AM
10473 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10474 printf (": [%s]\n",
10475 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10476 else
f7a99963
NC
10477 {
10478 printf (": ");
10479 print_vma (entry->d_un.d_val, PREFIX_HEX);
10480 putchar ('\n');
10481 }
252b5132
RH
10482 }
10483 break;
10484
dcefbbbd 10485 case DT_FEATURE:
252b5132
RH
10486 if (do_dynamic)
10487 {
10488 printf (_("Flags:"));
86f55779 10489
252b5132
RH
10490 if (entry->d_un.d_val == 0)
10491 printf (_(" None\n"));
10492 else
10493 {
10494 unsigned long int val = entry->d_un.d_val;
86f55779 10495
252b5132
RH
10496 if (val & DTF_1_PARINIT)
10497 {
10498 printf (" PARINIT");
10499 val ^= DTF_1_PARINIT;
10500 }
dcefbbbd
L
10501 if (val & DTF_1_CONFEXP)
10502 {
10503 printf (" CONFEXP");
10504 val ^= DTF_1_CONFEXP;
10505 }
252b5132
RH
10506 if (val != 0)
10507 printf (" %lx", val);
10508 puts ("");
10509 }
10510 }
10511 break;
10512
10513 case DT_POSFLAG_1:
10514 if (do_dynamic)
10515 {
10516 printf (_("Flags:"));
86f55779 10517
252b5132
RH
10518 if (entry->d_un.d_val == 0)
10519 printf (_(" None\n"));
10520 else
10521 {
10522 unsigned long int val = entry->d_un.d_val;
86f55779 10523
252b5132
RH
10524 if (val & DF_P1_LAZYLOAD)
10525 {
10526 printf (" LAZYLOAD");
10527 val ^= DF_P1_LAZYLOAD;
10528 }
10529 if (val & DF_P1_GROUPPERM)
10530 {
10531 printf (" GROUPPERM");
10532 val ^= DF_P1_GROUPPERM;
10533 }
10534 if (val != 0)
10535 printf (" %lx", val);
10536 puts ("");
10537 }
10538 }
10539 break;
10540
10541 case DT_FLAGS_1:
10542 if (do_dynamic)
10543 {
10544 printf (_("Flags:"));
10545 if (entry->d_un.d_val == 0)
10546 printf (_(" None\n"));
10547 else
10548 {
10549 unsigned long int val = entry->d_un.d_val;
86f55779 10550
252b5132
RH
10551 if (val & DF_1_NOW)
10552 {
10553 printf (" NOW");
10554 val ^= DF_1_NOW;
10555 }
10556 if (val & DF_1_GLOBAL)
10557 {
10558 printf (" GLOBAL");
10559 val ^= DF_1_GLOBAL;
10560 }
10561 if (val & DF_1_GROUP)
10562 {
10563 printf (" GROUP");
10564 val ^= DF_1_GROUP;
10565 }
10566 if (val & DF_1_NODELETE)
10567 {
10568 printf (" NODELETE");
10569 val ^= DF_1_NODELETE;
10570 }
10571 if (val & DF_1_LOADFLTR)
10572 {
10573 printf (" LOADFLTR");
10574 val ^= DF_1_LOADFLTR;
10575 }
10576 if (val & DF_1_INITFIRST)
10577 {
10578 printf (" INITFIRST");
10579 val ^= DF_1_INITFIRST;
10580 }
10581 if (val & DF_1_NOOPEN)
10582 {
10583 printf (" NOOPEN");
10584 val ^= DF_1_NOOPEN;
10585 }
10586 if (val & DF_1_ORIGIN)
10587 {
10588 printf (" ORIGIN");
10589 val ^= DF_1_ORIGIN;
10590 }
10591 if (val & DF_1_DIRECT)
10592 {
10593 printf (" DIRECT");
10594 val ^= DF_1_DIRECT;
10595 }
10596 if (val & DF_1_TRANS)
10597 {
10598 printf (" TRANS");
10599 val ^= DF_1_TRANS;
10600 }
10601 if (val & DF_1_INTERPOSE)
10602 {
10603 printf (" INTERPOSE");
10604 val ^= DF_1_INTERPOSE;
10605 }
f7db6139 10606 if (val & DF_1_NODEFLIB)
dcefbbbd 10607 {
f7db6139
L
10608 printf (" NODEFLIB");
10609 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10610 }
10611 if (val & DF_1_NODUMP)
10612 {
10613 printf (" NODUMP");
10614 val ^= DF_1_NODUMP;
10615 }
34b60028 10616 if (val & DF_1_CONFALT)
dcefbbbd 10617 {
34b60028
L
10618 printf (" CONFALT");
10619 val ^= DF_1_CONFALT;
10620 }
10621 if (val & DF_1_ENDFILTEE)
10622 {
10623 printf (" ENDFILTEE");
10624 val ^= DF_1_ENDFILTEE;
10625 }
10626 if (val & DF_1_DISPRELDNE)
10627 {
10628 printf (" DISPRELDNE");
10629 val ^= DF_1_DISPRELDNE;
10630 }
10631 if (val & DF_1_DISPRELPND)
10632 {
10633 printf (" DISPRELPND");
10634 val ^= DF_1_DISPRELPND;
10635 }
10636 if (val & DF_1_NODIRECT)
10637 {
10638 printf (" NODIRECT");
10639 val ^= DF_1_NODIRECT;
10640 }
10641 if (val & DF_1_IGNMULDEF)
10642 {
10643 printf (" IGNMULDEF");
10644 val ^= DF_1_IGNMULDEF;
10645 }
10646 if (val & DF_1_NOKSYMS)
10647 {
10648 printf (" NOKSYMS");
10649 val ^= DF_1_NOKSYMS;
10650 }
10651 if (val & DF_1_NOHDR)
10652 {
10653 printf (" NOHDR");
10654 val ^= DF_1_NOHDR;
10655 }
10656 if (val & DF_1_EDITED)
10657 {
10658 printf (" EDITED");
10659 val ^= DF_1_EDITED;
10660 }
10661 if (val & DF_1_NORELOC)
10662 {
10663 printf (" NORELOC");
10664 val ^= DF_1_NORELOC;
10665 }
10666 if (val & DF_1_SYMINTPOSE)
10667 {
10668 printf (" SYMINTPOSE");
10669 val ^= DF_1_SYMINTPOSE;
10670 }
10671 if (val & DF_1_GLOBAUDIT)
10672 {
10673 printf (" GLOBAUDIT");
10674 val ^= DF_1_GLOBAUDIT;
10675 }
10676 if (val & DF_1_SINGLETON)
10677 {
10678 printf (" SINGLETON");
10679 val ^= DF_1_SINGLETON;
dcefbbbd 10680 }
5c383f02
RO
10681 if (val & DF_1_STUB)
10682 {
10683 printf (" STUB");
10684 val ^= DF_1_STUB;
10685 }
10686 if (val & DF_1_PIE)
10687 {
10688 printf (" PIE");
10689 val ^= DF_1_PIE;
10690 }
b1202ffa
L
10691 if (val & DF_1_KMOD)
10692 {
10693 printf (" KMOD");
10694 val ^= DF_1_KMOD;
10695 }
10696 if (val & DF_1_WEAKFILTER)
10697 {
10698 printf (" WEAKFILTER");
10699 val ^= DF_1_WEAKFILTER;
10700 }
10701 if (val & DF_1_NOCOMMON)
10702 {
10703 printf (" NOCOMMON");
10704 val ^= DF_1_NOCOMMON;
10705 }
252b5132
RH
10706 if (val != 0)
10707 printf (" %lx", val);
10708 puts ("");
10709 }
10710 }
10711 break;
10712
10713 case DT_PLTREL:
978c4450 10714 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10715 if (do_dynamic)
dda8d76d 10716 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10717 break;
10718
10719 case DT_NULL :
10720 case DT_NEEDED :
10721 case DT_PLTGOT :
10722 case DT_HASH :
10723 case DT_STRTAB :
10724 case DT_SYMTAB :
10725 case DT_RELA :
10726 case DT_INIT :
10727 case DT_FINI :
10728 case DT_SONAME :
10729 case DT_RPATH :
10730 case DT_SYMBOLIC:
10731 case DT_REL :
10732 case DT_DEBUG :
10733 case DT_TEXTREL :
10734 case DT_JMPREL :
019148e4 10735 case DT_RUNPATH :
978c4450 10736 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
10737
10738 if (do_dynamic)
10739 {
2cf0635d 10740 char * name;
252b5132 10741
978c4450
AM
10742 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10743 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10744 else
d79b3d50 10745 name = NULL;
252b5132
RH
10746
10747 if (name)
10748 {
10749 switch (entry->d_tag)
10750 {
10751 case DT_NEEDED:
10752 printf (_("Shared library: [%s]"), name);
10753
978c4450 10754 if (streq (name, filedata->program_interpreter))
f7a99963 10755 printf (_(" program interpreter"));
252b5132
RH
10756 break;
10757
10758 case DT_SONAME:
f7a99963 10759 printf (_("Library soname: [%s]"), name);
252b5132
RH
10760 break;
10761
10762 case DT_RPATH:
f7a99963 10763 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10764 break;
10765
019148e4
L
10766 case DT_RUNPATH:
10767 printf (_("Library runpath: [%s]"), name);
10768 break;
10769
252b5132 10770 default:
f7a99963
NC
10771 print_vma (entry->d_un.d_val, PREFIX_HEX);
10772 break;
252b5132
RH
10773 }
10774 }
10775 else
f7a99963
NC
10776 print_vma (entry->d_un.d_val, PREFIX_HEX);
10777
10778 putchar ('\n');
252b5132
RH
10779 }
10780 break;
10781
10782 case DT_PLTRELSZ:
10783 case DT_RELASZ :
10784 case DT_STRSZ :
10785 case DT_RELSZ :
10786 case DT_RELAENT :
10787 case DT_SYMENT :
10788 case DT_RELENT :
978c4450 10789 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10790 /* Fall through. */
252b5132
RH
10791 case DT_PLTPADSZ:
10792 case DT_MOVEENT :
10793 case DT_MOVESZ :
10794 case DT_INIT_ARRAYSZ:
10795 case DT_FINI_ARRAYSZ:
047b2264
JJ
10796 case DT_GNU_CONFLICTSZ:
10797 case DT_GNU_LIBLISTSZ:
252b5132 10798 if (do_dynamic)
f7a99963
NC
10799 {
10800 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10801 printf (_(" (bytes)\n"));
f7a99963 10802 }
252b5132
RH
10803 break;
10804
10805 case DT_VERDEFNUM:
10806 case DT_VERNEEDNUM:
10807 case DT_RELACOUNT:
10808 case DT_RELCOUNT:
10809 if (do_dynamic)
f7a99963
NC
10810 {
10811 print_vma (entry->d_un.d_val, UNSIGNED);
10812 putchar ('\n');
10813 }
252b5132
RH
10814 break;
10815
10816 case DT_SYMINSZ:
10817 case DT_SYMINENT:
10818 case DT_SYMINFO:
10819 case DT_USED:
10820 case DT_INIT_ARRAY:
10821 case DT_FINI_ARRAY:
10822 if (do_dynamic)
10823 {
d79b3d50 10824 if (entry->d_tag == DT_USED
978c4450 10825 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 10826 {
978c4450 10827 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10828
b34976b6 10829 if (*name)
252b5132
RH
10830 {
10831 printf (_("Not needed object: [%s]\n"), name);
10832 break;
10833 }
10834 }
103f02d3 10835
f7a99963
NC
10836 print_vma (entry->d_un.d_val, PREFIX_HEX);
10837 putchar ('\n');
252b5132
RH
10838 }
10839 break;
10840
10841 case DT_BIND_NOW:
10842 /* The value of this entry is ignored. */
35b1837e
AM
10843 if (do_dynamic)
10844 putchar ('\n');
252b5132 10845 break;
103f02d3 10846
047b2264
JJ
10847 case DT_GNU_PRELINKED:
10848 if (do_dynamic)
10849 {
2cf0635d 10850 struct tm * tmp;
91d6fa6a 10851 time_t atime = entry->d_un.d_val;
047b2264 10852
91d6fa6a 10853 tmp = gmtime (&atime);
071436c6
NC
10854 /* PR 17533 file: 041-1244816-0.004. */
10855 if (tmp == NULL)
5a2cbcf4
L
10856 printf (_("<corrupt time val: %lx"),
10857 (unsigned long) atime);
071436c6
NC
10858 else
10859 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10860 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10861 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10862
10863 }
10864 break;
10865
fdc90cb4 10866 case DT_GNU_HASH:
978c4450 10867 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
10868 if (do_dynamic)
10869 {
10870 print_vma (entry->d_un.d_val, PREFIX_HEX);
10871 putchar ('\n');
10872 }
10873 break;
10874
252b5132
RH
10875 default:
10876 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
10877 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
10878 = entry->d_un.d_val;
252b5132
RH
10879
10880 if (do_dynamic)
10881 {
dda8d76d 10882 switch (filedata->file_header.e_machine)
252b5132 10883 {
37c18eed
SD
10884 case EM_AARCH64:
10885 dynamic_section_aarch64_val (entry);
10886 break;
252b5132 10887 case EM_MIPS:
4fe85591 10888 case EM_MIPS_RS3_LE:
978c4450 10889 dynamic_section_mips_val (filedata, entry);
252b5132 10890 break;
103f02d3 10891 case EM_PARISC:
b2d38a17 10892 dynamic_section_parisc_val (entry);
103f02d3 10893 break;
ecc51f48 10894 case EM_IA_64:
b2d38a17 10895 dynamic_section_ia64_val (entry);
ecc51f48 10896 break;
252b5132 10897 default:
f7a99963
NC
10898 print_vma (entry->d_un.d_val, PREFIX_HEX);
10899 putchar ('\n');
252b5132
RH
10900 }
10901 }
10902 break;
10903 }
10904 }
10905
32ec8896 10906 return TRUE;
252b5132
RH
10907}
10908
10909static char *
d3ba0551 10910get_ver_flags (unsigned int flags)
252b5132 10911{
6d4f21f6 10912 static char buff[128];
252b5132
RH
10913
10914 buff[0] = 0;
10915
10916 if (flags == 0)
10917 return _("none");
10918
10919 if (flags & VER_FLG_BASE)
7bb1ad17 10920 strcat (buff, "BASE");
252b5132
RH
10921
10922 if (flags & VER_FLG_WEAK)
10923 {
10924 if (flags & VER_FLG_BASE)
7bb1ad17 10925 strcat (buff, " | ");
252b5132 10926
7bb1ad17 10927 strcat (buff, "WEAK");
252b5132
RH
10928 }
10929
44ec90b9
RO
10930 if (flags & VER_FLG_INFO)
10931 {
10932 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 10933 strcat (buff, " | ");
44ec90b9 10934
7bb1ad17 10935 strcat (buff, "INFO");
44ec90b9
RO
10936 }
10937
10938 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
10939 {
10940 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
10941 strcat (buff, " | ");
10942
10943 strcat (buff, _("<unknown>"));
10944 }
252b5132
RH
10945
10946 return buff;
10947}
10948
10949/* Display the contents of the version sections. */
98fb390a 10950
32ec8896 10951static bfd_boolean
dda8d76d 10952process_version_sections (Filedata * filedata)
252b5132 10953{
2cf0635d 10954 Elf_Internal_Shdr * section;
b34976b6 10955 unsigned i;
32ec8896 10956 bfd_boolean found = FALSE;
252b5132
RH
10957
10958 if (! do_version)
32ec8896 10959 return TRUE;
252b5132 10960
dda8d76d
NC
10961 for (i = 0, section = filedata->section_headers;
10962 i < filedata->file_header.e_shnum;
b34976b6 10963 i++, section++)
252b5132
RH
10964 {
10965 switch (section->sh_type)
10966 {
10967 case SHT_GNU_verdef:
10968 {
2cf0635d 10969 Elf_External_Verdef * edefs;
452bf675
AM
10970 unsigned long idx;
10971 unsigned long cnt;
2cf0635d 10972 char * endbuf;
252b5132 10973
32ec8896 10974 found = TRUE;
252b5132 10975
d3a49aa8
AM
10976 printf (ngettext ("\nVersion definition section '%s' "
10977 "contains %u entry:\n",
10978 "\nVersion definition section '%s' "
10979 "contains %u entries:\n",
10980 section->sh_info),
dda8d76d 10981 printable_section_name (filedata, section),
74e1a04b 10982 section->sh_info);
252b5132 10983
ae9ac79e 10984 printf (_(" Addr: 0x"));
252b5132 10985 printf_vma (section->sh_addr);
233f82cf 10986 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10987 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10988 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10989
3f5e193b 10990 edefs = (Elf_External_Verdef *)
dda8d76d 10991 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 10992 _("version definition section"));
a6e9f9df
AM
10993 if (!edefs)
10994 break;
59245841 10995 endbuf = (char *) edefs + section->sh_size;
252b5132 10996
1445030f 10997 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 10998 {
2cf0635d
NC
10999 char * vstart;
11000 Elf_External_Verdef * edef;
b34976b6 11001 Elf_Internal_Verdef ent;
2cf0635d 11002 Elf_External_Verdaux * eaux;
b34976b6 11003 Elf_Internal_Verdaux aux;
452bf675 11004 unsigned long isum;
b34976b6 11005 int j;
103f02d3 11006
252b5132 11007 vstart = ((char *) edefs) + idx;
54806181
AM
11008 if (vstart + sizeof (*edef) > endbuf)
11009 break;
252b5132
RH
11010
11011 edef = (Elf_External_Verdef *) vstart;
11012
11013 ent.vd_version = BYTE_GET (edef->vd_version);
11014 ent.vd_flags = BYTE_GET (edef->vd_flags);
11015 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11016 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11017 ent.vd_hash = BYTE_GET (edef->vd_hash);
11018 ent.vd_aux = BYTE_GET (edef->vd_aux);
11019 ent.vd_next = BYTE_GET (edef->vd_next);
11020
452bf675 11021 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11022 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11023
11024 printf (_(" Index: %d Cnt: %d "),
11025 ent.vd_ndx, ent.vd_cnt);
11026
452bf675 11027 /* Check for overflow. */
1445030f 11028 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11029 break;
11030
252b5132
RH
11031 vstart += ent.vd_aux;
11032
1445030f
AM
11033 if (vstart + sizeof (*eaux) > endbuf)
11034 break;
252b5132
RH
11035 eaux = (Elf_External_Verdaux *) vstart;
11036
11037 aux.vda_name = BYTE_GET (eaux->vda_name);
11038 aux.vda_next = BYTE_GET (eaux->vda_next);
11039
978c4450
AM
11040 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11041 printf (_("Name: %s\n"),
11042 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11043 else
11044 printf (_("Name index: %ld\n"), aux.vda_name);
11045
11046 isum = idx + ent.vd_aux;
11047
b34976b6 11048 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11049 {
1445030f
AM
11050 if (aux.vda_next < sizeof (*eaux)
11051 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11052 {
11053 warn (_("Invalid vda_next field of %lx\n"),
11054 aux.vda_next);
11055 j = ent.vd_cnt;
11056 break;
11057 }
dd24e3da 11058 /* Check for overflow. */
7e26601c 11059 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11060 break;
11061
252b5132
RH
11062 isum += aux.vda_next;
11063 vstart += aux.vda_next;
11064
54806181
AM
11065 if (vstart + sizeof (*eaux) > endbuf)
11066 break;
1445030f 11067 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11068
11069 aux.vda_name = BYTE_GET (eaux->vda_name);
11070 aux.vda_next = BYTE_GET (eaux->vda_next);
11071
978c4450 11072 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11073 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11074 isum, j,
11075 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11076 else
452bf675 11077 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11078 isum, j, aux.vda_name);
11079 }
dd24e3da 11080
54806181
AM
11081 if (j < ent.vd_cnt)
11082 printf (_(" Version def aux past end of section\n"));
252b5132 11083
c9f02c3e
MR
11084 /* PR 17531:
11085 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11086 if (ent.vd_next < sizeof (*edef)
11087 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11088 {
11089 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11090 cnt = section->sh_info;
11091 break;
11092 }
452bf675 11093 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11094 break;
11095
252b5132
RH
11096 idx += ent.vd_next;
11097 }
dd24e3da 11098
54806181
AM
11099 if (cnt < section->sh_info)
11100 printf (_(" Version definition past end of section\n"));
252b5132
RH
11101
11102 free (edefs);
11103 }
11104 break;
103f02d3 11105
252b5132
RH
11106 case SHT_GNU_verneed:
11107 {
2cf0635d 11108 Elf_External_Verneed * eneed;
452bf675
AM
11109 unsigned long idx;
11110 unsigned long cnt;
2cf0635d 11111 char * endbuf;
252b5132 11112
32ec8896 11113 found = TRUE;
252b5132 11114
d3a49aa8
AM
11115 printf (ngettext ("\nVersion needs section '%s' "
11116 "contains %u entry:\n",
11117 "\nVersion needs section '%s' "
11118 "contains %u entries:\n",
11119 section->sh_info),
dda8d76d 11120 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11121
11122 printf (_(" Addr: 0x"));
11123 printf_vma (section->sh_addr);
72de5009 11124 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11125 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11126 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11127
dda8d76d 11128 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11129 section->sh_offset, 1,
11130 section->sh_size,
9cf03b7e 11131 _("Version Needs section"));
a6e9f9df
AM
11132 if (!eneed)
11133 break;
59245841 11134 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11135
11136 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11137 {
2cf0635d 11138 Elf_External_Verneed * entry;
b34976b6 11139 Elf_Internal_Verneed ent;
452bf675 11140 unsigned long isum;
b34976b6 11141 int j;
2cf0635d 11142 char * vstart;
252b5132
RH
11143
11144 vstart = ((char *) eneed) + idx;
54806181
AM
11145 if (vstart + sizeof (*entry) > endbuf)
11146 break;
252b5132
RH
11147
11148 entry = (Elf_External_Verneed *) vstart;
11149
11150 ent.vn_version = BYTE_GET (entry->vn_version);
11151 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11152 ent.vn_file = BYTE_GET (entry->vn_file);
11153 ent.vn_aux = BYTE_GET (entry->vn_aux);
11154 ent.vn_next = BYTE_GET (entry->vn_next);
11155
452bf675 11156 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11157
978c4450
AM
11158 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11159 printf (_(" File: %s"),
11160 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11161 else
11162 printf (_(" File: %lx"), ent.vn_file);
11163
11164 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11165
dd24e3da 11166 /* Check for overflow. */
7e26601c 11167 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11168 break;
252b5132
RH
11169 vstart += ent.vn_aux;
11170
11171 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11172 {
2cf0635d 11173 Elf_External_Vernaux * eaux;
b34976b6 11174 Elf_Internal_Vernaux aux;
252b5132 11175
54806181
AM
11176 if (vstart + sizeof (*eaux) > endbuf)
11177 break;
252b5132
RH
11178 eaux = (Elf_External_Vernaux *) vstart;
11179
11180 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11181 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11182 aux.vna_other = BYTE_GET (eaux->vna_other);
11183 aux.vna_name = BYTE_GET (eaux->vna_name);
11184 aux.vna_next = BYTE_GET (eaux->vna_next);
11185
978c4450 11186 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11187 printf (_(" %#06lx: Name: %s"),
978c4450 11188 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11189 else
452bf675 11190 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11191 isum, aux.vna_name);
11192
11193 printf (_(" Flags: %s Version: %d\n"),
11194 get_ver_flags (aux.vna_flags), aux.vna_other);
11195
1445030f
AM
11196 if (aux.vna_next < sizeof (*eaux)
11197 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11198 {
11199 warn (_("Invalid vna_next field of %lx\n"),
11200 aux.vna_next);
11201 j = ent.vn_cnt;
11202 break;
11203 }
1445030f
AM
11204 /* Check for overflow. */
11205 if (aux.vna_next > (size_t) (endbuf - vstart))
11206 break;
252b5132
RH
11207 isum += aux.vna_next;
11208 vstart += aux.vna_next;
11209 }
9cf03b7e 11210
54806181 11211 if (j < ent.vn_cnt)
9cf03b7e 11212 warn (_("Missing Version Needs auxillary information\n"));
252b5132 11213
1445030f
AM
11214 if (ent.vn_next < sizeof (*entry)
11215 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11216 {
452bf675 11217 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11218 cnt = section->sh_info;
11219 break;
11220 }
1445030f
AM
11221 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11222 break;
252b5132
RH
11223 idx += ent.vn_next;
11224 }
9cf03b7e 11225
54806181 11226 if (cnt < section->sh_info)
9cf03b7e 11227 warn (_("Missing Version Needs information\n"));
103f02d3 11228
252b5132
RH
11229 free (eneed);
11230 }
11231 break;
11232
11233 case SHT_GNU_versym:
11234 {
2cf0635d 11235 Elf_Internal_Shdr * link_section;
8b73c356
NC
11236 size_t total;
11237 unsigned int cnt;
2cf0635d
NC
11238 unsigned char * edata;
11239 unsigned short * data;
11240 char * strtab;
11241 Elf_Internal_Sym * symbols;
11242 Elf_Internal_Shdr * string_sec;
ba5cdace 11243 unsigned long num_syms;
d3ba0551 11244 long off;
252b5132 11245
dda8d76d 11246 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11247 break;
11248
dda8d76d 11249 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11250 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11251
dda8d76d 11252 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11253 break;
11254
32ec8896 11255 found = TRUE;
252b5132 11256
dda8d76d 11257 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11258 if (symbols == NULL)
11259 break;
252b5132 11260
dda8d76d 11261 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11262
dda8d76d 11263 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11264 string_sec->sh_size,
11265 _("version string table"));
a6e9f9df 11266 if (!strtab)
0429c154
MS
11267 {
11268 free (symbols);
11269 break;
11270 }
252b5132 11271
d3a49aa8
AM
11272 printf (ngettext ("\nVersion symbols section '%s' "
11273 "contains %lu entry:\n",
11274 "\nVersion symbols section '%s' "
11275 "contains %lu entries:\n",
11276 total),
dda8d76d 11277 printable_section_name (filedata, section), (unsigned long) total);
252b5132 11278
ae9ac79e 11279 printf (_(" Addr: 0x"));
252b5132 11280 printf_vma (section->sh_addr);
72de5009 11281 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11282 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11283 printable_section_name (filedata, link_section));
252b5132 11284
dda8d76d 11285 off = offset_from_vma (filedata,
978c4450 11286 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11287 total * sizeof (short));
95099889
AM
11288 edata = (unsigned char *) get_data (NULL, filedata, off,
11289 sizeof (short), total,
11290 _("version symbol data"));
a6e9f9df
AM
11291 if (!edata)
11292 {
11293 free (strtab);
0429c154 11294 free (symbols);
a6e9f9df
AM
11295 break;
11296 }
252b5132 11297
3f5e193b 11298 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11299
11300 for (cnt = total; cnt --;)
b34976b6
AM
11301 data[cnt] = byte_get (edata + cnt * sizeof (short),
11302 sizeof (short));
252b5132
RH
11303
11304 free (edata);
11305
11306 for (cnt = 0; cnt < total; cnt += 4)
11307 {
11308 int j, nn;
ab273396
AM
11309 char *name;
11310 char *invalid = _("*invalid*");
252b5132
RH
11311
11312 printf (" %03x:", cnt);
11313
11314 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11315 switch (data[cnt + j])
252b5132
RH
11316 {
11317 case 0:
11318 fputs (_(" 0 (*local*) "), stdout);
11319 break;
11320
11321 case 1:
11322 fputs (_(" 1 (*global*) "), stdout);
11323 break;
11324
11325 default:
c244d050
NC
11326 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11327 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11328
dd24e3da 11329 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11330 array, break to avoid an out-of-bounds read. */
11331 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11332 {
11333 warn (_("invalid index into symbol array\n"));
11334 break;
11335 }
11336
ab273396 11337 name = NULL;
978c4450 11338 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11339 {
b34976b6
AM
11340 Elf_Internal_Verneed ivn;
11341 unsigned long offset;
252b5132 11342
d93f0186 11343 offset = offset_from_vma
978c4450
AM
11344 (filedata,
11345 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11346 sizeof (Elf_External_Verneed));
252b5132 11347
b34976b6 11348 do
252b5132 11349 {
b34976b6
AM
11350 Elf_Internal_Vernaux ivna;
11351 Elf_External_Verneed evn;
11352 Elf_External_Vernaux evna;
11353 unsigned long a_off;
252b5132 11354
dda8d76d 11355 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11356 _("version need")) == NULL)
11357 break;
0b4362b0 11358
252b5132
RH
11359 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11360 ivn.vn_next = BYTE_GET (evn.vn_next);
11361
11362 a_off = offset + ivn.vn_aux;
11363
11364 do
11365 {
dda8d76d 11366 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11367 1, _("version need aux (2)")) == NULL)
11368 {
11369 ivna.vna_next = 0;
11370 ivna.vna_other = 0;
11371 }
11372 else
11373 {
11374 ivna.vna_next = BYTE_GET (evna.vna_next);
11375 ivna.vna_other = BYTE_GET (evna.vna_other);
11376 }
252b5132
RH
11377
11378 a_off += ivna.vna_next;
11379 }
b34976b6 11380 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11381 && ivna.vna_next != 0);
11382
b34976b6 11383 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11384 {
11385 ivna.vna_name = BYTE_GET (evna.vna_name);
11386
54806181 11387 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11388 name = invalid;
54806181
AM
11389 else
11390 name = strtab + ivna.vna_name;
252b5132
RH
11391 break;
11392 }
11393
11394 offset += ivn.vn_next;
11395 }
11396 while (ivn.vn_next);
11397 }
00d93f34 11398
ab273396 11399 if (data[cnt + j] != 0x8001
978c4450 11400 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11401 {
b34976b6
AM
11402 Elf_Internal_Verdef ivd;
11403 Elf_External_Verdef evd;
11404 unsigned long offset;
252b5132 11405
d93f0186 11406 offset = offset_from_vma
978c4450
AM
11407 (filedata,
11408 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11409 sizeof evd);
252b5132
RH
11410
11411 do
11412 {
dda8d76d 11413 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11414 _("version def")) == NULL)
11415 {
11416 ivd.vd_next = 0;
948f632f 11417 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11418 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11419 break;
59245841
NC
11420 }
11421 else
11422 {
11423 ivd.vd_next = BYTE_GET (evd.vd_next);
11424 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11425 }
252b5132
RH
11426
11427 offset += ivd.vd_next;
11428 }
c244d050 11429 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11430 && ivd.vd_next != 0);
11431
c244d050 11432 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11433 {
b34976b6
AM
11434 Elf_External_Verdaux evda;
11435 Elf_Internal_Verdaux ivda;
252b5132
RH
11436
11437 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11438
dda8d76d 11439 if (get_data (&evda, filedata,
59245841
NC
11440 offset - ivd.vd_next + ivd.vd_aux,
11441 sizeof (evda), 1,
11442 _("version def aux")) == NULL)
11443 break;
252b5132
RH
11444
11445 ivda.vda_name = BYTE_GET (evda.vda_name);
11446
54806181 11447 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11448 name = invalid;
11449 else if (name != NULL && name != invalid)
11450 name = _("*both*");
54806181
AM
11451 else
11452 name = strtab + ivda.vda_name;
252b5132
RH
11453 }
11454 }
ab273396
AM
11455 if (name != NULL)
11456 nn += printf ("(%s%-*s",
11457 name,
11458 12 - (int) strlen (name),
11459 ")");
252b5132
RH
11460
11461 if (nn < 18)
11462 printf ("%*c", 18 - nn, ' ');
11463 }
11464
11465 putchar ('\n');
11466 }
11467
11468 free (data);
11469 free (strtab);
11470 free (symbols);
11471 }
11472 break;
103f02d3 11473
252b5132
RH
11474 default:
11475 break;
11476 }
11477 }
11478
11479 if (! found)
11480 printf (_("\nNo version information found in this file.\n"));
11481
32ec8896 11482 return TRUE;
252b5132
RH
11483}
11484
d1133906 11485static const char *
dda8d76d 11486get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11487{
89246a0e 11488 static char buff[64];
252b5132
RH
11489
11490 switch (binding)
11491 {
b34976b6
AM
11492 case STB_LOCAL: return "LOCAL";
11493 case STB_GLOBAL: return "GLOBAL";
11494 case STB_WEAK: return "WEAK";
252b5132
RH
11495 default:
11496 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11497 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11498 binding);
252b5132 11499 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11500 {
11501 if (binding == STB_GNU_UNIQUE
df3a023b 11502 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11503 return "UNIQUE";
11504 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11505 }
252b5132 11506 else
e9e44622 11507 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11508 return buff;
11509 }
11510}
11511
d1133906 11512static const char *
dda8d76d 11513get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11514{
89246a0e 11515 static char buff[64];
252b5132
RH
11516
11517 switch (type)
11518 {
b34976b6
AM
11519 case STT_NOTYPE: return "NOTYPE";
11520 case STT_OBJECT: return "OBJECT";
11521 case STT_FUNC: return "FUNC";
11522 case STT_SECTION: return "SECTION";
11523 case STT_FILE: return "FILE";
11524 case STT_COMMON: return "COMMON";
11525 case STT_TLS: return "TLS";
15ab5209
DB
11526 case STT_RELC: return "RELC";
11527 case STT_SRELC: return "SRELC";
252b5132
RH
11528 default:
11529 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11530 {
dda8d76d 11531 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11532 return "THUMB_FUNC";
103f02d3 11533
dda8d76d 11534 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11535 return "REGISTER";
11536
dda8d76d 11537 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11538 return "PARISC_MILLI";
11539
e9e44622 11540 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11541 }
252b5132 11542 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11543 {
dda8d76d 11544 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11545 {
11546 if (type == STT_HP_OPAQUE)
11547 return "HP_OPAQUE";
11548 if (type == STT_HP_STUB)
11549 return "HP_STUB";
11550 }
11551
d8045f23 11552 if (type == STT_GNU_IFUNC
dda8d76d 11553 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11554 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11555 return "IFUNC";
11556
e9e44622 11557 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11558 }
252b5132 11559 else
e9e44622 11560 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11561 return buff;
11562 }
11563}
11564
d1133906 11565static const char *
d3ba0551 11566get_symbol_visibility (unsigned int visibility)
d1133906
NC
11567{
11568 switch (visibility)
11569 {
b34976b6
AM
11570 case STV_DEFAULT: return "DEFAULT";
11571 case STV_INTERNAL: return "INTERNAL";
11572 case STV_HIDDEN: return "HIDDEN";
d1133906 11573 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11574 default:
27a45f42 11575 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11576 return _("<unknown>");
d1133906
NC
11577 }
11578}
11579
2057d69d
CZ
11580static const char *
11581get_alpha_symbol_other (unsigned int other)
9abca702 11582{
2057d69d
CZ
11583 switch (other)
11584 {
11585 case STO_ALPHA_NOPV: return "NOPV";
11586 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11587 default:
27a45f42 11588 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11589 return _("<unknown>");
9abca702 11590 }
2057d69d
CZ
11591}
11592
fd85a6a1
NC
11593static const char *
11594get_solaris_symbol_visibility (unsigned int visibility)
11595{
11596 switch (visibility)
11597 {
11598 case 4: return "EXPORTED";
11599 case 5: return "SINGLETON";
11600 case 6: return "ELIMINATE";
11601 default: return get_symbol_visibility (visibility);
11602 }
11603}
11604
2301ed1c
SN
11605static const char *
11606get_aarch64_symbol_other (unsigned int other)
11607{
11608 static char buf[32];
11609
11610 if (other & STO_AARCH64_VARIANT_PCS)
11611 {
11612 other &= ~STO_AARCH64_VARIANT_PCS;
11613 if (other == 0)
11614 return "VARIANT_PCS";
11615 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
11616 return buf;
11617 }
11618 return NULL;
11619}
11620
5e2b0d47
NC
11621static const char *
11622get_mips_symbol_other (unsigned int other)
11623{
11624 switch (other)
11625 {
32ec8896
NC
11626 case STO_OPTIONAL: return "OPTIONAL";
11627 case STO_MIPS_PLT: return "MIPS PLT";
11628 case STO_MIPS_PIC: return "MIPS PIC";
11629 case STO_MICROMIPS: return "MICROMIPS";
11630 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11631 case STO_MIPS16: return "MIPS16";
11632 default: return NULL;
5e2b0d47
NC
11633 }
11634}
11635
28f997cf 11636static const char *
dda8d76d 11637get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11638{
dda8d76d 11639 if (is_ia64_vms (filedata))
28f997cf
TG
11640 {
11641 static char res[32];
11642
11643 res[0] = 0;
11644
11645 /* Function types is for images and .STB files only. */
dda8d76d 11646 switch (filedata->file_header.e_type)
28f997cf
TG
11647 {
11648 case ET_DYN:
11649 case ET_EXEC:
11650 switch (VMS_ST_FUNC_TYPE (other))
11651 {
11652 case VMS_SFT_CODE_ADDR:
11653 strcat (res, " CA");
11654 break;
11655 case VMS_SFT_SYMV_IDX:
11656 strcat (res, " VEC");
11657 break;
11658 case VMS_SFT_FD:
11659 strcat (res, " FD");
11660 break;
11661 case VMS_SFT_RESERVE:
11662 strcat (res, " RSV");
11663 break;
11664 default:
bee0ee85
NC
11665 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11666 VMS_ST_FUNC_TYPE (other));
11667 strcat (res, " <unknown>");
11668 break;
28f997cf
TG
11669 }
11670 break;
11671 default:
11672 break;
11673 }
11674 switch (VMS_ST_LINKAGE (other))
11675 {
11676 case VMS_STL_IGNORE:
11677 strcat (res, " IGN");
11678 break;
11679 case VMS_STL_RESERVE:
11680 strcat (res, " RSV");
11681 break;
11682 case VMS_STL_STD:
11683 strcat (res, " STD");
11684 break;
11685 case VMS_STL_LNK:
11686 strcat (res, " LNK");
11687 break;
11688 default:
bee0ee85
NC
11689 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11690 VMS_ST_LINKAGE (other));
11691 strcat (res, " <unknown>");
11692 break;
28f997cf
TG
11693 }
11694
11695 if (res[0] != 0)
11696 return res + 1;
11697 else
11698 return res;
11699 }
11700 return NULL;
11701}
11702
6911b7dc
AM
11703static const char *
11704get_ppc64_symbol_other (unsigned int other)
11705{
14732552
AM
11706 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11707 return NULL;
11708
11709 other >>= STO_PPC64_LOCAL_BIT;
11710 if (other <= 6)
6911b7dc 11711 {
89246a0e 11712 static char buf[64];
14732552
AM
11713 if (other >= 2)
11714 other = ppc64_decode_local_entry (other);
11715 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11716 return buf;
11717 }
11718 return NULL;
11719}
11720
5e2b0d47 11721static const char *
dda8d76d 11722get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11723{
11724 const char * result = NULL;
89246a0e 11725 static char buff [64];
5e2b0d47
NC
11726
11727 if (other == 0)
11728 return "";
11729
dda8d76d 11730 switch (filedata->file_header.e_machine)
5e2b0d47 11731 {
2057d69d
CZ
11732 case EM_ALPHA:
11733 result = get_alpha_symbol_other (other);
11734 break;
2301ed1c
SN
11735 case EM_AARCH64:
11736 result = get_aarch64_symbol_other (other);
11737 break;
5e2b0d47
NC
11738 case EM_MIPS:
11739 result = get_mips_symbol_other (other);
28f997cf
TG
11740 break;
11741 case EM_IA_64:
dda8d76d 11742 result = get_ia64_symbol_other (filedata, other);
28f997cf 11743 break;
6911b7dc
AM
11744 case EM_PPC64:
11745 result = get_ppc64_symbol_other (other);
11746 break;
5e2b0d47 11747 default:
fd85a6a1 11748 result = NULL;
5e2b0d47
NC
11749 break;
11750 }
11751
11752 if (result)
11753 return result;
11754
11755 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11756 return buff;
11757}
11758
d1133906 11759static const char *
dda8d76d 11760get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11761{
b34976b6 11762 static char buff[32];
5cf1065c 11763
252b5132
RH
11764 switch (type)
11765 {
b34976b6
AM
11766 case SHN_UNDEF: return "UND";
11767 case SHN_ABS: return "ABS";
11768 case SHN_COMMON: return "COM";
252b5132 11769 default:
9ce701e2 11770 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
11771 && filedata->file_header.e_machine == EM_IA_64
11772 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
11773 return "ANSI_COM";
11774 else if ((filedata->file_header.e_machine == EM_X86_64
11775 || filedata->file_header.e_machine == EM_L1OM
11776 || filedata->file_header.e_machine == EM_K1OM)
11777 && type == SHN_X86_64_LCOMMON)
11778 return "LARGE_COM";
11779 else if ((type == SHN_MIPS_SCOMMON
11780 && filedata->file_header.e_machine == EM_MIPS)
11781 || (type == SHN_TIC6X_SCOMMON
11782 && filedata->file_header.e_machine == EM_TI_C6000))
11783 return "SCOM";
11784 else if (type == SHN_MIPS_SUNDEFINED
11785 && filedata->file_header.e_machine == EM_MIPS)
11786 return "SUND";
11787 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
11788 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
11789 else if (type >= SHN_LOOS && type <= SHN_HIOS)
11790 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11791 else if (type >= SHN_LORESERVE)
11792 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
11793 else if (filedata->file_header.e_shnum != 0
11794 && type >= filedata->file_header.e_shnum)
11795 sprintf (buff, _("bad section index[%3d]"), type);
11796 else
11797 sprintf (buff, "%3d", type);
11798 break;
fd85a6a1
NC
11799 }
11800
10ca4b04 11801 return buff;
6bd1a22c
L
11802}
11803
bb4d2ac2 11804static const char *
dda8d76d 11805get_symbol_version_string (Filedata * filedata,
1449284b
NC
11806 bfd_boolean is_dynsym,
11807 const char * strtab,
11808 unsigned long int strtab_size,
11809 unsigned int si,
11810 Elf_Internal_Sym * psym,
11811 enum versioned_symbol_info * sym_info,
11812 unsigned short * vna_other)
bb4d2ac2 11813{
ab273396
AM
11814 unsigned char data[2];
11815 unsigned short vers_data;
11816 unsigned long offset;
7a815dd5 11817 unsigned short max_vd_ndx;
bb4d2ac2 11818
ab273396 11819 if (!is_dynsym
978c4450 11820 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 11821 return NULL;
bb4d2ac2 11822
978c4450
AM
11823 offset = offset_from_vma (filedata,
11824 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11825 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11826
dda8d76d 11827 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11828 sizeof (data), 1, _("version data")) == NULL)
11829 return NULL;
11830
11831 vers_data = byte_get (data, 2);
bb4d2ac2 11832
1f6f5dba 11833 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11834 return NULL;
bb4d2ac2 11835
0b8b7609 11836 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
11837 max_vd_ndx = 0;
11838
ab273396
AM
11839 /* Usually we'd only see verdef for defined symbols, and verneed for
11840 undefined symbols. However, symbols defined by the linker in
11841 .dynbss for variables copied from a shared library in order to
11842 avoid text relocations are defined yet have verneed. We could
11843 use a heuristic to detect the special case, for example, check
11844 for verneed first on symbols defined in SHT_NOBITS sections, but
11845 it is simpler and more reliable to just look for both verdef and
11846 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11847
ab273396
AM
11848 if (psym->st_shndx != SHN_UNDEF
11849 && vers_data != 0x8001
978c4450 11850 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
11851 {
11852 Elf_Internal_Verdef ivd;
11853 Elf_Internal_Verdaux ivda;
11854 Elf_External_Verdaux evda;
11855 unsigned long off;
bb4d2ac2 11856
dda8d76d 11857 off = offset_from_vma (filedata,
978c4450 11858 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
11859 sizeof (Elf_External_Verdef));
11860
11861 do
bb4d2ac2 11862 {
ab273396
AM
11863 Elf_External_Verdef evd;
11864
dda8d76d 11865 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11866 _("version def")) == NULL)
11867 {
11868 ivd.vd_ndx = 0;
11869 ivd.vd_aux = 0;
11870 ivd.vd_next = 0;
1f6f5dba 11871 ivd.vd_flags = 0;
ab273396
AM
11872 }
11873 else
bb4d2ac2 11874 {
ab273396
AM
11875 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11876 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11877 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 11878 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 11879 }
bb4d2ac2 11880
7a815dd5
L
11881 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
11882 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
11883
ab273396
AM
11884 off += ivd.vd_next;
11885 }
11886 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11887
ab273396
AM
11888 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11889 {
9abca702 11890 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
11891 return NULL;
11892
ab273396
AM
11893 off -= ivd.vd_next;
11894 off += ivd.vd_aux;
bb4d2ac2 11895
dda8d76d 11896 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
11897 _("version def aux")) != NULL)
11898 {
11899 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 11900
ab273396 11901 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
11902 return (ivda.vda_name < strtab_size
11903 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
11904 }
11905 }
11906 }
bb4d2ac2 11907
978c4450 11908 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
11909 {
11910 Elf_External_Verneed evn;
11911 Elf_Internal_Verneed ivn;
11912 Elf_Internal_Vernaux ivna;
bb4d2ac2 11913
dda8d76d 11914 offset = offset_from_vma (filedata,
978c4450 11915 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
11916 sizeof evn);
11917 do
11918 {
11919 unsigned long vna_off;
bb4d2ac2 11920
dda8d76d 11921 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
11922 _("version need")) == NULL)
11923 {
11924 ivna.vna_next = 0;
11925 ivna.vna_other = 0;
11926 ivna.vna_name = 0;
11927 break;
11928 }
bb4d2ac2 11929
ab273396
AM
11930 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11931 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 11932
ab273396 11933 vna_off = offset + ivn.vn_aux;
bb4d2ac2 11934
ab273396
AM
11935 do
11936 {
11937 Elf_External_Vernaux evna;
bb4d2ac2 11938
dda8d76d 11939 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 11940 _("version need aux (3)")) == NULL)
bb4d2ac2 11941 {
ab273396
AM
11942 ivna.vna_next = 0;
11943 ivna.vna_other = 0;
11944 ivna.vna_name = 0;
bb4d2ac2 11945 }
bb4d2ac2 11946 else
bb4d2ac2 11947 {
ab273396
AM
11948 ivna.vna_other = BYTE_GET (evna.vna_other);
11949 ivna.vna_next = BYTE_GET (evna.vna_next);
11950 ivna.vna_name = BYTE_GET (evna.vna_name);
11951 }
bb4d2ac2 11952
ab273396
AM
11953 vna_off += ivna.vna_next;
11954 }
11955 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 11956
ab273396
AM
11957 if (ivna.vna_other == vers_data)
11958 break;
bb4d2ac2 11959
ab273396
AM
11960 offset += ivn.vn_next;
11961 }
11962 while (ivn.vn_next != 0);
bb4d2ac2 11963
ab273396
AM
11964 if (ivna.vna_other == vers_data)
11965 {
11966 *sym_info = symbol_undefined;
11967 *vna_other = ivna.vna_other;
11968 return (ivna.vna_name < strtab_size
11969 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 11970 }
7a815dd5
L
11971 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
11972 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
11973 return _("<corrupt>");
bb4d2ac2 11974 }
ab273396 11975 return NULL;
bb4d2ac2
L
11976}
11977
10ca4b04
L
11978static void
11979print_dynamic_symbol (Filedata *filedata, unsigned long si,
11980 Elf_Internal_Sym *symtab,
11981 Elf_Internal_Shdr *section,
11982 char *strtab, size_t strtab_size)
252b5132 11983{
10ca4b04
L
11984 const char *version_string;
11985 enum versioned_symbol_info sym_info;
11986 unsigned short vna_other;
11987 Elf_Internal_Sym *psym = symtab + si;
252b5132 11988
10ca4b04
L
11989 printf ("%6ld: ", si);
11990 print_vma (psym->st_value, LONG_HEX);
11991 putchar (' ');
11992 print_vma (psym->st_size, DEC_5);
11993 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11994 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
11995 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
11996 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11997 else
252b5132 11998 {
10ca4b04 11999 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12000
10ca4b04
L
12001 printf (" %-7s", get_symbol_visibility (vis));
12002 /* Check to see if any other bits in the st_other field are set.
12003 Note - displaying this information disrupts the layout of the
12004 table being generated, but for the moment this case is very rare. */
12005 if (psym->st_other ^ vis)
12006 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12007 }
10ca4b04
L
12008 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
12009 print_symbol (25, VALID_SYMBOL_NAME (strtab, strtab_size,
12010 psym->st_name)
12011 ? strtab + psym->st_name : _("<corrupt>"));
12012
12013 version_string
12014 = get_symbol_version_string (filedata,
12015 (section == NULL
12016 || section->sh_type == SHT_DYNSYM),
12017 strtab, strtab_size, si,
12018 psym, &sym_info, &vna_other);
12019 if (version_string)
12020 {
12021 if (sym_info == symbol_undefined)
12022 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12023 else
10ca4b04
L
12024 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12025 version_string);
12026 }
6bd1a22c 12027
10ca4b04 12028 putchar ('\n');
6bd1a22c 12029
10ca4b04
L
12030 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12031 && section != NULL
12032 && si >= section->sh_info
12033 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12034 && filedata->file_header.e_machine != EM_MIPS
12035 /* Solaris binaries have been found to violate this requirement as
12036 well. Not sure if this is a bug or an ABI requirement. */
12037 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12038 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12039 si, printable_section_name (filedata, section), section->sh_info);
12040}
f16a9783 12041
10ca4b04
L
12042/* Dump the symbol table. */
12043static bfd_boolean
12044process_symbol_table (Filedata * filedata)
12045{
12046 Elf_Internal_Shdr * section;
f16a9783 12047
10ca4b04
L
12048 if (!do_syms && !do_dyn_syms && !do_histogram)
12049 return TRUE;
6bd1a22c 12050
978c4450 12051 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12052 && do_syms
12053 && do_using_dynamic
978c4450
AM
12054 && filedata->dynamic_strings != NULL
12055 && filedata->dynamic_symbols != NULL)
6bd1a22c 12056 {
10ca4b04 12057 unsigned long si;
6bd1a22c 12058
10ca4b04
L
12059 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12060 "\nSymbol table for image contains %lu entries:\n",
978c4450
AM
12061 filedata->num_dynamic_syms),
12062 filedata->num_dynamic_syms);
10ca4b04
L
12063 if (is_32bit_elf)
12064 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12065 else
12066 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12067
978c4450
AM
12068 for (si = 0; si < filedata->num_dynamic_syms; si++)
12069 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12070 filedata->dynamic_strings,
12071 filedata->dynamic_strings_length);
252b5132 12072 }
8b73c356 12073 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12074 && filedata->section_headers != NULL)
252b5132 12075 {
b34976b6 12076 unsigned int i;
252b5132 12077
dda8d76d
NC
12078 for (i = 0, section = filedata->section_headers;
12079 i < filedata->file_header.e_shnum;
252b5132
RH
12080 i++, section++)
12081 {
2cf0635d 12082 char * strtab = NULL;
c256ffe7 12083 unsigned long int strtab_size = 0;
2cf0635d 12084 Elf_Internal_Sym * symtab;
ef3df110 12085 unsigned long si, num_syms;
252b5132 12086
2c610e4b
L
12087 if ((section->sh_type != SHT_SYMTAB
12088 && section->sh_type != SHT_DYNSYM)
12089 || (!do_syms
12090 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12091 continue;
12092
dd24e3da
NC
12093 if (section->sh_entsize == 0)
12094 {
12095 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12096 printable_section_name (filedata, section));
dd24e3da
NC
12097 continue;
12098 }
12099
d3a49aa8
AM
12100 num_syms = section->sh_size / section->sh_entsize;
12101 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12102 "\nSymbol table '%s' contains %lu entries:\n",
12103 num_syms),
dda8d76d 12104 printable_section_name (filedata, section),
d3a49aa8 12105 num_syms);
dd24e3da 12106
f7a99963 12107 if (is_32bit_elf)
ca47b30c 12108 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12109 else
ca47b30c 12110 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12111
dda8d76d 12112 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12113 if (symtab == NULL)
12114 continue;
12115
dda8d76d 12116 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12117 {
dda8d76d
NC
12118 strtab = filedata->string_table;
12119 strtab_size = filedata->string_table_length;
c256ffe7 12120 }
dda8d76d 12121 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12122 {
2cf0635d 12123 Elf_Internal_Shdr * string_sec;
252b5132 12124
dda8d76d 12125 string_sec = filedata->section_headers + section->sh_link;
252b5132 12126
dda8d76d 12127 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12128 1, string_sec->sh_size,
12129 _("string table"));
c256ffe7 12130 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12131 }
12132
10ca4b04
L
12133 for (si = 0; si < num_syms; si++)
12134 print_dynamic_symbol (filedata, si, symtab, section,
12135 strtab, strtab_size);
252b5132
RH
12136
12137 free (symtab);
dda8d76d 12138 if (strtab != filedata->string_table)
252b5132
RH
12139 free (strtab);
12140 }
12141 }
12142 else if (do_syms)
12143 printf
12144 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12145
978c4450 12146 if (do_histogram && filedata->buckets != NULL)
252b5132 12147 {
2cf0635d
NC
12148 unsigned long * lengths;
12149 unsigned long * counts;
66543521
AM
12150 unsigned long hn;
12151 bfd_vma si;
12152 unsigned long maxlength = 0;
12153 unsigned long nzero_counts = 0;
12154 unsigned long nsyms = 0;
6bd6a03d 12155 char *visited;
252b5132 12156
d3a49aa8
AM
12157 printf (ngettext ("\nHistogram for bucket list length "
12158 "(total of %lu bucket):\n",
12159 "\nHistogram for bucket list length "
12160 "(total of %lu buckets):\n",
978c4450
AM
12161 (unsigned long) filedata->nbuckets),
12162 (unsigned long) filedata->nbuckets);
252b5132 12163
978c4450
AM
12164 lengths = (unsigned long *) calloc (filedata->nbuckets,
12165 sizeof (*lengths));
252b5132
RH
12166 if (lengths == NULL)
12167 {
8b73c356 12168 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12169 goto err_out;
252b5132 12170 }
978c4450
AM
12171 visited = xcmalloc (filedata->nchains, 1);
12172 memset (visited, 0, filedata->nchains);
8b73c356
NC
12173
12174 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12175 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12176 {
978c4450 12177 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12178 {
b34976b6 12179 ++nsyms;
252b5132 12180 if (maxlength < ++lengths[hn])
b34976b6 12181 ++maxlength;
978c4450 12182 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12183 {
12184 error (_("histogram chain is corrupt\n"));
12185 break;
12186 }
12187 visited[si] = 1;
252b5132
RH
12188 }
12189 }
6bd6a03d 12190 free (visited);
252b5132 12191
3f5e193b 12192 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12193 if (counts == NULL)
12194 {
b2e951ec 12195 free (lengths);
8b73c356 12196 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12197 goto err_out;
252b5132
RH
12198 }
12199
978c4450 12200 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12201 ++counts[lengths[hn]];
252b5132 12202
978c4450 12203 if (filedata->nbuckets > 0)
252b5132 12204 {
66543521
AM
12205 unsigned long i;
12206 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12207 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12208 for (i = 1; i <= maxlength; ++i)
103f02d3 12209 {
66543521
AM
12210 nzero_counts += counts[i] * i;
12211 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12212 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12213 (nzero_counts * 100.0) / nsyms);
12214 }
252b5132
RH
12215 }
12216
12217 free (counts);
12218 free (lengths);
12219 }
12220
978c4450
AM
12221 free (filedata->buckets);
12222 filedata->buckets = NULL;
12223 filedata->nbuckets = 0;
12224 free (filedata->chains);
12225 filedata->chains = NULL;
252b5132 12226
978c4450 12227 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 12228 {
2cf0635d
NC
12229 unsigned long * lengths;
12230 unsigned long * counts;
fdc90cb4
JJ
12231 unsigned long hn;
12232 unsigned long maxlength = 0;
12233 unsigned long nzero_counts = 0;
12234 unsigned long nsyms = 0;
fdc90cb4 12235
f16a9783 12236 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12237 "(total of %lu bucket):\n",
f16a9783 12238 "\nHistogram for `%s' bucket list length "
d3a49aa8 12239 "(total of %lu buckets):\n",
978c4450
AM
12240 (unsigned long) filedata->ngnubuckets),
12241 GNU_HASH_SECTION_NAME (filedata),
12242 (unsigned long) filedata->ngnubuckets);
8b73c356 12243
978c4450
AM
12244 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
12245 sizeof (*lengths));
fdc90cb4
JJ
12246 if (lengths == NULL)
12247 {
8b73c356 12248 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12249 goto err_out;
fdc90cb4
JJ
12250 }
12251
fdc90cb4
JJ
12252 printf (_(" Length Number %% of total Coverage\n"));
12253
978c4450
AM
12254 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12255 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
12256 {
12257 bfd_vma off, length = 1;
12258
978c4450 12259 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 12260 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
12261 off < filedata->ngnuchains
12262 && (filedata->gnuchains[off] & 1) == 0;
071436c6 12263 ++off)
fdc90cb4
JJ
12264 ++length;
12265 lengths[hn] = length;
12266 if (length > maxlength)
12267 maxlength = length;
12268 nsyms += length;
12269 }
12270
3f5e193b 12271 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12272 if (counts == NULL)
12273 {
b2e951ec 12274 free (lengths);
8b73c356 12275 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12276 goto err_out;
fdc90cb4
JJ
12277 }
12278
978c4450 12279 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
12280 ++counts[lengths[hn]];
12281
978c4450 12282 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
12283 {
12284 unsigned long j;
12285 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12286 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
12287 for (j = 1; j <= maxlength; ++j)
12288 {
12289 nzero_counts += counts[j] * j;
12290 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12291 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
12292 (nzero_counts * 100.0) / nsyms);
12293 }
12294 }
12295
12296 free (counts);
12297 free (lengths);
fdc90cb4 12298 }
978c4450
AM
12299 free (filedata->gnubuckets);
12300 filedata->gnubuckets = NULL;
12301 filedata->ngnubuckets = 0;
12302 free (filedata->gnuchains);
12303 filedata->gnuchains = NULL;
12304 filedata->ngnuchains = 0;
12305 free (filedata->mipsxlat);
12306 filedata->mipsxlat = NULL;
32ec8896 12307 return TRUE;
fd486f32
AM
12308
12309 err_out:
978c4450
AM
12310 free (filedata->gnubuckets);
12311 filedata->gnubuckets = NULL;
12312 filedata->ngnubuckets = 0;
12313 free (filedata->gnuchains);
12314 filedata->gnuchains = NULL;
12315 filedata->ngnuchains = 0;
12316 free (filedata->mipsxlat);
12317 filedata->mipsxlat = NULL;
12318 free (filedata->buckets);
12319 filedata->buckets = NULL;
12320 filedata->nbuckets = 0;
12321 free (filedata->chains);
12322 filedata->chains = NULL;
fd486f32 12323 return FALSE;
252b5132
RH
12324}
12325
32ec8896 12326static bfd_boolean
dda8d76d 12327process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12328{
b4c96d0d 12329 unsigned int i;
252b5132 12330
978c4450 12331 if (filedata->dynamic_syminfo == NULL
252b5132
RH
12332 || !do_dynamic)
12333 /* No syminfo, this is ok. */
32ec8896 12334 return TRUE;
252b5132
RH
12335
12336 /* There better should be a dynamic symbol section. */
978c4450 12337 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
32ec8896 12338 return FALSE;
252b5132 12339
978c4450 12340 if (filedata->dynamic_addr)
d3a49aa8
AM
12341 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12342 "contains %d entry:\n",
12343 "\nDynamic info segment at offset 0x%lx "
12344 "contains %d entries:\n",
978c4450
AM
12345 filedata->dynamic_syminfo_nent),
12346 filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent);
252b5132
RH
12347
12348 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 12349 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 12350 {
978c4450 12351 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 12352
31104126 12353 printf ("%4d: ", i);
978c4450 12354 if (i >= filedata->num_dynamic_syms)
4082ef84 12355 printf (_("<corrupt index>"));
978c4450
AM
12356 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
12357 print_symbol (30, GET_DYNAMIC_NAME (filedata,
12358 filedata->dynamic_symbols[i].st_name));
d79b3d50 12359 else
978c4450 12360 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 12361 putchar (' ');
252b5132 12362
978c4450 12363 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
12364 {
12365 case SYMINFO_BT_SELF:
12366 fputs ("SELF ", stdout);
12367 break;
12368 case SYMINFO_BT_PARENT:
12369 fputs ("PARENT ", stdout);
12370 break;
12371 default:
978c4450
AM
12372 if (filedata->dynamic_syminfo[i].si_boundto > 0
12373 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
12374 && VALID_DYNAMIC_NAME (filedata,
12375 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12376 {
978c4450
AM
12377 print_symbol (10, GET_DYNAMIC_NAME (filedata,
12378 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12379 putchar (' ' );
12380 }
252b5132 12381 else
978c4450 12382 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
12383 break;
12384 }
12385
12386 if (flags & SYMINFO_FLG_DIRECT)
12387 printf (" DIRECT");
12388 if (flags & SYMINFO_FLG_PASSTHRU)
12389 printf (" PASSTHRU");
12390 if (flags & SYMINFO_FLG_COPY)
12391 printf (" COPY");
12392 if (flags & SYMINFO_FLG_LAZYLOAD)
12393 printf (" LAZYLOAD");
12394
12395 puts ("");
12396 }
12397
32ec8896 12398 return TRUE;
252b5132
RH
12399}
12400
75802ccb
CE
12401/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
12402 is contained by the region START .. END. The types of ADDR, START
12403 and END should all be the same. Note both ADDR + NELEM and END
12404 point to just beyond the end of the regions that are being tested. */
12405#define IN_RANGE(START,END,ADDR,NELEM) \
12406 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 12407
cf13d699
NC
12408/* Check to see if the given reloc needs to be handled in a target specific
12409 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12410 FALSE.
12411
12412 If called with reloc == NULL, then this is a signal that reloc processing
12413 for the current section has finished, and any saved state should be
12414 discarded. */
09c11c86 12415
cf13d699 12416static bfd_boolean
dda8d76d
NC
12417target_specific_reloc_handling (Filedata * filedata,
12418 Elf_Internal_Rela * reloc,
12419 unsigned char * start,
12420 unsigned char * end,
12421 Elf_Internal_Sym * symtab,
12422 unsigned long num_syms)
252b5132 12423{
f84ce13b
NC
12424 unsigned int reloc_type = 0;
12425 unsigned long sym_index = 0;
12426
12427 if (reloc)
12428 {
dda8d76d 12429 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12430 sym_index = get_reloc_symindex (reloc->r_info);
12431 }
252b5132 12432
dda8d76d 12433 switch (filedata->file_header.e_machine)
252b5132 12434 {
13761a11
NC
12435 case EM_MSP430:
12436 case EM_MSP430_OLD:
12437 {
12438 static Elf_Internal_Sym * saved_sym = NULL;
12439
f84ce13b
NC
12440 if (reloc == NULL)
12441 {
12442 saved_sym = NULL;
12443 return TRUE;
12444 }
12445
13761a11
NC
12446 switch (reloc_type)
12447 {
12448 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12449 if (uses_msp430x_relocs (filedata))
13761a11 12450 break;
1a0670f3 12451 /* Fall through. */
13761a11 12452 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12453 /* PR 21139. */
12454 if (sym_index >= num_syms)
12455 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12456 sym_index);
12457 else
12458 saved_sym = symtab + sym_index;
13761a11
NC
12459 return TRUE;
12460
12461 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12462 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12463 goto handle_sym_diff;
0b4362b0 12464
13761a11
NC
12465 case 5: /* R_MSP430_16_BYTE */
12466 case 9: /* R_MSP430_8 */
dda8d76d 12467 if (uses_msp430x_relocs (filedata))
13761a11
NC
12468 break;
12469 goto handle_sym_diff;
12470
12471 case 2: /* R_MSP430_ABS16 */
12472 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12473 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12474 break;
12475 goto handle_sym_diff;
0b4362b0 12476
13761a11
NC
12477 handle_sym_diff:
12478 if (saved_sym != NULL)
12479 {
03f7786e 12480 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12481 bfd_vma value;
12482
f84ce13b
NC
12483 if (sym_index >= num_syms)
12484 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12485 sym_index);
03f7786e 12486 else
f84ce13b
NC
12487 {
12488 value = reloc->r_addend + (symtab[sym_index].st_value
12489 - saved_sym->st_value);
12490
b32e566b 12491 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12492 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12493 else
12494 /* PR 21137 */
12495 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12496 (long) reloc->r_offset);
f84ce13b 12497 }
13761a11
NC
12498
12499 saved_sym = NULL;
12500 return TRUE;
12501 }
12502 break;
12503
12504 default:
12505 if (saved_sym != NULL)
071436c6 12506 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12507 break;
12508 }
12509 break;
12510 }
12511
cf13d699
NC
12512 case EM_MN10300:
12513 case EM_CYGNUS_MN10300:
12514 {
12515 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12516
f84ce13b
NC
12517 if (reloc == NULL)
12518 {
12519 saved_sym = NULL;
12520 return TRUE;
12521 }
12522
cf13d699
NC
12523 switch (reloc_type)
12524 {
12525 case 34: /* R_MN10300_ALIGN */
12526 return TRUE;
12527 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12528 if (sym_index >= num_syms)
12529 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12530 sym_index);
12531 else
12532 saved_sym = symtab + sym_index;
cf13d699 12533 return TRUE;
f84ce13b 12534
cf13d699
NC
12535 case 1: /* R_MN10300_32 */
12536 case 2: /* R_MN10300_16 */
12537 if (saved_sym != NULL)
12538 {
03f7786e 12539 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12540 bfd_vma value;
252b5132 12541
f84ce13b
NC
12542 if (sym_index >= num_syms)
12543 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12544 sym_index);
03f7786e 12545 else
f84ce13b
NC
12546 {
12547 value = reloc->r_addend + (symtab[sym_index].st_value
12548 - saved_sym->st_value);
12549
b32e566b 12550 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12551 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12552 else
12553 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12554 (long) reloc->r_offset);
f84ce13b 12555 }
252b5132 12556
cf13d699
NC
12557 saved_sym = NULL;
12558 return TRUE;
12559 }
12560 break;
12561 default:
12562 if (saved_sym != NULL)
071436c6 12563 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12564 break;
12565 }
12566 break;
12567 }
6ff71e76
NC
12568
12569 case EM_RL78:
12570 {
12571 static bfd_vma saved_sym1 = 0;
12572 static bfd_vma saved_sym2 = 0;
12573 static bfd_vma value;
12574
f84ce13b
NC
12575 if (reloc == NULL)
12576 {
12577 saved_sym1 = saved_sym2 = 0;
12578 return TRUE;
12579 }
12580
6ff71e76
NC
12581 switch (reloc_type)
12582 {
12583 case 0x80: /* R_RL78_SYM. */
12584 saved_sym1 = saved_sym2;
f84ce13b
NC
12585 if (sym_index >= num_syms)
12586 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12587 sym_index);
12588 else
12589 {
12590 saved_sym2 = symtab[sym_index].st_value;
12591 saved_sym2 += reloc->r_addend;
12592 }
6ff71e76
NC
12593 return TRUE;
12594
12595 case 0x83: /* R_RL78_OPsub. */
12596 value = saved_sym1 - saved_sym2;
12597 saved_sym2 = saved_sym1 = 0;
12598 return TRUE;
12599 break;
12600
12601 case 0x41: /* R_RL78_ABS32. */
b32e566b 12602 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12603 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12604 else
12605 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12606 (long) reloc->r_offset);
6ff71e76
NC
12607 value = 0;
12608 return TRUE;
12609
12610 case 0x43: /* R_RL78_ABS16. */
b32e566b 12611 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12612 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12613 else
12614 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12615 (long) reloc->r_offset);
6ff71e76
NC
12616 value = 0;
12617 return TRUE;
12618
12619 default:
12620 break;
12621 }
12622 break;
12623 }
252b5132
RH
12624 }
12625
cf13d699 12626 return FALSE;
252b5132
RH
12627}
12628
aca88567
NC
12629/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12630 DWARF debug sections. This is a target specific test. Note - we do not
12631 go through the whole including-target-headers-multiple-times route, (as
12632 we have already done with <elf/h8.h>) because this would become very
12633 messy and even then this function would have to contain target specific
12634 information (the names of the relocs instead of their numeric values).
12635 FIXME: This is not the correct way to solve this problem. The proper way
12636 is to have target specific reloc sizing and typing functions created by
12637 the reloc-macros.h header, in the same way that it already creates the
12638 reloc naming functions. */
12639
12640static bfd_boolean
dda8d76d 12641is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12642{
d347c9df 12643 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12644 switch (filedata->file_header.e_machine)
aca88567 12645 {
41e92641 12646 case EM_386:
22abe556 12647 case EM_IAMCU:
41e92641 12648 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12649 case EM_68K:
12650 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12651 case EM_860:
12652 return reloc_type == 1; /* R_860_32. */
12653 case EM_960:
12654 return reloc_type == 2; /* R_960_32. */
a06ea964 12655 case EM_AARCH64:
9282b95a
JW
12656 return (reloc_type == 258
12657 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
12658 case EM_BPF:
12659 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
12660 case EM_ADAPTEVA_EPIPHANY:
12661 return reloc_type == 3;
aca88567 12662 case EM_ALPHA:
137b6b5f 12663 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12664 case EM_ARC:
12665 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12666 case EM_ARC_COMPACT:
12667 case EM_ARC_COMPACT2:
12668 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12669 case EM_ARM:
12670 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12671 case EM_AVR_OLD:
aca88567
NC
12672 case EM_AVR:
12673 return reloc_type == 1;
12674 case EM_BLACKFIN:
12675 return reloc_type == 0x12; /* R_byte4_data. */
12676 case EM_CRIS:
12677 return reloc_type == 3; /* R_CRIS_32. */
12678 case EM_CR16:
12679 return reloc_type == 3; /* R_CR16_NUM32. */
12680 case EM_CRX:
12681 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
12682 case EM_CSKY:
12683 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
12684 case EM_CYGNUS_FRV:
12685 return reloc_type == 1;
41e92641
NC
12686 case EM_CYGNUS_D10V:
12687 case EM_D10V:
12688 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12689 case EM_CYGNUS_D30V:
12690 case EM_D30V:
12691 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12692 case EM_DLX:
12693 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12694 case EM_CYGNUS_FR30:
12695 case EM_FR30:
12696 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12697 case EM_FT32:
12698 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12699 case EM_H8S:
12700 case EM_H8_300:
12701 case EM_H8_300H:
12702 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12703 case EM_IA_64:
262cdac7
AM
12704 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12705 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12706 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12707 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12708 case EM_IP2K_OLD:
12709 case EM_IP2K:
12710 return reloc_type == 2; /* R_IP2K_32. */
12711 case EM_IQ2000:
12712 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12713 case EM_LATTICEMICO32:
12714 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12715 case EM_M32C_OLD:
aca88567
NC
12716 case EM_M32C:
12717 return reloc_type == 3; /* R_M32C_32. */
12718 case EM_M32R:
12719 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12720 case EM_68HC11:
12721 case EM_68HC12:
12722 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 12723 case EM_S12Z:
2849d19f
JD
12724 return reloc_type == 7 || /* R_S12Z_EXT32 */
12725 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
12726 case EM_MCORE:
12727 return reloc_type == 1; /* R_MCORE_ADDR32. */
12728 case EM_CYGNUS_MEP:
12729 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12730 case EM_METAG:
12731 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12732 case EM_MICROBLAZE:
12733 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12734 case EM_MIPS:
12735 return reloc_type == 2; /* R_MIPS_32. */
12736 case EM_MMIX:
12737 return reloc_type == 4; /* R_MMIX_32. */
12738 case EM_CYGNUS_MN10200:
12739 case EM_MN10200:
12740 return reloc_type == 1; /* R_MN10200_32. */
12741 case EM_CYGNUS_MN10300:
12742 case EM_MN10300:
12743 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12744 case EM_MOXIE:
12745 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12746 case EM_MSP430_OLD:
12747 case EM_MSP430:
13761a11 12748 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12749 case EM_MT:
12750 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12751 case EM_NDS32:
12752 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12753 case EM_ALTERA_NIOS2:
36591ba1 12754 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12755 case EM_NIOS32:
12756 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12757 case EM_OR1K:
12758 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12759 case EM_PARISC:
9abca702 12760 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 12761 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12762 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12763 case EM_PJ:
12764 case EM_PJ_OLD:
12765 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12766 case EM_PPC64:
12767 return reloc_type == 1; /* R_PPC64_ADDR32. */
12768 case EM_PPC:
12769 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12770 case EM_TI_PRU:
12771 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12772 case EM_RISCV:
12773 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12774 case EM_RL78:
12775 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12776 case EM_RX:
12777 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12778 case EM_S370:
12779 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12780 case EM_S390_OLD:
12781 case EM_S390:
12782 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12783 case EM_SCORE:
12784 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12785 case EM_SH:
12786 return reloc_type == 1; /* R_SH_DIR32. */
12787 case EM_SPARC32PLUS:
12788 case EM_SPARCV9:
12789 case EM_SPARC:
12790 return reloc_type == 3 /* R_SPARC_32. */
12791 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12792 case EM_SPU:
12793 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12794 case EM_TI_C6000:
12795 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12796 case EM_TILEGX:
12797 return reloc_type == 2; /* R_TILEGX_32. */
12798 case EM_TILEPRO:
12799 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12800 case EM_CYGNUS_V850:
12801 case EM_V850:
12802 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12803 case EM_V800:
12804 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12805 case EM_VAX:
12806 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12807 case EM_VISIUM:
12808 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12809 case EM_WEBASSEMBLY:
12810 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12811 case EM_X86_64:
8a9036a4 12812 case EM_L1OM:
7a9068fe 12813 case EM_K1OM:
aca88567 12814 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12815 case EM_XC16X:
12816 case EM_C166:
12817 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12818 case EM_XGATE:
12819 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12820 case EM_XSTORMY16:
12821 return reloc_type == 1; /* R_XSTROMY16_32. */
12822 case EM_XTENSA_OLD:
12823 case EM_XTENSA:
12824 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
12825 case EM_Z80:
12826 return reloc_type == 6; /* R_Z80_32. */
aca88567 12827 default:
bee0ee85
NC
12828 {
12829 static unsigned int prev_warn = 0;
12830
12831 /* Avoid repeating the same warning multiple times. */
dda8d76d 12832 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12833 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12834 filedata->file_header.e_machine);
12835 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12836 return FALSE;
12837 }
aca88567
NC
12838 }
12839}
12840
12841/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12842 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12843
12844static bfd_boolean
dda8d76d 12845is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12846{
dda8d76d 12847 switch (filedata->file_header.e_machine)
d347c9df 12848 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12849 {
41e92641 12850 case EM_386:
22abe556 12851 case EM_IAMCU:
3e0873ac 12852 return reloc_type == 2; /* R_386_PC32. */
aca88567 12853 case EM_68K:
3e0873ac 12854 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12855 case EM_AARCH64:
12856 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12857 case EM_ADAPTEVA_EPIPHANY:
12858 return reloc_type == 6;
aca88567
NC
12859 case EM_ALPHA:
12860 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12861 case EM_ARC_COMPACT:
12862 case EM_ARC_COMPACT2:
12863 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12864 case EM_ARM:
3e0873ac 12865 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12866 case EM_AVR_OLD:
12867 case EM_AVR:
12868 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12869 case EM_MICROBLAZE:
12870 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12871 case EM_OR1K:
12872 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 12873 case EM_PARISC:
85acf597 12874 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
12875 case EM_PPC:
12876 return reloc_type == 26; /* R_PPC_REL32. */
12877 case EM_PPC64:
3e0873ac 12878 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
12879 case EM_RISCV:
12880 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
12881 case EM_S390_OLD:
12882 case EM_S390:
3e0873ac 12883 return reloc_type == 5; /* R_390_PC32. */
aca88567 12884 case EM_SH:
3e0873ac 12885 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
12886 case EM_SPARC32PLUS:
12887 case EM_SPARCV9:
12888 case EM_SPARC:
3e0873ac 12889 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
12890 case EM_SPU:
12891 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
12892 case EM_TILEGX:
12893 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
12894 case EM_TILEPRO:
12895 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
12896 case EM_VISIUM:
12897 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 12898 case EM_X86_64:
8a9036a4 12899 case EM_L1OM:
7a9068fe 12900 case EM_K1OM:
3e0873ac 12901 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
12902 case EM_VAX:
12903 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
12904 case EM_XTENSA_OLD:
12905 case EM_XTENSA:
12906 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
12907 default:
12908 /* Do not abort or issue an error message here. Not all targets use
12909 pc-relative 32-bit relocs in their DWARF debug information and we
12910 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
12911 more helpful warning message will be generated by apply_relocations
12912 anyway, so just return. */
aca88567
NC
12913 return FALSE;
12914 }
12915}
12916
12917/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12918 a 64-bit absolute RELA relocation used in DWARF debug sections. */
12919
12920static bfd_boolean
dda8d76d 12921is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12922{
dda8d76d 12923 switch (filedata->file_header.e_machine)
aca88567 12924 {
a06ea964
NC
12925 case EM_AARCH64:
12926 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
12927 case EM_ALPHA:
12928 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 12929 case EM_IA_64:
262cdac7
AM
12930 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
12931 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
12932 case EM_PARISC:
12933 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
12934 case EM_PPC64:
12935 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
12936 case EM_RISCV:
12937 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
12938 case EM_SPARC32PLUS:
12939 case EM_SPARCV9:
12940 case EM_SPARC:
714da62f
NC
12941 return reloc_type == 32 /* R_SPARC_64. */
12942 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 12943 case EM_X86_64:
8a9036a4 12944 case EM_L1OM:
7a9068fe 12945 case EM_K1OM:
aca88567 12946 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
12947 case EM_S390_OLD:
12948 case EM_S390:
aa137e4d
NC
12949 return reloc_type == 22; /* R_S390_64. */
12950 case EM_TILEGX:
12951 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 12952 case EM_MIPS:
aa137e4d 12953 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
12954 default:
12955 return FALSE;
12956 }
12957}
12958
85acf597
RH
12959/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
12960 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
12961
12962static bfd_boolean
dda8d76d 12963is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 12964{
dda8d76d 12965 switch (filedata->file_header.e_machine)
85acf597 12966 {
a06ea964
NC
12967 case EM_AARCH64:
12968 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 12969 case EM_ALPHA:
aa137e4d 12970 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 12971 case EM_IA_64:
262cdac7
AM
12972 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
12973 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 12974 case EM_PARISC:
aa137e4d 12975 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 12976 case EM_PPC64:
aa137e4d 12977 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
12978 case EM_SPARC32PLUS:
12979 case EM_SPARCV9:
12980 case EM_SPARC:
aa137e4d 12981 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 12982 case EM_X86_64:
8a9036a4 12983 case EM_L1OM:
7a9068fe 12984 case EM_K1OM:
aa137e4d 12985 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
12986 case EM_S390_OLD:
12987 case EM_S390:
aa137e4d
NC
12988 return reloc_type == 23; /* R_S390_PC64. */
12989 case EM_TILEGX:
12990 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
12991 default:
12992 return FALSE;
12993 }
12994}
12995
4dc3c23d
AM
12996/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12997 a 24-bit absolute RELA relocation used in DWARF debug sections. */
12998
12999static bfd_boolean
dda8d76d 13000is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13001{
dda8d76d 13002 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13003 {
13004 case EM_CYGNUS_MN10200:
13005 case EM_MN10200:
13006 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13007 case EM_FT32:
13008 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13009 case EM_Z80:
13010 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
13011 default:
13012 return FALSE;
13013 }
13014}
13015
aca88567
NC
13016/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13017 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13018
13019static bfd_boolean
dda8d76d 13020is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13021{
d347c9df 13022 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13023 switch (filedata->file_header.e_machine)
4b78141a 13024 {
886a2506
NC
13025 case EM_ARC:
13026 case EM_ARC_COMPACT:
13027 case EM_ARC_COMPACT2:
13028 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13029 case EM_ADAPTEVA_EPIPHANY:
13030 return reloc_type == 5;
aca88567
NC
13031 case EM_AVR_OLD:
13032 case EM_AVR:
13033 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13034 case EM_CYGNUS_D10V:
13035 case EM_D10V:
13036 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13037 case EM_FT32:
13038 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13039 case EM_H8S:
13040 case EM_H8_300:
13041 case EM_H8_300H:
aca88567
NC
13042 return reloc_type == R_H8_DIR16;
13043 case EM_IP2K_OLD:
13044 case EM_IP2K:
13045 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13046 case EM_M32C_OLD:
f4236fe4
DD
13047 case EM_M32C:
13048 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13049 case EM_CYGNUS_MN10200:
13050 case EM_MN10200:
13051 return reloc_type == 2; /* R_MN10200_16. */
13052 case EM_CYGNUS_MN10300:
13053 case EM_MN10300:
13054 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13055 case EM_MSP430:
dda8d76d 13056 if (uses_msp430x_relocs (filedata))
13761a11 13057 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13058 /* Fall through. */
78c8d46c 13059 case EM_MSP430_OLD:
aca88567 13060 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13061 case EM_NDS32:
13062 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13063 case EM_ALTERA_NIOS2:
36591ba1 13064 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13065 case EM_NIOS32:
13066 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13067 case EM_OR1K:
13068 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13069 case EM_RISCV:
13070 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13071 case EM_TI_PRU:
13072 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13073 case EM_TI_C6000:
13074 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13075 case EM_VISIUM:
13076 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13077 case EM_XC16X:
13078 case EM_C166:
13079 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13080 case EM_XGATE:
13081 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13082 case EM_Z80:
13083 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13084 default:
aca88567 13085 return FALSE;
4b78141a
NC
13086 }
13087}
13088
39e07931
AS
13089/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13090 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13091
13092static bfd_boolean
13093is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13094{
13095 switch (filedata->file_header.e_machine)
13096 {
13097 case EM_RISCV:
13098 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13099 case EM_Z80:
13100 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13101 default:
13102 return FALSE;
13103 }
13104}
13105
13106/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13107 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13108
13109static bfd_boolean
13110is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13111{
13112 switch (filedata->file_header.e_machine)
13113 {
13114 case EM_RISCV:
13115 return reloc_type == 53; /* R_RISCV_SET6. */
13116 default:
13117 return FALSE;
13118 }
13119}
13120
03336641
JW
13121/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13122 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13123
13124static bfd_boolean
13125is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13126{
13127 /* Please keep this table alpha-sorted for ease of visual lookup. */
13128 switch (filedata->file_header.e_machine)
13129 {
13130 case EM_RISCV:
13131 return reloc_type == 35; /* R_RISCV_ADD32. */
13132 default:
13133 return FALSE;
13134 }
13135}
13136
13137/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13138 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13139
13140static bfd_boolean
13141is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13142{
13143 /* Please keep this table alpha-sorted for ease of visual lookup. */
13144 switch (filedata->file_header.e_machine)
13145 {
13146 case EM_RISCV:
13147 return reloc_type == 39; /* R_RISCV_SUB32. */
13148 default:
13149 return FALSE;
13150 }
13151}
13152
13153/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13154 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13155
13156static bfd_boolean
13157is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13158{
13159 /* Please keep this table alpha-sorted for ease of visual lookup. */
13160 switch (filedata->file_header.e_machine)
13161 {
13162 case EM_RISCV:
13163 return reloc_type == 36; /* R_RISCV_ADD64. */
13164 default:
13165 return FALSE;
13166 }
13167}
13168
13169/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13170 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13171
13172static bfd_boolean
13173is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13174{
13175 /* Please keep this table alpha-sorted for ease of visual lookup. */
13176 switch (filedata->file_header.e_machine)
13177 {
13178 case EM_RISCV:
13179 return reloc_type == 40; /* R_RISCV_SUB64. */
13180 default:
13181 return FALSE;
13182 }
13183}
13184
13185/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13186 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13187
13188static bfd_boolean
13189is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13190{
13191 /* Please keep this table alpha-sorted for ease of visual lookup. */
13192 switch (filedata->file_header.e_machine)
13193 {
13194 case EM_RISCV:
13195 return reloc_type == 34; /* R_RISCV_ADD16. */
13196 default:
13197 return FALSE;
13198 }
13199}
13200
13201/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13202 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13203
13204static bfd_boolean
13205is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13206{
13207 /* Please keep this table alpha-sorted for ease of visual lookup. */
13208 switch (filedata->file_header.e_machine)
13209 {
13210 case EM_RISCV:
13211 return reloc_type == 38; /* R_RISCV_SUB16. */
13212 default:
13213 return FALSE;
13214 }
13215}
13216
13217/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13218 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13219
13220static bfd_boolean
13221is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13222{
13223 /* Please keep this table alpha-sorted for ease of visual lookup. */
13224 switch (filedata->file_header.e_machine)
13225 {
13226 case EM_RISCV:
13227 return reloc_type == 33; /* R_RISCV_ADD8. */
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 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13235
13236static bfd_boolean
13237is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13238{
13239 /* Please keep this table alpha-sorted for ease of visual lookup. */
13240 switch (filedata->file_header.e_machine)
13241 {
13242 case EM_RISCV:
13243 return reloc_type == 37; /* R_RISCV_SUB8. */
13244 default:
13245 return FALSE;
13246 }
13247}
13248
39e07931
AS
13249/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13250 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13251
13252static bfd_boolean
13253is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13254{
13255 switch (filedata->file_header.e_machine)
13256 {
13257 case EM_RISCV:
13258 return reloc_type == 52; /* R_RISCV_SUB6. */
13259 default:
13260 return FALSE;
13261 }
13262}
13263
2a7b2e88
JK
13264/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13265 relocation entries (possibly formerly used for SHT_GROUP sections). */
13266
13267static bfd_boolean
dda8d76d 13268is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13269{
dda8d76d 13270 switch (filedata->file_header.e_machine)
2a7b2e88 13271 {
cb8f3167 13272 case EM_386: /* R_386_NONE. */
d347c9df 13273 case EM_68K: /* R_68K_NONE. */
cfb8c092 13274 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13275 case EM_ALPHA: /* R_ALPHA_NONE. */
13276 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13277 case EM_ARC: /* R_ARC_NONE. */
886a2506 13278 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13279 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13280 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13281 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13282 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13283 case EM_FT32: /* R_FT32_NONE. */
13284 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13285 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13286 case EM_L1OM: /* R_X86_64_NONE. */
13287 case EM_M32R: /* R_M32R_NONE. */
13288 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13289 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13290 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13291 case EM_NIOS32: /* R_NIOS_NONE. */
13292 case EM_OR1K: /* R_OR1K_NONE. */
13293 case EM_PARISC: /* R_PARISC_NONE. */
13294 case EM_PPC64: /* R_PPC64_NONE. */
13295 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13296 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13297 case EM_S390: /* R_390_NONE. */
13298 case EM_S390_OLD:
13299 case EM_SH: /* R_SH_NONE. */
13300 case EM_SPARC32PLUS:
13301 case EM_SPARC: /* R_SPARC_NONE. */
13302 case EM_SPARCV9:
aa137e4d
NC
13303 case EM_TILEGX: /* R_TILEGX_NONE. */
13304 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13305 case EM_TI_C6000:/* R_C6000_NONE. */
13306 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13307 case EM_XC16X:
6655dba2 13308 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 13309 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13310 return reloc_type == 0;
d347c9df 13311
a06ea964
NC
13312 case EM_AARCH64:
13313 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13314 case EM_AVR_OLD:
13315 case EM_AVR:
13316 return (reloc_type == 0 /* R_AVR_NONE. */
13317 || reloc_type == 30 /* R_AVR_DIFF8. */
13318 || reloc_type == 31 /* R_AVR_DIFF16. */
13319 || reloc_type == 32 /* R_AVR_DIFF32. */);
13320 case EM_METAG:
13321 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13322 case EM_NDS32:
13323 return (reloc_type == 0 /* R_XTENSA_NONE. */
13324 || reloc_type == 204 /* R_NDS32_DIFF8. */
13325 || reloc_type == 205 /* R_NDS32_DIFF16. */
13326 || reloc_type == 206 /* R_NDS32_DIFF32. */
13327 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13328 case EM_TI_PRU:
13329 return (reloc_type == 0 /* R_PRU_NONE. */
13330 || reloc_type == 65 /* R_PRU_DIFF8. */
13331 || reloc_type == 66 /* R_PRU_DIFF16. */
13332 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13333 case EM_XTENSA_OLD:
13334 case EM_XTENSA:
4dc3c23d
AM
13335 return (reloc_type == 0 /* R_XTENSA_NONE. */
13336 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13337 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
13338 || reloc_type == 19 /* R_XTENSA_DIFF32. */
13339 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
13340 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
13341 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
13342 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
13343 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
13344 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88
JK
13345 }
13346 return FALSE;
13347}
13348
d1c4b12b
NC
13349/* Returns TRUE if there is a relocation against
13350 section NAME at OFFSET bytes. */
13351
13352bfd_boolean
13353reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13354{
13355 Elf_Internal_Rela * relocs;
13356 Elf_Internal_Rela * rp;
13357
13358 if (dsec == NULL || dsec->reloc_info == NULL)
13359 return FALSE;
13360
13361 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13362
13363 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13364 if (rp->r_offset == offset)
13365 return TRUE;
13366
13367 return FALSE;
13368}
13369
cf13d699 13370/* Apply relocations to a section.
32ec8896
NC
13371 Returns TRUE upon success, FALSE otherwise.
13372 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13373 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13374 will be set to the number of relocs loaded.
13375
cf13d699 13376 Note: So far support has been added only for those relocations
32ec8896
NC
13377 which can be found in debug sections. FIXME: Add support for
13378 more relocations ? */
1b315056 13379
32ec8896 13380static bfd_boolean
dda8d76d 13381apply_relocations (Filedata * filedata,
d1c4b12b
NC
13382 const Elf_Internal_Shdr * section,
13383 unsigned char * start,
13384 bfd_size_type size,
1449284b 13385 void ** relocs_return,
d1c4b12b 13386 unsigned long * num_relocs_return)
1b315056 13387{
cf13d699 13388 Elf_Internal_Shdr * relsec;
0d2a7a93 13389 unsigned char * end = start + size;
cb8f3167 13390
d1c4b12b
NC
13391 if (relocs_return != NULL)
13392 {
13393 * (Elf_Internal_Rela **) relocs_return = NULL;
13394 * num_relocs_return = 0;
13395 }
13396
dda8d76d 13397 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13398 /* No relocs to apply. */
13399 return TRUE;
1b315056 13400
cf13d699 13401 /* Find the reloc section associated with the section. */
dda8d76d
NC
13402 for (relsec = filedata->section_headers;
13403 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13404 ++relsec)
252b5132 13405 {
41e92641
NC
13406 bfd_boolean is_rela;
13407 unsigned long num_relocs;
2cf0635d
NC
13408 Elf_Internal_Rela * relocs;
13409 Elf_Internal_Rela * rp;
13410 Elf_Internal_Shdr * symsec;
13411 Elf_Internal_Sym * symtab;
ba5cdace 13412 unsigned long num_syms;
2cf0635d 13413 Elf_Internal_Sym * sym;
252b5132 13414
41e92641 13415 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13416 || relsec->sh_info >= filedata->file_header.e_shnum
13417 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13418 || relsec->sh_size == 0
dda8d76d 13419 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13420 continue;
428409d5 13421
a788aedd
AM
13422 symsec = filedata->section_headers + relsec->sh_link;
13423 if (symsec->sh_type != SHT_SYMTAB
13424 && symsec->sh_type != SHT_DYNSYM)
13425 return FALSE;
13426
41e92641
NC
13427 is_rela = relsec->sh_type == SHT_RELA;
13428
13429 if (is_rela)
13430 {
dda8d76d 13431 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13432 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13433 return FALSE;
41e92641
NC
13434 }
13435 else
13436 {
dda8d76d 13437 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13438 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13439 return FALSE;
41e92641
NC
13440 }
13441
13442 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13443 if (filedata->file_header.e_machine == EM_SH)
41e92641 13444 is_rela = FALSE;
428409d5 13445
dda8d76d 13446 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13447
41e92641 13448 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13449 {
41e92641
NC
13450 bfd_vma addend;
13451 unsigned int reloc_type;
13452 unsigned int reloc_size;
03336641
JW
13453 bfd_boolean reloc_inplace = FALSE;
13454 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13455 unsigned char * rloc;
ba5cdace 13456 unsigned long sym_index;
4b78141a 13457
dda8d76d 13458 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13459
dda8d76d 13460 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13461 continue;
dda8d76d 13462 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13463 continue;
dda8d76d
NC
13464 else if (is_32bit_abs_reloc (filedata, reloc_type)
13465 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13466 reloc_size = 4;
dda8d76d
NC
13467 else if (is_64bit_abs_reloc (filedata, reloc_type)
13468 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13469 reloc_size = 8;
dda8d76d 13470 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13471 reloc_size = 3;
dda8d76d 13472 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13473 reloc_size = 2;
39e07931
AS
13474 else if (is_8bit_abs_reloc (filedata, reloc_type)
13475 || is_6bit_abs_reloc (filedata, reloc_type))
13476 reloc_size = 1;
03336641
JW
13477 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13478 reloc_type))
13479 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13480 {
13481 reloc_size = 4;
13482 reloc_inplace = TRUE;
13483 }
13484 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13485 reloc_type))
13486 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13487 {
13488 reloc_size = 8;
13489 reloc_inplace = TRUE;
13490 }
13491 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13492 reloc_type))
13493 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13494 {
13495 reloc_size = 2;
13496 reloc_inplace = TRUE;
13497 }
13498 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13499 reloc_type))
13500 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13501 {
13502 reloc_size = 1;
13503 reloc_inplace = TRUE;
13504 }
39e07931
AS
13505 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13506 reloc_type)))
13507 {
13508 reloc_size = 1;
13509 reloc_inplace = TRUE;
13510 }
aca88567 13511 else
4b78141a 13512 {
bee0ee85 13513 static unsigned int prev_reloc = 0;
dda8d76d 13514
bee0ee85
NC
13515 if (reloc_type != prev_reloc)
13516 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13517 reloc_type, printable_section_name (filedata, section));
bee0ee85 13518 prev_reloc = reloc_type;
4b78141a
NC
13519 continue;
13520 }
103f02d3 13521
91d6fa6a 13522 rloc = start + rp->r_offset;
75802ccb 13523 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
13524 {
13525 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13526 (unsigned long) rp->r_offset,
dda8d76d 13527 printable_section_name (filedata, section));
700dd8b7
L
13528 continue;
13529 }
103f02d3 13530
ba5cdace
NC
13531 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13532 if (sym_index >= num_syms)
13533 {
13534 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13535 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
13536 continue;
13537 }
13538 sym = symtab + sym_index;
41e92641
NC
13539
13540 /* If the reloc has a symbol associated with it,
55f25fc3
L
13541 make sure that it is of an appropriate type.
13542
13543 Relocations against symbols without type can happen.
13544 Gcc -feliminate-dwarf2-dups may generate symbols
13545 without type for debug info.
13546
13547 Icc generates relocations against function symbols
13548 instead of local labels.
13549
13550 Relocations against object symbols can happen, eg when
13551 referencing a global array. For an example of this see
13552 the _clz.o binary in libgcc.a. */
aca88567 13553 if (sym != symtab
b8871f35 13554 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13555 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13556 {
d3a49aa8 13557 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13558 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13559 printable_section_name (filedata, relsec),
d3a49aa8 13560 (long int)(rp - relocs));
aca88567 13561 continue;
5b18a4bc 13562 }
252b5132 13563
4dc3c23d
AM
13564 addend = 0;
13565 if (is_rela)
13566 addend += rp->r_addend;
c47320c3
AM
13567 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13568 partial_inplace. */
4dc3c23d 13569 if (!is_rela
dda8d76d 13570 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13571 && reloc_type == 1)
dda8d76d
NC
13572 || ((filedata->file_header.e_machine == EM_PJ
13573 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13574 && reloc_type == 1)
dda8d76d
NC
13575 || ((filedata->file_header.e_machine == EM_D30V
13576 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13577 && reloc_type == 12)
13578 || reloc_inplace)
39e07931
AS
13579 {
13580 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
13581 addend += byte_get (rloc, reloc_size) & 0x3f;
13582 else
13583 addend += byte_get (rloc, reloc_size);
13584 }
cb8f3167 13585
dda8d76d
NC
13586 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13587 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13588 {
13589 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13590 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13591 addend -= 8;
91d6fa6a 13592 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13593 reloc_size);
13594 }
39e07931
AS
13595 else if (is_6bit_abs_reloc (filedata, reloc_type)
13596 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
13597 {
13598 if (reloc_subtract)
13599 addend -= sym->st_value;
13600 else
13601 addend += sym->st_value;
13602 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
13603 byte_put (rloc, addend, reloc_size);
13604 }
03336641
JW
13605 else if (reloc_subtract)
13606 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13607 else
91d6fa6a 13608 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13609 }
252b5132 13610
5b18a4bc 13611 free (symtab);
f84ce13b
NC
13612 /* Let the target specific reloc processing code know that
13613 we have finished with these relocs. */
dda8d76d 13614 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13615
13616 if (relocs_return)
13617 {
13618 * (Elf_Internal_Rela **) relocs_return = relocs;
13619 * num_relocs_return = num_relocs;
13620 }
13621 else
13622 free (relocs);
13623
5b18a4bc
NC
13624 break;
13625 }
32ec8896 13626
dfc616fa 13627 return TRUE;
5b18a4bc 13628}
103f02d3 13629
cf13d699 13630#ifdef SUPPORT_DISASSEMBLY
32ec8896 13631static bfd_boolean
dda8d76d 13632disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13633{
dda8d76d 13634 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13635
74e1a04b 13636 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13637
32ec8896 13638 return TRUE;
cf13d699
NC
13639}
13640#endif
13641
13642/* Reads in the contents of SECTION from FILE, returning a pointer
13643 to a malloc'ed buffer or NULL if something went wrong. */
13644
13645static char *
dda8d76d 13646get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13647{
dda8d76d 13648 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13649
13650 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13651 {
c6b78c96 13652 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13653 printable_section_name (filedata, section));
cf13d699
NC
13654 return NULL;
13655 }
13656
dda8d76d 13657 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13658 _("section contents"));
cf13d699
NC
13659}
13660
0e602686
NC
13661/* Uncompresses a section that was compressed using zlib, in place. */
13662
13663static bfd_boolean
dda8d76d
NC
13664uncompress_section_contents (unsigned char ** buffer,
13665 dwarf_size_type uncompressed_size,
13666 dwarf_size_type * size)
0e602686
NC
13667{
13668 dwarf_size_type compressed_size = *size;
13669 unsigned char * compressed_buffer = *buffer;
13670 unsigned char * uncompressed_buffer;
13671 z_stream strm;
13672 int rc;
13673
13674 /* It is possible the section consists of several compressed
13675 buffers concatenated together, so we uncompress in a loop. */
13676 /* PR 18313: The state field in the z_stream structure is supposed
13677 to be invisible to the user (ie us), but some compilers will
13678 still complain about it being used without initialisation. So
13679 we first zero the entire z_stream structure and then set the fields
13680 that we need. */
13681 memset (& strm, 0, sizeof strm);
13682 strm.avail_in = compressed_size;
13683 strm.next_in = (Bytef *) compressed_buffer;
13684 strm.avail_out = uncompressed_size;
13685 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13686
13687 rc = inflateInit (& strm);
13688 while (strm.avail_in > 0)
13689 {
13690 if (rc != Z_OK)
13691 goto fail;
13692 strm.next_out = ((Bytef *) uncompressed_buffer
13693 + (uncompressed_size - strm.avail_out));
13694 rc = inflate (&strm, Z_FINISH);
13695 if (rc != Z_STREAM_END)
13696 goto fail;
13697 rc = inflateReset (& strm);
13698 }
13699 rc = inflateEnd (& strm);
13700 if (rc != Z_OK
13701 || strm.avail_out != 0)
13702 goto fail;
13703
13704 *buffer = uncompressed_buffer;
13705 *size = uncompressed_size;
13706 return TRUE;
13707
13708 fail:
13709 free (uncompressed_buffer);
13710 /* Indicate decompression failure. */
13711 *buffer = NULL;
13712 return FALSE;
13713}
dd24e3da 13714
32ec8896 13715static bfd_boolean
dda8d76d 13716dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13717{
0e602686
NC
13718 Elf_Internal_Shdr * relsec;
13719 bfd_size_type num_bytes;
fd8008d8
L
13720 unsigned char * data;
13721 unsigned char * end;
13722 unsigned char * real_start;
13723 unsigned char * start;
0e602686 13724 bfd_boolean some_strings_shown;
cf13d699 13725
dda8d76d 13726 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13727 if (start == NULL)
c6b78c96
NC
13728 /* PR 21820: Do not fail if the section was empty. */
13729 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13730
0e602686 13731 num_bytes = section->sh_size;
cf13d699 13732
dda8d76d 13733 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13734
0e602686
NC
13735 if (decompress_dumps)
13736 {
13737 dwarf_size_type new_size = num_bytes;
13738 dwarf_size_type uncompressed_size = 0;
13739
13740 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13741 {
13742 Elf_Internal_Chdr chdr;
13743 unsigned int compression_header_size
ebdf1ebf
NC
13744 = get_compression_header (& chdr, (unsigned char *) start,
13745 num_bytes);
5844b465
NC
13746 if (compression_header_size == 0)
13747 /* An error message will have already been generated
13748 by get_compression_header. */
13749 goto error_out;
0e602686 13750
813dabb9 13751 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13752 {
813dabb9 13753 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13754 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 13755 goto error_out;
813dabb9 13756 }
813dabb9
L
13757 uncompressed_size = chdr.ch_size;
13758 start += compression_header_size;
13759 new_size -= compression_header_size;
0e602686
NC
13760 }
13761 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13762 {
13763 /* Read the zlib header. In this case, it should be "ZLIB"
13764 followed by the uncompressed section size, 8 bytes in
13765 big-endian order. */
13766 uncompressed_size = start[4]; uncompressed_size <<= 8;
13767 uncompressed_size += start[5]; uncompressed_size <<= 8;
13768 uncompressed_size += start[6]; uncompressed_size <<= 8;
13769 uncompressed_size += start[7]; uncompressed_size <<= 8;
13770 uncompressed_size += start[8]; uncompressed_size <<= 8;
13771 uncompressed_size += start[9]; uncompressed_size <<= 8;
13772 uncompressed_size += start[10]; uncompressed_size <<= 8;
13773 uncompressed_size += start[11];
13774 start += 12;
13775 new_size -= 12;
13776 }
13777
1835f746
NC
13778 if (uncompressed_size)
13779 {
13780 if (uncompress_section_contents (& start,
13781 uncompressed_size, & new_size))
13782 num_bytes = new_size;
13783 else
13784 {
13785 error (_("Unable to decompress section %s\n"),
dda8d76d 13786 printable_section_name (filedata, section));
f761cb13 13787 goto error_out;
1835f746
NC
13788 }
13789 }
bc303e5d
NC
13790 else
13791 start = real_start;
0e602686 13792 }
fd8008d8 13793
cf13d699
NC
13794 /* If the section being dumped has relocations against it the user might
13795 be expecting these relocations to have been applied. Check for this
13796 case and issue a warning message in order to avoid confusion.
13797 FIXME: Maybe we ought to have an option that dumps a section with
13798 relocs applied ? */
dda8d76d
NC
13799 for (relsec = filedata->section_headers;
13800 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13801 ++relsec)
13802 {
13803 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13804 || relsec->sh_info >= filedata->file_header.e_shnum
13805 || filedata->section_headers + relsec->sh_info != section
cf13d699 13806 || relsec->sh_size == 0
dda8d76d 13807 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13808 continue;
13809
13810 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13811 break;
13812 }
13813
cf13d699
NC
13814 data = start;
13815 end = start + num_bytes;
13816 some_strings_shown = FALSE;
13817
ba3265d0
NC
13818#ifdef HAVE_MBSTATE_T
13819 mbstate_t state;
13820 /* Initialise the multibyte conversion state. */
13821 memset (& state, 0, sizeof (state));
13822#endif
13823
13824 bfd_boolean continuing = FALSE;
13825
cf13d699
NC
13826 while (data < end)
13827 {
13828 while (!ISPRINT (* data))
13829 if (++ data >= end)
13830 break;
13831
13832 if (data < end)
13833 {
071436c6
NC
13834 size_t maxlen = end - data;
13835
ba3265d0
NC
13836 if (continuing)
13837 {
13838 printf (" ");
13839 continuing = FALSE;
13840 }
13841 else
13842 {
cf13d699 13843#ifndef __MSVCRT__
ba3265d0
NC
13844 /* PR 11128: Use two separate invocations in order to work
13845 around bugs in the Solaris 8 implementation of printf. */
13846 printf (" [%6tx] ", data - start);
cf13d699 13847#else
ba3265d0 13848 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 13849#endif
ba3265d0
NC
13850 }
13851
4082ef84
NC
13852 if (maxlen > 0)
13853 {
ba3265d0
NC
13854 char c;
13855
13856 while (maxlen)
13857 {
13858 c = *data++;
13859
13860 if (c == 0)
13861 break;
13862
13863 /* PR 25543: Treat new-lines as string-ending characters. */
13864 if (c == '\n')
13865 {
13866 printf ("\\n\n");
13867 if (*data != 0)
13868 continuing = TRUE;
13869 break;
13870 }
13871
13872 /* Do not print control characters directly as they can affect terminal
13873 settings. Such characters usually appear in the names generated
13874 by the assembler for local labels. */
13875 if (ISCNTRL (c))
13876 {
13877 printf ("^%c", c + 0x40);
13878 }
13879 else if (ISPRINT (c))
13880 {
13881 putchar (c);
13882 }
13883 else
13884 {
13885 size_t n;
13886#ifdef HAVE_MBSTATE_T
13887 wchar_t w;
13888#endif
13889 /* Let printf do the hard work of displaying multibyte characters. */
13890 printf ("%.1s", data - 1);
13891#ifdef HAVE_MBSTATE_T
13892 /* Try to find out how many bytes made up the character that was
13893 just printed. Advance the symbol pointer past the bytes that
13894 were displayed. */
13895 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
13896#else
13897 n = 1;
13898#endif
13899 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
13900 data += (n - 1);
13901 }
13902 }
13903
13904 if (c != '\n')
13905 putchar ('\n');
4082ef84
NC
13906 }
13907 else
13908 {
13909 printf (_("<corrupt>\n"));
13910 data = end;
13911 }
cf13d699
NC
13912 some_strings_shown = TRUE;
13913 }
13914 }
13915
13916 if (! some_strings_shown)
13917 printf (_(" No strings found in this section."));
13918
0e602686 13919 free (real_start);
cf13d699
NC
13920
13921 putchar ('\n');
32ec8896 13922 return TRUE;
f761cb13
AM
13923
13924error_out:
13925 free (real_start);
13926 return FALSE;
cf13d699
NC
13927}
13928
32ec8896 13929static bfd_boolean
dda8d76d
NC
13930dump_section_as_bytes (Elf_Internal_Shdr * section,
13931 Filedata * filedata,
13932 bfd_boolean relocate)
cf13d699
NC
13933{
13934 Elf_Internal_Shdr * relsec;
0e602686
NC
13935 bfd_size_type bytes;
13936 bfd_size_type section_size;
13937 bfd_vma addr;
13938 unsigned char * data;
13939 unsigned char * real_start;
13940 unsigned char * start;
13941
dda8d76d 13942 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13943 if (start == NULL)
c6b78c96
NC
13944 /* PR 21820: Do not fail if the section was empty. */
13945 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 13946
0e602686 13947 section_size = section->sh_size;
cf13d699 13948
dda8d76d 13949 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13950
0e602686
NC
13951 if (decompress_dumps)
13952 {
13953 dwarf_size_type new_size = section_size;
13954 dwarf_size_type uncompressed_size = 0;
13955
13956 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13957 {
13958 Elf_Internal_Chdr chdr;
13959 unsigned int compression_header_size
ebdf1ebf 13960 = get_compression_header (& chdr, start, section_size);
0e602686 13961
5844b465
NC
13962 if (compression_header_size == 0)
13963 /* An error message will have already been generated
13964 by get_compression_header. */
13965 goto error_out;
13966
813dabb9 13967 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13968 {
813dabb9 13969 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13970 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 13971 goto error_out;
0e602686 13972 }
813dabb9
L
13973 uncompressed_size = chdr.ch_size;
13974 start += compression_header_size;
13975 new_size -= compression_header_size;
0e602686
NC
13976 }
13977 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13978 {
13979 /* Read the zlib header. In this case, it should be "ZLIB"
13980 followed by the uncompressed section size, 8 bytes in
13981 big-endian order. */
13982 uncompressed_size = start[4]; uncompressed_size <<= 8;
13983 uncompressed_size += start[5]; uncompressed_size <<= 8;
13984 uncompressed_size += start[6]; uncompressed_size <<= 8;
13985 uncompressed_size += start[7]; uncompressed_size <<= 8;
13986 uncompressed_size += start[8]; uncompressed_size <<= 8;
13987 uncompressed_size += start[9]; uncompressed_size <<= 8;
13988 uncompressed_size += start[10]; uncompressed_size <<= 8;
13989 uncompressed_size += start[11];
13990 start += 12;
13991 new_size -= 12;
13992 }
13993
f055032e
NC
13994 if (uncompressed_size)
13995 {
13996 if (uncompress_section_contents (& start, uncompressed_size,
13997 & new_size))
bc303e5d
NC
13998 {
13999 section_size = new_size;
14000 }
f055032e
NC
14001 else
14002 {
14003 error (_("Unable to decompress section %s\n"),
dda8d76d 14004 printable_section_name (filedata, section));
bc303e5d 14005 /* FIXME: Print the section anyway ? */
f761cb13 14006 goto error_out;
f055032e
NC
14007 }
14008 }
bc303e5d
NC
14009 else
14010 start = real_start;
0e602686 14011 }
14ae95f2 14012
cf13d699
NC
14013 if (relocate)
14014 {
dda8d76d 14015 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14016 goto error_out;
cf13d699
NC
14017 }
14018 else
14019 {
14020 /* If the section being dumped has relocations against it the user might
14021 be expecting these relocations to have been applied. Check for this
14022 case and issue a warning message in order to avoid confusion.
14023 FIXME: Maybe we ought to have an option that dumps a section with
14024 relocs applied ? */
dda8d76d
NC
14025 for (relsec = filedata->section_headers;
14026 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14027 ++relsec)
14028 {
14029 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14030 || relsec->sh_info >= filedata->file_header.e_shnum
14031 || filedata->section_headers + relsec->sh_info != section
cf13d699 14032 || relsec->sh_size == 0
dda8d76d 14033 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14034 continue;
14035
14036 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14037 break;
14038 }
14039 }
14040
14041 addr = section->sh_addr;
0e602686 14042 bytes = section_size;
cf13d699
NC
14043 data = start;
14044
14045 while (bytes)
14046 {
14047 int j;
14048 int k;
14049 int lbytes;
14050
14051 lbytes = (bytes > 16 ? 16 : bytes);
14052
14053 printf (" 0x%8.8lx ", (unsigned long) addr);
14054
14055 for (j = 0; j < 16; j++)
14056 {
14057 if (j < lbytes)
14058 printf ("%2.2x", data[j]);
14059 else
14060 printf (" ");
14061
14062 if ((j & 3) == 3)
14063 printf (" ");
14064 }
14065
14066 for (j = 0; j < lbytes; j++)
14067 {
14068 k = data[j];
14069 if (k >= ' ' && k < 0x7f)
14070 printf ("%c", k);
14071 else
14072 printf (".");
14073 }
14074
14075 putchar ('\n');
14076
14077 data += lbytes;
14078 addr += lbytes;
14079 bytes -= lbytes;
14080 }
14081
0e602686 14082 free (real_start);
cf13d699
NC
14083
14084 putchar ('\n');
32ec8896 14085 return TRUE;
f761cb13
AM
14086
14087 error_out:
14088 free (real_start);
14089 return FALSE;
cf13d699
NC
14090}
14091
7d9813f1
NA
14092static ctf_sect_t *
14093shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14094{
90bd5423 14095 buf->cts_name = SECTION_NAME (shdr);
7d9813f1
NA
14096 buf->cts_size = shdr->sh_size;
14097 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14098
14099 return buf;
14100}
14101
14102/* Formatting callback function passed to ctf_dump. Returns either the pointer
14103 it is passed, or a pointer to newly-allocated storage, in which case
14104 dump_ctf() will free it when it no longer needs it. */
14105
14106static char *dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14107 char *s, void *arg)
14108{
3e50a591 14109 const char *blanks = arg;
7d9813f1
NA
14110 char *new_s;
14111
3e50a591 14112 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14113 return s;
14114 return new_s;
14115}
14116
14117static bfd_boolean
14118dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14119{
14120 Elf_Internal_Shdr * parent_sec = NULL;
14121 Elf_Internal_Shdr * symtab_sec = NULL;
14122 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14123 void * data = NULL;
14124 void * symdata = NULL;
14125 void * strdata = NULL;
14126 void * parentdata = NULL;
14127 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14128 ctf_sect_t * symsectp = NULL;
14129 ctf_sect_t * strsectp = NULL;
14130 ctf_file_t * ctf = NULL;
14131 ctf_file_t * parent = NULL;
7d9813f1 14132
9b32cba4
NA
14133 const char *things[] = {"Header", "Labels", "Data objects",
14134 "Function objects", "Variables", "Types", "Strings",
14135 ""};
7d9813f1
NA
14136 const char **thing;
14137 int err;
14138 bfd_boolean ret = FALSE;
14139 size_t i;
14140
14141 shdr_to_ctf_sect (&ctfsect, section, filedata);
14142 data = get_section_contents (section, filedata);
14143 ctfsect.cts_data = data;
14144
616febde
NA
14145 if (!dump_ctf_symtab_name)
14146 dump_ctf_symtab_name = strdup (".symtab");
14147
14148 if (!dump_ctf_strtab_name)
14149 dump_ctf_strtab_name = strdup (".strtab");
14150
14151 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14152 {
14153 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14154 {
14155 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14156 goto fail;
14157 }
14158 if ((symdata = (void *) get_data (NULL, filedata,
14159 symtab_sec->sh_offset, 1,
14160 symtab_sec->sh_size,
14161 _("symbols"))) == NULL)
14162 goto fail;
14163 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14164 symsect.cts_data = symdata;
14165 }
616febde 14166 if (dump_ctf_strtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14167 {
14168 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14169 {
14170 error (_("No string table section named %s\n"),
14171 dump_ctf_strtab_name);
14172 goto fail;
14173 }
14174 if ((strdata = (void *) get_data (NULL, filedata,
14175 strtab_sec->sh_offset, 1,
14176 strtab_sec->sh_size,
14177 _("strings"))) == NULL)
14178 goto fail;
14179 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14180 strsect.cts_data = strdata;
14181 }
14182 if (dump_ctf_parent_name)
14183 {
14184 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14185 {
14186 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14187 goto fail;
14188 }
14189 if ((parentdata = (void *) get_data (NULL, filedata,
14190 parent_sec->sh_offset, 1,
14191 parent_sec->sh_size,
14192 _("CTF parent"))) == NULL)
14193 goto fail;
14194 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14195 parentsect.cts_data = parentdata;
14196 }
14197
14198 /* Load the CTF file and dump it. */
14199
14200 if ((ctf = ctf_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
14201 {
14202 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14203 goto fail;
14204 }
14205
14206 if (parentdata)
14207 {
14208 if ((parent = ctf_bufopen (&parentsect, symsectp, strsectp, &err)) == NULL)
14209 {
14210 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14211 goto fail;
14212 }
14213
14214 ctf_import (ctf, parent);
14215 }
14216
14217 ret = TRUE;
14218
14219 printf (_("\nDump of CTF section '%s':\n"),
14220 printable_section_name (filedata, section));
14221
9b32cba4 14222 for (i = 0, thing = things; *thing[0]; thing++, i++)
7d9813f1
NA
14223 {
14224 ctf_dump_state_t *s = NULL;
14225 char *item;
14226
14227 printf ("\n %s:\n", *thing);
14228 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14229 (void *) " ")) != NULL)
14230 {
14231 printf ("%s\n", item);
14232 free (item);
14233 }
14234
14235 if (ctf_errno (ctf))
14236 {
14237 error (_("Iteration failed: %s, %s\n"), *thing,
14238 ctf_errmsg (ctf_errno (ctf)));
14239 ret = FALSE;
14240 }
14241 }
14242
14243 fail:
14244 ctf_file_close (ctf);
14245 ctf_file_close (parent);
14246 free (parentdata);
14247 free (data);
14248 free (symdata);
14249 free (strdata);
14250 return ret;
14251}
14252
32ec8896 14253static bfd_boolean
dda8d76d
NC
14254load_specific_debug_section (enum dwarf_section_display_enum debug,
14255 const Elf_Internal_Shdr * sec,
14256 void * data)
1007acb3 14257{
2cf0635d 14258 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 14259 char buf [64];
dda8d76d 14260 Filedata * filedata = (Filedata *) data;
9abca702 14261
19e6b90e 14262 if (section->start != NULL)
dda8d76d
NC
14263 {
14264 /* If it is already loaded, do nothing. */
14265 if (streq (section->filename, filedata->file_name))
14266 return TRUE;
14267 free (section->start);
14268 }
1007acb3 14269
19e6b90e
L
14270 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
14271 section->address = sec->sh_addr;
06614111 14272 section->user_data = NULL;
dda8d76d
NC
14273 section->filename = filedata->file_name;
14274 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
14275 sec->sh_offset, 1,
14276 sec->sh_size, buf);
59245841
NC
14277 if (section->start == NULL)
14278 section->size = 0;
14279 else
14280 {
77115a4a
L
14281 unsigned char *start = section->start;
14282 dwarf_size_type size = sec->sh_size;
dab394de 14283 dwarf_size_type uncompressed_size = 0;
77115a4a
L
14284
14285 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
14286 {
14287 Elf_Internal_Chdr chdr;
d8024a91
NC
14288 unsigned int compression_header_size;
14289
f53be977
L
14290 if (size < (is_32bit_elf
14291 ? sizeof (Elf32_External_Chdr)
14292 : sizeof (Elf64_External_Chdr)))
d8024a91 14293 {
55be8fd0 14294 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 14295 section->name);
32ec8896 14296 return FALSE;
d8024a91
NC
14297 }
14298
ebdf1ebf 14299 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
14300 if (compression_header_size == 0)
14301 /* An error message will have already been generated
14302 by get_compression_header. */
14303 return FALSE;
d8024a91 14304
813dabb9
L
14305 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
14306 {
14307 warn (_("section '%s' has unsupported compress type: %d\n"),
14308 section->name, chdr.ch_type);
32ec8896 14309 return FALSE;
813dabb9 14310 }
dab394de 14311 uncompressed_size = chdr.ch_size;
77115a4a
L
14312 start += compression_header_size;
14313 size -= compression_header_size;
14314 }
dab394de
L
14315 else if (size > 12 && streq ((char *) start, "ZLIB"))
14316 {
14317 /* Read the zlib header. In this case, it should be "ZLIB"
14318 followed by the uncompressed section size, 8 bytes in
14319 big-endian order. */
14320 uncompressed_size = start[4]; uncompressed_size <<= 8;
14321 uncompressed_size += start[5]; uncompressed_size <<= 8;
14322 uncompressed_size += start[6]; uncompressed_size <<= 8;
14323 uncompressed_size += start[7]; uncompressed_size <<= 8;
14324 uncompressed_size += start[8]; uncompressed_size <<= 8;
14325 uncompressed_size += start[9]; uncompressed_size <<= 8;
14326 uncompressed_size += start[10]; uncompressed_size <<= 8;
14327 uncompressed_size += start[11];
14328 start += 12;
14329 size -= 12;
14330 }
14331
1835f746 14332 if (uncompressed_size)
77115a4a 14333 {
1835f746
NC
14334 if (uncompress_section_contents (&start, uncompressed_size,
14335 &size))
14336 {
14337 /* Free the compressed buffer, update the section buffer
14338 and the section size if uncompress is successful. */
14339 free (section->start);
14340 section->start = start;
14341 }
14342 else
14343 {
14344 error (_("Unable to decompress section %s\n"),
dda8d76d 14345 printable_section_name (filedata, sec));
32ec8896 14346 return FALSE;
1835f746 14347 }
77115a4a 14348 }
bc303e5d 14349
77115a4a 14350 section->size = size;
59245841 14351 }
4a114e3e 14352
1b315056 14353 if (section->start == NULL)
32ec8896 14354 return FALSE;
1b315056 14355
19e6b90e 14356 if (debug_displays [debug].relocate)
32ec8896 14357 {
dda8d76d 14358 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
14359 & section->reloc_info, & section->num_relocs))
14360 return FALSE;
14361 }
d1c4b12b
NC
14362 else
14363 {
14364 section->reloc_info = NULL;
14365 section->num_relocs = 0;
14366 }
1007acb3 14367
32ec8896 14368 return TRUE;
1007acb3
L
14369}
14370
301a9420
AM
14371#if HAVE_LIBDEBUGINFOD
14372/* Return a hex string representation of the build-id. */
14373unsigned char *
14374get_build_id (void * data)
14375{
14376 Filedata * filedata = (Filedata *)data;
14377 Elf_Internal_Shdr * shdr;
14378 unsigned long i;
14379
55be8fd0
NC
14380 /* Iterate through notes to find note.gnu.build-id.
14381 FIXME: Only the first note in any note section is examined. */
301a9420
AM
14382 for (i = 0, shdr = filedata->section_headers;
14383 i < filedata->file_header.e_shnum && shdr != NULL;
14384 i++, shdr++)
14385 {
14386 if (shdr->sh_type != SHT_NOTE)
14387 continue;
14388
14389 char * next;
14390 char * end;
14391 size_t data_remaining;
14392 size_t min_notesz;
14393 Elf_External_Note * enote;
14394 Elf_Internal_Note inote;
14395
14396 bfd_vma offset = shdr->sh_offset;
14397 bfd_vma align = shdr->sh_addralign;
14398 bfd_vma length = shdr->sh_size;
14399
14400 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
14401 if (enote == NULL)
14402 continue;
14403
14404 if (align < 4)
14405 align = 4;
14406 else if (align != 4 && align != 8)
f761cb13
AM
14407 {
14408 free (enote);
14409 continue;
14410 }
301a9420
AM
14411
14412 end = (char *) enote + length;
14413 data_remaining = end - (char *) enote;
14414
14415 if (!is_ia64_vms (filedata))
14416 {
14417 min_notesz = offsetof (Elf_External_Note, name);
14418 if (data_remaining < min_notesz)
14419 {
55be8fd0
NC
14420 warn (_("\
14421malformed note encountered in section %s whilst scanning for build-id note\n"),
14422 printable_section_name (filedata, shdr));
f761cb13 14423 free (enote);
55be8fd0 14424 continue;
301a9420
AM
14425 }
14426 data_remaining -= min_notesz;
14427
14428 inote.type = BYTE_GET (enote->type);
14429 inote.namesz = BYTE_GET (enote->namesz);
14430 inote.namedata = enote->name;
14431 inote.descsz = BYTE_GET (enote->descsz);
14432 inote.descdata = ((char *) enote
14433 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
14434 inote.descpos = offset + (inote.descdata - (char *) enote);
14435 next = ((char *) enote
14436 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
14437 }
14438 else
14439 {
14440 Elf64_External_VMS_Note *vms_enote;
14441
14442 /* PR binutils/15191
14443 Make sure that there is enough data to read. */
14444 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14445 if (data_remaining < min_notesz)
14446 {
55be8fd0
NC
14447 warn (_("\
14448malformed note encountered in section %s whilst scanning for build-id note\n"),
14449 printable_section_name (filedata, shdr));
f761cb13 14450 free (enote);
55be8fd0 14451 continue;
301a9420
AM
14452 }
14453 data_remaining -= min_notesz;
14454
14455 vms_enote = (Elf64_External_VMS_Note *) enote;
14456 inote.type = BYTE_GET (vms_enote->type);
14457 inote.namesz = BYTE_GET (vms_enote->namesz);
14458 inote.namedata = vms_enote->name;
14459 inote.descsz = BYTE_GET (vms_enote->descsz);
14460 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14461 inote.descpos = offset + (inote.descdata - (char *) enote);
14462 next = inote.descdata + align_power (inote.descsz, 3);
14463 }
14464
14465 /* Skip malformed notes. */
14466 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
14467 || (size_t) (inote.descdata - inote.namedata) > data_remaining
14468 || (size_t) (next - inote.descdata) < inote.descsz
14469 || ((size_t) (next - inote.descdata)
14470 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
14471 {
55be8fd0
NC
14472 warn (_("\
14473malformed note encountered in section %s whilst scanning for build-id note\n"),
14474 printable_section_name (filedata, shdr));
f761cb13 14475 free (enote);
301a9420
AM
14476 continue;
14477 }
14478
14479 /* Check if this is the build-id note. If so then convert the build-id
14480 bytes to a hex string. */
14481 if (inote.namesz > 0
14482 && const_strneq (inote.namedata, "GNU")
14483 && inote.type == NT_GNU_BUILD_ID)
14484 {
14485 unsigned long j;
14486 char * build_id;
14487
14488 build_id = malloc (inote.descsz * 2 + 1);
14489 if (build_id == NULL)
f761cb13
AM
14490 {
14491 free (enote);
14492 return NULL;
14493 }
301a9420
AM
14494
14495 for (j = 0; j < inote.descsz; ++j)
14496 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
14497 build_id[inote.descsz * 2] = '\0';
f761cb13 14498 free (enote);
301a9420 14499
55be8fd0 14500 return (unsigned char *) build_id;
301a9420 14501 }
f761cb13 14502 free (enote);
301a9420
AM
14503 }
14504
14505 return NULL;
14506}
14507#endif /* HAVE_LIBDEBUGINFOD */
14508
657d0d47
CC
14509/* If this is not NULL, load_debug_section will only look for sections
14510 within the list of sections given here. */
32ec8896 14511static unsigned int * section_subset = NULL;
657d0d47 14512
32ec8896 14513bfd_boolean
dda8d76d 14514load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 14515{
2cf0635d
NC
14516 struct dwarf_section * section = &debug_displays [debug].section;
14517 Elf_Internal_Shdr * sec;
dda8d76d
NC
14518 Filedata * filedata = (Filedata *) data;
14519
f425ec66
NC
14520 /* Without section headers we cannot find any sections. */
14521 if (filedata->section_headers == NULL)
14522 return FALSE;
14523
9c1ce108
AM
14524 if (filedata->string_table == NULL
14525 && filedata->file_header.e_shstrndx != SHN_UNDEF
14526 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
14527 {
14528 Elf_Internal_Shdr * strs;
14529
14530 /* Read in the string table, so that we have section names to scan. */
14531 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
14532
4dff97b2 14533 if (strs != NULL && strs->sh_size != 0)
dda8d76d 14534 {
9c1ce108
AM
14535 filedata->string_table
14536 = (char *) get_data (NULL, filedata, strs->sh_offset,
14537 1, strs->sh_size, _("string table"));
dda8d76d 14538
9c1ce108
AM
14539 filedata->string_table_length
14540 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
14541 }
14542 }
d966045b
DJ
14543
14544 /* Locate the debug section. */
dda8d76d 14545 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
14546 if (sec != NULL)
14547 section->name = section->uncompressed_name;
14548 else
14549 {
dda8d76d 14550 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
14551 if (sec != NULL)
14552 section->name = section->compressed_name;
14553 }
14554 if (sec == NULL)
32ec8896 14555 return FALSE;
d966045b 14556
657d0d47
CC
14557 /* If we're loading from a subset of sections, and we've loaded
14558 a section matching this name before, it's likely that it's a
14559 different one. */
14560 if (section_subset != NULL)
14561 free_debug_section (debug);
14562
dda8d76d 14563 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
14564}
14565
19e6b90e
L
14566void
14567free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 14568{
2cf0635d 14569 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 14570
19e6b90e
L
14571 if (section->start == NULL)
14572 return;
1007acb3 14573
19e6b90e
L
14574 free ((char *) section->start);
14575 section->start = NULL;
14576 section->address = 0;
14577 section->size = 0;
a788aedd
AM
14578
14579 if (section->reloc_info != NULL)
14580 {
14581 free (section->reloc_info);
14582 section->reloc_info = NULL;
14583 section->num_relocs = 0;
14584 }
1007acb3
L
14585}
14586
32ec8896 14587static bfd_boolean
dda8d76d 14588display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 14589{
2cf0635d 14590 char * name = SECTION_NAME (section);
dda8d76d 14591 const char * print_name = printable_section_name (filedata, section);
19e6b90e 14592 bfd_size_type length;
32ec8896 14593 bfd_boolean result = TRUE;
3f5e193b 14594 int i;
1007acb3 14595
19e6b90e
L
14596 length = section->sh_size;
14597 if (length == 0)
1007acb3 14598 {
74e1a04b 14599 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 14600 return TRUE;
1007acb3 14601 }
5dff79d8
NC
14602 if (section->sh_type == SHT_NOBITS)
14603 {
14604 /* There is no point in dumping the contents of a debugging section
14605 which has the NOBITS type - the bits in the file will be random.
14606 This can happen when a file containing a .eh_frame section is
14607 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
14608 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
14609 print_name);
32ec8896 14610 return FALSE;
5dff79d8 14611 }
1007acb3 14612
0112cd26 14613 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 14614 name = ".debug_info";
1007acb3 14615
19e6b90e
L
14616 /* See if we know how to display the contents of this section. */
14617 for (i = 0; i < max; i++)
d85bf2ba
NC
14618 {
14619 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
14620 struct dwarf_section_display * display = debug_displays + i;
14621 struct dwarf_section * sec = & display->section;
d966045b 14622
d85bf2ba
NC
14623 if (streq (sec->uncompressed_name, name)
14624 || (id == line && const_strneq (name, ".debug_line."))
14625 || streq (sec->compressed_name, name))
14626 {
14627 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 14628
d85bf2ba
NC
14629 if (secondary)
14630 free_debug_section (id);
dda8d76d 14631
d85bf2ba
NC
14632 if (i == line && const_strneq (name, ".debug_line."))
14633 sec->name = name;
14634 else if (streq (sec->uncompressed_name, name))
14635 sec->name = sec->uncompressed_name;
14636 else
14637 sec->name = sec->compressed_name;
657d0d47 14638
d85bf2ba
NC
14639 if (load_specific_debug_section (id, section, filedata))
14640 {
14641 /* If this debug section is part of a CU/TU set in a .dwp file,
14642 restrict load_debug_section to the sections in that set. */
14643 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 14644
d85bf2ba 14645 result &= display->display (sec, filedata);
657d0d47 14646
d85bf2ba 14647 section_subset = NULL;
1007acb3 14648
d85bf2ba
NC
14649 if (secondary || (id != info && id != abbrev))
14650 free_debug_section (id);
14651 }
14652 break;
14653 }
14654 }
1007acb3 14655
19e6b90e 14656 if (i == max)
1007acb3 14657 {
74e1a04b 14658 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 14659 result = FALSE;
1007acb3
L
14660 }
14661
19e6b90e 14662 return result;
5b18a4bc 14663}
103f02d3 14664
aef1f6d0
DJ
14665/* Set DUMP_SECTS for all sections where dumps were requested
14666 based on section name. */
14667
14668static void
dda8d76d 14669initialise_dumps_byname (Filedata * filedata)
aef1f6d0 14670{
2cf0635d 14671 struct dump_list_entry * cur;
aef1f6d0
DJ
14672
14673 for (cur = dump_sects_byname; cur; cur = cur->next)
14674 {
14675 unsigned int i;
32ec8896 14676 bfd_boolean any = FALSE;
aef1f6d0 14677
dda8d76d
NC
14678 for (i = 0; i < filedata->file_header.e_shnum; i++)
14679 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 14680 {
6431e409 14681 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 14682 any = TRUE;
aef1f6d0
DJ
14683 }
14684
14685 if (!any)
14686 warn (_("Section '%s' was not dumped because it does not exist!\n"),
14687 cur->name);
14688 }
14689}
14690
32ec8896 14691static bfd_boolean
dda8d76d 14692process_section_contents (Filedata * filedata)
5b18a4bc 14693{
2cf0635d 14694 Elf_Internal_Shdr * section;
19e6b90e 14695 unsigned int i;
32ec8896 14696 bfd_boolean res = TRUE;
103f02d3 14697
19e6b90e 14698 if (! do_dump)
32ec8896 14699 return TRUE;
103f02d3 14700
dda8d76d 14701 initialise_dumps_byname (filedata);
aef1f6d0 14702
dda8d76d 14703 for (i = 0, section = filedata->section_headers;
6431e409 14704 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
14705 i++, section++)
14706 {
6431e409 14707 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 14708
19e6b90e 14709#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
14710 if (dump & DISASS_DUMP)
14711 {
14712 if (! disassemble_section (section, filedata))
14713 res = FALSE;
14714 }
19e6b90e 14715#endif
dda8d76d 14716 if (dump & HEX_DUMP)
32ec8896 14717 {
dda8d76d 14718 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
14719 res = FALSE;
14720 }
103f02d3 14721
dda8d76d 14722 if (dump & RELOC_DUMP)
32ec8896 14723 {
dda8d76d 14724 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
14725 res = FALSE;
14726 }
09c11c86 14727
dda8d76d 14728 if (dump & STRING_DUMP)
32ec8896 14729 {
dda8d76d 14730 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
14731 res = FALSE;
14732 }
cf13d699 14733
dda8d76d 14734 if (dump & DEBUG_DUMP)
32ec8896 14735 {
dda8d76d 14736 if (! display_debug_section (i, section, filedata))
32ec8896
NC
14737 res = FALSE;
14738 }
7d9813f1
NA
14739
14740 if (dump & CTF_DUMP)
14741 {
14742 if (! dump_section_as_ctf (section, filedata))
14743 res = FALSE;
14744 }
5b18a4bc 14745 }
103f02d3 14746
19e6b90e
L
14747 /* Check to see if the user requested a
14748 dump of a section that does not exist. */
6431e409 14749 while (i < filedata->dump.num_dump_sects)
0ee3043f 14750 {
6431e409 14751 if (filedata->dump.dump_sects[i])
32ec8896
NC
14752 {
14753 warn (_("Section %d was not dumped because it does not exist!\n"), i);
14754 res = FALSE;
14755 }
0ee3043f
NC
14756 i++;
14757 }
32ec8896
NC
14758
14759 return res;
5b18a4bc 14760}
103f02d3 14761
5b18a4bc 14762static void
19e6b90e 14763process_mips_fpe_exception (int mask)
5b18a4bc 14764{
19e6b90e
L
14765 if (mask)
14766 {
32ec8896
NC
14767 bfd_boolean first = TRUE;
14768
19e6b90e 14769 if (mask & OEX_FPU_INEX)
32ec8896 14770 fputs ("INEX", stdout), first = FALSE;
19e6b90e 14771 if (mask & OEX_FPU_UFLO)
32ec8896 14772 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14773 if (mask & OEX_FPU_OFLO)
32ec8896 14774 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14775 if (mask & OEX_FPU_DIV0)
32ec8896 14776 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
14777 if (mask & OEX_FPU_INVAL)
14778 printf ("%sINVAL", first ? "" : "|");
14779 }
5b18a4bc 14780 else
19e6b90e 14781 fputs ("0", stdout);
5b18a4bc 14782}
103f02d3 14783
f6f0e17b
NC
14784/* Display's the value of TAG at location P. If TAG is
14785 greater than 0 it is assumed to be an unknown tag, and
14786 a message is printed to this effect. Otherwise it is
14787 assumed that a message has already been printed.
14788
14789 If the bottom bit of TAG is set it assumed to have a
14790 string value, otherwise it is assumed to have an integer
14791 value.
14792
14793 Returns an updated P pointing to the first unread byte
14794 beyond the end of TAG's value.
14795
14796 Reads at or beyond END will not be made. */
14797
14798static unsigned char *
60abdbed 14799display_tag_value (signed int tag,
f6f0e17b
NC
14800 unsigned char * p,
14801 const unsigned char * const end)
14802{
14803 unsigned long val;
14804
14805 if (tag > 0)
14806 printf (" Tag_unknown_%d: ", tag);
14807
14808 if (p >= end)
14809 {
4082ef84 14810 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
14811 }
14812 else if (tag & 1)
14813 {
071436c6
NC
14814 /* PR 17531 file: 027-19978-0.004. */
14815 size_t maxlen = (end - p) - 1;
14816
14817 putchar ('"');
4082ef84
NC
14818 if (maxlen > 0)
14819 {
14820 print_symbol ((int) maxlen, (const char *) p);
14821 p += strnlen ((char *) p, maxlen) + 1;
14822 }
14823 else
14824 {
14825 printf (_("<corrupt string tag>"));
14826 p = (unsigned char *) end;
14827 }
071436c6 14828 printf ("\"\n");
f6f0e17b
NC
14829 }
14830 else
14831 {
cd30bcef 14832 READ_ULEB (val, p, end);
f6f0e17b
NC
14833 printf ("%ld (0x%lx)\n", val, val);
14834 }
14835
4082ef84 14836 assert (p <= end);
f6f0e17b
NC
14837 return p;
14838}
14839
53a346d8
CZ
14840/* ARC ABI attributes section. */
14841
14842static unsigned char *
14843display_arc_attribute (unsigned char * p,
14844 const unsigned char * const end)
14845{
14846 unsigned int tag;
53a346d8
CZ
14847 unsigned int val;
14848
cd30bcef 14849 READ_ULEB (tag, p, end);
53a346d8
CZ
14850
14851 switch (tag)
14852 {
14853 case Tag_ARC_PCS_config:
cd30bcef 14854 READ_ULEB (val, p, end);
53a346d8
CZ
14855 printf (" Tag_ARC_PCS_config: ");
14856 switch (val)
14857 {
14858 case 0:
14859 printf (_("Absent/Non standard\n"));
14860 break;
14861 case 1:
14862 printf (_("Bare metal/mwdt\n"));
14863 break;
14864 case 2:
14865 printf (_("Bare metal/newlib\n"));
14866 break;
14867 case 3:
14868 printf (_("Linux/uclibc\n"));
14869 break;
14870 case 4:
14871 printf (_("Linux/glibc\n"));
14872 break;
14873 default:
14874 printf (_("Unknown\n"));
14875 break;
14876 }
14877 break;
14878
14879 case Tag_ARC_CPU_base:
cd30bcef 14880 READ_ULEB (val, p, end);
53a346d8
CZ
14881 printf (" Tag_ARC_CPU_base: ");
14882 switch (val)
14883 {
14884 default:
14885 case TAG_CPU_NONE:
14886 printf (_("Absent\n"));
14887 break;
14888 case TAG_CPU_ARC6xx:
14889 printf ("ARC6xx\n");
14890 break;
14891 case TAG_CPU_ARC7xx:
14892 printf ("ARC7xx\n");
14893 break;
14894 case TAG_CPU_ARCEM:
14895 printf ("ARCEM\n");
14896 break;
14897 case TAG_CPU_ARCHS:
14898 printf ("ARCHS\n");
14899 break;
14900 }
14901 break;
14902
14903 case Tag_ARC_CPU_variation:
cd30bcef 14904 READ_ULEB (val, p, end);
53a346d8
CZ
14905 printf (" Tag_ARC_CPU_variation: ");
14906 switch (val)
14907 {
14908 default:
14909 if (val > 0 && val < 16)
53a346d8 14910 printf ("Core%d\n", val);
d8cbc93b
JL
14911 else
14912 printf ("Unknown\n");
14913 break;
14914
53a346d8
CZ
14915 case 0:
14916 printf (_("Absent\n"));
14917 break;
14918 }
14919 break;
14920
14921 case Tag_ARC_CPU_name:
14922 printf (" Tag_ARC_CPU_name: ");
14923 p = display_tag_value (-1, p, end);
14924 break;
14925
14926 case Tag_ARC_ABI_rf16:
cd30bcef 14927 READ_ULEB (val, p, end);
53a346d8
CZ
14928 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
14929 break;
14930
14931 case Tag_ARC_ABI_osver:
cd30bcef 14932 READ_ULEB (val, p, end);
53a346d8
CZ
14933 printf (" Tag_ARC_ABI_osver: v%d\n", val);
14934 break;
14935
14936 case Tag_ARC_ABI_pic:
14937 case Tag_ARC_ABI_sda:
cd30bcef 14938 READ_ULEB (val, p, end);
53a346d8
CZ
14939 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
14940 : " Tag_ARC_ABI_pic: ");
14941 switch (val)
14942 {
14943 case 0:
14944 printf (_("Absent\n"));
14945 break;
14946 case 1:
14947 printf ("MWDT\n");
14948 break;
14949 case 2:
14950 printf ("GNU\n");
14951 break;
14952 default:
14953 printf (_("Unknown\n"));
14954 break;
14955 }
14956 break;
14957
14958 case Tag_ARC_ABI_tls:
cd30bcef 14959 READ_ULEB (val, p, end);
53a346d8
CZ
14960 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
14961 break;
14962
14963 case Tag_ARC_ABI_enumsize:
cd30bcef 14964 READ_ULEB (val, p, end);
53a346d8
CZ
14965 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
14966 _("smallest"));
14967 break;
14968
14969 case Tag_ARC_ABI_exceptions:
cd30bcef 14970 READ_ULEB (val, p, end);
53a346d8
CZ
14971 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
14972 : _("default"));
14973 break;
14974
14975 case Tag_ARC_ABI_double_size:
cd30bcef 14976 READ_ULEB (val, p, end);
53a346d8
CZ
14977 printf (" Tag_ARC_ABI_double_size: %d\n", val);
14978 break;
14979
14980 case Tag_ARC_ISA_config:
14981 printf (" Tag_ARC_ISA_config: ");
14982 p = display_tag_value (-1, p, end);
14983 break;
14984
14985 case Tag_ARC_ISA_apex:
14986 printf (" Tag_ARC_ISA_apex: ");
14987 p = display_tag_value (-1, p, end);
14988 break;
14989
14990 case Tag_ARC_ISA_mpy_option:
cd30bcef 14991 READ_ULEB (val, p, end);
53a346d8
CZ
14992 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
14993 break;
14994
db1e1b45 14995 case Tag_ARC_ATR_version:
cd30bcef 14996 READ_ULEB (val, p, end);
db1e1b45 14997 printf (" Tag_ARC_ATR_version: %d\n", val);
14998 break;
14999
53a346d8
CZ
15000 default:
15001 return display_tag_value (tag & 1, p, end);
15002 }
15003
15004 return p;
15005}
15006
11c1ff18
PB
15007/* ARM EABI attributes section. */
15008typedef struct
15009{
70e99720 15010 unsigned int tag;
2cf0635d 15011 const char * name;
11c1ff18 15012 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15013 unsigned int type;
2cf0635d 15014 const char ** table;
11c1ff18
PB
15015} arm_attr_public_tag;
15016
2cf0635d 15017static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 15018 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15019 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15020 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
2cf0635d
NC
15021static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15022static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15023 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 15024static const char * arm_attr_tag_FP_arch[] =
bca38921 15025 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15026 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 15027static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 15028static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15029 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15030 "NEON for ARMv8.1"};
2cf0635d 15031static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
15032 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15033 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 15034static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15035 {"V6", "SB", "TLS", "Unused"};
2cf0635d 15036static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15037 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 15038static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15039 {"Absolute", "PC-relative", "None"};
2cf0635d 15040static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15041 {"None", "direct", "GOT-indirect"};
2cf0635d 15042static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15043 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
15044static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15045static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15046 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
15047static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15048static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15049static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15050 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 15051static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 15052 {"Unused", "small", "int", "forced to int"};
2cf0635d 15053static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15054 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 15055static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 15056 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 15057static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15058 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 15059static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15060 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15061 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 15062static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15063 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15064 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 15065static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 15066static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 15067 {"Not Allowed", "Allowed"};
2cf0635d 15068static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15069 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
15070static const char * arm_attr_tag_DSP_extension[] =
15071 {"Follow architecture", "Allowed"};
dd24e3da 15072static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
15073 {"Not Allowed", "Allowed"};
15074static const char * arm_attr_tag_DIV_use[] =
dd24e3da 15075 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15076 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
15077static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15078static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 15079 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15080 "TrustZone and Virtualization Extensions"};
dd24e3da 15081static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15082 {"Not Allowed", "Allowed"};
11c1ff18 15083
a7ad558c
AV
15084static const char * arm_attr_tag_MVE_arch[] =
15085 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15086
11c1ff18
PB
15087#define LOOKUP(id, name) \
15088 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15089static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15090{
15091 {4, "CPU_raw_name", 1, NULL},
15092 {5, "CPU_name", 1, NULL},
15093 LOOKUP(6, CPU_arch),
15094 {7, "CPU_arch_profile", 0, NULL},
15095 LOOKUP(8, ARM_ISA_use),
15096 LOOKUP(9, THUMB_ISA_use),
75375b3e 15097 LOOKUP(10, FP_arch),
11c1ff18 15098 LOOKUP(11, WMMX_arch),
f5f53991
AS
15099 LOOKUP(12, Advanced_SIMD_arch),
15100 LOOKUP(13, PCS_config),
11c1ff18
PB
15101 LOOKUP(14, ABI_PCS_R9_use),
15102 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15103 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15104 LOOKUP(17, ABI_PCS_GOT_use),
15105 LOOKUP(18, ABI_PCS_wchar_t),
15106 LOOKUP(19, ABI_FP_rounding),
15107 LOOKUP(20, ABI_FP_denormal),
15108 LOOKUP(21, ABI_FP_exceptions),
15109 LOOKUP(22, ABI_FP_user_exceptions),
15110 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15111 {24, "ABI_align_needed", 0, NULL},
15112 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15113 LOOKUP(26, ABI_enum_size),
15114 LOOKUP(27, ABI_HardFP_use),
15115 LOOKUP(28, ABI_VFP_args),
15116 LOOKUP(29, ABI_WMMX_args),
15117 LOOKUP(30, ABI_optimization_goals),
15118 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15119 {32, "compatibility", 0, NULL},
f5f53991 15120 LOOKUP(34, CPU_unaligned_access),
75375b3e 15121 LOOKUP(36, FP_HP_extension),
8e79c3df 15122 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15123 LOOKUP(42, MPextension_use),
15124 LOOKUP(44, DIV_use),
15afaa63 15125 LOOKUP(46, DSP_extension),
a7ad558c 15126 LOOKUP(48, MVE_arch),
f5f53991
AS
15127 {64, "nodefaults", 0, NULL},
15128 {65, "also_compatible_with", 0, NULL},
15129 LOOKUP(66, T2EE_use),
15130 {67, "conformance", 1, NULL},
15131 LOOKUP(68, Virtualization_use),
cd21e546 15132 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15133};
15134#undef LOOKUP
15135
11c1ff18 15136static unsigned char *
f6f0e17b
NC
15137display_arm_attribute (unsigned char * p,
15138 const unsigned char * const end)
11c1ff18 15139{
70e99720 15140 unsigned int tag;
70e99720 15141 unsigned int val;
2cf0635d 15142 arm_attr_public_tag * attr;
11c1ff18 15143 unsigned i;
70e99720 15144 unsigned int type;
11c1ff18 15145
cd30bcef 15146 READ_ULEB (tag, p, end);
11c1ff18 15147 attr = NULL;
2cf0635d 15148 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15149 {
15150 if (arm_attr_public_tags[i].tag == tag)
15151 {
15152 attr = &arm_attr_public_tags[i];
15153 break;
15154 }
15155 }
15156
15157 if (attr)
15158 {
15159 printf (" Tag_%s: ", attr->name);
15160 switch (attr->type)
15161 {
15162 case 0:
15163 switch (tag)
15164 {
15165 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15166 READ_ULEB (val, p, end);
11c1ff18
PB
15167 switch (val)
15168 {
2b692964
NC
15169 case 0: printf (_("None\n")); break;
15170 case 'A': printf (_("Application\n")); break;
15171 case 'R': printf (_("Realtime\n")); break;
15172 case 'M': printf (_("Microcontroller\n")); break;
15173 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15174 default: printf ("??? (%d)\n", val); break;
15175 }
15176 break;
15177
75375b3e 15178 case 24: /* Tag_align_needed. */
cd30bcef 15179 READ_ULEB (val, p, end);
75375b3e
MGD
15180 switch (val)
15181 {
2b692964
NC
15182 case 0: printf (_("None\n")); break;
15183 case 1: printf (_("8-byte\n")); break;
15184 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15185 case 3: printf ("??? 3\n"); break;
15186 default:
15187 if (val <= 12)
dd24e3da 15188 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15189 1 << val);
15190 else
15191 printf ("??? (%d)\n", val);
15192 break;
15193 }
15194 break;
15195
15196 case 25: /* Tag_align_preserved. */
cd30bcef 15197 READ_ULEB (val, p, end);
75375b3e
MGD
15198 switch (val)
15199 {
2b692964
NC
15200 case 0: printf (_("None\n")); break;
15201 case 1: printf (_("8-byte, except leaf SP\n")); break;
15202 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
15203 case 3: printf ("??? 3\n"); break;
15204 default:
15205 if (val <= 12)
dd24e3da 15206 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15207 1 << val);
15208 else
15209 printf ("??? (%d)\n", val);
15210 break;
15211 }
15212 break;
15213
11c1ff18 15214 case 32: /* Tag_compatibility. */
071436c6 15215 {
cd30bcef 15216 READ_ULEB (val, p, end);
071436c6 15217 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15218 if (p < end - 1)
15219 {
15220 size_t maxlen = (end - p) - 1;
15221
15222 print_symbol ((int) maxlen, (const char *) p);
15223 p += strnlen ((char *) p, maxlen) + 1;
15224 }
15225 else
15226 {
15227 printf (_("<corrupt>"));
15228 p = (unsigned char *) end;
15229 }
071436c6 15230 putchar ('\n');
071436c6 15231 }
11c1ff18
PB
15232 break;
15233
f5f53991 15234 case 64: /* Tag_nodefaults. */
541a3cbd
NC
15235 /* PR 17531: file: 001-505008-0.01. */
15236 if (p < end)
15237 p++;
2b692964 15238 printf (_("True\n"));
f5f53991
AS
15239 break;
15240
15241 case 65: /* Tag_also_compatible_with. */
cd30bcef 15242 READ_ULEB (val, p, end);
f5f53991
AS
15243 if (val == 6 /* Tag_CPU_arch. */)
15244 {
cd30bcef 15245 READ_ULEB (val, p, end);
071436c6 15246 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
15247 printf ("??? (%d)\n", val);
15248 else
15249 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
15250 }
15251 else
15252 printf ("???\n");
071436c6
NC
15253 while (p < end && *(p++) != '\0' /* NUL terminator. */)
15254 ;
f5f53991
AS
15255 break;
15256
11c1ff18 15257 default:
bee0ee85
NC
15258 printf (_("<unknown: %d>\n"), tag);
15259 break;
11c1ff18
PB
15260 }
15261 return p;
15262
15263 case 1:
f6f0e17b 15264 return display_tag_value (-1, p, end);
11c1ff18 15265 case 2:
f6f0e17b 15266 return display_tag_value (0, p, end);
11c1ff18
PB
15267
15268 default:
15269 assert (attr->type & 0x80);
cd30bcef 15270 READ_ULEB (val, p, end);
11c1ff18
PB
15271 type = attr->type & 0x7f;
15272 if (val >= type)
15273 printf ("??? (%d)\n", val);
15274 else
15275 printf ("%s\n", attr->table[val]);
15276 return p;
15277 }
15278 }
11c1ff18 15279
f6f0e17b 15280 return display_tag_value (tag, p, end);
11c1ff18
PB
15281}
15282
104d59d1 15283static unsigned char *
60bca95a 15284display_gnu_attribute (unsigned char * p,
60abdbed 15285 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 15286 const unsigned char * const end)
104d59d1 15287{
cd30bcef 15288 unsigned int tag;
60abdbed 15289 unsigned int val;
104d59d1 15290
cd30bcef 15291 READ_ULEB (tag, p, end);
104d59d1
JM
15292
15293 /* Tag_compatibility is the only generic GNU attribute defined at
15294 present. */
15295 if (tag == 32)
15296 {
cd30bcef 15297 READ_ULEB (val, p, end);
071436c6
NC
15298
15299 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
15300 if (p == end)
15301 {
071436c6 15302 printf (_("<corrupt>\n"));
f6f0e17b
NC
15303 warn (_("corrupt vendor attribute\n"));
15304 }
15305 else
15306 {
4082ef84
NC
15307 if (p < end - 1)
15308 {
15309 size_t maxlen = (end - p) - 1;
071436c6 15310
4082ef84
NC
15311 print_symbol ((int) maxlen, (const char *) p);
15312 p += strnlen ((char *) p, maxlen) + 1;
15313 }
15314 else
15315 {
15316 printf (_("<corrupt>"));
15317 p = (unsigned char *) end;
15318 }
071436c6 15319 putchar ('\n');
f6f0e17b 15320 }
104d59d1
JM
15321 return p;
15322 }
15323
15324 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 15325 return display_proc_gnu_attribute (p, tag, end);
104d59d1 15326
f6f0e17b 15327 return display_tag_value (tag, p, end);
104d59d1
JM
15328}
15329
34c8bcba 15330static unsigned char *
f6f0e17b 15331display_power_gnu_attribute (unsigned char * p,
60abdbed 15332 unsigned int tag,
f6f0e17b 15333 const unsigned char * const end)
34c8bcba 15334{
005d79fd 15335 unsigned int val;
34c8bcba
JM
15336
15337 if (tag == Tag_GNU_Power_ABI_FP)
15338 {
34c8bcba 15339 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 15340 if (p == end)
005d79fd
AM
15341 {
15342 printf (_("<corrupt>\n"));
15343 return p;
15344 }
cd30bcef 15345 READ_ULEB (val, p, end);
60bca95a 15346
005d79fd
AM
15347 if (val > 15)
15348 printf ("(%#x), ", val);
15349
15350 switch (val & 3)
34c8bcba
JM
15351 {
15352 case 0:
005d79fd 15353 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
15354 break;
15355 case 1:
005d79fd 15356 printf (_("hard float, "));
34c8bcba
JM
15357 break;
15358 case 2:
005d79fd 15359 printf (_("soft float, "));
34c8bcba 15360 break;
3c7b9897 15361 case 3:
005d79fd 15362 printf (_("single-precision hard float, "));
3c7b9897 15363 break;
005d79fd
AM
15364 }
15365
15366 switch (val & 0xC)
15367 {
15368 case 0:
15369 printf (_("unspecified long double\n"));
15370 break;
15371 case 4:
15372 printf (_("128-bit IBM long double\n"));
15373 break;
15374 case 8:
15375 printf (_("64-bit long double\n"));
15376 break;
15377 case 12:
15378 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
15379 break;
15380 }
15381 return p;
005d79fd 15382 }
34c8bcba 15383
c6e65352
DJ
15384 if (tag == Tag_GNU_Power_ABI_Vector)
15385 {
c6e65352 15386 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 15387 if (p == end)
005d79fd
AM
15388 {
15389 printf (_("<corrupt>\n"));
15390 return p;
15391 }
cd30bcef 15392 READ_ULEB (val, p, end);
005d79fd
AM
15393
15394 if (val > 3)
15395 printf ("(%#x), ", val);
15396
15397 switch (val & 3)
c6e65352
DJ
15398 {
15399 case 0:
005d79fd 15400 printf (_("unspecified\n"));
c6e65352
DJ
15401 break;
15402 case 1:
005d79fd 15403 printf (_("generic\n"));
c6e65352
DJ
15404 break;
15405 case 2:
15406 printf ("AltiVec\n");
15407 break;
15408 case 3:
15409 printf ("SPE\n");
15410 break;
c6e65352
DJ
15411 }
15412 return p;
005d79fd 15413 }
c6e65352 15414
f82e0623
NF
15415 if (tag == Tag_GNU_Power_ABI_Struct_Return)
15416 {
005d79fd 15417 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 15418 if (p == end)
f6f0e17b 15419 {
005d79fd 15420 printf (_("<corrupt>\n"));
f6f0e17b
NC
15421 return p;
15422 }
cd30bcef 15423 READ_ULEB (val, p, end);
0b4362b0 15424
005d79fd
AM
15425 if (val > 2)
15426 printf ("(%#x), ", val);
15427
15428 switch (val & 3)
15429 {
15430 case 0:
15431 printf (_("unspecified\n"));
15432 break;
15433 case 1:
15434 printf ("r3/r4\n");
15435 break;
15436 case 2:
15437 printf (_("memory\n"));
15438 break;
15439 case 3:
15440 printf ("???\n");
15441 break;
15442 }
f82e0623
NF
15443 return p;
15444 }
15445
f6f0e17b 15446 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
15447}
15448
643f7afb
AK
15449static unsigned char *
15450display_s390_gnu_attribute (unsigned char * p,
60abdbed 15451 unsigned int tag,
643f7afb
AK
15452 const unsigned char * const end)
15453{
cd30bcef 15454 unsigned int val;
643f7afb
AK
15455
15456 if (tag == Tag_GNU_S390_ABI_Vector)
15457 {
643f7afb 15458 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 15459 READ_ULEB (val, p, end);
643f7afb
AK
15460
15461 switch (val)
15462 {
15463 case 0:
15464 printf (_("any\n"));
15465 break;
15466 case 1:
15467 printf (_("software\n"));
15468 break;
15469 case 2:
15470 printf (_("hardware\n"));
15471 break;
15472 default:
15473 printf ("??? (%d)\n", val);
15474 break;
15475 }
15476 return p;
15477 }
15478
15479 return display_tag_value (tag & 1, p, end);
15480}
15481
9e8c70f9 15482static void
60abdbed 15483display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
15484{
15485 if (mask)
15486 {
32ec8896 15487 bfd_boolean first = TRUE;
071436c6 15488
9e8c70f9 15489 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 15490 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 15491 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 15492 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 15493 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 15494 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 15495 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 15496 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 15497 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 15498 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 15499 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 15500 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 15501 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 15502 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 15503 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 15504 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 15505 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 15506 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 15507 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 15508 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 15509 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 15510 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 15511 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 15512 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 15513 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 15514 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 15515 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 15516 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 15517 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 15518 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 15519 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 15520 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
15521 }
15522 else
071436c6
NC
15523 fputc ('0', stdout);
15524 fputc ('\n', stdout);
9e8c70f9
DM
15525}
15526
3d68f91c 15527static void
60abdbed 15528display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
15529{
15530 if (mask)
15531 {
32ec8896 15532 bfd_boolean first = TRUE;
071436c6 15533
3d68f91c 15534 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 15535 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 15536 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 15537 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 15538 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 15539 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 15540 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 15541 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 15542 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 15543 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 15544 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 15545 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 15546 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 15547 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 15548 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 15549 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 15550 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 15551 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 15552 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 15553 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 15554 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 15555 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
15556 }
15557 else
071436c6
NC
15558 fputc ('0', stdout);
15559 fputc ('\n', stdout);
3d68f91c
JM
15560}
15561
9e8c70f9 15562static unsigned char *
f6f0e17b 15563display_sparc_gnu_attribute (unsigned char * p,
60abdbed 15564 unsigned int tag,
f6f0e17b 15565 const unsigned char * const end)
9e8c70f9 15566{
cd30bcef 15567 unsigned int val;
3d68f91c 15568
9e8c70f9
DM
15569 if (tag == Tag_GNU_Sparc_HWCAPS)
15570 {
cd30bcef 15571 READ_ULEB (val, p, end);
9e8c70f9 15572 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
15573 display_sparc_hwcaps (val);
15574 return p;
3d68f91c
JM
15575 }
15576 if (tag == Tag_GNU_Sparc_HWCAPS2)
15577 {
cd30bcef 15578 READ_ULEB (val, p, end);
3d68f91c
JM
15579 printf (" Tag_GNU_Sparc_HWCAPS2: ");
15580 display_sparc_hwcaps2 (val);
15581 return p;
15582 }
9e8c70f9 15583
f6f0e17b 15584 return display_tag_value (tag, p, end);
9e8c70f9
DM
15585}
15586
351cdf24 15587static void
32ec8896 15588print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
15589{
15590 switch (val)
15591 {
15592 case Val_GNU_MIPS_ABI_FP_ANY:
15593 printf (_("Hard or soft float\n"));
15594 break;
15595 case Val_GNU_MIPS_ABI_FP_DOUBLE:
15596 printf (_("Hard float (double precision)\n"));
15597 break;
15598 case Val_GNU_MIPS_ABI_FP_SINGLE:
15599 printf (_("Hard float (single precision)\n"));
15600 break;
15601 case Val_GNU_MIPS_ABI_FP_SOFT:
15602 printf (_("Soft float\n"));
15603 break;
15604 case Val_GNU_MIPS_ABI_FP_OLD_64:
15605 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
15606 break;
15607 case Val_GNU_MIPS_ABI_FP_XX:
15608 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
15609 break;
15610 case Val_GNU_MIPS_ABI_FP_64:
15611 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
15612 break;
15613 case Val_GNU_MIPS_ABI_FP_64A:
15614 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
15615 break;
3350cc01
CM
15616 case Val_GNU_MIPS_ABI_FP_NAN2008:
15617 printf (_("NaN 2008 compatibility\n"));
15618 break;
351cdf24
MF
15619 default:
15620 printf ("??? (%d)\n", val);
15621 break;
15622 }
15623}
15624
2cf19d5c 15625static unsigned char *
f6f0e17b 15626display_mips_gnu_attribute (unsigned char * p,
60abdbed 15627 unsigned int tag,
f6f0e17b 15628 const unsigned char * const end)
2cf19d5c 15629{
2cf19d5c
JM
15630 if (tag == Tag_GNU_MIPS_ABI_FP)
15631 {
32ec8896 15632 unsigned int val;
f6f0e17b 15633
2cf19d5c 15634 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 15635 READ_ULEB (val, p, end);
351cdf24 15636 print_mips_fp_abi_value (val);
2cf19d5c
JM
15637 return p;
15638 }
15639
a9f58168
CF
15640 if (tag == Tag_GNU_MIPS_ABI_MSA)
15641 {
32ec8896 15642 unsigned int val;
a9f58168 15643
a9f58168 15644 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 15645 READ_ULEB (val, p, end);
a9f58168
CF
15646
15647 switch (val)
15648 {
15649 case Val_GNU_MIPS_ABI_MSA_ANY:
15650 printf (_("Any MSA or not\n"));
15651 break;
15652 case Val_GNU_MIPS_ABI_MSA_128:
15653 printf (_("128-bit MSA\n"));
15654 break;
15655 default:
15656 printf ("??? (%d)\n", val);
15657 break;
15658 }
15659 return p;
15660 }
15661
f6f0e17b 15662 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
15663}
15664
59e6276b 15665static unsigned char *
f6f0e17b
NC
15666display_tic6x_attribute (unsigned char * p,
15667 const unsigned char * const end)
59e6276b 15668{
60abdbed 15669 unsigned int tag;
cd30bcef 15670 unsigned int val;
59e6276b 15671
cd30bcef 15672 READ_ULEB (tag, p, end);
59e6276b
JM
15673
15674 switch (tag)
15675 {
75fa6dc1 15676 case Tag_ISA:
75fa6dc1 15677 printf (" Tag_ISA: ");
cd30bcef 15678 READ_ULEB (val, p, end);
59e6276b
JM
15679
15680 switch (val)
15681 {
75fa6dc1 15682 case C6XABI_Tag_ISA_none:
59e6276b
JM
15683 printf (_("None\n"));
15684 break;
75fa6dc1 15685 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
15686 printf ("C62x\n");
15687 break;
75fa6dc1 15688 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
15689 printf ("C67x\n");
15690 break;
75fa6dc1 15691 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
15692 printf ("C67x+\n");
15693 break;
75fa6dc1 15694 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
15695 printf ("C64x\n");
15696 break;
75fa6dc1 15697 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
15698 printf ("C64x+\n");
15699 break;
75fa6dc1 15700 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
15701 printf ("C674x\n");
15702 break;
15703 default:
15704 printf ("??? (%d)\n", val);
15705 break;
15706 }
15707 return p;
15708
87779176 15709 case Tag_ABI_wchar_t:
87779176 15710 printf (" Tag_ABI_wchar_t: ");
cd30bcef 15711 READ_ULEB (val, p, end);
87779176
JM
15712 switch (val)
15713 {
15714 case 0:
15715 printf (_("Not used\n"));
15716 break;
15717 case 1:
15718 printf (_("2 bytes\n"));
15719 break;
15720 case 2:
15721 printf (_("4 bytes\n"));
15722 break;
15723 default:
15724 printf ("??? (%d)\n", val);
15725 break;
15726 }
15727 return p;
15728
15729 case Tag_ABI_stack_align_needed:
87779176 15730 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 15731 READ_ULEB (val, p, end);
87779176
JM
15732 switch (val)
15733 {
15734 case 0:
15735 printf (_("8-byte\n"));
15736 break;
15737 case 1:
15738 printf (_("16-byte\n"));
15739 break;
15740 default:
15741 printf ("??? (%d)\n", val);
15742 break;
15743 }
15744 return p;
15745
15746 case Tag_ABI_stack_align_preserved:
cd30bcef 15747 READ_ULEB (val, p, end);
87779176
JM
15748 printf (" Tag_ABI_stack_align_preserved: ");
15749 switch (val)
15750 {
15751 case 0:
15752 printf (_("8-byte\n"));
15753 break;
15754 case 1:
15755 printf (_("16-byte\n"));
15756 break;
15757 default:
15758 printf ("??? (%d)\n", val);
15759 break;
15760 }
15761 return p;
15762
b5593623 15763 case Tag_ABI_DSBT:
cd30bcef 15764 READ_ULEB (val, p, end);
b5593623
JM
15765 printf (" Tag_ABI_DSBT: ");
15766 switch (val)
15767 {
15768 case 0:
15769 printf (_("DSBT addressing not used\n"));
15770 break;
15771 case 1:
15772 printf (_("DSBT addressing used\n"));
15773 break;
15774 default:
15775 printf ("??? (%d)\n", val);
15776 break;
15777 }
15778 return p;
15779
87779176 15780 case Tag_ABI_PID:
cd30bcef 15781 READ_ULEB (val, p, end);
87779176
JM
15782 printf (" Tag_ABI_PID: ");
15783 switch (val)
15784 {
15785 case 0:
15786 printf (_("Data addressing position-dependent\n"));
15787 break;
15788 case 1:
15789 printf (_("Data addressing position-independent, GOT near DP\n"));
15790 break;
15791 case 2:
15792 printf (_("Data addressing position-independent, GOT far from DP\n"));
15793 break;
15794 default:
15795 printf ("??? (%d)\n", val);
15796 break;
15797 }
15798 return p;
15799
15800 case Tag_ABI_PIC:
cd30bcef 15801 READ_ULEB (val, p, end);
87779176
JM
15802 printf (" Tag_ABI_PIC: ");
15803 switch (val)
15804 {
15805 case 0:
15806 printf (_("Code addressing position-dependent\n"));
15807 break;
15808 case 1:
15809 printf (_("Code addressing position-independent\n"));
15810 break;
15811 default:
15812 printf ("??? (%d)\n", val);
15813 break;
15814 }
15815 return p;
15816
15817 case Tag_ABI_array_object_alignment:
cd30bcef 15818 READ_ULEB (val, p, end);
87779176
JM
15819 printf (" Tag_ABI_array_object_alignment: ");
15820 switch (val)
15821 {
15822 case 0:
15823 printf (_("8-byte\n"));
15824 break;
15825 case 1:
15826 printf (_("4-byte\n"));
15827 break;
15828 case 2:
15829 printf (_("16-byte\n"));
15830 break;
15831 default:
15832 printf ("??? (%d)\n", val);
15833 break;
15834 }
15835 return p;
15836
15837 case Tag_ABI_array_object_align_expected:
cd30bcef 15838 READ_ULEB (val, p, end);
87779176
JM
15839 printf (" Tag_ABI_array_object_align_expected: ");
15840 switch (val)
15841 {
15842 case 0:
15843 printf (_("8-byte\n"));
15844 break;
15845 case 1:
15846 printf (_("4-byte\n"));
15847 break;
15848 case 2:
15849 printf (_("16-byte\n"));
15850 break;
15851 default:
15852 printf ("??? (%d)\n", val);
15853 break;
15854 }
15855 return p;
15856
3cbd1c06 15857 case Tag_ABI_compatibility:
071436c6 15858 {
cd30bcef 15859 READ_ULEB (val, p, end);
071436c6 15860 printf (" Tag_ABI_compatibility: ");
071436c6 15861 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15862 if (p < end - 1)
15863 {
15864 size_t maxlen = (end - p) - 1;
15865
15866 print_symbol ((int) maxlen, (const char *) p);
15867 p += strnlen ((char *) p, maxlen) + 1;
15868 }
15869 else
15870 {
15871 printf (_("<corrupt>"));
15872 p = (unsigned char *) end;
15873 }
071436c6 15874 putchar ('\n');
071436c6
NC
15875 return p;
15876 }
87779176
JM
15877
15878 case Tag_ABI_conformance:
071436c6 15879 {
4082ef84
NC
15880 printf (" Tag_ABI_conformance: \"");
15881 if (p < end - 1)
15882 {
15883 size_t maxlen = (end - p) - 1;
071436c6 15884
4082ef84
NC
15885 print_symbol ((int) maxlen, (const char *) p);
15886 p += strnlen ((char *) p, maxlen) + 1;
15887 }
15888 else
15889 {
15890 printf (_("<corrupt>"));
15891 p = (unsigned char *) end;
15892 }
071436c6 15893 printf ("\"\n");
071436c6
NC
15894 return p;
15895 }
59e6276b
JM
15896 }
15897
f6f0e17b
NC
15898 return display_tag_value (tag, p, end);
15899}
59e6276b 15900
f6f0e17b 15901static void
60abdbed 15902display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
15903{
15904 unsigned long addr = 0;
15905 size_t bytes = end - p;
15906
feceaa59 15907 assert (end >= p);
f6f0e17b 15908 while (bytes)
87779176 15909 {
f6f0e17b
NC
15910 int j;
15911 int k;
15912 int lbytes = (bytes > 16 ? 16 : bytes);
15913
15914 printf (" 0x%8.8lx ", addr);
15915
15916 for (j = 0; j < 16; j++)
15917 {
15918 if (j < lbytes)
15919 printf ("%2.2x", p[j]);
15920 else
15921 printf (" ");
15922
15923 if ((j & 3) == 3)
15924 printf (" ");
15925 }
15926
15927 for (j = 0; j < lbytes; j++)
15928 {
15929 k = p[j];
15930 if (k >= ' ' && k < 0x7f)
15931 printf ("%c", k);
15932 else
15933 printf (".");
15934 }
15935
15936 putchar ('\n');
15937
15938 p += lbytes;
15939 bytes -= lbytes;
15940 addr += lbytes;
87779176 15941 }
59e6276b 15942
f6f0e17b 15943 putchar ('\n');
59e6276b
JM
15944}
15945
13761a11
NC
15946static unsigned char *
15947display_msp430x_attribute (unsigned char * p,
15948 const unsigned char * const end)
15949{
60abdbed
NC
15950 unsigned int val;
15951 unsigned int tag;
13761a11 15952
cd30bcef 15953 READ_ULEB (tag, p, end);
0b4362b0 15954
13761a11
NC
15955 switch (tag)
15956 {
15957 case OFBA_MSPABI_Tag_ISA:
13761a11 15958 printf (" Tag_ISA: ");
cd30bcef 15959 READ_ULEB (val, p, end);
13761a11
NC
15960 switch (val)
15961 {
15962 case 0: printf (_("None\n")); break;
15963 case 1: printf (_("MSP430\n")); break;
15964 case 2: printf (_("MSP430X\n")); break;
15965 default: printf ("??? (%d)\n", val); break;
15966 }
15967 break;
15968
15969 case OFBA_MSPABI_Tag_Code_Model:
13761a11 15970 printf (" Tag_Code_Model: ");
cd30bcef 15971 READ_ULEB (val, p, end);
13761a11
NC
15972 switch (val)
15973 {
15974 case 0: printf (_("None\n")); break;
15975 case 1: printf (_("Small\n")); break;
15976 case 2: printf (_("Large\n")); break;
15977 default: printf ("??? (%d)\n", val); break;
15978 }
15979 break;
15980
15981 case OFBA_MSPABI_Tag_Data_Model:
13761a11 15982 printf (" Tag_Data_Model: ");
cd30bcef 15983 READ_ULEB (val, p, end);
13761a11
NC
15984 switch (val)
15985 {
15986 case 0: printf (_("None\n")); break;
15987 case 1: printf (_("Small\n")); break;
15988 case 2: printf (_("Large\n")); break;
15989 case 3: printf (_("Restricted Large\n")); break;
15990 default: printf ("??? (%d)\n", val); break;
15991 }
15992 break;
15993
15994 default:
15995 printf (_(" <unknown tag %d>: "), tag);
15996
15997 if (tag & 1)
15998 {
071436c6 15999 putchar ('"');
4082ef84
NC
16000 if (p < end - 1)
16001 {
16002 size_t maxlen = (end - p) - 1;
16003
16004 print_symbol ((int) maxlen, (const char *) p);
16005 p += strnlen ((char *) p, maxlen) + 1;
16006 }
16007 else
16008 {
16009 printf (_("<corrupt>"));
16010 p = (unsigned char *) end;
16011 }
071436c6 16012 printf ("\"\n");
13761a11
NC
16013 }
16014 else
16015 {
cd30bcef 16016 READ_ULEB (val, p, end);
13761a11
NC
16017 printf ("%d (0x%x)\n", val, val);
16018 }
16019 break;
16020 }
16021
4082ef84 16022 assert (p <= end);
13761a11
NC
16023 return p;
16024}
16025
c0ea7c52
JL
16026static unsigned char *
16027display_msp430_gnu_attribute (unsigned char * p,
16028 unsigned int tag,
16029 const unsigned char * const end)
16030{
16031 if (tag == Tag_GNU_MSP430_Data_Region)
16032 {
cd30bcef 16033 unsigned int val;
c0ea7c52 16034
c0ea7c52 16035 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16036 READ_ULEB (val, p, end);
c0ea7c52
JL
16037
16038 switch (val)
16039 {
16040 case Val_GNU_MSP430_Data_Region_Any:
16041 printf (_("Any Region\n"));
16042 break;
16043 case Val_GNU_MSP430_Data_Region_Lower:
16044 printf (_("Lower Region Only\n"));
16045 break;
16046 default:
cd30bcef 16047 printf ("??? (%u)\n", val);
c0ea7c52
JL
16048 }
16049 return p;
16050 }
16051 return display_tag_value (tag & 1, p, end);
16052}
16053
2dc8dd17
JW
16054struct riscv_attr_tag_t {
16055 const char *name;
cd30bcef 16056 unsigned int tag;
2dc8dd17
JW
16057};
16058
16059static struct riscv_attr_tag_t riscv_attr_tag[] =
16060{
16061#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16062 T(arch),
16063 T(priv_spec),
16064 T(priv_spec_minor),
16065 T(priv_spec_revision),
16066 T(unaligned_access),
16067 T(stack_align),
16068#undef T
16069};
16070
16071static unsigned char *
16072display_riscv_attribute (unsigned char *p,
16073 const unsigned char * const end)
16074{
cd30bcef
AM
16075 unsigned int val;
16076 unsigned int tag;
2dc8dd17
JW
16077 struct riscv_attr_tag_t *attr = NULL;
16078 unsigned i;
16079
cd30bcef 16080 READ_ULEB (tag, p, end);
2dc8dd17
JW
16081
16082 /* Find the name of attribute. */
16083 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16084 {
16085 if (riscv_attr_tag[i].tag == tag)
16086 {
16087 attr = &riscv_attr_tag[i];
16088 break;
16089 }
16090 }
16091
16092 if (attr)
16093 printf (" %s: ", attr->name);
16094 else
16095 return display_tag_value (tag, p, end);
16096
16097 switch (tag)
16098 {
16099 case Tag_RISCV_priv_spec:
16100 case Tag_RISCV_priv_spec_minor:
16101 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16102 READ_ULEB (val, p, end);
16103 printf (_("%u\n"), val);
2dc8dd17
JW
16104 break;
16105 case Tag_RISCV_unaligned_access:
cd30bcef 16106 READ_ULEB (val, p, end);
2dc8dd17
JW
16107 switch (val)
16108 {
16109 case 0:
16110 printf (_("No unaligned access\n"));
16111 break;
16112 case 1:
16113 printf (_("Unaligned access\n"));
16114 break;
16115 }
16116 break;
16117 case Tag_RISCV_stack_align:
cd30bcef
AM
16118 READ_ULEB (val, p, end);
16119 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16120 break;
16121 case Tag_RISCV_arch:
16122 p = display_tag_value (-1, p, end);
16123 break;
16124 default:
16125 return display_tag_value (tag, p, end);
16126 }
16127
16128 return p;
16129}
16130
32ec8896 16131static bfd_boolean
dda8d76d 16132process_attributes (Filedata * filedata,
60bca95a 16133 const char * public_name,
104d59d1 16134 unsigned int proc_type,
f6f0e17b 16135 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 16136 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 16137{
2cf0635d 16138 Elf_Internal_Shdr * sect;
11c1ff18 16139 unsigned i;
32ec8896 16140 bfd_boolean res = TRUE;
11c1ff18
PB
16141
16142 /* Find the section header so that we get the size. */
dda8d76d
NC
16143 for (i = 0, sect = filedata->section_headers;
16144 i < filedata->file_header.e_shnum;
11c1ff18
PB
16145 i++, sect++)
16146 {
071436c6
NC
16147 unsigned char * contents;
16148 unsigned char * p;
16149
104d59d1 16150 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
16151 continue;
16152
dda8d76d 16153 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 16154 sect->sh_size, _("attributes"));
60bca95a 16155 if (contents == NULL)
32ec8896
NC
16156 {
16157 res = FALSE;
16158 continue;
16159 }
60bca95a 16160
11c1ff18 16161 p = contents;
60abdbed
NC
16162 /* The first character is the version of the attributes.
16163 Currently only version 1, (aka 'A') is recognised here. */
16164 if (*p != 'A')
32ec8896
NC
16165 {
16166 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
16167 res = FALSE;
16168 }
60abdbed 16169 else
11c1ff18 16170 {
071436c6
NC
16171 bfd_vma section_len;
16172
16173 section_len = sect->sh_size - 1;
11c1ff18 16174 p++;
60bca95a 16175
071436c6 16176 while (section_len > 0)
11c1ff18 16177 {
071436c6 16178 bfd_vma attr_len;
e9847026 16179 unsigned int namelen;
11c1ff18 16180 bfd_boolean public_section;
104d59d1 16181 bfd_boolean gnu_section;
11c1ff18 16182
071436c6 16183 if (section_len <= 4)
e0a31db1
NC
16184 {
16185 error (_("Tag section ends prematurely\n"));
32ec8896 16186 res = FALSE;
e0a31db1
NC
16187 break;
16188 }
071436c6 16189 attr_len = byte_get (p, 4);
11c1ff18 16190 p += 4;
60bca95a 16191
071436c6 16192 if (attr_len > section_len)
11c1ff18 16193 {
071436c6
NC
16194 error (_("Bad attribute length (%u > %u)\n"),
16195 (unsigned) attr_len, (unsigned) section_len);
16196 attr_len = section_len;
32ec8896 16197 res = FALSE;
11c1ff18 16198 }
74e1a04b 16199 /* PR 17531: file: 001-101425-0.004 */
071436c6 16200 else if (attr_len < 5)
74e1a04b 16201 {
071436c6 16202 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 16203 res = FALSE;
74e1a04b
NC
16204 break;
16205 }
e9847026 16206
071436c6
NC
16207 section_len -= attr_len;
16208 attr_len -= 4;
16209
16210 namelen = strnlen ((char *) p, attr_len) + 1;
16211 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
16212 {
16213 error (_("Corrupt attribute section name\n"));
32ec8896 16214 res = FALSE;
e9847026
NC
16215 break;
16216 }
16217
071436c6
NC
16218 printf (_("Attribute Section: "));
16219 print_symbol (INT_MAX, (const char *) p);
16220 putchar ('\n');
60bca95a
NC
16221
16222 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
16223 public_section = TRUE;
16224 else
16225 public_section = FALSE;
60bca95a
NC
16226
16227 if (streq ((char *) p, "gnu"))
104d59d1
JM
16228 gnu_section = TRUE;
16229 else
16230 gnu_section = FALSE;
60bca95a 16231
11c1ff18 16232 p += namelen;
071436c6 16233 attr_len -= namelen;
e0a31db1 16234
071436c6 16235 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 16236 {
e0a31db1 16237 int tag;
cd30bcef 16238 unsigned int val;
11c1ff18 16239 bfd_vma size;
071436c6 16240 unsigned char * end;
60bca95a 16241
e0a31db1 16242 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 16243 if (attr_len < 6)
e0a31db1
NC
16244 {
16245 error (_("Unused bytes at end of section\n"));
32ec8896 16246 res = FALSE;
e0a31db1
NC
16247 section_len = 0;
16248 break;
16249 }
16250
16251 tag = *(p++);
11c1ff18 16252 size = byte_get (p, 4);
071436c6 16253 if (size > attr_len)
11c1ff18 16254 {
e9847026 16255 error (_("Bad subsection length (%u > %u)\n"),
071436c6 16256 (unsigned) size, (unsigned) attr_len);
32ec8896 16257 res = FALSE;
071436c6 16258 size = attr_len;
11c1ff18 16259 }
e0a31db1
NC
16260 /* PR binutils/17531: Safe handling of corrupt files. */
16261 if (size < 6)
16262 {
16263 error (_("Bad subsection length (%u < 6)\n"),
16264 (unsigned) size);
32ec8896 16265 res = FALSE;
e0a31db1
NC
16266 section_len = 0;
16267 break;
16268 }
60bca95a 16269
071436c6 16270 attr_len -= size;
11c1ff18 16271 end = p + size - 1;
071436c6 16272 assert (end <= contents + sect->sh_size);
11c1ff18 16273 p += 4;
60bca95a 16274
11c1ff18
PB
16275 switch (tag)
16276 {
16277 case 1:
2b692964 16278 printf (_("File Attributes\n"));
11c1ff18
PB
16279 break;
16280 case 2:
2b692964 16281 printf (_("Section Attributes:"));
11c1ff18
PB
16282 goto do_numlist;
16283 case 3:
2b692964 16284 printf (_("Symbol Attributes:"));
1a0670f3 16285 /* Fall through. */
11c1ff18
PB
16286 do_numlist:
16287 for (;;)
16288 {
cd30bcef 16289 READ_ULEB (val, p, end);
11c1ff18
PB
16290 if (val == 0)
16291 break;
16292 printf (" %d", val);
16293 }
16294 printf ("\n");
16295 break;
16296 default:
2b692964 16297 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
16298 public_section = FALSE;
16299 break;
16300 }
60bca95a 16301
071436c6 16302 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
16303 {
16304 while (p < end)
f6f0e17b 16305 p = display_pub_attribute (p, end);
60abdbed 16306 assert (p == end);
104d59d1 16307 }
071436c6 16308 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
16309 {
16310 while (p < end)
16311 p = display_gnu_attribute (p,
f6f0e17b
NC
16312 display_proc_gnu_attribute,
16313 end);
60abdbed 16314 assert (p == end);
11c1ff18 16315 }
071436c6 16316 else if (p < end)
11c1ff18 16317 {
071436c6 16318 printf (_(" Unknown attribute:\n"));
f6f0e17b 16319 display_raw_attribute (p, end);
11c1ff18
PB
16320 p = end;
16321 }
071436c6
NC
16322 else
16323 attr_len = 0;
11c1ff18
PB
16324 }
16325 }
16326 }
d70c5fc7 16327
60bca95a 16328 free (contents);
11c1ff18 16329 }
32ec8896
NC
16330
16331 return res;
11c1ff18
PB
16332}
16333
ccb4c951
RS
16334/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
16335 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
16336 and return the VMA of the next entry, or -1 if there was a problem.
16337 Does not read from DATA_END or beyond. */
ccb4c951
RS
16338
16339static bfd_vma
82b1b41b
NC
16340print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
16341 unsigned char * data_end)
ccb4c951
RS
16342{
16343 printf (" ");
16344 print_vma (addr, LONG_HEX);
16345 printf (" ");
16346 if (addr < pltgot + 0xfff0)
16347 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
16348 else
16349 printf ("%10s", "");
16350 printf (" ");
16351 if (data == NULL)
2b692964 16352 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
16353 else
16354 {
16355 bfd_vma entry;
82b1b41b 16356 unsigned char * from = data + addr - pltgot;
ccb4c951 16357
82b1b41b
NC
16358 if (from + (is_32bit_elf ? 4 : 8) > data_end)
16359 {
16360 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
16361 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
16362 return (bfd_vma) -1;
16363 }
16364 else
16365 {
16366 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16367 print_vma (entry, LONG_HEX);
16368 }
ccb4c951
RS
16369 }
16370 return addr + (is_32bit_elf ? 4 : 8);
16371}
16372
861fb55a
DJ
16373/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
16374 PLTGOT. Print the Address and Initial fields of an entry at VMA
16375 ADDR and return the VMA of the next entry. */
16376
16377static bfd_vma
2cf0635d 16378print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
16379{
16380 printf (" ");
16381 print_vma (addr, LONG_HEX);
16382 printf (" ");
16383 if (data == NULL)
2b692964 16384 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
16385 else
16386 {
16387 bfd_vma entry;
16388
16389 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16390 print_vma (entry, LONG_HEX);
16391 }
16392 return addr + (is_32bit_elf ? 4 : 8);
16393}
16394
351cdf24
MF
16395static void
16396print_mips_ases (unsigned int mask)
16397{
16398 if (mask & AFL_ASE_DSP)
16399 fputs ("\n\tDSP ASE", stdout);
16400 if (mask & AFL_ASE_DSPR2)
16401 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
16402 if (mask & AFL_ASE_DSPR3)
16403 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
16404 if (mask & AFL_ASE_EVA)
16405 fputs ("\n\tEnhanced VA Scheme", stdout);
16406 if (mask & AFL_ASE_MCU)
16407 fputs ("\n\tMCU (MicroController) ASE", stdout);
16408 if (mask & AFL_ASE_MDMX)
16409 fputs ("\n\tMDMX ASE", stdout);
16410 if (mask & AFL_ASE_MIPS3D)
16411 fputs ("\n\tMIPS-3D ASE", stdout);
16412 if (mask & AFL_ASE_MT)
16413 fputs ("\n\tMT ASE", stdout);
16414 if (mask & AFL_ASE_SMARTMIPS)
16415 fputs ("\n\tSmartMIPS ASE", stdout);
16416 if (mask & AFL_ASE_VIRT)
16417 fputs ("\n\tVZ ASE", stdout);
16418 if (mask & AFL_ASE_MSA)
16419 fputs ("\n\tMSA ASE", stdout);
16420 if (mask & AFL_ASE_MIPS16)
16421 fputs ("\n\tMIPS16 ASE", stdout);
16422 if (mask & AFL_ASE_MICROMIPS)
16423 fputs ("\n\tMICROMIPS ASE", stdout);
16424 if (mask & AFL_ASE_XPA)
16425 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
16426 if (mask & AFL_ASE_MIPS16E2)
16427 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
16428 if (mask & AFL_ASE_CRC)
16429 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
16430 if (mask & AFL_ASE_GINV)
16431 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
16432 if (mask & AFL_ASE_LOONGSON_MMI)
16433 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
16434 if (mask & AFL_ASE_LOONGSON_CAM)
16435 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
16436 if (mask & AFL_ASE_LOONGSON_EXT)
16437 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
16438 if (mask & AFL_ASE_LOONGSON_EXT2)
16439 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
16440 if (mask == 0)
16441 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
16442 else if ((mask & ~AFL_ASE_MASK) != 0)
16443 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
16444}
16445
16446static void
16447print_mips_isa_ext (unsigned int isa_ext)
16448{
16449 switch (isa_ext)
16450 {
16451 case 0:
16452 fputs (_("None"), stdout);
16453 break;
16454 case AFL_EXT_XLR:
16455 fputs ("RMI XLR", stdout);
16456 break;
2c629856
N
16457 case AFL_EXT_OCTEON3:
16458 fputs ("Cavium Networks Octeon3", stdout);
16459 break;
351cdf24
MF
16460 case AFL_EXT_OCTEON2:
16461 fputs ("Cavium Networks Octeon2", stdout);
16462 break;
16463 case AFL_EXT_OCTEONP:
16464 fputs ("Cavium Networks OcteonP", stdout);
16465 break;
351cdf24
MF
16466 case AFL_EXT_OCTEON:
16467 fputs ("Cavium Networks Octeon", stdout);
16468 break;
16469 case AFL_EXT_5900:
16470 fputs ("Toshiba R5900", stdout);
16471 break;
16472 case AFL_EXT_4650:
16473 fputs ("MIPS R4650", stdout);
16474 break;
16475 case AFL_EXT_4010:
16476 fputs ("LSI R4010", stdout);
16477 break;
16478 case AFL_EXT_4100:
16479 fputs ("NEC VR4100", stdout);
16480 break;
16481 case AFL_EXT_3900:
16482 fputs ("Toshiba R3900", stdout);
16483 break;
16484 case AFL_EXT_10000:
16485 fputs ("MIPS R10000", stdout);
16486 break;
16487 case AFL_EXT_SB1:
16488 fputs ("Broadcom SB-1", stdout);
16489 break;
16490 case AFL_EXT_4111:
16491 fputs ("NEC VR4111/VR4181", stdout);
16492 break;
16493 case AFL_EXT_4120:
16494 fputs ("NEC VR4120", stdout);
16495 break;
16496 case AFL_EXT_5400:
16497 fputs ("NEC VR5400", stdout);
16498 break;
16499 case AFL_EXT_5500:
16500 fputs ("NEC VR5500", stdout);
16501 break;
16502 case AFL_EXT_LOONGSON_2E:
16503 fputs ("ST Microelectronics Loongson 2E", stdout);
16504 break;
16505 case AFL_EXT_LOONGSON_2F:
16506 fputs ("ST Microelectronics Loongson 2F", stdout);
16507 break;
38bf472a
MR
16508 case AFL_EXT_INTERAPTIV_MR2:
16509 fputs ("Imagination interAptiv MR2", stdout);
16510 break;
351cdf24 16511 default:
00ac7aa0 16512 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
16513 }
16514}
16515
32ec8896 16516static signed int
351cdf24
MF
16517get_mips_reg_size (int reg_size)
16518{
16519 return (reg_size == AFL_REG_NONE) ? 0
16520 : (reg_size == AFL_REG_32) ? 32
16521 : (reg_size == AFL_REG_64) ? 64
16522 : (reg_size == AFL_REG_128) ? 128
16523 : -1;
16524}
16525
32ec8896 16526static bfd_boolean
dda8d76d 16527process_mips_specific (Filedata * filedata)
5b18a4bc 16528{
2cf0635d 16529 Elf_Internal_Dyn * entry;
351cdf24 16530 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
16531 size_t liblist_offset = 0;
16532 size_t liblistno = 0;
16533 size_t conflictsno = 0;
16534 size_t options_offset = 0;
16535 size_t conflicts_offset = 0;
861fb55a
DJ
16536 size_t pltrelsz = 0;
16537 size_t pltrel = 0;
ccb4c951 16538 bfd_vma pltgot = 0;
861fb55a
DJ
16539 bfd_vma mips_pltgot = 0;
16540 bfd_vma jmprel = 0;
ccb4c951
RS
16541 bfd_vma local_gotno = 0;
16542 bfd_vma gotsym = 0;
16543 bfd_vma symtabno = 0;
32ec8896 16544 bfd_boolean res = TRUE;
103f02d3 16545
dda8d76d 16546 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
16547 display_mips_gnu_attribute))
16548 res = FALSE;
2cf19d5c 16549
dda8d76d 16550 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
16551
16552 if (sect != NULL)
16553 {
16554 Elf_External_ABIFlags_v0 *abiflags_ext;
16555 Elf_Internal_ABIFlags_v0 abiflags_in;
16556
16557 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
16558 {
16559 error (_("Corrupt MIPS ABI Flags section.\n"));
16560 res = FALSE;
16561 }
351cdf24
MF
16562 else
16563 {
dda8d76d 16564 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
16565 sect->sh_size, _("MIPS ABI Flags section"));
16566 if (abiflags_ext)
16567 {
16568 abiflags_in.version = BYTE_GET (abiflags_ext->version);
16569 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
16570 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
16571 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
16572 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
16573 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
16574 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
16575 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
16576 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
16577 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
16578 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
16579
16580 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
16581 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
16582 if (abiflags_in.isa_rev > 1)
16583 printf ("r%d", abiflags_in.isa_rev);
16584 printf ("\nGPR size: %d",
16585 get_mips_reg_size (abiflags_in.gpr_size));
16586 printf ("\nCPR1 size: %d",
16587 get_mips_reg_size (abiflags_in.cpr1_size));
16588 printf ("\nCPR2 size: %d",
16589 get_mips_reg_size (abiflags_in.cpr2_size));
16590 fputs ("\nFP ABI: ", stdout);
16591 print_mips_fp_abi_value (abiflags_in.fp_abi);
16592 fputs ("ISA Extension: ", stdout);
16593 print_mips_isa_ext (abiflags_in.isa_ext);
16594 fputs ("\nASEs:", stdout);
16595 print_mips_ases (abiflags_in.ases);
16596 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
16597 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
16598 fputc ('\n', stdout);
16599 free (abiflags_ext);
16600 }
16601 }
16602 }
16603
19e6b90e 16604 /* We have a lot of special sections. Thanks SGI! */
978c4450 16605 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
16606 {
16607 /* No dynamic information available. See if there is static GOT. */
dda8d76d 16608 sect = find_section (filedata, ".got");
bbdd9a68
MR
16609 if (sect != NULL)
16610 {
16611 unsigned char *data_end;
16612 unsigned char *data;
16613 bfd_vma ent, end;
16614 int addr_size;
16615
16616 pltgot = sect->sh_addr;
16617
16618 ent = pltgot;
16619 addr_size = (is_32bit_elf ? 4 : 8);
16620 end = pltgot + sect->sh_size;
16621
dda8d76d 16622 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
16623 end - pltgot, 1,
16624 _("Global Offset Table data"));
16625 /* PR 12855: Null data is handled gracefully throughout. */
16626 data_end = data + (end - pltgot);
16627
16628 printf (_("\nStatic GOT:\n"));
16629 printf (_(" Canonical gp value: "));
16630 print_vma (ent + 0x7ff0, LONG_HEX);
16631 printf ("\n\n");
16632
16633 /* In a dynamic binary GOT[0] is reserved for the dynamic
16634 loader to store the lazy resolver pointer, however in
16635 a static binary it may well have been omitted and GOT
16636 reduced to a table of addresses.
16637 PR 21344: Check for the entry being fully available
16638 before fetching it. */
16639 if (data
16640 && data + ent - pltgot + addr_size <= data_end
16641 && byte_get (data + ent - pltgot, addr_size) == 0)
16642 {
16643 printf (_(" Reserved entries:\n"));
16644 printf (_(" %*s %10s %*s\n"),
16645 addr_size * 2, _("Address"), _("Access"),
16646 addr_size * 2, _("Value"));
16647 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16648 printf ("\n");
16649 if (ent == (bfd_vma) -1)
16650 goto sgot_print_fail;
16651
16652 /* Check for the MSB of GOT[1] being set, identifying a
16653 GNU object. This entry will be used by some runtime
16654 loaders, to store the module pointer. Otherwise this
16655 is an ordinary local entry.
16656 PR 21344: Check for the entry being fully available
16657 before fetching it. */
16658 if (data
16659 && data + ent - pltgot + addr_size <= data_end
16660 && (byte_get (data + ent - pltgot, addr_size)
16661 >> (addr_size * 8 - 1)) != 0)
16662 {
16663 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16664 printf ("\n");
16665 if (ent == (bfd_vma) -1)
16666 goto sgot_print_fail;
16667 }
16668 printf ("\n");
16669 }
16670
f17e9d8a 16671 if (data != NULL && ent < end)
bbdd9a68
MR
16672 {
16673 printf (_(" Local entries:\n"));
16674 printf (" %*s %10s %*s\n",
16675 addr_size * 2, _("Address"), _("Access"),
16676 addr_size * 2, _("Value"));
16677 while (ent < end)
16678 {
16679 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16680 printf ("\n");
16681 if (ent == (bfd_vma) -1)
16682 goto sgot_print_fail;
16683 }
16684 printf ("\n");
16685 }
16686
16687 sgot_print_fail:
16688 if (data)
16689 free (data);
16690 }
16691 return res;
16692 }
252b5132 16693
978c4450 16694 for (entry = filedata->dynamic_section;
071436c6 16695 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
16696 (entry < filedata->dynamic_section + filedata->dynamic_nent
16697 && entry->d_tag != DT_NULL);
071436c6 16698 ++entry)
252b5132
RH
16699 switch (entry->d_tag)
16700 {
16701 case DT_MIPS_LIBLIST:
d93f0186 16702 liblist_offset
dda8d76d 16703 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16704 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
16705 break;
16706 case DT_MIPS_LIBLISTNO:
16707 liblistno = entry->d_un.d_val;
16708 break;
16709 case DT_MIPS_OPTIONS:
dda8d76d 16710 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
16711 break;
16712 case DT_MIPS_CONFLICT:
d93f0186 16713 conflicts_offset
dda8d76d 16714 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16715 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
16716 break;
16717 case DT_MIPS_CONFLICTNO:
16718 conflictsno = entry->d_un.d_val;
16719 break;
ccb4c951 16720 case DT_PLTGOT:
861fb55a
DJ
16721 pltgot = entry->d_un.d_ptr;
16722 break;
ccb4c951
RS
16723 case DT_MIPS_LOCAL_GOTNO:
16724 local_gotno = entry->d_un.d_val;
16725 break;
16726 case DT_MIPS_GOTSYM:
16727 gotsym = entry->d_un.d_val;
16728 break;
16729 case DT_MIPS_SYMTABNO:
16730 symtabno = entry->d_un.d_val;
16731 break;
861fb55a
DJ
16732 case DT_MIPS_PLTGOT:
16733 mips_pltgot = entry->d_un.d_ptr;
16734 break;
16735 case DT_PLTREL:
16736 pltrel = entry->d_un.d_val;
16737 break;
16738 case DT_PLTRELSZ:
16739 pltrelsz = entry->d_un.d_val;
16740 break;
16741 case DT_JMPREL:
16742 jmprel = entry->d_un.d_ptr;
16743 break;
252b5132
RH
16744 default:
16745 break;
16746 }
16747
16748 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
16749 {
2cf0635d 16750 Elf32_External_Lib * elib;
252b5132
RH
16751 size_t cnt;
16752
dda8d76d 16753 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
16754 sizeof (Elf32_External_Lib),
16755 liblistno,
16756 _("liblist section data"));
a6e9f9df 16757 if (elib)
252b5132 16758 {
d3a49aa8
AM
16759 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
16760 "\nSection '.liblist' contains %lu entries:\n",
16761 (unsigned long) liblistno),
a6e9f9df 16762 (unsigned long) liblistno);
2b692964 16763 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
16764 stdout);
16765
16766 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 16767 {
a6e9f9df 16768 Elf32_Lib liblist;
91d6fa6a 16769 time_t atime;
d5b07ef4 16770 char timebuf[128];
2cf0635d 16771 struct tm * tmp;
a6e9f9df
AM
16772
16773 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16774 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
16775 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16776 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16777 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16778
91d6fa6a 16779 tmp = gmtime (&atime);
e9e44622
JJ
16780 snprintf (timebuf, sizeof (timebuf),
16781 "%04u-%02u-%02uT%02u:%02u:%02u",
16782 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16783 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 16784
31104126 16785 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
16786 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
16787 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 16788 else
2b692964 16789 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
16790 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
16791 liblist.l_version);
a6e9f9df
AM
16792
16793 if (liblist.l_flags == 0)
2b692964 16794 puts (_(" NONE"));
a6e9f9df
AM
16795 else
16796 {
16797 static const struct
252b5132 16798 {
2cf0635d 16799 const char * name;
a6e9f9df 16800 int bit;
252b5132 16801 }
a6e9f9df
AM
16802 l_flags_vals[] =
16803 {
16804 { " EXACT_MATCH", LL_EXACT_MATCH },
16805 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
16806 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
16807 { " EXPORTS", LL_EXPORTS },
16808 { " DELAY_LOAD", LL_DELAY_LOAD },
16809 { " DELTA", LL_DELTA }
16810 };
16811 int flags = liblist.l_flags;
16812 size_t fcnt;
16813
60bca95a 16814 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
16815 if ((flags & l_flags_vals[fcnt].bit) != 0)
16816 {
16817 fputs (l_flags_vals[fcnt].name, stdout);
16818 flags ^= l_flags_vals[fcnt].bit;
16819 }
16820 if (flags != 0)
16821 printf (" %#x", (unsigned int) flags);
252b5132 16822
a6e9f9df
AM
16823 puts ("");
16824 }
252b5132 16825 }
252b5132 16826
a6e9f9df
AM
16827 free (elib);
16828 }
32ec8896
NC
16829 else
16830 res = FALSE;
252b5132
RH
16831 }
16832
16833 if (options_offset != 0)
16834 {
2cf0635d 16835 Elf_External_Options * eopt;
252b5132
RH
16836 size_t offset;
16837 int cnt;
dda8d76d 16838 sect = filedata->section_headers;
252b5132
RH
16839
16840 /* Find the section header so that we get the size. */
dda8d76d 16841 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 16842 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
16843 if (sect == NULL)
16844 {
16845 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 16846 return FALSE;
071436c6 16847 }
7fc0c668
NC
16848 /* PR 24243 */
16849 if (sect->sh_size < sizeof (* eopt))
16850 {
16851 error (_("The MIPS options section is too small.\n"));
16852 return FALSE;
16853 }
252b5132 16854
dda8d76d 16855 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 16856 sect->sh_size, _("options"));
a6e9f9df 16857 if (eopt)
252b5132 16858 {
2e6be59c
NC
16859 Elf_Internal_Options * iopt;
16860 Elf_Internal_Options * option;
16861 Elf_Internal_Options * iopt_end;
16862
3f5e193b
NC
16863 iopt = (Elf_Internal_Options *)
16864 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
16865 if (iopt == NULL)
16866 {
fb324ee9 16867 error (_("Out of memory allocating space for MIPS options\n"));
645f43a8 16868 free (eopt);
32ec8896 16869 return FALSE;
a6e9f9df 16870 }
76da6bbe 16871
a6e9f9df
AM
16872 offset = cnt = 0;
16873 option = iopt;
2e6be59c
NC
16874 iopt_end = iopt + (sect->sh_size / sizeof (eopt));
16875
82b1b41b 16876 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 16877 {
2cf0635d 16878 Elf_External_Options * eoption;
252b5132 16879
a6e9f9df 16880 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 16881
a6e9f9df
AM
16882 option->kind = BYTE_GET (eoption->kind);
16883 option->size = BYTE_GET (eoption->size);
16884 option->section = BYTE_GET (eoption->section);
16885 option->info = BYTE_GET (eoption->info);
76da6bbe 16886
82b1b41b
NC
16887 /* PR 17531: file: ffa0fa3b. */
16888 if (option->size < sizeof (* eopt)
16889 || offset + option->size > sect->sh_size)
16890 {
645f43a8
AM
16891 error (_("Invalid size (%u) for MIPS option\n"),
16892 option->size);
16893 free (iopt);
16894 free (eopt);
32ec8896 16895 return FALSE;
82b1b41b 16896 }
a6e9f9df 16897 offset += option->size;
14ae95f2 16898
a6e9f9df
AM
16899 ++option;
16900 ++cnt;
16901 }
252b5132 16902
d3a49aa8
AM
16903 printf (ngettext ("\nSection '%s' contains %d entry:\n",
16904 "\nSection '%s' contains %d entries:\n",
16905 cnt),
dda8d76d 16906 printable_section_name (filedata, sect), cnt);
76da6bbe 16907
a6e9f9df 16908 option = iopt;
82b1b41b 16909 offset = 0;
252b5132 16910
a6e9f9df 16911 while (cnt-- > 0)
252b5132 16912 {
a6e9f9df
AM
16913 size_t len;
16914
16915 switch (option->kind)
252b5132 16916 {
a6e9f9df
AM
16917 case ODK_NULL:
16918 /* This shouldn't happen. */
16919 printf (" NULL %d %lx", option->section, option->info);
16920 break;
2e6be59c 16921
a6e9f9df
AM
16922 case ODK_REGINFO:
16923 printf (" REGINFO ");
dda8d76d 16924 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 16925 {
2cf0635d 16926 Elf32_External_RegInfo * ereg;
b34976b6 16927 Elf32_RegInfo reginfo;
a6e9f9df 16928
2e6be59c
NC
16929 /* 32bit form. */
16930 if (option + 2 > iopt_end)
16931 {
16932 printf (_("<corrupt>\n"));
16933 error (_("Truncated MIPS REGINFO option\n"));
16934 cnt = 0;
16935 break;
16936 }
16937
a6e9f9df 16938 ereg = (Elf32_External_RegInfo *) (option + 1);
2e6be59c 16939
a6e9f9df
AM
16940 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
16941 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
16942 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16943 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16944 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
16945 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
16946
16947 printf ("GPR %08lx GP 0x%lx\n",
16948 reginfo.ri_gprmask,
16949 (unsigned long) reginfo.ri_gp_value);
16950 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
16951 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
16952 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
16953 }
16954 else
16955 {
16956 /* 64 bit form. */
2cf0635d 16957 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
16958 Elf64_Internal_RegInfo reginfo;
16959
2e6be59c
NC
16960 if (option + 2 > iopt_end)
16961 {
16962 printf (_("<corrupt>\n"));
16963 error (_("Truncated MIPS REGINFO option\n"));
16964 cnt = 0;
16965 break;
16966 }
16967
a6e9f9df
AM
16968 ereg = (Elf64_External_RegInfo *) (option + 1);
16969 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
16970 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
16971 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16972 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16973 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 16974 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
16975
16976 printf ("GPR %08lx GP 0x",
16977 reginfo.ri_gprmask);
16978 printf_vma (reginfo.ri_gp_value);
16979 printf ("\n");
16980
16981 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
16982 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
16983 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
16984 }
16985 ++option;
16986 continue;
2e6be59c 16987
a6e9f9df
AM
16988 case ODK_EXCEPTIONS:
16989 fputs (" EXCEPTIONS fpe_min(", stdout);
16990 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
16991 fputs (") fpe_max(", stdout);
16992 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
16993 fputs (")", stdout);
16994
16995 if (option->info & OEX_PAGE0)
16996 fputs (" PAGE0", stdout);
16997 if (option->info & OEX_SMM)
16998 fputs (" SMM", stdout);
16999 if (option->info & OEX_FPDBUG)
17000 fputs (" FPDBUG", stdout);
17001 if (option->info & OEX_DISMISS)
17002 fputs (" DISMISS", stdout);
17003 break;
2e6be59c 17004
a6e9f9df
AM
17005 case ODK_PAD:
17006 fputs (" PAD ", stdout);
17007 if (option->info & OPAD_PREFIX)
17008 fputs (" PREFIX", stdout);
17009 if (option->info & OPAD_POSTFIX)
17010 fputs (" POSTFIX", stdout);
17011 if (option->info & OPAD_SYMBOL)
17012 fputs (" SYMBOL", stdout);
17013 break;
2e6be59c 17014
a6e9f9df
AM
17015 case ODK_HWPATCH:
17016 fputs (" HWPATCH ", stdout);
17017 if (option->info & OHW_R4KEOP)
17018 fputs (" R4KEOP", stdout);
17019 if (option->info & OHW_R8KPFETCH)
17020 fputs (" R8KPFETCH", stdout);
17021 if (option->info & OHW_R5KEOP)
17022 fputs (" R5KEOP", stdout);
17023 if (option->info & OHW_R5KCVTL)
17024 fputs (" R5KCVTL", stdout);
17025 break;
2e6be59c 17026
a6e9f9df
AM
17027 case ODK_FILL:
17028 fputs (" FILL ", stdout);
17029 /* XXX Print content of info word? */
17030 break;
2e6be59c 17031
a6e9f9df
AM
17032 case ODK_TAGS:
17033 fputs (" TAGS ", stdout);
17034 /* XXX Print content of info word? */
17035 break;
2e6be59c 17036
a6e9f9df
AM
17037 case ODK_HWAND:
17038 fputs (" HWAND ", stdout);
17039 if (option->info & OHWA0_R4KEOP_CHECKED)
17040 fputs (" R4KEOP_CHECKED", stdout);
17041 if (option->info & OHWA0_R4KEOP_CLEAN)
17042 fputs (" R4KEOP_CLEAN", stdout);
17043 break;
2e6be59c 17044
a6e9f9df
AM
17045 case ODK_HWOR:
17046 fputs (" HWOR ", stdout);
17047 if (option->info & OHWA0_R4KEOP_CHECKED)
17048 fputs (" R4KEOP_CHECKED", stdout);
17049 if (option->info & OHWA0_R4KEOP_CLEAN)
17050 fputs (" R4KEOP_CLEAN", stdout);
17051 break;
2e6be59c 17052
a6e9f9df
AM
17053 case ODK_GP_GROUP:
17054 printf (" GP_GROUP %#06lx self-contained %#06lx",
17055 option->info & OGP_GROUP,
17056 (option->info & OGP_SELF) >> 16);
17057 break;
2e6be59c 17058
a6e9f9df
AM
17059 case ODK_IDENT:
17060 printf (" IDENT %#06lx self-contained %#06lx",
17061 option->info & OGP_GROUP,
17062 (option->info & OGP_SELF) >> 16);
17063 break;
2e6be59c 17064
a6e9f9df
AM
17065 default:
17066 /* This shouldn't happen. */
17067 printf (" %3d ??? %d %lx",
17068 option->kind, option->section, option->info);
17069 break;
252b5132 17070 }
a6e9f9df 17071
2cf0635d 17072 len = sizeof (* eopt);
a6e9f9df 17073 while (len < option->size)
82b1b41b 17074 {
7e27a9d5 17075 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 17076
82b1b41b
NC
17077 if (ISPRINT (datum))
17078 printf ("%c", datum);
17079 else
17080 printf ("\\%03o", datum);
17081 len ++;
17082 }
a6e9f9df 17083 fputs ("\n", stdout);
82b1b41b
NC
17084
17085 offset += option->size;
252b5132 17086 ++option;
252b5132 17087 }
645f43a8 17088 free (iopt);
a6e9f9df 17089 free (eopt);
252b5132 17090 }
32ec8896
NC
17091 else
17092 res = FALSE;
252b5132
RH
17093 }
17094
17095 if (conflicts_offset != 0 && conflictsno != 0)
17096 {
2cf0635d 17097 Elf32_Conflict * iconf;
252b5132
RH
17098 size_t cnt;
17099
978c4450 17100 if (filedata->dynamic_symbols == NULL)
252b5132 17101 {
591a748a 17102 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 17103 return FALSE;
252b5132
RH
17104 }
17105
7296a62a
NC
17106 /* PR 21345 - print a slightly more helpful error message
17107 if we are sure that the cmalloc will fail. */
645f43a8 17108 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
17109 {
17110 error (_("Overlarge number of conflicts detected: %lx\n"),
17111 (long) conflictsno);
17112 return FALSE;
17113 }
17114
3f5e193b 17115 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
17116 if (iconf == NULL)
17117 {
8b73c356 17118 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 17119 return FALSE;
252b5132
RH
17120 }
17121
9ea033b2 17122 if (is_32bit_elf)
252b5132 17123 {
2cf0635d 17124 Elf32_External_Conflict * econf32;
a6e9f9df 17125
3f5e193b 17126 econf32 = (Elf32_External_Conflict *)
95099889
AM
17127 get_data (NULL, filedata, conflicts_offset,
17128 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 17129 if (!econf32)
5a814d6d
AM
17130 {
17131 free (iconf);
17132 return FALSE;
17133 }
252b5132
RH
17134
17135 for (cnt = 0; cnt < conflictsno; ++cnt)
17136 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
17137
17138 free (econf32);
252b5132
RH
17139 }
17140 else
17141 {
2cf0635d 17142 Elf64_External_Conflict * econf64;
a6e9f9df 17143
3f5e193b 17144 econf64 = (Elf64_External_Conflict *)
95099889
AM
17145 get_data (NULL, filedata, conflicts_offset,
17146 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 17147 if (!econf64)
5a814d6d
AM
17148 {
17149 free (iconf);
17150 return FALSE;
17151 }
252b5132
RH
17152
17153 for (cnt = 0; cnt < conflictsno; ++cnt)
17154 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
17155
17156 free (econf64);
252b5132
RH
17157 }
17158
d3a49aa8
AM
17159 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
17160 "\nSection '.conflict' contains %lu entries:\n",
17161 (unsigned long) conflictsno),
c7e7ca54 17162 (unsigned long) conflictsno);
252b5132
RH
17163 puts (_(" Num: Index Value Name"));
17164
17165 for (cnt = 0; cnt < conflictsno; ++cnt)
17166 {
b34976b6 17167 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 17168
978c4450 17169 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 17170 printf (_("<corrupt symbol index>"));
d79b3d50 17171 else
e0a31db1
NC
17172 {
17173 Elf_Internal_Sym * psym;
17174
978c4450 17175 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
17176 print_vma (psym->st_value, FULL_HEX);
17177 putchar (' ');
978c4450
AM
17178 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17179 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17180 else
17181 printf (_("<corrupt: %14ld>"), psym->st_name);
17182 }
31104126 17183 putchar ('\n');
252b5132
RH
17184 }
17185
252b5132
RH
17186 free (iconf);
17187 }
17188
ccb4c951
RS
17189 if (pltgot != 0 && local_gotno != 0)
17190 {
91d6fa6a 17191 bfd_vma ent, local_end, global_end;
bbeee7ea 17192 size_t i, offset;
2cf0635d 17193 unsigned char * data;
82b1b41b 17194 unsigned char * data_end;
bbeee7ea 17195 int addr_size;
ccb4c951 17196
91d6fa6a 17197 ent = pltgot;
ccb4c951
RS
17198 addr_size = (is_32bit_elf ? 4 : 8);
17199 local_end = pltgot + local_gotno * addr_size;
ccb4c951 17200
74e1a04b
NC
17201 /* PR binutils/17533 file: 012-111227-0.004 */
17202 if (symtabno < gotsym)
17203 {
17204 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 17205 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 17206 return FALSE;
74e1a04b 17207 }
82b1b41b 17208
74e1a04b 17209 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
17210 /* PR 17531: file: 54c91a34. */
17211 if (global_end < local_end)
17212 {
17213 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 17214 return FALSE;
82b1b41b 17215 }
948f632f 17216
dda8d76d
NC
17217 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
17218 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
17219 global_end - pltgot, 1,
17220 _("Global Offset Table data"));
919383ac 17221 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 17222 data_end = data + (global_end - pltgot);
59245841 17223
ccb4c951
RS
17224 printf (_("\nPrimary GOT:\n"));
17225 printf (_(" Canonical gp value: "));
17226 print_vma (pltgot + 0x7ff0, LONG_HEX);
17227 printf ("\n\n");
17228
17229 printf (_(" Reserved entries:\n"));
17230 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
17231 addr_size * 2, _("Address"), _("Access"),
17232 addr_size * 2, _("Initial"));
82b1b41b 17233 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 17234 printf (_(" Lazy resolver\n"));
82b1b41b
NC
17235 if (ent == (bfd_vma) -1)
17236 goto got_print_fail;
75ec1fdb 17237
c4ab9505
MR
17238 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
17239 This entry will be used by some runtime loaders, to store the
17240 module pointer. Otherwise this is an ordinary local entry.
17241 PR 21344: Check for the entry being fully available before
17242 fetching it. */
17243 if (data
17244 && data + ent - pltgot + addr_size <= data_end
17245 && (byte_get (data + ent - pltgot, addr_size)
17246 >> (addr_size * 8 - 1)) != 0)
17247 {
17248 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17249 printf (_(" Module pointer (GNU extension)\n"));
17250 if (ent == (bfd_vma) -1)
17251 goto got_print_fail;
ccb4c951
RS
17252 }
17253 printf ("\n");
17254
f17e9d8a 17255 if (data != NULL && ent < local_end)
ccb4c951
RS
17256 {
17257 printf (_(" Local entries:\n"));
cc5914eb 17258 printf (" %*s %10s %*s\n",
2b692964
NC
17259 addr_size * 2, _("Address"), _("Access"),
17260 addr_size * 2, _("Initial"));
91d6fa6a 17261 while (ent < local_end)
ccb4c951 17262 {
82b1b41b 17263 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17264 printf ("\n");
82b1b41b
NC
17265 if (ent == (bfd_vma) -1)
17266 goto got_print_fail;
ccb4c951
RS
17267 }
17268 printf ("\n");
17269 }
17270
f17e9d8a 17271 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
17272 {
17273 int sym_width;
17274
17275 printf (_(" Global entries:\n"));
cc5914eb 17276 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
17277 addr_size * 2, _("Address"),
17278 _("Access"),
2b692964 17279 addr_size * 2, _("Initial"),
9cf03b7e
NC
17280 addr_size * 2, _("Sym.Val."),
17281 _("Type"),
17282 /* Note for translators: "Ndx" = abbreviated form of "Index". */
17283 _("Ndx"), _("Name"));
0b4362b0 17284
ccb4c951 17285 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 17286
ccb4c951
RS
17287 for (i = gotsym; i < symtabno; i++)
17288 {
82b1b41b 17289 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17290 printf (" ");
e0a31db1 17291
978c4450 17292 if (filedata->dynamic_symbols == NULL)
e0a31db1 17293 printf (_("<no dynamic symbols>"));
978c4450 17294 else if (i < filedata->num_dynamic_syms)
e0a31db1 17295 {
978c4450 17296 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
17297
17298 print_vma (psym->st_value, LONG_HEX);
17299 printf (" %-7s %3s ",
dda8d76d
NC
17300 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17301 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 17302
978c4450
AM
17303 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17304 print_symbol (sym_width,
17305 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17306 else
17307 printf (_("<corrupt: %14ld>"), psym->st_name);
17308 }
ccb4c951 17309 else
7fc5ac57
JBG
17310 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
17311 (unsigned long) i);
e0a31db1 17312
ccb4c951 17313 printf ("\n");
82b1b41b
NC
17314 if (ent == (bfd_vma) -1)
17315 break;
ccb4c951
RS
17316 }
17317 printf ("\n");
17318 }
17319
82b1b41b 17320 got_print_fail:
ccb4c951
RS
17321 if (data)
17322 free (data);
17323 }
17324
861fb55a
DJ
17325 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
17326 {
91d6fa6a 17327 bfd_vma ent, end;
861fb55a
DJ
17328 size_t offset, rel_offset;
17329 unsigned long count, i;
2cf0635d 17330 unsigned char * data;
861fb55a 17331 int addr_size, sym_width;
2cf0635d 17332 Elf_Internal_Rela * rels;
861fb55a 17333
dda8d76d 17334 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
17335 if (pltrel == DT_RELA)
17336 {
dda8d76d 17337 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17338 return FALSE;
861fb55a
DJ
17339 }
17340 else
17341 {
dda8d76d 17342 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17343 return FALSE;
861fb55a
DJ
17344 }
17345
91d6fa6a 17346 ent = mips_pltgot;
861fb55a
DJ
17347 addr_size = (is_32bit_elf ? 4 : 8);
17348 end = mips_pltgot + (2 + count) * addr_size;
17349
dda8d76d
NC
17350 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
17351 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 17352 1, _("Procedure Linkage Table data"));
59245841 17353 if (data == NULL)
32ec8896 17354 return FALSE;
59245841 17355
9cf03b7e 17356 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
17357 printf (_(" Reserved entries:\n"));
17358 printf (_(" %*s %*s Purpose\n"),
2b692964 17359 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 17360 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17361 printf (_(" PLT lazy resolver\n"));
91d6fa6a 17362 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17363 printf (_(" Module pointer\n"));
861fb55a
DJ
17364 printf ("\n");
17365
17366 printf (_(" Entries:\n"));
cc5914eb 17367 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
17368 addr_size * 2, _("Address"),
17369 addr_size * 2, _("Initial"),
17370 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
17371 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
17372 for (i = 0; i < count; i++)
17373 {
df97ab2a 17374 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 17375
91d6fa6a 17376 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 17377 printf (" ");
e0a31db1 17378
978c4450 17379 if (idx >= filedata->num_dynamic_syms)
df97ab2a 17380 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 17381 else
e0a31db1 17382 {
978c4450 17383 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
17384
17385 print_vma (psym->st_value, LONG_HEX);
17386 printf (" %-7s %3s ",
dda8d76d
NC
17387 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17388 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
17389 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17390 print_symbol (sym_width,
17391 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17392 else
17393 printf (_("<corrupt: %14ld>"), psym->st_name);
17394 }
861fb55a
DJ
17395 printf ("\n");
17396 }
17397 printf ("\n");
17398
17399 if (data)
17400 free (data);
17401 free (rels);
17402 }
17403
32ec8896 17404 return res;
252b5132
RH
17405}
17406
32ec8896 17407static bfd_boolean
dda8d76d 17408process_nds32_specific (Filedata * filedata)
35c08157
KLC
17409{
17410 Elf_Internal_Shdr *sect = NULL;
17411
dda8d76d 17412 sect = find_section (filedata, ".nds32_e_flags");
35c08157
KLC
17413 if (sect != NULL)
17414 {
17415 unsigned int *flag;
17416
17417 printf ("\nNDS32 elf flags section:\n");
dda8d76d 17418 flag = get_data (NULL, filedata, sect->sh_offset, 1,
35c08157
KLC
17419 sect->sh_size, _("NDS32 elf flags section"));
17420
32ec8896
NC
17421 if (! flag)
17422 return FALSE;
17423
35c08157
KLC
17424 switch ((*flag) & 0x3)
17425 {
17426 case 0:
17427 printf ("(VEC_SIZE):\tNo entry.\n");
17428 break;
17429 case 1:
17430 printf ("(VEC_SIZE):\t4 bytes\n");
17431 break;
17432 case 2:
17433 printf ("(VEC_SIZE):\t16 bytes\n");
17434 break;
17435 case 3:
17436 printf ("(VEC_SIZE):\treserved\n");
17437 break;
17438 }
17439 }
17440
17441 return TRUE;
17442}
17443
32ec8896 17444static bfd_boolean
dda8d76d 17445process_gnu_liblist (Filedata * filedata)
047b2264 17446{
2cf0635d
NC
17447 Elf_Internal_Shdr * section;
17448 Elf_Internal_Shdr * string_sec;
17449 Elf32_External_Lib * elib;
17450 char * strtab;
c256ffe7 17451 size_t strtab_size;
047b2264 17452 size_t cnt;
d3a49aa8 17453 unsigned long num_liblist;
047b2264 17454 unsigned i;
32ec8896 17455 bfd_boolean res = TRUE;
047b2264
JJ
17456
17457 if (! do_arch)
32ec8896 17458 return TRUE;
047b2264 17459
dda8d76d
NC
17460 for (i = 0, section = filedata->section_headers;
17461 i < filedata->file_header.e_shnum;
b34976b6 17462 i++, section++)
047b2264
JJ
17463 {
17464 switch (section->sh_type)
17465 {
17466 case SHT_GNU_LIBLIST:
dda8d76d 17467 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
17468 break;
17469
3f5e193b 17470 elib = (Elf32_External_Lib *)
dda8d76d 17471 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 17472 _("liblist section data"));
047b2264
JJ
17473
17474 if (elib == NULL)
32ec8896
NC
17475 {
17476 res = FALSE;
17477 break;
17478 }
047b2264 17479
dda8d76d
NC
17480 string_sec = filedata->section_headers + section->sh_link;
17481 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
17482 string_sec->sh_size,
17483 _("liblist string table"));
047b2264
JJ
17484 if (strtab == NULL
17485 || section->sh_entsize != sizeof (Elf32_External_Lib))
17486 {
17487 free (elib);
2842702f 17488 free (strtab);
32ec8896 17489 res = FALSE;
047b2264
JJ
17490 break;
17491 }
59245841 17492 strtab_size = string_sec->sh_size;
047b2264 17493
d3a49aa8
AM
17494 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
17495 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
17496 "\nLibrary list section '%s' contains %lu entries:\n",
17497 num_liblist),
dda8d76d 17498 printable_section_name (filedata, section),
d3a49aa8 17499 num_liblist);
047b2264 17500
2b692964 17501 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
17502
17503 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
17504 ++cnt)
17505 {
17506 Elf32_Lib liblist;
91d6fa6a 17507 time_t atime;
d5b07ef4 17508 char timebuf[128];
2cf0635d 17509 struct tm * tmp;
047b2264
JJ
17510
17511 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17512 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
17513 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17514 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17515 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17516
91d6fa6a 17517 tmp = gmtime (&atime);
e9e44622
JJ
17518 snprintf (timebuf, sizeof (timebuf),
17519 "%04u-%02u-%02uT%02u:%02u:%02u",
17520 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17521 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
17522
17523 printf ("%3lu: ", (unsigned long) cnt);
17524 if (do_wide)
c256ffe7 17525 printf ("%-20s", liblist.l_name < strtab_size
2b692964 17526 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 17527 else
c256ffe7 17528 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 17529 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
17530 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
17531 liblist.l_version, liblist.l_flags);
17532 }
17533
17534 free (elib);
2842702f 17535 free (strtab);
047b2264
JJ
17536 }
17537 }
17538
32ec8896 17539 return res;
047b2264
JJ
17540}
17541
9437c45b 17542static const char *
dda8d76d 17543get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
17544{
17545 static char buff[64];
103f02d3 17546
dda8d76d 17547 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
17548 switch (e_type)
17549 {
57346661 17550 case NT_AUXV:
1ec5cd37 17551 return _("NT_AUXV (auxiliary vector)");
57346661 17552 case NT_PRSTATUS:
1ec5cd37 17553 return _("NT_PRSTATUS (prstatus structure)");
57346661 17554 case NT_FPREGSET:
1ec5cd37 17555 return _("NT_FPREGSET (floating point registers)");
57346661 17556 case NT_PRPSINFO:
1ec5cd37 17557 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 17558 case NT_TASKSTRUCT:
1ec5cd37 17559 return _("NT_TASKSTRUCT (task structure)");
57346661 17560 case NT_PRXFPREG:
1ec5cd37 17561 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
17562 case NT_PPC_VMX:
17563 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
17564 case NT_PPC_VSX:
17565 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
17566 case NT_PPC_TAR:
17567 return _("NT_PPC_TAR (ppc TAR register)");
17568 case NT_PPC_PPR:
17569 return _("NT_PPC_PPR (ppc PPR register)");
17570 case NT_PPC_DSCR:
17571 return _("NT_PPC_DSCR (ppc DSCR register)");
17572 case NT_PPC_EBB:
17573 return _("NT_PPC_EBB (ppc EBB registers)");
17574 case NT_PPC_PMU:
17575 return _("NT_PPC_PMU (ppc PMU registers)");
17576 case NT_PPC_TM_CGPR:
17577 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
17578 case NT_PPC_TM_CFPR:
17579 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
17580 case NT_PPC_TM_CVMX:
17581 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
17582 case NT_PPC_TM_CVSX:
3fd21718 17583 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
17584 case NT_PPC_TM_SPR:
17585 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
17586 case NT_PPC_TM_CTAR:
17587 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
17588 case NT_PPC_TM_CPPR:
17589 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
17590 case NT_PPC_TM_CDSCR:
17591 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
17592 case NT_386_TLS:
17593 return _("NT_386_TLS (x86 TLS information)");
17594 case NT_386_IOPERM:
17595 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
17596 case NT_X86_XSTATE:
17597 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
17598 case NT_S390_HIGH_GPRS:
17599 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
17600 case NT_S390_TIMER:
17601 return _("NT_S390_TIMER (s390 timer register)");
17602 case NT_S390_TODCMP:
17603 return _("NT_S390_TODCMP (s390 TOD comparator register)");
17604 case NT_S390_TODPREG:
17605 return _("NT_S390_TODPREG (s390 TOD programmable register)");
17606 case NT_S390_CTRS:
17607 return _("NT_S390_CTRS (s390 control registers)");
17608 case NT_S390_PREFIX:
17609 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
17610 case NT_S390_LAST_BREAK:
17611 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
17612 case NT_S390_SYSTEM_CALL:
17613 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
17614 case NT_S390_TDB:
17615 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
17616 case NT_S390_VXRS_LOW:
17617 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
17618 case NT_S390_VXRS_HIGH:
17619 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
17620 case NT_S390_GS_CB:
17621 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
17622 case NT_S390_GS_BC:
17623 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
17624 case NT_ARM_VFP:
17625 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
17626 case NT_ARM_TLS:
17627 return _("NT_ARM_TLS (AArch TLS registers)");
17628 case NT_ARM_HW_BREAK:
17629 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
17630 case NT_ARM_HW_WATCH:
17631 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
17632 case NT_ARC_V2:
17633 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
57346661 17634 case NT_PSTATUS:
1ec5cd37 17635 return _("NT_PSTATUS (pstatus structure)");
57346661 17636 case NT_FPREGS:
1ec5cd37 17637 return _("NT_FPREGS (floating point registers)");
57346661 17638 case NT_PSINFO:
1ec5cd37 17639 return _("NT_PSINFO (psinfo structure)");
57346661 17640 case NT_LWPSTATUS:
1ec5cd37 17641 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 17642 case NT_LWPSINFO:
1ec5cd37 17643 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 17644 case NT_WIN32PSTATUS:
1ec5cd37 17645 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
17646 case NT_SIGINFO:
17647 return _("NT_SIGINFO (siginfo_t data)");
17648 case NT_FILE:
17649 return _("NT_FILE (mapped files)");
1ec5cd37
NC
17650 default:
17651 break;
17652 }
17653 else
17654 switch (e_type)
17655 {
17656 case NT_VERSION:
17657 return _("NT_VERSION (version)");
17658 case NT_ARCH:
17659 return _("NT_ARCH (architecture)");
9ef920e9 17660 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 17661 return _("OPEN");
9ef920e9 17662 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 17663 return _("func");
1ec5cd37
NC
17664 default:
17665 break;
17666 }
17667
e9e44622 17668 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 17669 return buff;
779fe533
NC
17670}
17671
32ec8896 17672static bfd_boolean
9ece1fa9
TT
17673print_core_note (Elf_Internal_Note *pnote)
17674{
17675 unsigned int addr_size = is_32bit_elf ? 4 : 8;
17676 bfd_vma count, page_size;
17677 unsigned char *descdata, *filenames, *descend;
17678
17679 if (pnote->type != NT_FILE)
04ac15ab
AS
17680 {
17681 if (do_wide)
17682 printf ("\n");
17683 return TRUE;
17684 }
9ece1fa9
TT
17685
17686#ifndef BFD64
17687 if (!is_32bit_elf)
17688 {
17689 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
17690 /* Still "successful". */
32ec8896 17691 return TRUE;
9ece1fa9
TT
17692 }
17693#endif
17694
17695 if (pnote->descsz < 2 * addr_size)
17696 {
32ec8896
NC
17697 error (_(" Malformed note - too short for header\n"));
17698 return FALSE;
9ece1fa9
TT
17699 }
17700
17701 descdata = (unsigned char *) pnote->descdata;
17702 descend = descdata + pnote->descsz;
17703
17704 if (descdata[pnote->descsz - 1] != '\0')
17705 {
32ec8896
NC
17706 error (_(" Malformed note - does not end with \\0\n"));
17707 return FALSE;
9ece1fa9
TT
17708 }
17709
17710 count = byte_get (descdata, addr_size);
17711 descdata += addr_size;
17712
17713 page_size = byte_get (descdata, addr_size);
17714 descdata += addr_size;
17715
5396a86e
AM
17716 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
17717 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 17718 {
32ec8896
NC
17719 error (_(" Malformed note - too short for supplied file count\n"));
17720 return FALSE;
9ece1fa9
TT
17721 }
17722
17723 printf (_(" Page size: "));
17724 print_vma (page_size, DEC);
17725 printf ("\n");
17726
17727 printf (_(" %*s%*s%*s\n"),
17728 (int) (2 + 2 * addr_size), _("Start"),
17729 (int) (4 + 2 * addr_size), _("End"),
17730 (int) (4 + 2 * addr_size), _("Page Offset"));
17731 filenames = descdata + count * 3 * addr_size;
595712bb 17732 while (count-- > 0)
9ece1fa9
TT
17733 {
17734 bfd_vma start, end, file_ofs;
17735
17736 if (filenames == descend)
17737 {
32ec8896
NC
17738 error (_(" Malformed note - filenames end too early\n"));
17739 return FALSE;
9ece1fa9
TT
17740 }
17741
17742 start = byte_get (descdata, addr_size);
17743 descdata += addr_size;
17744 end = byte_get (descdata, addr_size);
17745 descdata += addr_size;
17746 file_ofs = byte_get (descdata, addr_size);
17747 descdata += addr_size;
17748
17749 printf (" ");
17750 print_vma (start, FULL_HEX);
17751 printf (" ");
17752 print_vma (end, FULL_HEX);
17753 printf (" ");
17754 print_vma (file_ofs, FULL_HEX);
17755 printf ("\n %s\n", filenames);
17756
17757 filenames += 1 + strlen ((char *) filenames);
17758 }
17759
32ec8896 17760 return TRUE;
9ece1fa9
TT
17761}
17762
1118d252
RM
17763static const char *
17764get_gnu_elf_note_type (unsigned e_type)
17765{
1449284b 17766 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
17767 switch (e_type)
17768 {
17769 case NT_GNU_ABI_TAG:
17770 return _("NT_GNU_ABI_TAG (ABI version tag)");
17771 case NT_GNU_HWCAP:
17772 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
17773 case NT_GNU_BUILD_ID:
17774 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
17775 case NT_GNU_GOLD_VERSION:
17776 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
17777 case NT_GNU_PROPERTY_TYPE_0:
17778 return _("NT_GNU_PROPERTY_TYPE_0");
17779 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
17780 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
17781 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
17782 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 17783 default:
1449284b
NC
17784 {
17785 static char buff[64];
1118d252 17786
1449284b
NC
17787 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17788 return buff;
17789 }
17790 }
1118d252
RM
17791}
17792
a9eafb08
L
17793static void
17794decode_x86_compat_isa (unsigned int bitmask)
17795{
17796 while (bitmask)
17797 {
17798 unsigned int bit = bitmask & (- bitmask);
17799
17800 bitmask &= ~ bit;
17801 switch (bit)
17802 {
17803 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
17804 printf ("i486");
17805 break;
17806 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
17807 printf ("586");
17808 break;
17809 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
17810 printf ("686");
17811 break;
17812 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
17813 printf ("SSE");
17814 break;
17815 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
17816 printf ("SSE2");
17817 break;
17818 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
17819 printf ("SSE3");
17820 break;
17821 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
17822 printf ("SSSE3");
17823 break;
17824 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
17825 printf ("SSE4_1");
17826 break;
17827 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
17828 printf ("SSE4_2");
17829 break;
17830 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
17831 printf ("AVX");
17832 break;
17833 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
17834 printf ("AVX2");
17835 break;
17836 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
17837 printf ("AVX512F");
17838 break;
17839 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
17840 printf ("AVX512CD");
17841 break;
17842 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
17843 printf ("AVX512ER");
17844 break;
17845 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
17846 printf ("AVX512PF");
17847 break;
17848 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
17849 printf ("AVX512VL");
17850 break;
17851 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
17852 printf ("AVX512DQ");
17853 break;
17854 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
17855 printf ("AVX512BW");
17856 break;
65b3d26e
L
17857 default:
17858 printf (_("<unknown: %x>"), bit);
17859 break;
a9eafb08
L
17860 }
17861 if (bitmask)
17862 printf (", ");
17863 }
17864}
17865
9ef920e9 17866static void
1fc87489 17867decode_x86_isa (unsigned int bitmask)
9ef920e9 17868{
0a59decb 17869 if (!bitmask)
90c745dc
L
17870 {
17871 printf (_("<None>"));
17872 return;
17873 }
90c745dc 17874
9ef920e9
NC
17875 while (bitmask)
17876 {
1fc87489 17877 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
17878
17879 bitmask &= ~ bit;
17880 switch (bit)
17881 {
a9eafb08
L
17882 case GNU_PROPERTY_X86_ISA_1_CMOV:
17883 printf ("CMOV");
17884 break;
17885 case GNU_PROPERTY_X86_ISA_1_SSE:
17886 printf ("SSE");
17887 break;
17888 case GNU_PROPERTY_X86_ISA_1_SSE2:
17889 printf ("SSE2");
17890 break;
17891 case GNU_PROPERTY_X86_ISA_1_SSE3:
17892 printf ("SSE3");
17893 break;
17894 case GNU_PROPERTY_X86_ISA_1_SSSE3:
17895 printf ("SSSE3");
17896 break;
17897 case GNU_PROPERTY_X86_ISA_1_SSE4_1:
17898 printf ("SSE4_1");
17899 break;
17900 case GNU_PROPERTY_X86_ISA_1_SSE4_2:
17901 printf ("SSE4_2");
17902 break;
17903 case GNU_PROPERTY_X86_ISA_1_AVX:
17904 printf ("AVX");
17905 break;
17906 case GNU_PROPERTY_X86_ISA_1_AVX2:
17907 printf ("AVX2");
17908 break;
17909 case GNU_PROPERTY_X86_ISA_1_FMA:
17910 printf ("FMA");
17911 break;
17912 case GNU_PROPERTY_X86_ISA_1_AVX512F:
17913 printf ("AVX512F");
17914 break;
17915 case GNU_PROPERTY_X86_ISA_1_AVX512CD:
17916 printf ("AVX512CD");
17917 break;
17918 case GNU_PROPERTY_X86_ISA_1_AVX512ER:
17919 printf ("AVX512ER");
17920 break;
17921 case GNU_PROPERTY_X86_ISA_1_AVX512PF:
17922 printf ("AVX512PF");
17923 break;
17924 case GNU_PROPERTY_X86_ISA_1_AVX512VL:
17925 printf ("AVX512VL");
17926 break;
17927 case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
17928 printf ("AVX512DQ");
17929 break;
17930 case GNU_PROPERTY_X86_ISA_1_AVX512BW:
17931 printf ("AVX512BW");
17932 break;
17933 case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
17934 printf ("AVX512_4FMAPS");
17935 break;
17936 case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
17937 printf ("AVX512_4VNNIW");
17938 break;
17939 case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
17940 printf ("AVX512_BITALG");
17941 break;
17942 case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
17943 printf ("AVX512_IFMA");
17944 break;
17945 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
17946 printf ("AVX512_VBMI");
17947 break;
17948 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
17949 printf ("AVX512_VBMI2");
17950 break;
17951 case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
17952 printf ("AVX512_VNNI");
17953 break;
462cac58
L
17954 case GNU_PROPERTY_X86_ISA_1_AVX512_BF16:
17955 printf ("AVX512_BF16");
17956 break;
65b3d26e
L
17957 default:
17958 printf (_("<unknown: %x>"), bit);
17959 break;
9ef920e9
NC
17960 }
17961 if (bitmask)
17962 printf (", ");
17963 }
17964}
17965
ee2fdd6f 17966static void
a9eafb08 17967decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 17968{
0a59decb 17969 if (!bitmask)
90c745dc
L
17970 {
17971 printf (_("<None>"));
17972 return;
17973 }
90c745dc 17974
ee2fdd6f
L
17975 while (bitmask)
17976 {
17977 unsigned int bit = bitmask & (- bitmask);
17978
17979 bitmask &= ~ bit;
17980 switch (bit)
17981 {
17982 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 17983 printf ("IBT");
ee2fdd6f 17984 break;
48580982 17985 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 17986 printf ("SHSTK");
48580982 17987 break;
ee2fdd6f
L
17988 default:
17989 printf (_("<unknown: %x>"), bit);
17990 break;
17991 }
17992 if (bitmask)
17993 printf (", ");
17994 }
17995}
17996
a9eafb08
L
17997static void
17998decode_x86_feature_2 (unsigned int bitmask)
17999{
0a59decb 18000 if (!bitmask)
90c745dc
L
18001 {
18002 printf (_("<None>"));
18003 return;
18004 }
90c745dc 18005
a9eafb08
L
18006 while (bitmask)
18007 {
18008 unsigned int bit = bitmask & (- bitmask);
18009
18010 bitmask &= ~ bit;
18011 switch (bit)
18012 {
18013 case GNU_PROPERTY_X86_FEATURE_2_X86:
18014 printf ("x86");
18015 break;
18016 case GNU_PROPERTY_X86_FEATURE_2_X87:
18017 printf ("x87");
18018 break;
18019 case GNU_PROPERTY_X86_FEATURE_2_MMX:
18020 printf ("MMX");
18021 break;
18022 case GNU_PROPERTY_X86_FEATURE_2_XMM:
18023 printf ("XMM");
18024 break;
18025 case GNU_PROPERTY_X86_FEATURE_2_YMM:
18026 printf ("YMM");
18027 break;
18028 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
18029 printf ("ZMM");
18030 break;
18031 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
18032 printf ("FXSR");
18033 break;
18034 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
18035 printf ("XSAVE");
18036 break;
18037 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
18038 printf ("XSAVEOPT");
18039 break;
18040 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
18041 printf ("XSAVEC");
18042 break;
65b3d26e
L
18043 default:
18044 printf (_("<unknown: %x>"), bit);
18045 break;
a9eafb08
L
18046 }
18047 if (bitmask)
18048 printf (", ");
18049 }
18050}
18051
cd702818
SD
18052static void
18053decode_aarch64_feature_1_and (unsigned int bitmask)
18054{
18055 while (bitmask)
18056 {
18057 unsigned int bit = bitmask & (- bitmask);
18058
18059 bitmask &= ~ bit;
18060 switch (bit)
18061 {
18062 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
18063 printf ("BTI");
18064 break;
18065
18066 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
18067 printf ("PAC");
18068 break;
18069
18070 default:
18071 printf (_("<unknown: %x>"), bit);
18072 break;
18073 }
18074 if (bitmask)
18075 printf (", ");
18076 }
18077}
18078
9ef920e9 18079static void
dda8d76d 18080print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
18081{
18082 unsigned char * ptr = (unsigned char *) pnote->descdata;
18083 unsigned char * ptr_end = ptr + pnote->descsz;
18084 unsigned int size = is_32bit_elf ? 4 : 8;
18085
18086 printf (_(" Properties: "));
18087
1fc87489 18088 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
18089 {
18090 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
18091 return;
18092 }
18093
6ab2c4ed 18094 while (ptr < ptr_end)
9ef920e9 18095 {
1fc87489 18096 unsigned int j;
6ab2c4ed
MC
18097 unsigned int type;
18098 unsigned int datasz;
18099
18100 if ((size_t) (ptr_end - ptr) < 8)
18101 {
18102 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
18103 break;
18104 }
18105
18106 type = byte_get (ptr, 4);
18107 datasz = byte_get (ptr + 4, 4);
9ef920e9 18108
1fc87489 18109 ptr += 8;
9ef920e9 18110
6ab2c4ed 18111 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 18112 {
1fc87489
L
18113 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
18114 type, datasz);
9ef920e9 18115 break;
1fc87489 18116 }
9ef920e9 18117
1fc87489
L
18118 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
18119 {
dda8d76d
NC
18120 if (filedata->file_header.e_machine == EM_X86_64
18121 || filedata->file_header.e_machine == EM_IAMCU
18122 || filedata->file_header.e_machine == EM_386)
1fc87489 18123 {
aa7bca9b
L
18124 unsigned int bitmask;
18125
18126 if (datasz == 4)
0a59decb 18127 bitmask = byte_get (ptr, 4);
aa7bca9b
L
18128 else
18129 bitmask = 0;
18130
1fc87489
L
18131 switch (type)
18132 {
18133 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 18134 if (datasz != 4)
aa7bca9b
L
18135 printf (_("x86 ISA used: <corrupt length: %#x> "),
18136 datasz);
1fc87489 18137 else
aa7bca9b
L
18138 {
18139 printf ("x86 ISA used: ");
18140 decode_x86_isa (bitmask);
18141 }
1fc87489 18142 goto next;
9ef920e9 18143
1fc87489 18144 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 18145 if (datasz != 4)
aa7bca9b
L
18146 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18147 datasz);
1fc87489 18148 else
aa7bca9b
L
18149 {
18150 printf ("x86 ISA needed: ");
18151 decode_x86_isa (bitmask);
18152 }
1fc87489 18153 goto next;
9ef920e9 18154
ee2fdd6f 18155 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 18156 if (datasz != 4)
aa7bca9b
L
18157 printf (_("x86 feature: <corrupt length: %#x> "),
18158 datasz);
ee2fdd6f 18159 else
aa7bca9b
L
18160 {
18161 printf ("x86 feature: ");
a9eafb08
L
18162 decode_x86_feature_1 (bitmask);
18163 }
18164 goto next;
18165
18166 case GNU_PROPERTY_X86_FEATURE_2_USED:
18167 if (datasz != 4)
18168 printf (_("x86 feature used: <corrupt length: %#x> "),
18169 datasz);
18170 else
18171 {
18172 printf ("x86 feature used: ");
18173 decode_x86_feature_2 (bitmask);
18174 }
18175 goto next;
18176
18177 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
18178 if (datasz != 4)
18179 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
18180 else
18181 {
18182 printf ("x86 feature needed: ");
18183 decode_x86_feature_2 (bitmask);
18184 }
18185 goto next;
18186
18187 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
18188 if (datasz != 4)
18189 printf (_("x86 ISA used: <corrupt length: %#x> "),
18190 datasz);
18191 else
18192 {
18193 printf ("x86 ISA used: ");
18194 decode_x86_compat_isa (bitmask);
18195 }
18196 goto next;
18197
18198 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
18199 if (datasz != 4)
18200 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18201 datasz);
18202 else
18203 {
18204 printf ("x86 ISA needed: ");
18205 decode_x86_compat_isa (bitmask);
aa7bca9b 18206 }
ee2fdd6f
L
18207 goto next;
18208
1fc87489
L
18209 default:
18210 break;
18211 }
18212 }
cd702818
SD
18213 else if (filedata->file_header.e_machine == EM_AARCH64)
18214 {
18215 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
18216 {
18217 printf ("AArch64 feature: ");
18218 if (datasz != 4)
18219 printf (_("<corrupt length: %#x> "), datasz);
18220 else
18221 decode_aarch64_feature_1_and (byte_get (ptr, 4));
18222 goto next;
18223 }
18224 }
1fc87489
L
18225 }
18226 else
18227 {
18228 switch (type)
9ef920e9 18229 {
1fc87489
L
18230 case GNU_PROPERTY_STACK_SIZE:
18231 printf (_("stack size: "));
18232 if (datasz != size)
18233 printf (_("<corrupt length: %#x> "), datasz);
18234 else
18235 printf ("%#lx", (unsigned long) byte_get (ptr, size));
18236 goto next;
18237
18238 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
18239 printf ("no copy on protected ");
18240 if (datasz)
18241 printf (_("<corrupt length: %#x> "), datasz);
18242 goto next;
18243
18244 default:
9ef920e9
NC
18245 break;
18246 }
9ef920e9
NC
18247 }
18248
1fc87489
L
18249 if (type < GNU_PROPERTY_LOPROC)
18250 printf (_("<unknown type %#x data: "), type);
18251 else if (type < GNU_PROPERTY_LOUSER)
18252 printf (_("<procesor-specific type %#x data: "), type);
18253 else
18254 printf (_("<application-specific type %#x data: "), type);
18255 for (j = 0; j < datasz; ++j)
18256 printf ("%02x ", ptr[j] & 0xff);
18257 printf (">");
18258
dc1e8a47 18259 next:
9ef920e9 18260 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
18261 if (ptr == ptr_end)
18262 break;
1fc87489 18263
6ab2c4ed
MC
18264 if (do_wide)
18265 printf (", ");
18266 else
18267 printf ("\n\t");
9ef920e9
NC
18268 }
18269
18270 printf ("\n");
18271}
18272
32ec8896 18273static bfd_boolean
dda8d76d 18274print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 18275{
1449284b 18276 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
18277 switch (pnote->type)
18278 {
18279 case NT_GNU_BUILD_ID:
18280 {
18281 unsigned long i;
18282
18283 printf (_(" Build ID: "));
18284 for (i = 0; i < pnote->descsz; ++i)
18285 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 18286 printf ("\n");
664f90a3
TT
18287 }
18288 break;
18289
18290 case NT_GNU_ABI_TAG:
18291 {
18292 unsigned long os, major, minor, subminor;
18293 const char *osname;
18294
3102e897
NC
18295 /* PR 17531: file: 030-599401-0.004. */
18296 if (pnote->descsz < 16)
18297 {
18298 printf (_(" <corrupt GNU_ABI_TAG>\n"));
18299 break;
18300 }
18301
664f90a3
TT
18302 os = byte_get ((unsigned char *) pnote->descdata, 4);
18303 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18304 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
18305 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
18306
18307 switch (os)
18308 {
18309 case GNU_ABI_TAG_LINUX:
18310 osname = "Linux";
18311 break;
18312 case GNU_ABI_TAG_HURD:
18313 osname = "Hurd";
18314 break;
18315 case GNU_ABI_TAG_SOLARIS:
18316 osname = "Solaris";
18317 break;
18318 case GNU_ABI_TAG_FREEBSD:
18319 osname = "FreeBSD";
18320 break;
18321 case GNU_ABI_TAG_NETBSD:
18322 osname = "NetBSD";
18323 break;
14ae95f2
RM
18324 case GNU_ABI_TAG_SYLLABLE:
18325 osname = "Syllable";
18326 break;
18327 case GNU_ABI_TAG_NACL:
18328 osname = "NaCl";
18329 break;
664f90a3
TT
18330 default:
18331 osname = "Unknown";
18332 break;
18333 }
18334
18335 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
18336 major, minor, subminor);
18337 }
18338 break;
926c5385
CC
18339
18340 case NT_GNU_GOLD_VERSION:
18341 {
18342 unsigned long i;
18343
18344 printf (_(" Version: "));
18345 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
18346 printf ("%c", pnote->descdata[i]);
18347 printf ("\n");
18348 }
18349 break;
1449284b
NC
18350
18351 case NT_GNU_HWCAP:
18352 {
18353 unsigned long num_entries, mask;
18354
18355 /* Hardware capabilities information. Word 0 is the number of entries.
18356 Word 1 is a bitmask of enabled entries. The rest of the descriptor
18357 is a series of entries, where each entry is a single byte followed
18358 by a nul terminated string. The byte gives the bit number to test
18359 if enabled in the bitmask. */
18360 printf (_(" Hardware Capabilities: "));
18361 if (pnote->descsz < 8)
18362 {
32ec8896
NC
18363 error (_("<corrupt GNU_HWCAP>\n"));
18364 return FALSE;
1449284b
NC
18365 }
18366 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
18367 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18368 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
18369 /* FIXME: Add code to display the entries... */
18370 }
18371 break;
18372
9ef920e9 18373 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 18374 print_gnu_property_note (filedata, pnote);
9ef920e9 18375 break;
9abca702 18376
1449284b
NC
18377 default:
18378 /* Handle unrecognised types. An error message should have already been
18379 created by get_gnu_elf_note_type(), so all that we need to do is to
18380 display the data. */
18381 {
18382 unsigned long i;
18383
18384 printf (_(" Description data: "));
18385 for (i = 0; i < pnote->descsz; ++i)
18386 printf ("%02x ", pnote->descdata[i] & 0xff);
18387 printf ("\n");
18388 }
18389 break;
664f90a3
TT
18390 }
18391
32ec8896 18392 return TRUE;
664f90a3
TT
18393}
18394
685080f2
NC
18395static const char *
18396get_v850_elf_note_type (enum v850_notes n_type)
18397{
18398 static char buff[64];
18399
18400 switch (n_type)
18401 {
18402 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
18403 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
18404 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
18405 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
18406 case V850_NOTE_CACHE_INFO: return _("Use of cache");
18407 case V850_NOTE_MMU_INFO: return _("Use of MMU");
18408 default:
18409 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
18410 return buff;
18411 }
18412}
18413
32ec8896 18414static bfd_boolean
685080f2
NC
18415print_v850_note (Elf_Internal_Note * pnote)
18416{
18417 unsigned int val;
18418
18419 if (pnote->descsz != 4)
32ec8896
NC
18420 return FALSE;
18421
685080f2
NC
18422 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
18423
18424 if (val == 0)
18425 {
18426 printf (_("not set\n"));
32ec8896 18427 return TRUE;
685080f2
NC
18428 }
18429
18430 switch (pnote->type)
18431 {
18432 case V850_NOTE_ALIGNMENT:
18433 switch (val)
18434 {
32ec8896
NC
18435 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
18436 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
18437 }
18438 break;
14ae95f2 18439
685080f2
NC
18440 case V850_NOTE_DATA_SIZE:
18441 switch (val)
18442 {
32ec8896
NC
18443 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
18444 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
18445 }
18446 break;
14ae95f2 18447
685080f2
NC
18448 case V850_NOTE_FPU_INFO:
18449 switch (val)
18450 {
32ec8896
NC
18451 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
18452 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
18453 }
18454 break;
14ae95f2 18455
685080f2
NC
18456 case V850_NOTE_MMU_INFO:
18457 case V850_NOTE_CACHE_INFO:
18458 case V850_NOTE_SIMD_INFO:
18459 if (val == EF_RH850_SIMD)
18460 {
18461 printf (_("yes\n"));
32ec8896 18462 return TRUE;
685080f2
NC
18463 }
18464 break;
18465
18466 default:
18467 /* An 'unknown note type' message will already have been displayed. */
18468 break;
18469 }
18470
18471 printf (_("unknown value: %x\n"), val);
32ec8896 18472 return FALSE;
685080f2
NC
18473}
18474
32ec8896 18475static bfd_boolean
c6056a74
SF
18476process_netbsd_elf_note (Elf_Internal_Note * pnote)
18477{
18478 unsigned int version;
18479
18480 switch (pnote->type)
18481 {
18482 case NT_NETBSD_IDENT:
b966f55f
AM
18483 if (pnote->descsz < 1)
18484 break;
c6056a74
SF
18485 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18486 if ((version / 10000) % 100)
b966f55f 18487 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
18488 version, version / 100000000, (version / 1000000) % 100,
18489 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 18490 'A' + (version / 10000) % 26);
c6056a74
SF
18491 else
18492 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 18493 version, version / 100000000, (version / 1000000) % 100,
15f205b1 18494 (version / 100) % 100);
32ec8896 18495 return TRUE;
c6056a74
SF
18496
18497 case NT_NETBSD_MARCH:
9abca702 18498 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 18499 pnote->descdata);
32ec8896 18500 return TRUE;
c6056a74 18501
9abca702
CZ
18502#ifdef NT_NETBSD_PAX
18503 case NT_NETBSD_PAX:
b966f55f
AM
18504 if (pnote->descsz < 1)
18505 break;
9abca702
CZ
18506 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18507 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
18508 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
18509 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
18510 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
18511 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
18512 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
18513 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
18514 return TRUE;
18515#endif
c6056a74 18516 }
b966f55f
AM
18517
18518 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
18519 pnote->descsz, pnote->type);
18520 return FALSE;
c6056a74
SF
18521}
18522
f4ddf30f 18523static const char *
dda8d76d 18524get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 18525{
f4ddf30f
JB
18526 switch (e_type)
18527 {
18528 case NT_FREEBSD_THRMISC:
18529 return _("NT_THRMISC (thrmisc structure)");
18530 case NT_FREEBSD_PROCSTAT_PROC:
18531 return _("NT_PROCSTAT_PROC (proc data)");
18532 case NT_FREEBSD_PROCSTAT_FILES:
18533 return _("NT_PROCSTAT_FILES (files data)");
18534 case NT_FREEBSD_PROCSTAT_VMMAP:
18535 return _("NT_PROCSTAT_VMMAP (vmmap data)");
18536 case NT_FREEBSD_PROCSTAT_GROUPS:
18537 return _("NT_PROCSTAT_GROUPS (groups data)");
18538 case NT_FREEBSD_PROCSTAT_UMASK:
18539 return _("NT_PROCSTAT_UMASK (umask data)");
18540 case NT_FREEBSD_PROCSTAT_RLIMIT:
18541 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
18542 case NT_FREEBSD_PROCSTAT_OSREL:
18543 return _("NT_PROCSTAT_OSREL (osreldate data)");
18544 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
18545 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
18546 case NT_FREEBSD_PROCSTAT_AUXV:
18547 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
18548 case NT_FREEBSD_PTLWPINFO:
18549 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 18550 }
dda8d76d 18551 return get_note_type (filedata, e_type);
f4ddf30f
JB
18552}
18553
9437c45b 18554static const char *
dda8d76d 18555get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
18556{
18557 static char buff[64];
18558
540e6170
CZ
18559 switch (e_type)
18560 {
18561 case NT_NETBSDCORE_PROCINFO:
18562 /* NetBSD core "procinfo" structure. */
18563 return _("NetBSD procinfo structure");
9437c45b 18564
540e6170
CZ
18565#ifdef NT_NETBSDCORE_AUXV
18566 case NT_NETBSDCORE_AUXV:
18567 return _("NetBSD ELF auxiliary vector data");
18568#endif
9437c45b 18569
06d949ec
KR
18570#ifdef NT_NETBSDCORE_LWPSTATUS
18571 case NT_NETBSDCORE_LWPSTATUS:
18572 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
18573#endif
18574
540e6170 18575 default:
06d949ec 18576 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
18577 defined for NetBSD core files. If the note type is less
18578 than the start of the machine-dependent note types, we don't
18579 understand it. */
18580
18581 if (e_type < NT_NETBSDCORE_FIRSTMACH)
18582 {
18583 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18584 return buff;
18585 }
18586 break;
9437c45b
JT
18587 }
18588
dda8d76d 18589 switch (filedata->file_header.e_machine)
9437c45b
JT
18590 {
18591 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
18592 and PT_GETFPREGS == mach+2. */
18593
18594 case EM_OLD_ALPHA:
18595 case EM_ALPHA:
18596 case EM_SPARC:
18597 case EM_SPARC32PLUS:
18598 case EM_SPARCV9:
18599 switch (e_type)
18600 {
2b692964 18601 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 18602 return _("PT_GETREGS (reg structure)");
2b692964 18603 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 18604 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18605 default:
18606 break;
18607 }
18608 break;
18609
c0d38b0e
CZ
18610 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
18611 There's also old PT___GETREGS40 == mach + 1 for old reg
18612 structure which lacks GBR. */
18613 case EM_SH:
18614 switch (e_type)
18615 {
18616 case NT_NETBSDCORE_FIRSTMACH + 1:
18617 return _("PT___GETREGS40 (old reg structure)");
18618 case NT_NETBSDCORE_FIRSTMACH + 3:
18619 return _("PT_GETREGS (reg structure)");
18620 case NT_NETBSDCORE_FIRSTMACH + 5:
18621 return _("PT_GETFPREGS (fpreg structure)");
18622 default:
18623 break;
18624 }
18625 break;
18626
9437c45b
JT
18627 /* On all other arch's, PT_GETREGS == mach+1 and
18628 PT_GETFPREGS == mach+3. */
18629 default:
18630 switch (e_type)
18631 {
2b692964 18632 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 18633 return _("PT_GETREGS (reg structure)");
2b692964 18634 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 18635 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18636 default:
18637 break;
18638 }
18639 }
18640
9cf03b7e 18641 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 18642 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
18643 return buff;
18644}
18645
70616151
TT
18646static const char *
18647get_stapsdt_note_type (unsigned e_type)
18648{
18649 static char buff[64];
18650
18651 switch (e_type)
18652 {
18653 case NT_STAPSDT:
18654 return _("NT_STAPSDT (SystemTap probe descriptors)");
18655
18656 default:
18657 break;
18658 }
18659
18660 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18661 return buff;
18662}
18663
32ec8896 18664static bfd_boolean
c6a9fc58
TT
18665print_stapsdt_note (Elf_Internal_Note *pnote)
18666{
3ca60c57
NC
18667 size_t len, maxlen;
18668 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
18669 char *data = pnote->descdata;
18670 char *data_end = pnote->descdata + pnote->descsz;
18671 bfd_vma pc, base_addr, semaphore;
18672 char *provider, *probe, *arg_fmt;
18673
3ca60c57
NC
18674 if (pnote->descsz < (addr_size * 3))
18675 goto stapdt_note_too_small;
18676
c6a9fc58
TT
18677 pc = byte_get ((unsigned char *) data, addr_size);
18678 data += addr_size;
3ca60c57 18679
c6a9fc58
TT
18680 base_addr = byte_get ((unsigned char *) data, addr_size);
18681 data += addr_size;
3ca60c57 18682
c6a9fc58
TT
18683 semaphore = byte_get ((unsigned char *) data, addr_size);
18684 data += addr_size;
18685
3ca60c57
NC
18686 if (data >= data_end)
18687 goto stapdt_note_too_small;
18688 maxlen = data_end - data;
18689 len = strnlen (data, maxlen);
18690 if (len < maxlen)
18691 {
18692 provider = data;
18693 data += len + 1;
18694 }
18695 else
18696 goto stapdt_note_too_small;
18697
18698 if (data >= data_end)
18699 goto stapdt_note_too_small;
18700 maxlen = data_end - data;
18701 len = strnlen (data, maxlen);
18702 if (len < maxlen)
18703 {
18704 probe = data;
18705 data += len + 1;
18706 }
18707 else
18708 goto stapdt_note_too_small;
9abca702 18709
3ca60c57
NC
18710 if (data >= data_end)
18711 goto stapdt_note_too_small;
18712 maxlen = data_end - data;
18713 len = strnlen (data, maxlen);
18714 if (len < maxlen)
18715 {
18716 arg_fmt = data;
18717 data += len + 1;
18718 }
18719 else
18720 goto stapdt_note_too_small;
c6a9fc58
TT
18721
18722 printf (_(" Provider: %s\n"), provider);
18723 printf (_(" Name: %s\n"), probe);
18724 printf (_(" Location: "));
18725 print_vma (pc, FULL_HEX);
18726 printf (_(", Base: "));
18727 print_vma (base_addr, FULL_HEX);
18728 printf (_(", Semaphore: "));
18729 print_vma (semaphore, FULL_HEX);
9cf03b7e 18730 printf ("\n");
c6a9fc58
TT
18731 printf (_(" Arguments: %s\n"), arg_fmt);
18732
18733 return data == data_end;
3ca60c57
NC
18734
18735 stapdt_note_too_small:
18736 printf (_(" <corrupt - note is too small>\n"));
18737 error (_("corrupt stapdt note - the data size is too small\n"));
18738 return FALSE;
c6a9fc58
TT
18739}
18740
00e98fc7
TG
18741static const char *
18742get_ia64_vms_note_type (unsigned e_type)
18743{
18744 static char buff[64];
18745
18746 switch (e_type)
18747 {
18748 case NT_VMS_MHD:
18749 return _("NT_VMS_MHD (module header)");
18750 case NT_VMS_LNM:
18751 return _("NT_VMS_LNM (language name)");
18752 case NT_VMS_SRC:
18753 return _("NT_VMS_SRC (source files)");
18754 case NT_VMS_TITLE:
9cf03b7e 18755 return "NT_VMS_TITLE";
00e98fc7
TG
18756 case NT_VMS_EIDC:
18757 return _("NT_VMS_EIDC (consistency check)");
18758 case NT_VMS_FPMODE:
18759 return _("NT_VMS_FPMODE (FP mode)");
18760 case NT_VMS_LINKTIME:
9cf03b7e 18761 return "NT_VMS_LINKTIME";
00e98fc7
TG
18762 case NT_VMS_IMGNAM:
18763 return _("NT_VMS_IMGNAM (image name)");
18764 case NT_VMS_IMGID:
18765 return _("NT_VMS_IMGID (image id)");
18766 case NT_VMS_LINKID:
18767 return _("NT_VMS_LINKID (link id)");
18768 case NT_VMS_IMGBID:
18769 return _("NT_VMS_IMGBID (build id)");
18770 case NT_VMS_GSTNAM:
18771 return _("NT_VMS_GSTNAM (sym table name)");
18772 case NT_VMS_ORIG_DYN:
9cf03b7e 18773 return "NT_VMS_ORIG_DYN";
00e98fc7 18774 case NT_VMS_PATCHTIME:
9cf03b7e 18775 return "NT_VMS_PATCHTIME";
00e98fc7
TG
18776 default:
18777 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18778 return buff;
18779 }
18780}
18781
32ec8896 18782static bfd_boolean
00e98fc7
TG
18783print_ia64_vms_note (Elf_Internal_Note * pnote)
18784{
8d18bf79
NC
18785 int maxlen = pnote->descsz;
18786
18787 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
18788 goto desc_size_fail;
18789
00e98fc7
TG
18790 switch (pnote->type)
18791 {
18792 case NT_VMS_MHD:
8d18bf79
NC
18793 if (maxlen <= 36)
18794 goto desc_size_fail;
18795
18796 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
18797
18798 printf (_(" Creation date : %.17s\n"), pnote->descdata);
18799 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
18800 if (l + 34 < maxlen)
18801 {
18802 printf (_(" Module name : %s\n"), pnote->descdata + 34);
18803 if (l + 35 < maxlen)
18804 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
18805 else
18806 printf (_(" Module version : <missing>\n"));
18807 }
00e98fc7 18808 else
8d18bf79
NC
18809 {
18810 printf (_(" Module name : <missing>\n"));
18811 printf (_(" Module version : <missing>\n"));
18812 }
00e98fc7 18813 break;
8d18bf79 18814
00e98fc7 18815 case NT_VMS_LNM:
8d18bf79 18816 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18817 break;
8d18bf79 18818
00e98fc7
TG
18819#ifdef BFD64
18820 case NT_VMS_FPMODE:
9cf03b7e 18821 printf (_(" Floating Point mode: "));
8d18bf79
NC
18822 if (maxlen < 8)
18823 goto desc_size_fail;
18824 /* FIXME: Generate an error if descsz > 8 ? */
18825
4a5cb34f 18826 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 18827 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 18828 break;
8d18bf79 18829
00e98fc7
TG
18830 case NT_VMS_LINKTIME:
18831 printf (_(" Link time: "));
8d18bf79
NC
18832 if (maxlen < 8)
18833 goto desc_size_fail;
18834 /* FIXME: Generate an error if descsz > 8 ? */
18835
00e98fc7 18836 print_vms_time
8d18bf79 18837 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
18838 printf ("\n");
18839 break;
8d18bf79 18840
00e98fc7
TG
18841 case NT_VMS_PATCHTIME:
18842 printf (_(" Patch time: "));
8d18bf79
NC
18843 if (maxlen < 8)
18844 goto desc_size_fail;
18845 /* FIXME: Generate an error if descsz > 8 ? */
18846
00e98fc7 18847 print_vms_time
8d18bf79 18848 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
18849 printf ("\n");
18850 break;
8d18bf79 18851
00e98fc7 18852 case NT_VMS_ORIG_DYN:
8d18bf79
NC
18853 if (maxlen < 34)
18854 goto desc_size_fail;
18855
00e98fc7
TG
18856 printf (_(" Major id: %u, minor id: %u\n"),
18857 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
18858 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 18859 printf (_(" Last modified : "));
00e98fc7
TG
18860 print_vms_time
18861 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 18862 printf (_("\n Link flags : "));
4a5cb34f 18863 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 18864 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 18865 printf (_(" Header flags: 0x%08x\n"),
948f632f 18866 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 18867 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
18868 break;
18869#endif
8d18bf79 18870
00e98fc7 18871 case NT_VMS_IMGNAM:
8d18bf79 18872 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18873 break;
8d18bf79 18874
00e98fc7 18875 case NT_VMS_GSTNAM:
8d18bf79 18876 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18877 break;
8d18bf79 18878
00e98fc7 18879 case NT_VMS_IMGID:
8d18bf79 18880 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18881 break;
8d18bf79 18882
00e98fc7 18883 case NT_VMS_LINKID:
8d18bf79 18884 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18885 break;
8d18bf79 18886
00e98fc7 18887 default:
32ec8896 18888 return FALSE;
00e98fc7 18889 }
8d18bf79 18890
32ec8896 18891 return TRUE;
8d18bf79
NC
18892
18893 desc_size_fail:
18894 printf (_(" <corrupt - data size is too small>\n"));
18895 error (_("corrupt IA64 note: data size is too small\n"));
18896 return FALSE;
00e98fc7
TG
18897}
18898
fd486f32
AM
18899struct build_attr_cache {
18900 Filedata *filedata;
18901 char *strtab;
18902 unsigned long strtablen;
18903 Elf_Internal_Sym *symtab;
18904 unsigned long nsyms;
18905} ba_cache;
18906
6f156d7a
NC
18907/* Find the symbol associated with a build attribute that is attached
18908 to address OFFSET. If PNAME is non-NULL then store the name of
18909 the symbol (if found) in the provided pointer, Returns NULL if a
18910 symbol could not be found. */
c799a79d 18911
6f156d7a
NC
18912static Elf_Internal_Sym *
18913get_symbol_for_build_attribute (Filedata * filedata,
18914 unsigned long offset,
18915 bfd_boolean is_open_attr,
18916 const char ** pname)
9ef920e9 18917{
fd486f32
AM
18918 Elf_Internal_Sym *saved_sym = NULL;
18919 Elf_Internal_Sym *sym;
9ef920e9 18920
dda8d76d 18921 if (filedata->section_headers != NULL
fd486f32 18922 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 18923 {
c799a79d 18924 Elf_Internal_Shdr * symsec;
9ef920e9 18925
fd486f32
AM
18926 free (ba_cache.strtab);
18927 ba_cache.strtab = NULL;
18928 free (ba_cache.symtab);
18929 ba_cache.symtab = NULL;
18930
c799a79d 18931 /* Load the symbol and string sections. */
dda8d76d
NC
18932 for (symsec = filedata->section_headers;
18933 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 18934 symsec ++)
9ef920e9 18935 {
28d13567
AM
18936 if (symsec->sh_type == SHT_SYMTAB
18937 && get_symtab (filedata, symsec,
18938 &ba_cache.symtab, &ba_cache.nsyms,
18939 &ba_cache.strtab, &ba_cache.strtablen))
18940 break;
9ef920e9 18941 }
fd486f32 18942 ba_cache.filedata = filedata;
9ef920e9
NC
18943 }
18944
fd486f32 18945 if (ba_cache.symtab == NULL)
6f156d7a 18946 return NULL;
9ef920e9 18947
c799a79d 18948 /* Find a symbol whose value matches offset. */
fd486f32 18949 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
18950 if (sym->st_value == offset)
18951 {
fd486f32 18952 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
18953 /* Huh ? This should not happen. */
18954 continue;
9ef920e9 18955
fd486f32 18956 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 18957 continue;
9ef920e9 18958
8fd75781
NC
18959 /* The AArch64 and ARM architectures define mapping symbols
18960 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
18961 if (ba_cache.strtab[sym->st_name] == '$'
18962 && ba_cache.strtab[sym->st_name + 1] != 0
18963 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
18964 continue;
18965
c799a79d
NC
18966 if (is_open_attr)
18967 {
18968 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
18969 and FILE or OBJECT symbols over NOTYPE symbols. We skip
18970 FUNC symbols entirely. */
18971 switch (ELF_ST_TYPE (sym->st_info))
18972 {
c799a79d 18973 case STT_OBJECT:
6f156d7a 18974 case STT_FILE:
c799a79d 18975 saved_sym = sym;
6f156d7a
NC
18976 if (sym->st_size)
18977 {
18978 /* If the symbol has a size associated
18979 with it then we can stop searching. */
fd486f32 18980 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 18981 }
c799a79d 18982 continue;
9ef920e9 18983
c799a79d
NC
18984 case STT_FUNC:
18985 /* Ignore function symbols. */
18986 continue;
18987
18988 default:
18989 break;
18990 }
18991
18992 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 18993 {
c799a79d
NC
18994 case STB_GLOBAL:
18995 if (saved_sym == NULL
18996 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
18997 saved_sym = sym;
18998 break;
c871dade 18999
c799a79d
NC
19000 case STB_LOCAL:
19001 if (saved_sym == NULL)
19002 saved_sym = sym;
19003 break;
19004
19005 default:
9ef920e9
NC
19006 break;
19007 }
19008 }
c799a79d
NC
19009 else
19010 {
19011 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
19012 continue;
19013
19014 saved_sym = sym;
19015 break;
19016 }
19017 }
19018
6f156d7a 19019 if (saved_sym && pname)
fd486f32 19020 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
19021
19022 return saved_sym;
c799a79d
NC
19023}
19024
d20e98ab
NC
19025/* Returns true iff addr1 and addr2 are in the same section. */
19026
19027static bfd_boolean
19028same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
19029{
19030 Elf_Internal_Shdr * a1;
19031 Elf_Internal_Shdr * a2;
19032
19033 a1 = find_section_by_address (filedata, addr1);
19034 a2 = find_section_by_address (filedata, addr2);
9abca702 19035
d20e98ab
NC
19036 return a1 == a2 && a1 != NULL;
19037}
19038
c799a79d 19039static bfd_boolean
dda8d76d
NC
19040print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
19041 Filedata * filedata)
c799a79d 19042{
6f156d7a
NC
19043 static unsigned long global_offset = 0;
19044 static unsigned long global_end = 0;
19045 static unsigned long func_offset = 0;
19046 static unsigned long func_end = 0;
c871dade 19047
6f156d7a
NC
19048 Elf_Internal_Sym * sym;
19049 const char * name;
19050 unsigned long start;
19051 unsigned long end;
19052 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
19053
19054 switch (pnote->descsz)
c799a79d 19055 {
6f156d7a
NC
19056 case 0:
19057 /* A zero-length description means that the range of
19058 the previous note of the same type should be used. */
c799a79d 19059 if (is_open_attr)
c871dade 19060 {
6f156d7a
NC
19061 if (global_end > global_offset)
19062 printf (_(" Applies to region from %#lx to %#lx\n"),
19063 global_offset, global_end);
19064 else
19065 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
19066 }
19067 else
19068 {
6f156d7a
NC
19069 if (func_end > func_offset)
19070 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
19071 else
19072 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 19073 }
6f156d7a 19074 return TRUE;
9ef920e9 19075
6f156d7a
NC
19076 case 4:
19077 start = byte_get ((unsigned char *) pnote->descdata, 4);
19078 end = 0;
19079 break;
19080
19081 case 8:
19082 if (is_32bit_elf)
19083 {
19084 /* FIXME: We should check that version 3+ notes are being used here... */
19085 start = byte_get ((unsigned char *) pnote->descdata, 4);
19086 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19087 }
19088 else
19089 {
19090 start = byte_get ((unsigned char *) pnote->descdata, 8);
19091 end = 0;
19092 }
19093 break;
19094
19095 case 16:
19096 start = byte_get ((unsigned char *) pnote->descdata, 8);
19097 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
19098 break;
9abca702 19099
6f156d7a 19100 default:
c799a79d
NC
19101 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
19102 printf (_(" <invalid descsz>"));
19103 return FALSE;
19104 }
19105
6f156d7a
NC
19106 name = NULL;
19107 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
19108 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
19109 in order to avoid them being confused with the start address of the
19110 first function in the file... */
19111 if (sym == NULL && is_open_attr)
19112 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
19113 & name);
6f156d7a
NC
19114
19115 if (end == 0 && sym != NULL && sym->st_size > 0)
19116 end = start + sym->st_size;
c799a79d
NC
19117
19118 if (is_open_attr)
19119 {
d20e98ab
NC
19120 /* FIXME: Need to properly allow for section alignment.
19121 16 is just the alignment used on x86_64. */
19122 if (global_end > 0
19123 && start > BFD_ALIGN (global_end, 16)
19124 /* Build notes are not guaranteed to be organised in order of
19125 increasing address, but we should find the all of the notes
19126 for one section in the same place. */
19127 && same_section (filedata, start, global_end))
6f156d7a
NC
19128 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
19129 global_end + 1, start - 1);
19130
19131 printf (_(" Applies to region from %#lx"), start);
19132 global_offset = start;
19133
19134 if (end)
19135 {
19136 printf (_(" to %#lx"), end);
19137 global_end = end;
19138 }
c799a79d
NC
19139 }
19140 else
19141 {
6f156d7a
NC
19142 printf (_(" Applies to region from %#lx"), start);
19143 func_offset = start;
19144
19145 if (end)
19146 {
19147 printf (_(" to %#lx"), end);
19148 func_end = end;
19149 }
c799a79d
NC
19150 }
19151
6f156d7a
NC
19152 if (sym && name)
19153 printf (_(" (%s)"), name);
19154
19155 printf ("\n");
19156 return TRUE;
9ef920e9
NC
19157}
19158
19159static bfd_boolean
19160print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
19161{
1d15e434
NC
19162 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
19163 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
19164 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
19165 char name_type;
19166 char name_attribute;
1d15e434 19167 const char * expected_types;
9ef920e9
NC
19168 const char * name = pnote->namedata;
19169 const char * text;
88305e1b 19170 signed int left;
9ef920e9
NC
19171
19172 if (name == NULL || pnote->namesz < 2)
19173 {
19174 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 19175 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
19176 return FALSE;
19177 }
19178
6f156d7a
NC
19179 if (do_wide)
19180 left = 28;
19181 else
19182 left = 20;
88305e1b
NC
19183
19184 /* Version 2 of the spec adds a "GA" prefix to the name field. */
19185 if (name[0] == 'G' && name[1] == 'A')
19186 {
6f156d7a
NC
19187 if (pnote->namesz < 4)
19188 {
19189 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
19190 print_symbol (-20, _(" <corrupt name>"));
19191 return FALSE;
19192 }
19193
88305e1b
NC
19194 printf ("GA");
19195 name += 2;
19196 left -= 2;
19197 }
19198
9ef920e9
NC
19199 switch ((name_type = * name))
19200 {
19201 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19202 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19203 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19204 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19205 printf ("%c", * name);
88305e1b 19206 left --;
9ef920e9
NC
19207 break;
19208 default:
19209 error (_("unrecognised attribute type in name field: %d\n"), name_type);
19210 print_symbol (-20, _("<unknown name type>"));
19211 return FALSE;
19212 }
19213
9ef920e9
NC
19214 ++ name;
19215 text = NULL;
19216
19217 switch ((name_attribute = * name))
19218 {
19219 case GNU_BUILD_ATTRIBUTE_VERSION:
19220 text = _("<version>");
1d15e434 19221 expected_types = string_expected;
9ef920e9
NC
19222 ++ name;
19223 break;
19224 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19225 text = _("<stack prot>");
75d7d298 19226 expected_types = "!+*";
9ef920e9
NC
19227 ++ name;
19228 break;
19229 case GNU_BUILD_ATTRIBUTE_RELRO:
19230 text = _("<relro>");
1d15e434 19231 expected_types = bool_expected;
9ef920e9
NC
19232 ++ name;
19233 break;
19234 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
19235 text = _("<stack size>");
1d15e434 19236 expected_types = number_expected;
9ef920e9
NC
19237 ++ name;
19238 break;
19239 case GNU_BUILD_ATTRIBUTE_TOOL:
19240 text = _("<tool>");
1d15e434 19241 expected_types = string_expected;
9ef920e9
NC
19242 ++ name;
19243 break;
19244 case GNU_BUILD_ATTRIBUTE_ABI:
19245 text = _("<ABI>");
19246 expected_types = "$*";
19247 ++ name;
19248 break;
19249 case GNU_BUILD_ATTRIBUTE_PIC:
19250 text = _("<PIC>");
1d15e434 19251 expected_types = number_expected;
9ef920e9
NC
19252 ++ name;
19253 break;
a8be5506
NC
19254 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
19255 text = _("<short enum>");
1d15e434 19256 expected_types = bool_expected;
a8be5506
NC
19257 ++ name;
19258 break;
9ef920e9
NC
19259 default:
19260 if (ISPRINT (* name))
19261 {
19262 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
19263
19264 if (len > left && ! do_wide)
19265 len = left;
75d7d298 19266 printf ("%.*s:", len, name);
9ef920e9 19267 left -= len;
0dd6ae21 19268 name += len;
9ef920e9
NC
19269 }
19270 else
19271 {
3e6b6445 19272 static char tmpbuf [128];
88305e1b 19273
3e6b6445
NC
19274 error (_("unrecognised byte in name field: %d\n"), * name);
19275 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
19276 text = tmpbuf;
19277 name ++;
9ef920e9
NC
19278 }
19279 expected_types = "*$!+";
19280 break;
19281 }
19282
19283 if (text)
88305e1b 19284 left -= printf ("%s", text);
9ef920e9
NC
19285
19286 if (strchr (expected_types, name_type) == NULL)
75d7d298 19287 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
19288
19289 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
19290 {
19291 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
19292 (unsigned long) pnote->namesz,
19293 (long) (name - pnote->namedata));
19294 return FALSE;
19295 }
19296
19297 if (left < 1 && ! do_wide)
19298 return TRUE;
19299
19300 switch (name_type)
19301 {
19302 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19303 {
b06b2c92 19304 unsigned int bytes;
ddef72cd
NC
19305 unsigned long long val = 0;
19306 unsigned int shift = 0;
19307 char * decoded = NULL;
19308
b06b2c92
NC
19309 bytes = pnote->namesz - (name - pnote->namedata);
19310 if (bytes > 0)
19311 /* The -1 is because the name field is always 0 terminated, and we
19312 want to be able to ensure that the shift in the while loop below
19313 will not overflow. */
19314 -- bytes;
19315
ddef72cd
NC
19316 if (bytes > sizeof (val))
19317 {
3e6b6445
NC
19318 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
19319 bytes);
19320 bytes = sizeof (val);
ddef72cd 19321 }
3e6b6445
NC
19322 /* We do not bother to warn if bytes == 0 as this can
19323 happen with some early versions of the gcc plugin. */
9ef920e9
NC
19324
19325 while (bytes --)
19326 {
79a964dc
NC
19327 unsigned long byte = (* name ++) & 0xff;
19328
19329 val |= byte << shift;
9ef920e9
NC
19330 shift += 8;
19331 }
19332
75d7d298 19333 switch (name_attribute)
9ef920e9 19334 {
75d7d298 19335 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
19336 switch (val)
19337 {
75d7d298
NC
19338 case 0: decoded = "static"; break;
19339 case 1: decoded = "pic"; break;
19340 case 2: decoded = "PIC"; break;
19341 case 3: decoded = "pie"; break;
19342 case 4: decoded = "PIE"; break;
19343 default: break;
9ef920e9 19344 }
75d7d298
NC
19345 break;
19346 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19347 switch (val)
9ef920e9 19348 {
75d7d298
NC
19349 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
19350 case 0: decoded = "off"; break;
19351 case 1: decoded = "on"; break;
19352 case 2: decoded = "all"; break;
19353 case 3: decoded = "strong"; break;
19354 case 4: decoded = "explicit"; break;
19355 default: break;
9ef920e9 19356 }
75d7d298
NC
19357 break;
19358 default:
19359 break;
9ef920e9
NC
19360 }
19361
75d7d298 19362 if (decoded != NULL)
3e6b6445
NC
19363 {
19364 print_symbol (-left, decoded);
19365 left = 0;
19366 }
19367 else if (val == 0)
19368 {
19369 printf ("0x0");
19370 left -= 3;
19371 }
9ef920e9 19372 else
75d7d298
NC
19373 {
19374 if (do_wide)
ddef72cd 19375 left -= printf ("0x%llx", val);
75d7d298 19376 else
ddef72cd 19377 left -= printf ("0x%-.*llx", left, val);
75d7d298 19378 }
9ef920e9
NC
19379 }
19380 break;
19381 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19382 left -= print_symbol (- left, name);
19383 break;
19384 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19385 left -= print_symbol (- left, "true");
19386 break;
19387 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19388 left -= print_symbol (- left, "false");
19389 break;
19390 }
19391
19392 if (do_wide && left > 0)
19393 printf ("%-*s", left, " ");
9abca702 19394
9ef920e9
NC
19395 return TRUE;
19396}
19397
6d118b09
NC
19398/* Note that by the ELF standard, the name field is already null byte
19399 terminated, and namesz includes the terminating null byte.
19400 I.E. the value of namesz for the name "FSF" is 4.
19401
e3c8793a 19402 If the value of namesz is zero, there is no name present. */
9ef920e9 19403
32ec8896 19404static bfd_boolean
9ef920e9 19405process_note (Elf_Internal_Note * pnote,
dda8d76d 19406 Filedata * filedata)
779fe533 19407{
2cf0635d
NC
19408 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
19409 const char * nt;
9437c45b
JT
19410
19411 if (pnote->namesz == 0)
1ec5cd37
NC
19412 /* If there is no note name, then use the default set of
19413 note type strings. */
dda8d76d 19414 nt = get_note_type (filedata, pnote->type);
1ec5cd37 19415
1118d252
RM
19416 else if (const_strneq (pnote->namedata, "GNU"))
19417 /* GNU-specific object file notes. */
19418 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
19419
19420 else if (const_strneq (pnote->namedata, "FreeBSD"))
19421 /* FreeBSD-specific core file notes. */
dda8d76d 19422 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 19423
0112cd26 19424 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 19425 /* NetBSD-specific core file notes. */
dda8d76d 19426 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 19427
c6056a74
SF
19428 else if (const_strneq (pnote->namedata, "NetBSD"))
19429 /* NetBSD-specific core file notes. */
19430 return process_netbsd_elf_note (pnote);
19431
9abca702
CZ
19432 else if (const_strneq (pnote->namedata, "PaX"))
19433 /* NetBSD-specific core file notes. */
19434 return process_netbsd_elf_note (pnote);
19435
b15fa79e
AM
19436 else if (strneq (pnote->namedata, "SPU/", 4))
19437 {
19438 /* SPU-specific core file notes. */
19439 nt = pnote->namedata + 4;
19440 name = "SPU";
19441 }
19442
00e98fc7
TG
19443 else if (const_strneq (pnote->namedata, "IPF/VMS"))
19444 /* VMS/ia64-specific file notes. */
19445 nt = get_ia64_vms_note_type (pnote->type);
19446
70616151
TT
19447 else if (const_strneq (pnote->namedata, "stapsdt"))
19448 nt = get_stapsdt_note_type (pnote->type);
19449
9437c45b 19450 else
1ec5cd37
NC
19451 /* Don't recognize this note name; just use the default set of
19452 note type strings. */
dda8d76d 19453 nt = get_note_type (filedata, pnote->type);
9437c45b 19454
1449284b 19455 printf (" ");
9ef920e9 19456
483767a3
AM
19457 if (((const_strneq (pnote->namedata, "GA")
19458 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19459 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19460 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19461 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
19462 print_gnu_build_attribute_name (pnote);
19463 else
19464 print_symbol (-20, name);
19465
19466 if (do_wide)
19467 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
19468 else
19469 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
19470
19471 if (const_strneq (pnote->namedata, "IPF/VMS"))
19472 return print_ia64_vms_note (pnote);
664f90a3 19473 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 19474 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
19475 else if (const_strneq (pnote->namedata, "stapsdt"))
19476 return print_stapsdt_note (pnote);
9ece1fa9
TT
19477 else if (const_strneq (pnote->namedata, "CORE"))
19478 return print_core_note (pnote);
483767a3
AM
19479 else if (((const_strneq (pnote->namedata, "GA")
19480 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19481 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19482 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19483 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 19484 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 19485
9ef920e9 19486 if (pnote->descsz)
1449284b
NC
19487 {
19488 unsigned long i;
19489
19490 printf (_(" description data: "));
19491 for (i = 0; i < pnote->descsz; i++)
178d8719 19492 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
19493 if (!do_wide)
19494 printf ("\n");
1449284b
NC
19495 }
19496
9ef920e9
NC
19497 if (do_wide)
19498 printf ("\n");
19499
32ec8896 19500 return TRUE;
1449284b 19501}
6d118b09 19502
32ec8896 19503static bfd_boolean
dda8d76d
NC
19504process_notes_at (Filedata * filedata,
19505 Elf_Internal_Shdr * section,
19506 bfd_vma offset,
82ed9683
L
19507 bfd_vma length,
19508 bfd_vma align)
779fe533 19509{
2cf0635d
NC
19510 Elf_External_Note * pnotes;
19511 Elf_External_Note * external;
4dff97b2
NC
19512 char * end;
19513 bfd_boolean res = TRUE;
103f02d3 19514
779fe533 19515 if (length <= 0)
32ec8896 19516 return FALSE;
103f02d3 19517
1449284b
NC
19518 if (section)
19519 {
dda8d76d 19520 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 19521 if (pnotes)
32ec8896 19522 {
dda8d76d 19523 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
19524 {
19525 free (pnotes);
19526 return FALSE;
19527 }
32ec8896 19528 }
1449284b
NC
19529 }
19530 else
82ed9683 19531 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 19532 _("notes"));
4dff97b2 19533
dd24e3da 19534 if (pnotes == NULL)
32ec8896 19535 return FALSE;
779fe533 19536
103f02d3 19537 external = pnotes;
103f02d3 19538
1449284b 19539 if (section)
dda8d76d 19540 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
19541 else
19542 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
19543 (unsigned long) offset, (unsigned long) length);
19544
82ed9683
L
19545 /* NB: Some note sections may have alignment value of 0 or 1. gABI
19546 specifies that notes should be aligned to 4 bytes in 32-bit
19547 objects and to 8 bytes in 64-bit objects. As a Linux extension,
19548 we also support 4 byte alignment in 64-bit objects. If section
19549 alignment is less than 4, we treate alignment as 4 bytes. */
19550 if (align < 4)
19551 align = 4;
19552 else if (align != 4 && align != 8)
19553 {
19554 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
19555 (long) align);
a788aedd 19556 free (pnotes);
82ed9683
L
19557 return FALSE;
19558 }
19559
dbe15e4e 19560 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 19561
c8071705
NC
19562 end = (char *) pnotes + length;
19563 while ((char *) external < end)
779fe533 19564 {
b34976b6 19565 Elf_Internal_Note inote;
15b42fb0 19566 size_t min_notesz;
4dff97b2 19567 char * next;
2cf0635d 19568 char * temp = NULL;
c8071705 19569 size_t data_remaining = end - (char *) external;
6d118b09 19570
dda8d76d 19571 if (!is_ia64_vms (filedata))
15b42fb0 19572 {
9dd3a467
NC
19573 /* PR binutils/15191
19574 Make sure that there is enough data to read. */
15b42fb0
AM
19575 min_notesz = offsetof (Elf_External_Note, name);
19576 if (data_remaining < min_notesz)
9dd3a467 19577 {
d3a49aa8
AM
19578 warn (ngettext ("Corrupt note: only %ld byte remains, "
19579 "not enough for a full note\n",
19580 "Corrupt note: only %ld bytes remain, "
19581 "not enough for a full note\n",
19582 data_remaining),
19583 (long) data_remaining);
9dd3a467
NC
19584 break;
19585 }
5396a86e
AM
19586 data_remaining -= min_notesz;
19587
15b42fb0
AM
19588 inote.type = BYTE_GET (external->type);
19589 inote.namesz = BYTE_GET (external->namesz);
19590 inote.namedata = external->name;
19591 inote.descsz = BYTE_GET (external->descsz);
276da9b3 19592 inote.descdata = ((char *) external
4dff97b2 19593 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 19594 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 19595 next = ((char *) external
4dff97b2 19596 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 19597 }
00e98fc7 19598 else
15b42fb0
AM
19599 {
19600 Elf64_External_VMS_Note *vms_external;
00e98fc7 19601
9dd3a467
NC
19602 /* PR binutils/15191
19603 Make sure that there is enough data to read. */
15b42fb0
AM
19604 min_notesz = offsetof (Elf64_External_VMS_Note, name);
19605 if (data_remaining < min_notesz)
9dd3a467 19606 {
d3a49aa8
AM
19607 warn (ngettext ("Corrupt note: only %ld byte remains, "
19608 "not enough for a full note\n",
19609 "Corrupt note: only %ld bytes remain, "
19610 "not enough for a full note\n",
19611 data_remaining),
19612 (long) data_remaining);
9dd3a467
NC
19613 break;
19614 }
5396a86e 19615 data_remaining -= min_notesz;
3e55a963 19616
15b42fb0
AM
19617 vms_external = (Elf64_External_VMS_Note *) external;
19618 inote.type = BYTE_GET (vms_external->type);
19619 inote.namesz = BYTE_GET (vms_external->namesz);
19620 inote.namedata = vms_external->name;
19621 inote.descsz = BYTE_GET (vms_external->descsz);
19622 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
19623 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19624 next = inote.descdata + align_power (inote.descsz, 3);
19625 }
19626
5396a86e
AM
19627 /* PR 17531: file: 3443835e. */
19628 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
19629 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
19630 || (size_t) (inote.descdata - inote.namedata) > data_remaining
19631 || (size_t) (next - inote.descdata) < inote.descsz
19632 || ((size_t) (next - inote.descdata)
19633 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 19634 {
15b42fb0 19635 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 19636 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
19637 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
19638 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
19639 break;
19640 }
19641
15b42fb0 19642 external = (Elf_External_Note *) next;
dd24e3da 19643
6d118b09
NC
19644 /* Verify that name is null terminated. It appears that at least
19645 one version of Linux (RedHat 6.0) generates corefiles that don't
19646 comply with the ELF spec by failing to include the null byte in
19647 namesz. */
18344509 19648 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 19649 {
5396a86e 19650 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 19651 {
5396a86e
AM
19652 temp = (char *) malloc (inote.namesz + 1);
19653 if (temp == NULL)
19654 {
19655 error (_("Out of memory allocating space for inote name\n"));
19656 res = FALSE;
19657 break;
19658 }
76da6bbe 19659
5396a86e
AM
19660 memcpy (temp, inote.namedata, inote.namesz);
19661 inote.namedata = temp;
19662 }
19663 inote.namedata[inote.namesz] = 0;
6d118b09
NC
19664 }
19665
dda8d76d 19666 if (! process_note (& inote, filedata))
6b4bf3bc 19667 res = FALSE;
103f02d3 19668
6d118b09
NC
19669 if (temp != NULL)
19670 {
19671 free (temp);
19672 temp = NULL;
19673 }
779fe533
NC
19674 }
19675
19676 free (pnotes);
103f02d3 19677
779fe533
NC
19678 return res;
19679}
19680
32ec8896 19681static bfd_boolean
dda8d76d 19682process_corefile_note_segments (Filedata * filedata)
779fe533 19683{
2cf0635d 19684 Elf_Internal_Phdr * segment;
b34976b6 19685 unsigned int i;
32ec8896 19686 bfd_boolean res = TRUE;
103f02d3 19687
dda8d76d 19688 if (! get_program_headers (filedata))
6b4bf3bc 19689 return TRUE;
103f02d3 19690
dda8d76d
NC
19691 for (i = 0, segment = filedata->program_headers;
19692 i < filedata->file_header.e_phnum;
b34976b6 19693 i++, segment++)
779fe533
NC
19694 {
19695 if (segment->p_type == PT_NOTE)
dda8d76d 19696 if (! process_notes_at (filedata, NULL,
32ec8896 19697 (bfd_vma) segment->p_offset,
82ed9683
L
19698 (bfd_vma) segment->p_filesz,
19699 (bfd_vma) segment->p_align))
32ec8896 19700 res = FALSE;
779fe533 19701 }
103f02d3 19702
779fe533
NC
19703 return res;
19704}
19705
32ec8896 19706static bfd_boolean
dda8d76d 19707process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
19708{
19709 Elf_External_Note * pnotes;
19710 Elf_External_Note * external;
c8071705 19711 char * end;
32ec8896 19712 bfd_boolean res = TRUE;
685080f2
NC
19713
19714 if (length <= 0)
32ec8896 19715 return FALSE;
685080f2 19716
dda8d76d 19717 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
19718 _("v850 notes"));
19719 if (pnotes == NULL)
32ec8896 19720 return FALSE;
685080f2
NC
19721
19722 external = pnotes;
c8071705 19723 end = (char*) pnotes + length;
685080f2
NC
19724
19725 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
19726 (unsigned long) offset, (unsigned long) length);
19727
c8071705 19728 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
19729 {
19730 Elf_External_Note * next;
19731 Elf_Internal_Note inote;
19732
19733 inote.type = BYTE_GET (external->type);
19734 inote.namesz = BYTE_GET (external->namesz);
19735 inote.namedata = external->name;
19736 inote.descsz = BYTE_GET (external->descsz);
19737 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
19738 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19739
c8071705
NC
19740 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
19741 {
19742 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
19743 inote.descdata = inote.namedata;
19744 inote.namesz = 0;
19745 }
19746
685080f2
NC
19747 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
19748
c8071705 19749 if ( ((char *) next > end)
685080f2
NC
19750 || ((char *) next < (char *) pnotes))
19751 {
19752 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
19753 (unsigned long) ((char *) external - (char *) pnotes));
19754 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19755 inote.type, inote.namesz, inote.descsz);
19756 break;
19757 }
19758
19759 external = next;
19760
19761 /* Prevent out-of-bounds indexing. */
c8071705 19762 if ( inote.namedata + inote.namesz > end
685080f2
NC
19763 || inote.namedata + inote.namesz < inote.namedata)
19764 {
19765 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
19766 (unsigned long) ((char *) external - (char *) pnotes));
19767 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19768 inote.type, inote.namesz, inote.descsz);
19769 break;
19770 }
19771
19772 printf (" %s: ", get_v850_elf_note_type (inote.type));
19773
19774 if (! print_v850_note (& inote))
19775 {
32ec8896 19776 res = FALSE;
685080f2
NC
19777 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
19778 inote.namesz, inote.descsz);
19779 }
19780 }
19781
19782 free (pnotes);
19783
19784 return res;
19785}
19786
32ec8896 19787static bfd_boolean
dda8d76d 19788process_note_sections (Filedata * filedata)
1ec5cd37 19789{
2cf0635d 19790 Elf_Internal_Shdr * section;
1ec5cd37 19791 unsigned long i;
32ec8896
NC
19792 unsigned int n = 0;
19793 bfd_boolean res = TRUE;
1ec5cd37 19794
dda8d76d
NC
19795 for (i = 0, section = filedata->section_headers;
19796 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 19797 i++, section++)
685080f2
NC
19798 {
19799 if (section->sh_type == SHT_NOTE)
19800 {
dda8d76d 19801 if (! process_notes_at (filedata, section,
32ec8896 19802 (bfd_vma) section->sh_offset,
82ed9683
L
19803 (bfd_vma) section->sh_size,
19804 (bfd_vma) section->sh_addralign))
32ec8896 19805 res = FALSE;
685080f2
NC
19806 n++;
19807 }
19808
dda8d76d
NC
19809 if (( filedata->file_header.e_machine == EM_V800
19810 || filedata->file_header.e_machine == EM_V850
19811 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
19812 && section->sh_type == SHT_RENESAS_INFO)
19813 {
dda8d76d 19814 if (! process_v850_notes (filedata,
32ec8896
NC
19815 (bfd_vma) section->sh_offset,
19816 (bfd_vma) section->sh_size))
19817 res = FALSE;
685080f2
NC
19818 n++;
19819 }
19820 }
df565f32
NC
19821
19822 if (n == 0)
19823 /* Try processing NOTE segments instead. */
dda8d76d 19824 return process_corefile_note_segments (filedata);
1ec5cd37
NC
19825
19826 return res;
19827}
19828
32ec8896 19829static bfd_boolean
dda8d76d 19830process_notes (Filedata * filedata)
779fe533
NC
19831{
19832 /* If we have not been asked to display the notes then do nothing. */
19833 if (! do_notes)
32ec8896 19834 return TRUE;
103f02d3 19835
dda8d76d
NC
19836 if (filedata->file_header.e_type != ET_CORE)
19837 return process_note_sections (filedata);
103f02d3 19838
779fe533 19839 /* No program headers means no NOTE segment. */
dda8d76d
NC
19840 if (filedata->file_header.e_phnum > 0)
19841 return process_corefile_note_segments (filedata);
779fe533 19842
1ec5cd37 19843 printf (_("No note segments present in the core file.\n"));
32ec8896 19844 return TRUE;
779fe533
NC
19845}
19846
60abdbed
NC
19847static unsigned char *
19848display_public_gnu_attributes (unsigned char * start,
19849 const unsigned char * const end)
19850{
19851 printf (_(" Unknown GNU attribute: %s\n"), start);
19852
19853 start += strnlen ((char *) start, end - start);
19854 display_raw_attribute (start, end);
19855
19856 return (unsigned char *) end;
19857}
19858
19859static unsigned char *
19860display_generic_attribute (unsigned char * start,
19861 unsigned int tag,
19862 const unsigned char * const end)
19863{
19864 if (tag == 0)
19865 return (unsigned char *) end;
19866
19867 return display_tag_value (tag, start, end);
19868}
19869
32ec8896 19870static bfd_boolean
dda8d76d 19871process_arch_specific (Filedata * filedata)
252b5132 19872{
a952a375 19873 if (! do_arch)
32ec8896 19874 return TRUE;
a952a375 19875
dda8d76d 19876 switch (filedata->file_header.e_machine)
252b5132 19877 {
53a346d8
CZ
19878 case EM_ARC:
19879 case EM_ARC_COMPACT:
19880 case EM_ARC_COMPACT2:
dda8d76d 19881 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
19882 display_arc_attribute,
19883 display_generic_attribute);
11c1ff18 19884 case EM_ARM:
dda8d76d 19885 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
19886 display_arm_attribute,
19887 display_generic_attribute);
19888
252b5132 19889 case EM_MIPS:
4fe85591 19890 case EM_MIPS_RS3_LE:
dda8d76d 19891 return process_mips_specific (filedata);
60abdbed
NC
19892
19893 case EM_MSP430:
dda8d76d
NC
19894 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
19895 display_msp430x_attribute,
c0ea7c52 19896 display_msp430_gnu_attribute);
60abdbed 19897
2dc8dd17
JW
19898 case EM_RISCV:
19899 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
19900 display_riscv_attribute,
19901 display_generic_attribute);
19902
35c08157 19903 case EM_NDS32:
dda8d76d 19904 return process_nds32_specific (filedata);
60abdbed 19905
34c8bcba 19906 case EM_PPC:
b82317dd 19907 case EM_PPC64:
dda8d76d 19908 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19909 display_power_gnu_attribute);
19910
643f7afb
AK
19911 case EM_S390:
19912 case EM_S390_OLD:
dda8d76d 19913 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19914 display_s390_gnu_attribute);
19915
9e8c70f9
DM
19916 case EM_SPARC:
19917 case EM_SPARC32PLUS:
19918 case EM_SPARCV9:
dda8d76d 19919 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19920 display_sparc_gnu_attribute);
19921
59e6276b 19922 case EM_TI_C6000:
dda8d76d 19923 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
19924 display_tic6x_attribute,
19925 display_generic_attribute);
19926
252b5132 19927 default:
dda8d76d 19928 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
19929 display_public_gnu_attributes,
19930 display_generic_attribute);
252b5132 19931 }
252b5132
RH
19932}
19933
32ec8896 19934static bfd_boolean
dda8d76d 19935get_file_header (Filedata * filedata)
252b5132 19936{
9ea033b2 19937 /* Read in the identity array. */
dda8d76d 19938 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 19939 return FALSE;
252b5132 19940
9ea033b2 19941 /* Determine how to read the rest of the header. */
dda8d76d 19942 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 19943 {
1a0670f3
AM
19944 default:
19945 case ELFDATANONE:
adab8cdc
AO
19946 case ELFDATA2LSB:
19947 byte_get = byte_get_little_endian;
19948 byte_put = byte_put_little_endian;
19949 break;
19950 case ELFDATA2MSB:
19951 byte_get = byte_get_big_endian;
19952 byte_put = byte_put_big_endian;
19953 break;
9ea033b2
NC
19954 }
19955
19956 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 19957 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
19958
19959 /* Read in the rest of the header. */
19960 if (is_32bit_elf)
19961 {
19962 Elf32_External_Ehdr ehdr32;
252b5132 19963
dda8d76d 19964 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 19965 return FALSE;
103f02d3 19966
dda8d76d
NC
19967 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
19968 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
19969 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
19970 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
19971 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
19972 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
19973 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
19974 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
19975 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
19976 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
19977 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
19978 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
19979 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 19980 }
252b5132 19981 else
9ea033b2
NC
19982 {
19983 Elf64_External_Ehdr ehdr64;
a952a375
NC
19984
19985 /* If we have been compiled with sizeof (bfd_vma) == 4, then
19986 we will not be able to cope with the 64bit data found in
19987 64 ELF files. Detect this now and abort before we start
50c2245b 19988 overwriting things. */
a952a375
NC
19989 if (sizeof (bfd_vma) < 8)
19990 {
e3c8793a
NC
19991 error (_("This instance of readelf has been built without support for a\n\
1999264 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 19993 return FALSE;
a952a375 19994 }
103f02d3 19995
dda8d76d 19996 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 19997 return FALSE;
103f02d3 19998
dda8d76d
NC
19999 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
20000 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
20001 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
20002 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
20003 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
20004 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
20005 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
20006 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
20007 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
20008 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
20009 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
20010 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
20011 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 20012 }
252b5132 20013
dda8d76d 20014 if (filedata->file_header.e_shoff)
7ece0d85
JJ
20015 {
20016 /* There may be some extensions in the first section header. Don't
20017 bomb if we can't read it. */
20018 if (is_32bit_elf)
dda8d76d 20019 get_32bit_section_headers (filedata, TRUE);
7ece0d85 20020 else
dda8d76d 20021 get_64bit_section_headers (filedata, TRUE);
7ece0d85 20022 }
560f3c1c 20023
32ec8896 20024 return TRUE;
252b5132
RH
20025}
20026
dda8d76d
NC
20027static void
20028close_file (Filedata * filedata)
20029{
20030 if (filedata)
20031 {
20032 if (filedata->handle)
20033 fclose (filedata->handle);
20034 free (filedata);
20035 }
20036}
20037
20038void
20039close_debug_file (void * data)
20040{
20041 close_file ((Filedata *) data);
20042}
20043
20044static Filedata *
20045open_file (const char * pathname)
20046{
20047 struct stat statbuf;
20048 Filedata * filedata = NULL;
20049
20050 if (stat (pathname, & statbuf) < 0
20051 || ! S_ISREG (statbuf.st_mode))
20052 goto fail;
20053
20054 filedata = calloc (1, sizeof * filedata);
20055 if (filedata == NULL)
20056 goto fail;
20057
20058 filedata->handle = fopen (pathname, "rb");
20059 if (filedata->handle == NULL)
20060 goto fail;
20061
20062 filedata->file_size = (bfd_size_type) statbuf.st_size;
20063 filedata->file_name = pathname;
20064
20065 if (! get_file_header (filedata))
20066 goto fail;
20067
20068 if (filedata->file_header.e_shoff)
20069 {
20070 bfd_boolean res;
20071
20072 /* Read the section headers again, this time for real. */
20073 if (is_32bit_elf)
20074 res = get_32bit_section_headers (filedata, FALSE);
20075 else
20076 res = get_64bit_section_headers (filedata, FALSE);
20077
20078 if (!res)
20079 goto fail;
20080 }
20081
20082 return filedata;
20083
20084 fail:
20085 if (filedata)
20086 {
20087 if (filedata->handle)
20088 fclose (filedata->handle);
20089 free (filedata);
20090 }
20091 return NULL;
20092}
20093
20094void *
20095open_debug_file (const char * pathname)
20096{
20097 return open_file (pathname);
20098}
20099
fb52b2f4
NC
20100/* Process one ELF object file according to the command line options.
20101 This file may actually be stored in an archive. The file is
32ec8896
NC
20102 positioned at the start of the ELF object. Returns TRUE if no
20103 problems were encountered, FALSE otherwise. */
fb52b2f4 20104
32ec8896 20105static bfd_boolean
dda8d76d 20106process_object (Filedata * filedata)
252b5132 20107{
24841daa 20108 bfd_boolean have_separate_files;
252b5132 20109 unsigned int i;
2482f306 20110 bfd_boolean res;
252b5132 20111
dda8d76d 20112 if (! get_file_header (filedata))
252b5132 20113 {
dda8d76d 20114 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 20115 return FALSE;
252b5132
RH
20116 }
20117
20118 /* Initialise per file variables. */
978c4450
AM
20119 for (i = ARRAY_SIZE (filedata->version_info); i--;)
20120 filedata->version_info[i] = 0;
252b5132 20121
978c4450
AM
20122 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
20123 filedata->dynamic_info[i] = 0;
20124 filedata->dynamic_info_DT_GNU_HASH = 0;
20125 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
20126
20127 /* Process the file. */
20128 if (show_name)
dda8d76d 20129 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 20130
18bd398b
NC
20131 /* Initialise the dump_sects array from the cmdline_dump_sects array.
20132 Note we do this even if cmdline_dump_sects is empty because we
20133 must make sure that the dump_sets array is zeroed out before each
20134 object file is processed. */
6431e409
AM
20135 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
20136 memset (filedata->dump.dump_sects, 0,
20137 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20138
dda8d76d 20139 if (cmdline.num_dump_sects > 0)
18bd398b 20140 {
6431e409 20141 if (filedata->dump.num_dump_sects == 0)
18bd398b 20142 /* A sneaky way of allocating the dump_sects array. */
6431e409 20143 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 20144
6431e409
AM
20145 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
20146 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
20147 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20148 }
d70c5fc7 20149
dda8d76d 20150 if (! process_file_header (filedata))
32ec8896 20151 return FALSE;
252b5132 20152
dda8d76d 20153 if (! process_section_headers (filedata))
2f62977e 20154 {
32ec8896
NC
20155 /* Without loaded section headers we cannot process lots of things. */
20156 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 20157
2f62977e 20158 if (! do_using_dynamic)
32ec8896 20159 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 20160 }
252b5132 20161
dda8d76d 20162 if (! process_section_groups (filedata))
32ec8896
NC
20163 /* Without loaded section groups we cannot process unwind. */
20164 do_unwind = FALSE;
d1f5c6e3 20165
2482f306
AM
20166 res = process_program_headers (filedata);
20167 if (res)
20168 res = process_dynamic_section (filedata);
252b5132 20169
dda8d76d 20170 if (! process_relocs (filedata))
32ec8896 20171 res = FALSE;
252b5132 20172
dda8d76d 20173 if (! process_unwind (filedata))
32ec8896 20174 res = FALSE;
4d6ed7c8 20175
dda8d76d 20176 if (! process_symbol_table (filedata))
32ec8896 20177 res = FALSE;
252b5132 20178
dda8d76d 20179 if (! process_syminfo (filedata))
32ec8896 20180 res = FALSE;
252b5132 20181
dda8d76d 20182 if (! process_version_sections (filedata))
32ec8896 20183 res = FALSE;
252b5132 20184
82ed9683 20185 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 20186 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 20187 else
24841daa 20188 have_separate_files = FALSE;
dda8d76d
NC
20189
20190 if (! process_section_contents (filedata))
32ec8896 20191 res = FALSE;
f5842774 20192
24841daa 20193 if (have_separate_files)
dda8d76d 20194 {
24841daa
NC
20195 separate_info * d;
20196
20197 for (d = first_separate_info; d != NULL; d = d->next)
20198 {
20199 if (! process_section_headers (d->handle))
20200 res = FALSE;
20201 else if (! process_section_contents (d->handle))
20202 res = FALSE;
20203 }
20204
20205 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
20206 }
20207
20208 if (! process_notes (filedata))
32ec8896 20209 res = FALSE;
103f02d3 20210
dda8d76d 20211 if (! process_gnu_liblist (filedata))
32ec8896 20212 res = FALSE;
047b2264 20213
dda8d76d 20214 if (! process_arch_specific (filedata))
32ec8896 20215 res = FALSE;
252b5132 20216
dda8d76d
NC
20217 free (filedata->program_headers);
20218 filedata->program_headers = NULL;
d93f0186 20219
dda8d76d
NC
20220 free (filedata->section_headers);
20221 filedata->section_headers = NULL;
252b5132 20222
dda8d76d
NC
20223 free (filedata->string_table);
20224 filedata->string_table = NULL;
20225 filedata->string_table_length = 0;
252b5132 20226
6431e409 20227 if (filedata->dump.dump_sects != NULL)
a788aedd 20228 {
6431e409
AM
20229 free (filedata->dump.dump_sects);
20230 filedata->dump.dump_sects = NULL;
20231 filedata->dump.num_dump_sects = 0;
a788aedd
AM
20232 }
20233
978c4450 20234 if (filedata->dynamic_strings)
252b5132 20235 {
978c4450
AM
20236 free (filedata->dynamic_strings);
20237 filedata->dynamic_strings = NULL;
20238 filedata->dynamic_strings_length = 0;
252b5132
RH
20239 }
20240
978c4450 20241 if (filedata->dynamic_symbols)
252b5132 20242 {
978c4450
AM
20243 free (filedata->dynamic_symbols);
20244 filedata->dynamic_symbols = NULL;
20245 filedata->num_dynamic_syms = 0;
252b5132
RH
20246 }
20247
978c4450 20248 if (filedata->dynamic_syminfo)
252b5132 20249 {
978c4450
AM
20250 free (filedata->dynamic_syminfo);
20251 filedata->dynamic_syminfo = NULL;
252b5132 20252 }
ff78d6d6 20253
978c4450 20254 if (filedata->dynamic_section)
293c573e 20255 {
978c4450
AM
20256 free (filedata->dynamic_section);
20257 filedata->dynamic_section = NULL;
293c573e
MR
20258 }
20259
978c4450 20260 while (filedata->symtab_shndx_list != NULL)
8fb879cd 20261 {
978c4450
AM
20262 elf_section_list *next = filedata->symtab_shndx_list->next;
20263 free (filedata->symtab_shndx_list);
20264 filedata->symtab_shndx_list = next;
8fb879cd
AM
20265 }
20266
978c4450 20267 if (filedata->section_headers_groups)
e4b17d5c 20268 {
978c4450
AM
20269 free (filedata->section_headers_groups);
20270 filedata->section_headers_groups = NULL;
e4b17d5c
L
20271 }
20272
978c4450 20273 if (filedata->section_groups)
e4b17d5c 20274 {
2cf0635d
NC
20275 struct group_list * g;
20276 struct group_list * next;
e4b17d5c 20277
978c4450 20278 for (i = 0; i < filedata->group_count; i++)
e4b17d5c 20279 {
978c4450 20280 for (g = filedata->section_groups [i].root; g != NULL; g = next)
e4b17d5c
L
20281 {
20282 next = g->next;
20283 free (g);
20284 }
20285 }
20286
978c4450
AM
20287 free (filedata->section_groups);
20288 filedata->section_groups = NULL;
e4b17d5c
L
20289 }
20290
19e6b90e 20291 free_debug_memory ();
18bd398b 20292
32ec8896 20293 return res;
252b5132
RH
20294}
20295
2cf0635d 20296/* Process an ELF archive.
32ec8896
NC
20297 On entry the file is positioned just after the ARMAG string.
20298 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 20299
32ec8896 20300static bfd_boolean
dda8d76d 20301process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
20302{
20303 struct archive_info arch;
20304 struct archive_info nested_arch;
20305 size_t got;
32ec8896 20306 bfd_boolean ret = TRUE;
2cf0635d 20307
32ec8896 20308 show_name = TRUE;
2cf0635d
NC
20309
20310 /* The ARCH structure is used to hold information about this archive. */
20311 arch.file_name = NULL;
20312 arch.file = NULL;
20313 arch.index_array = NULL;
20314 arch.sym_table = NULL;
20315 arch.longnames = NULL;
20316
20317 /* The NESTED_ARCH structure is used as a single-item cache of information
20318 about a nested archive (when members of a thin archive reside within
20319 another regular archive file). */
20320 nested_arch.file_name = NULL;
20321 nested_arch.file = NULL;
20322 nested_arch.index_array = NULL;
20323 nested_arch.sym_table = NULL;
20324 nested_arch.longnames = NULL;
20325
dda8d76d 20326 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
20327 filedata->file_size, is_thin_archive,
20328 do_archive_index) != 0)
2cf0635d 20329 {
32ec8896 20330 ret = FALSE;
2cf0635d 20331 goto out;
4145f1d5 20332 }
fb52b2f4 20333
4145f1d5
NC
20334 if (do_archive_index)
20335 {
2cf0635d 20336 if (arch.sym_table == NULL)
1cb7d8b1
AM
20337 error (_("%s: unable to dump the index as none was found\n"),
20338 filedata->file_name);
4145f1d5
NC
20339 else
20340 {
591f7597 20341 unsigned long i, l;
4145f1d5
NC
20342 unsigned long current_pos;
20343
1cb7d8b1
AM
20344 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
20345 "in the symbol table)\n"),
20346 filedata->file_name, (unsigned long) arch.index_num,
20347 arch.sym_size);
dda8d76d
NC
20348
20349 current_pos = ftell (filedata->handle);
4145f1d5 20350
2cf0635d 20351 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 20352 {
1cb7d8b1
AM
20353 if (i == 0
20354 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
20355 {
20356 char * member_name
20357 = get_archive_member_name_at (&arch, arch.index_array[i],
20358 &nested_arch);
2cf0635d 20359
1cb7d8b1
AM
20360 if (member_name != NULL)
20361 {
20362 char * qualified_name
20363 = make_qualified_name (&arch, &nested_arch,
20364 member_name);
2cf0635d 20365
1cb7d8b1
AM
20366 if (qualified_name != NULL)
20367 {
20368 printf (_("Contents of binary %s at offset "),
20369 qualified_name);
c2a7d3f5
NC
20370 (void) print_vma (arch.index_array[i], PREFIX_HEX);
20371 putchar ('\n');
1cb7d8b1
AM
20372 free (qualified_name);
20373 }
fd486f32 20374 free (member_name);
4145f1d5
NC
20375 }
20376 }
2cf0635d
NC
20377
20378 if (l >= arch.sym_size)
4145f1d5 20379 {
1cb7d8b1
AM
20380 error (_("%s: end of the symbol table reached "
20381 "before the end of the index\n"),
dda8d76d 20382 filedata->file_name);
32ec8896 20383 ret = FALSE;
cb8f3167 20384 break;
4145f1d5 20385 }
591f7597 20386 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
20387 printf ("\t%.*s\n",
20388 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 20389 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
20390 }
20391
67ce483b 20392 if (arch.uses_64bit_indices)
c2a7d3f5
NC
20393 l = (l + 7) & ~ 7;
20394 else
20395 l += l & 1;
20396
2cf0635d 20397 if (l < arch.sym_size)
32ec8896 20398 {
d3a49aa8
AM
20399 error (ngettext ("%s: %ld byte remains in the symbol table, "
20400 "but without corresponding entries in "
20401 "the index table\n",
20402 "%s: %ld bytes remain in the symbol table, "
20403 "but without corresponding entries in "
20404 "the index table\n",
20405 arch.sym_size - l),
dda8d76d 20406 filedata->file_name, arch.sym_size - l);
32ec8896
NC
20407 ret = FALSE;
20408 }
4145f1d5 20409
dda8d76d 20410 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 20411 {
1cb7d8b1
AM
20412 error (_("%s: failed to seek back to start of object files "
20413 "in the archive\n"),
dda8d76d 20414 filedata->file_name);
32ec8896 20415 ret = FALSE;
2cf0635d 20416 goto out;
4145f1d5 20417 }
fb52b2f4 20418 }
4145f1d5
NC
20419
20420 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
20421 && !do_segments && !do_header && !do_dump && !do_version
20422 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 20423 && !do_section_groups && !do_dyn_syms)
2cf0635d 20424 {
32ec8896 20425 ret = TRUE; /* Archive index only. */
2cf0635d
NC
20426 goto out;
20427 }
fb52b2f4
NC
20428 }
20429
fb52b2f4
NC
20430 while (1)
20431 {
2cf0635d
NC
20432 char * name;
20433 size_t namelen;
20434 char * qualified_name;
20435
20436 /* Read the next archive header. */
dda8d76d 20437 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
20438 {
20439 error (_("%s: failed to seek to next archive header\n"),
20440 arch.file_name);
20441 ret = FALSE;
20442 break;
20443 }
dda8d76d 20444 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 20445 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
20446 {
20447 if (got == 0)
2cf0635d 20448 break;
28e817cc
NC
20449 /* PR 24049 - we cannot use filedata->file_name as this will
20450 have already been freed. */
20451 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 20452
1cb7d8b1
AM
20453 ret = FALSE;
20454 break;
20455 }
2cf0635d 20456 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
20457 {
20458 error (_("%s: did not find a valid archive header\n"),
20459 arch.file_name);
20460 ret = FALSE;
20461 break;
20462 }
2cf0635d
NC
20463
20464 arch.next_arhdr_offset += sizeof arch.arhdr;
20465
978c4450
AM
20466 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
20467 if (filedata->archive_file_size & 01)
20468 ++filedata->archive_file_size;
2cf0635d
NC
20469
20470 name = get_archive_member_name (&arch, &nested_arch);
20471 if (name == NULL)
fb52b2f4 20472 {
28e817cc 20473 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 20474 ret = FALSE;
d989285c 20475 break;
fb52b2f4 20476 }
2cf0635d 20477 namelen = strlen (name);
fb52b2f4 20478
2cf0635d
NC
20479 qualified_name = make_qualified_name (&arch, &nested_arch, name);
20480 if (qualified_name == NULL)
fb52b2f4 20481 {
28e817cc 20482 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 20483 free (name);
32ec8896 20484 ret = FALSE;
d989285c 20485 break;
fb52b2f4
NC
20486 }
20487
2cf0635d 20488 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
20489 {
20490 /* This is a proxy for an external member of a thin archive. */
20491 Filedata * member_filedata;
20492 char * member_file_name = adjust_relative_path
dda8d76d 20493 (filedata->file_name, name, namelen);
32ec8896 20494
fd486f32 20495 free (name);
1cb7d8b1
AM
20496 if (member_file_name == NULL)
20497 {
fd486f32 20498 free (qualified_name);
1cb7d8b1
AM
20499 ret = FALSE;
20500 break;
20501 }
2cf0635d 20502
1cb7d8b1
AM
20503 member_filedata = open_file (member_file_name);
20504 if (member_filedata == NULL)
20505 {
20506 error (_("Input file '%s' is not readable.\n"), member_file_name);
20507 free (member_file_name);
fd486f32 20508 free (qualified_name);
1cb7d8b1
AM
20509 ret = FALSE;
20510 break;
20511 }
2cf0635d 20512
978c4450 20513 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 20514 member_filedata->file_name = qualified_name;
2cf0635d 20515
1cb7d8b1 20516 if (! process_object (member_filedata))
32ec8896 20517 ret = FALSE;
2cf0635d 20518
1cb7d8b1
AM
20519 close_file (member_filedata);
20520 free (member_file_name);
1cb7d8b1 20521 }
2cf0635d 20522 else if (is_thin_archive)
1cb7d8b1
AM
20523 {
20524 Filedata thin_filedata;
eb02c04d 20525
1cb7d8b1 20526 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 20527
a043396b
NC
20528 /* PR 15140: Allow for corrupt thin archives. */
20529 if (nested_arch.file == NULL)
20530 {
20531 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 20532 qualified_name, name);
fd486f32
AM
20533 free (qualified_name);
20534 free (name);
32ec8896 20535 ret = FALSE;
a043396b
NC
20536 break;
20537 }
fd486f32 20538 free (name);
a043396b 20539
1cb7d8b1 20540 /* This is a proxy for a member of a nested archive. */
978c4450
AM
20541 filedata->archive_file_offset
20542 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 20543
1cb7d8b1
AM
20544 /* The nested archive file will have been opened and setup by
20545 get_archive_member_name. */
978c4450
AM
20546 if (fseek (nested_arch.file, filedata->archive_file_offset,
20547 SEEK_SET) != 0)
1cb7d8b1
AM
20548 {
20549 error (_("%s: failed to seek to archive member.\n"),
20550 nested_arch.file_name);
fd486f32 20551 free (qualified_name);
1cb7d8b1
AM
20552 ret = FALSE;
20553 break;
20554 }
2cf0635d 20555
dda8d76d
NC
20556 thin_filedata.handle = nested_arch.file;
20557 thin_filedata.file_name = qualified_name;
9abca702 20558
1cb7d8b1 20559 if (! process_object (& thin_filedata))
32ec8896 20560 ret = FALSE;
1cb7d8b1 20561 }
2cf0635d 20562 else
1cb7d8b1 20563 {
fd486f32 20564 free (name);
978c4450 20565 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 20566 filedata->file_name = qualified_name;
1cb7d8b1 20567 if (! process_object (filedata))
32ec8896 20568 ret = FALSE;
978c4450 20569 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 20570 /* Stop looping with "negative" archive_file_size. */
978c4450 20571 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 20572 arch.next_arhdr_offset = -1ul;
1cb7d8b1 20573 }
fb52b2f4 20574
2cf0635d 20575 free (qualified_name);
fb52b2f4
NC
20576 }
20577
4145f1d5 20578 out:
2cf0635d
NC
20579 if (nested_arch.file != NULL)
20580 fclose (nested_arch.file);
20581 release_archive (&nested_arch);
20582 release_archive (&arch);
fb52b2f4 20583
d989285c 20584 return ret;
fb52b2f4
NC
20585}
20586
32ec8896 20587static bfd_boolean
2cf0635d 20588process_file (char * file_name)
fb52b2f4 20589{
dda8d76d 20590 Filedata * filedata = NULL;
fb52b2f4
NC
20591 struct stat statbuf;
20592 char armag[SARMAG];
32ec8896 20593 bfd_boolean ret = TRUE;
fb52b2f4
NC
20594
20595 if (stat (file_name, &statbuf) < 0)
20596 {
f24ddbdd
NC
20597 if (errno == ENOENT)
20598 error (_("'%s': No such file\n"), file_name);
20599 else
20600 error (_("Could not locate '%s'. System error message: %s\n"),
20601 file_name, strerror (errno));
32ec8896 20602 return FALSE;
f24ddbdd
NC
20603 }
20604
20605 if (! S_ISREG (statbuf.st_mode))
20606 {
20607 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 20608 return FALSE;
fb52b2f4
NC
20609 }
20610
dda8d76d
NC
20611 filedata = calloc (1, sizeof * filedata);
20612 if (filedata == NULL)
20613 {
20614 error (_("Out of memory allocating file data structure\n"));
20615 return FALSE;
20616 }
20617
20618 filedata->file_name = file_name;
20619 filedata->handle = fopen (file_name, "rb");
20620 if (filedata->handle == NULL)
fb52b2f4 20621 {
f24ddbdd 20622 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 20623 free (filedata);
32ec8896 20624 return FALSE;
fb52b2f4
NC
20625 }
20626
dda8d76d 20627 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 20628 {
4145f1d5 20629 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
20630 fclose (filedata->handle);
20631 free (filedata);
32ec8896 20632 return FALSE;
fb52b2f4
NC
20633 }
20634
dda8d76d 20635 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 20636
fb52b2f4 20637 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 20638 {
dda8d76d 20639 if (! process_archive (filedata, FALSE))
32ec8896
NC
20640 ret = FALSE;
20641 }
2cf0635d 20642 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 20643 {
dda8d76d 20644 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
20645 ret = FALSE;
20646 }
fb52b2f4
NC
20647 else
20648 {
4145f1d5
NC
20649 if (do_archive_index)
20650 error (_("File %s is not an archive so its index cannot be displayed.\n"),
20651 file_name);
20652
dda8d76d 20653 rewind (filedata->handle);
978c4450 20654 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 20655
dda8d76d 20656 if (! process_object (filedata))
32ec8896 20657 ret = FALSE;
fb52b2f4
NC
20658 }
20659
dda8d76d 20660 fclose (filedata->handle);
8fb879cd
AM
20661 free (filedata->section_headers);
20662 free (filedata->program_headers);
20663 free (filedata->string_table);
6431e409 20664 free (filedata->dump.dump_sects);
dda8d76d 20665 free (filedata);
32ec8896 20666
fd486f32 20667 free (ba_cache.strtab);
1bd6175a 20668 ba_cache.strtab = NULL;
fd486f32 20669 free (ba_cache.symtab);
1bd6175a 20670 ba_cache.symtab = NULL;
fd486f32
AM
20671 ba_cache.filedata = NULL;
20672
fb52b2f4
NC
20673 return ret;
20674}
20675
252b5132
RH
20676#ifdef SUPPORT_DISASSEMBLY
20677/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 20678 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 20679 symbols. */
252b5132
RH
20680
20681void
2cf0635d 20682print_address (unsigned int addr, FILE * outfile)
252b5132
RH
20683{
20684 fprintf (outfile,"0x%8.8x", addr);
20685}
20686
e3c8793a 20687/* Needed by the i386 disassembler. */
dda8d76d 20688
252b5132
RH
20689void
20690db_task_printsym (unsigned int addr)
20691{
20692 print_address (addr, stderr);
20693}
20694#endif
20695
20696int
2cf0635d 20697main (int argc, char ** argv)
252b5132 20698{
ff78d6d6
L
20699 int err;
20700
252b5132
RH
20701#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
20702 setlocale (LC_MESSAGES, "");
3882b010
L
20703#endif
20704#if defined (HAVE_SETLOCALE)
20705 setlocale (LC_CTYPE, "");
252b5132
RH
20706#endif
20707 bindtextdomain (PACKAGE, LOCALEDIR);
20708 textdomain (PACKAGE);
20709
869b9d07
MM
20710 expandargv (&argc, &argv);
20711
dda8d76d 20712 parse_args (& cmdline, argc, argv);
59f14fc0 20713
18bd398b 20714 if (optind < (argc - 1))
32ec8896 20715 show_name = TRUE;
5656ba2c
L
20716 else if (optind >= argc)
20717 {
20718 warn (_("Nothing to do.\n"));
20719 usage (stderr);
20720 }
18bd398b 20721
32ec8896 20722 err = FALSE;
252b5132 20723 while (optind < argc)
32ec8896
NC
20724 if (! process_file (argv[optind++]))
20725 err = TRUE;
252b5132 20726
dda8d76d
NC
20727 if (cmdline.dump_sects != NULL)
20728 free (cmdline.dump_sects);
252b5132 20729
7d9813f1
NA
20730 free (dump_ctf_symtab_name);
20731 free (dump_ctf_strtab_name);
20732 free (dump_ctf_parent_name);
20733
32ec8896 20734 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 20735}
This page took 3.456052 seconds and 4 git commands to generate.