]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Add demangling support to readelf.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
b3adc24a 2 Copyright (C) 1998-2020 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
3bfcb652 47#ifdef HAVE_WCHAR_H
7bfd842d 48#include <wchar.h>
3bfcb652 49#endif
252b5132 50
a952a375 51#if __GNUC__ >= 2
19936277 52/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 53 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 54 Only do this if we believe that the compiler can support a 64 bit
a952a375 55 data type. For now we only rely on GCC being able to do this. */
19936277 56#define BFD64
a952a375
NC
57#endif
58
3db64b00
AM
59#include "bfd.h"
60#include "bucomm.h"
3284fe0c 61#include "elfcomm.h"
19e6b90e 62#include "dwarf.h"
7d9813f1 63#include "ctf-api.h"
79bc120c 64#include "demangle.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
b8891f8d 103#include "elf/csky.h"
252b5132
RH
104#include "elf/d10v.h"
105#include "elf/d30v.h"
d172d4ba 106#include "elf/dlx.h"
aca4efc7 107#include "elf/bpf.h"
cfb8c092 108#include "elf/epiphany.h"
252b5132 109#include "elf/fr30.h"
5c70f934 110#include "elf/frv.h"
3f8107ab 111#include "elf/ft32.h"
3b16e843
NC
112#include "elf/h8.h"
113#include "elf/hppa.h"
114#include "elf/i386.h"
f954747f
AM
115#include "elf/i370.h"
116#include "elf/i860.h"
117#include "elf/i960.h"
3b16e843 118#include "elf/ia64.h"
1e4cf259 119#include "elf/ip2k.h"
84e94c90 120#include "elf/lm32.h"
1c0d3aa6 121#include "elf/iq2000.h"
49f58d10 122#include "elf/m32c.h"
3b16e843
NC
123#include "elf/m32r.h"
124#include "elf/m68k.h"
75751cd9 125#include "elf/m68hc11.h"
7b4ae824 126#include "elf/s12z.h"
252b5132 127#include "elf/mcore.h"
15ab5209 128#include "elf/mep.h"
a3c62988 129#include "elf/metag.h"
7ba29e2a 130#include "elf/microblaze.h"
3b16e843 131#include "elf/mips.h"
3c3bdf30 132#include "elf/mmix.h"
3b16e843
NC
133#include "elf/mn10200.h"
134#include "elf/mn10300.h"
5506d11a 135#include "elf/moxie.h"
4970f871 136#include "elf/mt.h"
2469cfa2 137#include "elf/msp430.h"
35c08157 138#include "elf/nds32.h"
fe944acf 139#include "elf/nfp.h"
13761a11 140#include "elf/nios2.h"
73589c9d 141#include "elf/or1k.h"
7d466069 142#include "elf/pj.h"
3b16e843 143#include "elf/ppc.h"
c833c019 144#include "elf/ppc64.h"
2b100bb5 145#include "elf/pru.h"
03336641 146#include "elf/riscv.h"
99c513f6 147#include "elf/rl78.h"
c7927a3c 148#include "elf/rx.h"
a85d7ed0 149#include "elf/s390.h"
1c0d3aa6 150#include "elf/score.h"
3b16e843
NC
151#include "elf/sh.h"
152#include "elf/sparc.h"
e9f53129 153#include "elf/spu.h"
40b36596 154#include "elf/tic6x.h"
aa137e4d
NC
155#include "elf/tilegx.h"
156#include "elf/tilepro.h"
3b16e843 157#include "elf/v850.h"
179d3252 158#include "elf/vax.h"
619ed720 159#include "elf/visium.h"
f96bd6c2 160#include "elf/wasm32.h"
3b16e843 161#include "elf/x86-64.h"
c29aca4a 162#include "elf/xc16x.h"
f6c1a2d5 163#include "elf/xgate.h"
93fbbb04 164#include "elf/xstormy16.h"
88da6820 165#include "elf/xtensa.h"
6655dba2 166#include "elf/z80.h"
252b5132 167
252b5132 168#include "getopt.h"
566b0d53 169#include "libiberty.h"
09c11c86 170#include "safe-ctype.h"
2cf0635d 171#include "filenames.h"
252b5132 172
15b42fb0
AM
173#ifndef offsetof
174#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
175#endif
176
6a40cf0c
NC
177typedef struct elf_section_list
178{
dda8d76d
NC
179 Elf_Internal_Shdr * hdr;
180 struct elf_section_list * next;
6a40cf0c
NC
181} elf_section_list;
182
dda8d76d
NC
183/* Flag bits indicating particular types of dump. */
184#define HEX_DUMP (1 << 0) /* The -x command line switch. */
185#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
186#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
187#define STRING_DUMP (1 << 3) /* The -p command line switch. */
188#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 189#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
190
191typedef unsigned char dump_type;
192
193/* A linked list of the section names for which dumps were requested. */
194struct dump_list_entry
195{
196 char * name;
197 dump_type type;
198 struct dump_list_entry * next;
199};
200
6431e409
AM
201/* A dynamic array of flags indicating for which sections a dump
202 has been requested via command line switches. */
1b513401
NC
203struct dump_data
204{
6431e409
AM
205 dump_type * dump_sects;
206 unsigned int num_dump_sects;
207};
208
209static struct dump_data cmdline;
210
211static struct dump_list_entry * dump_sects_byname;
212
2cf0635d 213char * program_name = "readelf";
dda8d76d 214
32ec8896
NC
215static bfd_boolean show_name = FALSE;
216static bfd_boolean do_dynamic = FALSE;
217static bfd_boolean do_syms = FALSE;
218static bfd_boolean do_dyn_syms = FALSE;
219static bfd_boolean do_reloc = FALSE;
220static bfd_boolean do_sections = FALSE;
221static bfd_boolean do_section_groups = FALSE;
222static bfd_boolean do_section_details = FALSE;
223static bfd_boolean do_segments = FALSE;
224static bfd_boolean do_unwind = FALSE;
225static bfd_boolean do_using_dynamic = FALSE;
226static bfd_boolean do_header = FALSE;
227static bfd_boolean do_dump = FALSE;
228static bfd_boolean do_version = FALSE;
229static bfd_boolean do_histogram = FALSE;
230static bfd_boolean do_debugging = FALSE;
7d9813f1 231static bfd_boolean do_ctf = FALSE;
32ec8896
NC
232static bfd_boolean do_arch = FALSE;
233static bfd_boolean do_notes = FALSE;
234static bfd_boolean do_archive_index = FALSE;
1b513401 235static bfd_boolean check_all = FALSE;
32ec8896
NC
236static bfd_boolean is_32bit_elf = FALSE;
237static bfd_boolean decompress_dumps = FALSE;
0942c7ab 238static bfd_boolean do_not_show_symbol_truncation = FALSE;
79bc120c
NC
239static bfd_boolean do_demangle = FALSE; /* Pretty print C++ symbol names. */
240static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
252b5132 241
7d9813f1
NA
242static char *dump_ctf_parent_name;
243static char *dump_ctf_symtab_name;
244static char *dump_ctf_strtab_name;
245
e4b17d5c
L
246struct group_list
247{
dda8d76d
NC
248 struct group_list * next;
249 unsigned int section_index;
e4b17d5c
L
250};
251
252struct group
253{
dda8d76d
NC
254 struct group_list * root;
255 unsigned int group_index;
e4b17d5c
L
256};
257
978c4450
AM
258typedef struct filedata
259{
260 const char * file_name;
261 FILE * handle;
262 bfd_size_type file_size;
263 Elf_Internal_Ehdr file_header;
264 Elf_Internal_Shdr * section_headers;
265 Elf_Internal_Phdr * program_headers;
266 char * string_table;
267 unsigned long string_table_length;
268 unsigned long archive_file_offset;
269 unsigned long archive_file_size;
270 unsigned long dynamic_addr;
271 bfd_size_type dynamic_size;
272 size_t dynamic_nent;
273 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 274 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
275 char * dynamic_strings;
276 unsigned long dynamic_strings_length;
8ac10c5b 277 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
278 unsigned long num_dynamic_syms;
279 Elf_Internal_Sym * dynamic_symbols;
280 bfd_vma version_info[16];
281 unsigned int dynamic_syminfo_nent;
282 Elf_Internal_Syminfo * dynamic_syminfo;
283 unsigned long dynamic_syminfo_offset;
284 bfd_size_type nbuckets;
285 bfd_size_type nchains;
286 bfd_vma * buckets;
287 bfd_vma * chains;
288 bfd_size_type ngnubuckets;
289 bfd_size_type ngnuchains;
290 bfd_vma * gnubuckets;
291 bfd_vma * gnuchains;
292 bfd_vma * mipsxlat;
293 bfd_vma gnusymidx;
294 char program_interpreter[PATH_MAX];
295 bfd_vma dynamic_info[DT_ENCODING];
296 bfd_vma dynamic_info_DT_GNU_HASH;
297 bfd_vma dynamic_info_DT_MIPS_XHASH;
298 elf_section_list * symtab_shndx_list;
299 size_t group_count;
300 struct group * section_groups;
301 struct group ** section_headers_groups;
302 /* A dynamic array of flags indicating for which sections a dump of
303 some kind has been requested. It is reset on a per-object file
304 basis and then initialised from the cmdline_dump_sects array,
305 the results of interpreting the -w switch, and the
306 dump_sects_byname list. */
307 struct dump_data dump;
308} Filedata;
aef1f6d0 309
c256ffe7 310/* How to print a vma value. */
843dd992
NC
311typedef enum print_mode
312{
313 HEX,
314 DEC,
315 DEC_5,
316 UNSIGNED,
317 PREFIX_HEX,
318 FULL_HEX,
319 LONG_HEX
320}
321print_mode;
322
bb4d2ac2
L
323/* Versioned symbol info. */
324enum versioned_symbol_info
325{
326 symbol_undefined,
327 symbol_hidden,
328 symbol_public
329};
330
32ec8896 331static const char * get_symbol_version_string
dda8d76d 332 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 333 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 334
9c19a809
NC
335#define UNKNOWN -1
336
2b692964
NC
337#define SECTION_NAME(X) \
338 ((X) == NULL ? _("<none>") \
dda8d76d
NC
339 : filedata->string_table == NULL ? _("<no-strings>") \
340 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
341 : filedata->string_table + (X)->sh_name))
252b5132 342
ee42cf8c 343#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 344
ba5cdace
NC
345#define GET_ELF_SYMBOLS(file, section, sym_count) \
346 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
347 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 348
10ca4b04
L
349#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
350 (strtab != NULL && offset < strtab_size)
978c4450
AM
351#define VALID_DYNAMIC_NAME(filedata, offset) \
352 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
353 filedata->dynamic_strings_length, offset)
d79b3d50
NC
354/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
355 already been called and verified that the string exists. */
978c4450
AM
356#define GET_DYNAMIC_NAME(filedata, offset) \
357 (filedata->dynamic_strings + offset)
18bd398b 358
61865e30
NC
359#define REMOVE_ARCH_BITS(ADDR) \
360 do \
361 { \
dda8d76d 362 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
363 (ADDR) &= ~1; \
364 } \
365 while (0)
f16a9783
MS
366
367/* Get the correct GNU hash section name. */
978c4450
AM
368#define GNU_HASH_SECTION_NAME(filedata) \
369 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 370\f
66cfc0fd
AM
371/* Print a BFD_VMA to an internal buffer, for use in error messages.
372 BFD_FMA_FMT can't be used in translated strings. */
373
374static const char *
375bfd_vmatoa (char *fmtch, bfd_vma value)
376{
377 /* bfd_vmatoa is used more then once in a printf call for output.
378 Cycle through an array of buffers. */
379 static int buf_pos = 0;
380 static struct bfd_vmatoa_buf
381 {
382 char place[64];
383 } buf[4];
384 char *ret;
385 char fmt[32];
386
387 ret = buf[buf_pos++].place;
388 buf_pos %= ARRAY_SIZE (buf);
389
390 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
391 snprintf (ret, sizeof (buf[0].place), fmt, value);
392 return ret;
393}
394
dda8d76d
NC
395/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
396 OFFSET + the offset of the current archive member, if we are examining an
397 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
398 allocate a buffer using malloc and fill that. In either case return the
399 pointer to the start of the retrieved data or NULL if something went wrong.
400 If something does go wrong and REASON is not NULL then emit an error
401 message using REASON as part of the context. */
59245841 402
c256ffe7 403static void *
dda8d76d
NC
404get_data (void * var,
405 Filedata * filedata,
406 unsigned long offset,
407 bfd_size_type size,
408 bfd_size_type nmemb,
409 const char * reason)
a6e9f9df 410{
2cf0635d 411 void * mvar;
57028622 412 bfd_size_type amt = size * nmemb;
a6e9f9df 413
c256ffe7 414 if (size == 0 || nmemb == 0)
a6e9f9df
AM
415 return NULL;
416
57028622
NC
417 /* If the size_t type is smaller than the bfd_size_type, eg because
418 you are building a 32-bit tool on a 64-bit host, then make sure
419 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
420 if ((size_t) size != size
421 || (size_t) nmemb != nmemb
422 || (size_t) amt != amt)
57028622
NC
423 {
424 if (reason)
66cfc0fd
AM
425 error (_("Size truncation prevents reading %s"
426 " elements of size %s for %s\n"),
427 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
428 return NULL;
429 }
430
431 /* Check for size overflow. */
7c1c1904 432 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
433 {
434 if (reason)
66cfc0fd
AM
435 error (_("Size overflow prevents reading %s"
436 " elements of size %s for %s\n"),
437 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
438 return NULL;
439 }
440
c22b42ce 441 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 442 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
443 if (filedata->archive_file_offset > filedata->file_size
444 || offset > filedata->file_size - filedata->archive_file_offset
445 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 446 {
049b0c3a 447 if (reason)
66cfc0fd
AM
448 error (_("Reading %s bytes extends past end of file for %s\n"),
449 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
450 return NULL;
451 }
452
978c4450
AM
453 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
454 SEEK_SET))
071436c6
NC
455 {
456 if (reason)
c9c1d674 457 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 458 filedata->archive_file_offset + offset, reason);
071436c6
NC
459 return NULL;
460 }
461
a6e9f9df
AM
462 mvar = var;
463 if (mvar == NULL)
464 {
7c1c1904
AM
465 /* + 1 so that we can '\0' terminate invalid string table sections. */
466 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
467
468 if (mvar == NULL)
469 {
049b0c3a 470 if (reason)
66cfc0fd
AM
471 error (_("Out of memory allocating %s bytes for %s\n"),
472 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
473 return NULL;
474 }
c256ffe7 475
c9c1d674 476 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
477 }
478
dda8d76d 479 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 480 {
049b0c3a 481 if (reason)
66cfc0fd
AM
482 error (_("Unable to read in %s bytes of %s\n"),
483 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
484 if (mvar != var)
485 free (mvar);
486 return NULL;
487 }
488
489 return mvar;
490}
491
32ec8896
NC
492/* Print a VMA value in the MODE specified.
493 Returns the number of characters displayed. */
cb8f3167 494
32ec8896 495static unsigned int
14a91970 496print_vma (bfd_vma vma, print_mode mode)
66543521 497{
32ec8896 498 unsigned int nc = 0;
66543521 499
14a91970 500 switch (mode)
66543521 501 {
14a91970
AM
502 case FULL_HEX:
503 nc = printf ("0x");
1a0670f3 504 /* Fall through. */
14a91970 505 case LONG_HEX:
f7a99963 506#ifdef BFD64
14a91970 507 if (is_32bit_elf)
437c2fb7 508 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 509#endif
14a91970
AM
510 printf_vma (vma);
511 return nc + 16;
b19aac67 512
14a91970
AM
513 case DEC_5:
514 if (vma <= 99999)
515 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 516 /* Fall through. */
14a91970
AM
517 case PREFIX_HEX:
518 nc = printf ("0x");
1a0670f3 519 /* Fall through. */
14a91970
AM
520 case HEX:
521 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 522
14a91970
AM
523 case DEC:
524 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 525
14a91970
AM
526 case UNSIGNED:
527 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
528
529 default:
530 /* FIXME: Report unrecognised mode ? */
531 return 0;
f7a99963 532 }
f7a99963
NC
533}
534
7bfd842d 535/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 536 multibye characters (assuming the host environment supports them).
31104126 537
7bfd842d
NC
538 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
539
0942c7ab
NC
540 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
541 abs(WIDTH) - 5 characters followed by "[...]".
542
7bfd842d
NC
543 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
544 padding as necessary.
171191ba
NC
545
546 Returns the number of emitted characters. */
547
548static unsigned int
0942c7ab 549print_symbol (signed int width, const char * symbol)
31104126 550{
171191ba 551 bfd_boolean extra_padding = FALSE;
0942c7ab 552 bfd_boolean do_dots = FALSE;
32ec8896 553 signed int num_printed = 0;
3bfcb652 554#ifdef HAVE_MBSTATE_T
7bfd842d 555 mbstate_t state;
3bfcb652 556#endif
32ec8896 557 unsigned int width_remaining;
79bc120c 558 const void * alloced_symbol = NULL;
961c521f 559
7bfd842d 560 if (width < 0)
961c521f 561 {
88305e1b 562 /* Keep the width positive. This helps the code below. */
961c521f 563 width = - width;
171191ba 564 extra_padding = TRUE;
0b4362b0 565 }
56d8f8a9
NC
566 else if (width == 0)
567 return 0;
961c521f 568
7bfd842d
NC
569 if (do_wide)
570 /* Set the remaining width to a very large value.
571 This simplifies the code below. */
572 width_remaining = INT_MAX;
573 else
0942c7ab
NC
574 {
575 width_remaining = width;
576 if (! do_not_show_symbol_truncation
577 && (int) strlen (symbol) > width)
578 {
579 width_remaining -= 5;
580 if ((int) width_remaining < 0)
581 width_remaining = 0;
582 do_dots = TRUE;
583 }
584 }
cb8f3167 585
3bfcb652 586#ifdef HAVE_MBSTATE_T
7bfd842d
NC
587 /* Initialise the multibyte conversion state. */
588 memset (& state, 0, sizeof (state));
3bfcb652 589#endif
961c521f 590
79bc120c
NC
591 if (do_demangle && *symbol)
592 {
593 const char * res = cplus_demangle (symbol, demangle_flags);
594
595 if (res != NULL)
596 alloced_symbol = symbol = res;
597 }
598
7bfd842d
NC
599 while (width_remaining)
600 {
601 size_t n;
7bfd842d 602 const char c = *symbol++;
961c521f 603
7bfd842d 604 if (c == 0)
961c521f
NC
605 break;
606
7bfd842d
NC
607 /* Do not print control characters directly as they can affect terminal
608 settings. Such characters usually appear in the names generated
609 by the assembler for local labels. */
610 if (ISCNTRL (c))
961c521f 611 {
7bfd842d 612 if (width_remaining < 2)
961c521f
NC
613 break;
614
7bfd842d
NC
615 printf ("^%c", c + 0x40);
616 width_remaining -= 2;
171191ba 617 num_printed += 2;
961c521f 618 }
7bfd842d
NC
619 else if (ISPRINT (c))
620 {
621 putchar (c);
622 width_remaining --;
623 num_printed ++;
624 }
961c521f
NC
625 else
626 {
3bfcb652
NC
627#ifdef HAVE_MBSTATE_T
628 wchar_t w;
629#endif
7bfd842d
NC
630 /* Let printf do the hard work of displaying multibyte characters. */
631 printf ("%.1s", symbol - 1);
632 width_remaining --;
633 num_printed ++;
634
3bfcb652 635#ifdef HAVE_MBSTATE_T
7bfd842d
NC
636 /* Try to find out how many bytes made up the character that was
637 just printed. Advance the symbol pointer past the bytes that
638 were displayed. */
639 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
640#else
641 n = 1;
642#endif
7bfd842d
NC
643 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
644 symbol += (n - 1);
961c521f 645 }
961c521f 646 }
171191ba 647
0942c7ab
NC
648 if (do_dots)
649 num_printed += printf ("[...]");
650
7bfd842d 651 if (extra_padding && num_printed < width)
171191ba
NC
652 {
653 /* Fill in the remaining spaces. */
7bfd842d
NC
654 printf ("%-*s", width - num_printed, " ");
655 num_printed = width;
171191ba
NC
656 }
657
79bc120c 658 free ((void *) alloced_symbol);
171191ba 659 return num_printed;
31104126
NC
660}
661
1449284b 662/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
663 the given section's name. Like print_symbol, except that it does not try
664 to print multibyte characters, it just interprets them as hex values. */
665
666static const char *
dda8d76d 667printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
668{
669#define MAX_PRINT_SEC_NAME_LEN 128
670 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
671 const char * name = SECTION_NAME (sec);
672 char * buf = sec_name_buf;
673 char c;
674 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
675
676 while ((c = * name ++) != 0)
677 {
678 if (ISCNTRL (c))
679 {
680 if (remaining < 2)
681 break;
948f632f 682
74e1a04b
NC
683 * buf ++ = '^';
684 * buf ++ = c + 0x40;
685 remaining -= 2;
686 }
687 else if (ISPRINT (c))
688 {
689 * buf ++ = c;
690 remaining -= 1;
691 }
692 else
693 {
694 static char hex[17] = "0123456789ABCDEF";
695
696 if (remaining < 4)
697 break;
698 * buf ++ = '<';
699 * buf ++ = hex[(c & 0xf0) >> 4];
700 * buf ++ = hex[c & 0x0f];
701 * buf ++ = '>';
702 remaining -= 4;
703 }
704
705 if (remaining == 0)
706 break;
707 }
708
709 * buf = 0;
710 return sec_name_buf;
711}
712
713static const char *
dda8d76d 714printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 715{
dda8d76d 716 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
717 return _("<corrupt>");
718
dda8d76d 719 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
720}
721
89fac5e3
RS
722/* Return a pointer to section NAME, or NULL if no such section exists. */
723
724static Elf_Internal_Shdr *
dda8d76d 725find_section (Filedata * filedata, const char * name)
89fac5e3
RS
726{
727 unsigned int i;
728
68807c3c
NC
729 if (filedata->section_headers == NULL)
730 return NULL;
dda8d76d
NC
731
732 for (i = 0; i < filedata->file_header.e_shnum; i++)
733 if (streq (SECTION_NAME (filedata->section_headers + i), name))
734 return filedata->section_headers + i;
89fac5e3
RS
735
736 return NULL;
737}
738
0b6ae522
DJ
739/* Return a pointer to a section containing ADDR, or NULL if no such
740 section exists. */
741
742static Elf_Internal_Shdr *
dda8d76d 743find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
744{
745 unsigned int i;
746
68807c3c
NC
747 if (filedata->section_headers == NULL)
748 return NULL;
749
dda8d76d 750 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 751 {
dda8d76d
NC
752 Elf_Internal_Shdr *sec = filedata->section_headers + i;
753
0b6ae522
DJ
754 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
755 return sec;
756 }
757
758 return NULL;
759}
760
071436c6 761static Elf_Internal_Shdr *
dda8d76d 762find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
763{
764 unsigned int i;
765
68807c3c
NC
766 if (filedata->section_headers == NULL)
767 return NULL;
768
dda8d76d 769 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 770 {
dda8d76d
NC
771 Elf_Internal_Shdr *sec = filedata->section_headers + i;
772
071436c6
NC
773 if (sec->sh_type == type)
774 return sec;
775 }
776
777 return NULL;
778}
779
657d0d47
CC
780/* Return a pointer to section NAME, or NULL if no such section exists,
781 restricted to the list of sections given in SET. */
782
783static Elf_Internal_Shdr *
dda8d76d 784find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
785{
786 unsigned int i;
787
68807c3c
NC
788 if (filedata->section_headers == NULL)
789 return NULL;
790
657d0d47
CC
791 if (set != NULL)
792 {
793 while ((i = *set++) > 0)
b814a36d
NC
794 {
795 /* See PR 21156 for a reproducer. */
dda8d76d 796 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
797 continue; /* FIXME: Should we issue an error message ? */
798
dda8d76d
NC
799 if (streq (SECTION_NAME (filedata->section_headers + i), name))
800 return filedata->section_headers + i;
b814a36d 801 }
657d0d47
CC
802 }
803
dda8d76d 804 return find_section (filedata, name);
657d0d47
CC
805}
806
32ec8896 807/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
808 This OS has so many departures from the ELF standard that we test it at
809 many places. */
810
32ec8896 811static inline bfd_boolean
dda8d76d 812is_ia64_vms (Filedata * filedata)
28f997cf 813{
dda8d76d
NC
814 return filedata->file_header.e_machine == EM_IA_64
815 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
816}
817
bcedfee6 818/* Guess the relocation size commonly used by the specific machines. */
252b5132 819
32ec8896 820static bfd_boolean
2dc4cec1 821guess_is_rela (unsigned int e_machine)
252b5132 822{
9c19a809 823 switch (e_machine)
252b5132
RH
824 {
825 /* Targets that use REL relocations. */
252b5132 826 case EM_386:
22abe556 827 case EM_IAMCU:
f954747f 828 case EM_960:
e9f53129 829 case EM_ARM:
2b0337b0 830 case EM_D10V:
252b5132 831 case EM_CYGNUS_D10V:
e9f53129 832 case EM_DLX:
252b5132 833 case EM_MIPS:
4fe85591 834 case EM_MIPS_RS3_LE:
e9f53129 835 case EM_CYGNUS_M32R:
1c0d3aa6 836 case EM_SCORE:
f6c1a2d5 837 case EM_XGATE:
fe944acf 838 case EM_NFP:
aca4efc7 839 case EM_BPF:
9c19a809 840 return FALSE;
103f02d3 841
252b5132
RH
842 /* Targets that use RELA relocations. */
843 case EM_68K:
f954747f 844 case EM_860:
a06ea964 845 case EM_AARCH64:
cfb8c092 846 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
847 case EM_ALPHA:
848 case EM_ALTERA_NIOS2:
886a2506
NC
849 case EM_ARC:
850 case EM_ARC_COMPACT:
851 case EM_ARC_COMPACT2:
e9f53129
AM
852 case EM_AVR:
853 case EM_AVR_OLD:
854 case EM_BLACKFIN:
60bca95a 855 case EM_CR16:
e9f53129
AM
856 case EM_CRIS:
857 case EM_CRX:
b8891f8d 858 case EM_CSKY:
2b0337b0 859 case EM_D30V:
252b5132 860 case EM_CYGNUS_D30V:
2b0337b0 861 case EM_FR30:
3f8107ab 862 case EM_FT32:
252b5132 863 case EM_CYGNUS_FR30:
5c70f934 864 case EM_CYGNUS_FRV:
e9f53129
AM
865 case EM_H8S:
866 case EM_H8_300:
867 case EM_H8_300H:
800eeca4 868 case EM_IA_64:
1e4cf259
NC
869 case EM_IP2K:
870 case EM_IP2K_OLD:
3b36097d 871 case EM_IQ2000:
84e94c90 872 case EM_LATTICEMICO32:
ff7eeb89 873 case EM_M32C_OLD:
49f58d10 874 case EM_M32C:
e9f53129
AM
875 case EM_M32R:
876 case EM_MCORE:
15ab5209 877 case EM_CYGNUS_MEP:
a3c62988 878 case EM_METAG:
e9f53129
AM
879 case EM_MMIX:
880 case EM_MN10200:
881 case EM_CYGNUS_MN10200:
882 case EM_MN10300:
883 case EM_CYGNUS_MN10300:
5506d11a 884 case EM_MOXIE:
e9f53129
AM
885 case EM_MSP430:
886 case EM_MSP430_OLD:
d031aafb 887 case EM_MT:
35c08157 888 case EM_NDS32:
64fd6348 889 case EM_NIOS32:
73589c9d 890 case EM_OR1K:
e9f53129
AM
891 case EM_PPC64:
892 case EM_PPC:
2b100bb5 893 case EM_TI_PRU:
e23eba97 894 case EM_RISCV:
99c513f6 895 case EM_RL78:
c7927a3c 896 case EM_RX:
e9f53129
AM
897 case EM_S390:
898 case EM_S390_OLD:
899 case EM_SH:
900 case EM_SPARC:
901 case EM_SPARC32PLUS:
902 case EM_SPARCV9:
903 case EM_SPU:
40b36596 904 case EM_TI_C6000:
aa137e4d
NC
905 case EM_TILEGX:
906 case EM_TILEPRO:
708e2187 907 case EM_V800:
e9f53129
AM
908 case EM_V850:
909 case EM_CYGNUS_V850:
910 case EM_VAX:
619ed720 911 case EM_VISIUM:
e9f53129 912 case EM_X86_64:
8a9036a4 913 case EM_L1OM:
7a9068fe 914 case EM_K1OM:
e9f53129
AM
915 case EM_XSTORMY16:
916 case EM_XTENSA:
917 case EM_XTENSA_OLD:
7ba29e2a
NC
918 case EM_MICROBLAZE:
919 case EM_MICROBLAZE_OLD:
f96bd6c2 920 case EM_WEBASSEMBLY:
9c19a809 921 return TRUE;
103f02d3 922
e9f53129
AM
923 case EM_68HC05:
924 case EM_68HC08:
925 case EM_68HC11:
926 case EM_68HC16:
927 case EM_FX66:
928 case EM_ME16:
d1133906 929 case EM_MMA:
d1133906
NC
930 case EM_NCPU:
931 case EM_NDR1:
e9f53129 932 case EM_PCP:
d1133906 933 case EM_ST100:
e9f53129 934 case EM_ST19:
d1133906 935 case EM_ST7:
e9f53129
AM
936 case EM_ST9PLUS:
937 case EM_STARCORE:
d1133906 938 case EM_SVX:
e9f53129 939 case EM_TINYJ:
9c19a809
NC
940 default:
941 warn (_("Don't know about relocations on this machine architecture\n"));
942 return FALSE;
943 }
944}
252b5132 945
dda8d76d 946/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
947 Returns TRUE upon success, FALSE otherwise. If successful then a
948 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
949 and the number of relocs loaded is placed in *NRELASP. It is the caller's
950 responsibility to free the allocated buffer. */
951
952static bfd_boolean
dda8d76d
NC
953slurp_rela_relocs (Filedata * filedata,
954 unsigned long rel_offset,
955 unsigned long rel_size,
956 Elf_Internal_Rela ** relasp,
957 unsigned long * nrelasp)
9c19a809 958{
2cf0635d 959 Elf_Internal_Rela * relas;
8b73c356 960 size_t nrelas;
4d6ed7c8 961 unsigned int i;
252b5132 962
4d6ed7c8
NC
963 if (is_32bit_elf)
964 {
2cf0635d 965 Elf32_External_Rela * erelas;
103f02d3 966
dda8d76d 967 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 968 rel_size, _("32-bit relocation data"));
a6e9f9df 969 if (!erelas)
32ec8896 970 return FALSE;
252b5132 971
4d6ed7c8 972 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 973
3f5e193b
NC
974 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
975 sizeof (Elf_Internal_Rela));
103f02d3 976
4d6ed7c8
NC
977 if (relas == NULL)
978 {
c256ffe7 979 free (erelas);
591a748a 980 error (_("out of memory parsing relocs\n"));
32ec8896 981 return FALSE;
4d6ed7c8 982 }
103f02d3 983
4d6ed7c8
NC
984 for (i = 0; i < nrelas; i++)
985 {
986 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
987 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 988 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 989 }
103f02d3 990
4d6ed7c8
NC
991 free (erelas);
992 }
993 else
994 {
2cf0635d 995 Elf64_External_Rela * erelas;
103f02d3 996
dda8d76d 997 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 998 rel_size, _("64-bit relocation data"));
a6e9f9df 999 if (!erelas)
32ec8896 1000 return FALSE;
4d6ed7c8
NC
1001
1002 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1003
3f5e193b
NC
1004 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1005 sizeof (Elf_Internal_Rela));
103f02d3 1006
4d6ed7c8
NC
1007 if (relas == NULL)
1008 {
c256ffe7 1009 free (erelas);
591a748a 1010 error (_("out of memory parsing relocs\n"));
32ec8896 1011 return FALSE;
9c19a809 1012 }
4d6ed7c8
NC
1013
1014 for (i = 0; i < nrelas; i++)
9c19a809 1015 {
66543521
AM
1016 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1017 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1018 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1019
1020 /* The #ifdef BFD64 below is to prevent a compile time
1021 warning. We know that if we do not have a 64 bit data
1022 type that we will never execute this code anyway. */
1023#ifdef BFD64
dda8d76d
NC
1024 if (filedata->file_header.e_machine == EM_MIPS
1025 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1026 {
1027 /* In little-endian objects, r_info isn't really a
1028 64-bit little-endian value: it has a 32-bit
1029 little-endian symbol index followed by four
1030 individual byte fields. Reorder INFO
1031 accordingly. */
91d6fa6a
NC
1032 bfd_vma inf = relas[i].r_info;
1033 inf = (((inf & 0xffffffff) << 32)
1034 | ((inf >> 56) & 0xff)
1035 | ((inf >> 40) & 0xff00)
1036 | ((inf >> 24) & 0xff0000)
1037 | ((inf >> 8) & 0xff000000));
1038 relas[i].r_info = inf;
861fb55a
DJ
1039 }
1040#endif /* BFD64 */
4d6ed7c8 1041 }
103f02d3 1042
4d6ed7c8
NC
1043 free (erelas);
1044 }
32ec8896 1045
4d6ed7c8
NC
1046 *relasp = relas;
1047 *nrelasp = nrelas;
32ec8896 1048 return TRUE;
4d6ed7c8 1049}
103f02d3 1050
dda8d76d 1051/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1052 Returns TRUE upon success, FALSE otherwise. If successful then a
1053 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1054 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1055 responsibility to free the allocated buffer. */
1056
1057static bfd_boolean
dda8d76d
NC
1058slurp_rel_relocs (Filedata * filedata,
1059 unsigned long rel_offset,
1060 unsigned long rel_size,
1061 Elf_Internal_Rela ** relsp,
1062 unsigned long * nrelsp)
4d6ed7c8 1063{
2cf0635d 1064 Elf_Internal_Rela * rels;
8b73c356 1065 size_t nrels;
4d6ed7c8 1066 unsigned int i;
103f02d3 1067
4d6ed7c8
NC
1068 if (is_32bit_elf)
1069 {
2cf0635d 1070 Elf32_External_Rel * erels;
103f02d3 1071
dda8d76d 1072 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1073 rel_size, _("32-bit relocation data"));
a6e9f9df 1074 if (!erels)
32ec8896 1075 return FALSE;
103f02d3 1076
4d6ed7c8 1077 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1078
3f5e193b 1079 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1080
4d6ed7c8
NC
1081 if (rels == NULL)
1082 {
c256ffe7 1083 free (erels);
591a748a 1084 error (_("out of memory parsing relocs\n"));
32ec8896 1085 return FALSE;
4d6ed7c8
NC
1086 }
1087
1088 for (i = 0; i < nrels; i++)
1089 {
1090 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1091 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1092 rels[i].r_addend = 0;
9ea033b2 1093 }
4d6ed7c8
NC
1094
1095 free (erels);
9c19a809
NC
1096 }
1097 else
1098 {
2cf0635d 1099 Elf64_External_Rel * erels;
9ea033b2 1100
dda8d76d 1101 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1102 rel_size, _("64-bit relocation data"));
a6e9f9df 1103 if (!erels)
32ec8896 1104 return FALSE;
103f02d3 1105
4d6ed7c8 1106 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1107
3f5e193b 1108 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1109
4d6ed7c8 1110 if (rels == NULL)
9c19a809 1111 {
c256ffe7 1112 free (erels);
591a748a 1113 error (_("out of memory parsing relocs\n"));
32ec8896 1114 return FALSE;
4d6ed7c8 1115 }
103f02d3 1116
4d6ed7c8
NC
1117 for (i = 0; i < nrels; i++)
1118 {
66543521
AM
1119 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1120 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1121 rels[i].r_addend = 0;
861fb55a
DJ
1122
1123 /* The #ifdef BFD64 below is to prevent a compile time
1124 warning. We know that if we do not have a 64 bit data
1125 type that we will never execute this code anyway. */
1126#ifdef BFD64
dda8d76d
NC
1127 if (filedata->file_header.e_machine == EM_MIPS
1128 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1129 {
1130 /* In little-endian objects, r_info isn't really a
1131 64-bit little-endian value: it has a 32-bit
1132 little-endian symbol index followed by four
1133 individual byte fields. Reorder INFO
1134 accordingly. */
91d6fa6a
NC
1135 bfd_vma inf = rels[i].r_info;
1136 inf = (((inf & 0xffffffff) << 32)
1137 | ((inf >> 56) & 0xff)
1138 | ((inf >> 40) & 0xff00)
1139 | ((inf >> 24) & 0xff0000)
1140 | ((inf >> 8) & 0xff000000));
1141 rels[i].r_info = inf;
861fb55a
DJ
1142 }
1143#endif /* BFD64 */
4d6ed7c8 1144 }
103f02d3 1145
4d6ed7c8
NC
1146 free (erels);
1147 }
32ec8896 1148
4d6ed7c8
NC
1149 *relsp = rels;
1150 *nrelsp = nrels;
32ec8896 1151 return TRUE;
4d6ed7c8 1152}
103f02d3 1153
aca88567
NC
1154/* Returns the reloc type extracted from the reloc info field. */
1155
1156static unsigned int
dda8d76d 1157get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1158{
1159 if (is_32bit_elf)
1160 return ELF32_R_TYPE (reloc_info);
1161
dda8d76d 1162 switch (filedata->file_header.e_machine)
aca88567
NC
1163 {
1164 case EM_MIPS:
1165 /* Note: We assume that reloc_info has already been adjusted for us. */
1166 return ELF64_MIPS_R_TYPE (reloc_info);
1167
1168 case EM_SPARCV9:
1169 return ELF64_R_TYPE_ID (reloc_info);
1170
1171 default:
1172 return ELF64_R_TYPE (reloc_info);
1173 }
1174}
1175
1176/* Return the symbol index extracted from the reloc info field. */
1177
1178static bfd_vma
1179get_reloc_symindex (bfd_vma reloc_info)
1180{
1181 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1182}
1183
13761a11 1184static inline bfd_boolean
dda8d76d 1185uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1186{
1187 return
dda8d76d 1188 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1189 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1190 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1191 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1192 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1193}
1194
d3ba0551
AM
1195/* Display the contents of the relocation data found at the specified
1196 offset. */
ee42cf8c 1197
32ec8896 1198static bfd_boolean
dda8d76d
NC
1199dump_relocations (Filedata * filedata,
1200 unsigned long rel_offset,
1201 unsigned long rel_size,
1202 Elf_Internal_Sym * symtab,
1203 unsigned long nsyms,
1204 char * strtab,
1205 unsigned long strtablen,
1206 int is_rela,
1207 bfd_boolean is_dynsym)
4d6ed7c8 1208{
32ec8896 1209 unsigned long i;
2cf0635d 1210 Elf_Internal_Rela * rels;
32ec8896 1211 bfd_boolean res = TRUE;
103f02d3 1212
4d6ed7c8 1213 if (is_rela == UNKNOWN)
dda8d76d 1214 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1215
4d6ed7c8
NC
1216 if (is_rela)
1217 {
dda8d76d 1218 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1219 return FALSE;
4d6ed7c8
NC
1220 }
1221 else
1222 {
dda8d76d 1223 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1224 return FALSE;
252b5132
RH
1225 }
1226
410f7a12
L
1227 if (is_32bit_elf)
1228 {
1229 if (is_rela)
2c71103e
NC
1230 {
1231 if (do_wide)
1232 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1233 else
1234 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1235 }
410f7a12 1236 else
2c71103e
NC
1237 {
1238 if (do_wide)
1239 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1240 else
1241 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1242 }
410f7a12 1243 }
252b5132 1244 else
410f7a12
L
1245 {
1246 if (is_rela)
2c71103e
NC
1247 {
1248 if (do_wide)
8beeaeb7 1249 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1250 else
1251 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1252 }
410f7a12 1253 else
2c71103e
NC
1254 {
1255 if (do_wide)
8beeaeb7 1256 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1257 else
1258 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1259 }
410f7a12 1260 }
252b5132
RH
1261
1262 for (i = 0; i < rel_size; i++)
1263 {
2cf0635d 1264 const char * rtype;
b34976b6 1265 bfd_vma offset;
91d6fa6a 1266 bfd_vma inf;
b34976b6
AM
1267 bfd_vma symtab_index;
1268 bfd_vma type;
103f02d3 1269
b34976b6 1270 offset = rels[i].r_offset;
91d6fa6a 1271 inf = rels[i].r_info;
103f02d3 1272
dda8d76d 1273 type = get_reloc_type (filedata, inf);
91d6fa6a 1274 symtab_index = get_reloc_symindex (inf);
252b5132 1275
410f7a12
L
1276 if (is_32bit_elf)
1277 {
39dbeff8
AM
1278 printf ("%8.8lx %8.8lx ",
1279 (unsigned long) offset & 0xffffffff,
91d6fa6a 1280 (unsigned long) inf & 0xffffffff);
410f7a12
L
1281 }
1282 else
1283 {
39dbeff8
AM
1284#if BFD_HOST_64BIT_LONG
1285 printf (do_wide
1286 ? "%16.16lx %16.16lx "
1287 : "%12.12lx %12.12lx ",
91d6fa6a 1288 offset, inf);
39dbeff8 1289#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1290#ifndef __MSVCRT__
39dbeff8
AM
1291 printf (do_wide
1292 ? "%16.16llx %16.16llx "
1293 : "%12.12llx %12.12llx ",
91d6fa6a 1294 offset, inf);
6e3d6dc1
NC
1295#else
1296 printf (do_wide
1297 ? "%16.16I64x %16.16I64x "
1298 : "%12.12I64x %12.12I64x ",
91d6fa6a 1299 offset, inf);
6e3d6dc1 1300#endif
39dbeff8 1301#else
2c71103e
NC
1302 printf (do_wide
1303 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1304 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1305 _bfd_int64_high (offset),
1306 _bfd_int64_low (offset),
91d6fa6a
NC
1307 _bfd_int64_high (inf),
1308 _bfd_int64_low (inf));
9ea033b2 1309#endif
410f7a12 1310 }
103f02d3 1311
dda8d76d 1312 switch (filedata->file_header.e_machine)
252b5132
RH
1313 {
1314 default:
1315 rtype = NULL;
1316 break;
1317
a06ea964
NC
1318 case EM_AARCH64:
1319 rtype = elf_aarch64_reloc_type (type);
1320 break;
1321
2b0337b0 1322 case EM_M32R:
252b5132 1323 case EM_CYGNUS_M32R:
9ea033b2 1324 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1325 break;
1326
1327 case EM_386:
22abe556 1328 case EM_IAMCU:
9ea033b2 1329 rtype = elf_i386_reloc_type (type);
252b5132
RH
1330 break;
1331
ba2685cc
AM
1332 case EM_68HC11:
1333 case EM_68HC12:
1334 rtype = elf_m68hc11_reloc_type (type);
1335 break;
75751cd9 1336
7b4ae824
JD
1337 case EM_S12Z:
1338 rtype = elf_s12z_reloc_type (type);
1339 break;
1340
252b5132 1341 case EM_68K:
9ea033b2 1342 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1343 break;
1344
f954747f
AM
1345 case EM_960:
1346 rtype = elf_i960_reloc_type (type);
1347 break;
1348
adde6300 1349 case EM_AVR:
2b0337b0 1350 case EM_AVR_OLD:
adde6300
AM
1351 rtype = elf_avr_reloc_type (type);
1352 break;
1353
9ea033b2
NC
1354 case EM_OLD_SPARCV9:
1355 case EM_SPARC32PLUS:
1356 case EM_SPARCV9:
252b5132 1357 case EM_SPARC:
9ea033b2 1358 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1359 break;
1360
e9f53129
AM
1361 case EM_SPU:
1362 rtype = elf_spu_reloc_type (type);
1363 break;
1364
708e2187
NC
1365 case EM_V800:
1366 rtype = v800_reloc_type (type);
1367 break;
2b0337b0 1368 case EM_V850:
252b5132 1369 case EM_CYGNUS_V850:
9ea033b2 1370 rtype = v850_reloc_type (type);
252b5132
RH
1371 break;
1372
2b0337b0 1373 case EM_D10V:
252b5132 1374 case EM_CYGNUS_D10V:
9ea033b2 1375 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1376 break;
1377
2b0337b0 1378 case EM_D30V:
252b5132 1379 case EM_CYGNUS_D30V:
9ea033b2 1380 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1381 break;
1382
d172d4ba
NC
1383 case EM_DLX:
1384 rtype = elf_dlx_reloc_type (type);
1385 break;
1386
252b5132 1387 case EM_SH:
9ea033b2 1388 rtype = elf_sh_reloc_type (type);
252b5132
RH
1389 break;
1390
2b0337b0 1391 case EM_MN10300:
252b5132 1392 case EM_CYGNUS_MN10300:
9ea033b2 1393 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1394 break;
1395
2b0337b0 1396 case EM_MN10200:
252b5132 1397 case EM_CYGNUS_MN10200:
9ea033b2 1398 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1399 break;
1400
2b0337b0 1401 case EM_FR30:
252b5132 1402 case EM_CYGNUS_FR30:
9ea033b2 1403 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1404 break;
1405
ba2685cc
AM
1406 case EM_CYGNUS_FRV:
1407 rtype = elf_frv_reloc_type (type);
1408 break;
5c70f934 1409
b8891f8d
AJ
1410 case EM_CSKY:
1411 rtype = elf_csky_reloc_type (type);
1412 break;
1413
3f8107ab
AM
1414 case EM_FT32:
1415 rtype = elf_ft32_reloc_type (type);
1416 break;
1417
252b5132 1418 case EM_MCORE:
9ea033b2 1419 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1420 break;
1421
3c3bdf30
NC
1422 case EM_MMIX:
1423 rtype = elf_mmix_reloc_type (type);
1424 break;
1425
5506d11a
AM
1426 case EM_MOXIE:
1427 rtype = elf_moxie_reloc_type (type);
1428 break;
1429
2469cfa2 1430 case EM_MSP430:
dda8d76d 1431 if (uses_msp430x_relocs (filedata))
13761a11
NC
1432 {
1433 rtype = elf_msp430x_reloc_type (type);
1434 break;
1435 }
1a0670f3 1436 /* Fall through. */
2469cfa2
NC
1437 case EM_MSP430_OLD:
1438 rtype = elf_msp430_reloc_type (type);
1439 break;
1440
35c08157
KLC
1441 case EM_NDS32:
1442 rtype = elf_nds32_reloc_type (type);
1443 break;
1444
252b5132 1445 case EM_PPC:
9ea033b2 1446 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1447 break;
1448
c833c019
AM
1449 case EM_PPC64:
1450 rtype = elf_ppc64_reloc_type (type);
1451 break;
1452
252b5132 1453 case EM_MIPS:
4fe85591 1454 case EM_MIPS_RS3_LE:
9ea033b2 1455 rtype = elf_mips_reloc_type (type);
252b5132
RH
1456 break;
1457
e23eba97
NC
1458 case EM_RISCV:
1459 rtype = elf_riscv_reloc_type (type);
1460 break;
1461
252b5132 1462 case EM_ALPHA:
9ea033b2 1463 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1464 break;
1465
1466 case EM_ARM:
9ea033b2 1467 rtype = elf_arm_reloc_type (type);
252b5132
RH
1468 break;
1469
584da044 1470 case EM_ARC:
886a2506
NC
1471 case EM_ARC_COMPACT:
1472 case EM_ARC_COMPACT2:
9ea033b2 1473 rtype = elf_arc_reloc_type (type);
252b5132
RH
1474 break;
1475
1476 case EM_PARISC:
69e617ca 1477 rtype = elf_hppa_reloc_type (type);
252b5132 1478 break;
7d466069 1479
b8720f9d
JL
1480 case EM_H8_300:
1481 case EM_H8_300H:
1482 case EM_H8S:
1483 rtype = elf_h8_reloc_type (type);
1484 break;
1485
73589c9d
CS
1486 case EM_OR1K:
1487 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1488 break;
1489
7d466069 1490 case EM_PJ:
2b0337b0 1491 case EM_PJ_OLD:
7d466069
ILT
1492 rtype = elf_pj_reloc_type (type);
1493 break;
800eeca4
JW
1494 case EM_IA_64:
1495 rtype = elf_ia64_reloc_type (type);
1496 break;
1b61cf92
HPN
1497
1498 case EM_CRIS:
1499 rtype = elf_cris_reloc_type (type);
1500 break;
535c37ff 1501
f954747f
AM
1502 case EM_860:
1503 rtype = elf_i860_reloc_type (type);
1504 break;
1505
bcedfee6 1506 case EM_X86_64:
8a9036a4 1507 case EM_L1OM:
7a9068fe 1508 case EM_K1OM:
bcedfee6
NC
1509 rtype = elf_x86_64_reloc_type (type);
1510 break;
a85d7ed0 1511
f954747f
AM
1512 case EM_S370:
1513 rtype = i370_reloc_type (type);
1514 break;
1515
53c7db4b
KH
1516 case EM_S390_OLD:
1517 case EM_S390:
1518 rtype = elf_s390_reloc_type (type);
1519 break;
93fbbb04 1520
1c0d3aa6
NC
1521 case EM_SCORE:
1522 rtype = elf_score_reloc_type (type);
1523 break;
1524
93fbbb04
GK
1525 case EM_XSTORMY16:
1526 rtype = elf_xstormy16_reloc_type (type);
1527 break;
179d3252 1528
1fe1f39c
NC
1529 case EM_CRX:
1530 rtype = elf_crx_reloc_type (type);
1531 break;
1532
179d3252
JT
1533 case EM_VAX:
1534 rtype = elf_vax_reloc_type (type);
1535 break;
1e4cf259 1536
619ed720
EB
1537 case EM_VISIUM:
1538 rtype = elf_visium_reloc_type (type);
1539 break;
1540
aca4efc7
JM
1541 case EM_BPF:
1542 rtype = elf_bpf_reloc_type (type);
1543 break;
1544
cfb8c092
NC
1545 case EM_ADAPTEVA_EPIPHANY:
1546 rtype = elf_epiphany_reloc_type (type);
1547 break;
1548
1e4cf259
NC
1549 case EM_IP2K:
1550 case EM_IP2K_OLD:
1551 rtype = elf_ip2k_reloc_type (type);
1552 break;
3b36097d
SC
1553
1554 case EM_IQ2000:
1555 rtype = elf_iq2000_reloc_type (type);
1556 break;
88da6820
NC
1557
1558 case EM_XTENSA_OLD:
1559 case EM_XTENSA:
1560 rtype = elf_xtensa_reloc_type (type);
1561 break;
a34e3ecb 1562
84e94c90
NC
1563 case EM_LATTICEMICO32:
1564 rtype = elf_lm32_reloc_type (type);
1565 break;
1566
ff7eeb89 1567 case EM_M32C_OLD:
49f58d10
JB
1568 case EM_M32C:
1569 rtype = elf_m32c_reloc_type (type);
1570 break;
1571
d031aafb
NS
1572 case EM_MT:
1573 rtype = elf_mt_reloc_type (type);
a34e3ecb 1574 break;
1d65ded4
CM
1575
1576 case EM_BLACKFIN:
1577 rtype = elf_bfin_reloc_type (type);
1578 break;
15ab5209
DB
1579
1580 case EM_CYGNUS_MEP:
1581 rtype = elf_mep_reloc_type (type);
1582 break;
60bca95a
NC
1583
1584 case EM_CR16:
1585 rtype = elf_cr16_reloc_type (type);
1586 break;
dd24e3da 1587
7ba29e2a
NC
1588 case EM_MICROBLAZE:
1589 case EM_MICROBLAZE_OLD:
1590 rtype = elf_microblaze_reloc_type (type);
1591 break;
c7927a3c 1592
99c513f6
DD
1593 case EM_RL78:
1594 rtype = elf_rl78_reloc_type (type);
1595 break;
1596
c7927a3c
NC
1597 case EM_RX:
1598 rtype = elf_rx_reloc_type (type);
1599 break;
c29aca4a 1600
a3c62988
NC
1601 case EM_METAG:
1602 rtype = elf_metag_reloc_type (type);
1603 break;
1604
c29aca4a
NC
1605 case EM_XC16X:
1606 case EM_C166:
1607 rtype = elf_xc16x_reloc_type (type);
1608 break;
40b36596
JM
1609
1610 case EM_TI_C6000:
1611 rtype = elf_tic6x_reloc_type (type);
1612 break;
aa137e4d
NC
1613
1614 case EM_TILEGX:
1615 rtype = elf_tilegx_reloc_type (type);
1616 break;
1617
1618 case EM_TILEPRO:
1619 rtype = elf_tilepro_reloc_type (type);
1620 break;
f6c1a2d5 1621
f96bd6c2
PC
1622 case EM_WEBASSEMBLY:
1623 rtype = elf_wasm32_reloc_type (type);
1624 break;
1625
f6c1a2d5
NC
1626 case EM_XGATE:
1627 rtype = elf_xgate_reloc_type (type);
1628 break;
36591ba1
SL
1629
1630 case EM_ALTERA_NIOS2:
1631 rtype = elf_nios2_reloc_type (type);
1632 break;
2b100bb5
DD
1633
1634 case EM_TI_PRU:
1635 rtype = elf_pru_reloc_type (type);
1636 break;
fe944acf
FT
1637
1638 case EM_NFP:
1639 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1640 rtype = elf_nfp3200_reloc_type (type);
1641 else
1642 rtype = elf_nfp_reloc_type (type);
1643 break;
6655dba2
SB
1644
1645 case EM_Z80:
1646 rtype = elf_z80_reloc_type (type);
1647 break;
252b5132
RH
1648 }
1649
1650 if (rtype == NULL)
39dbeff8 1651 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1652 else
5c144731 1653 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1654
dda8d76d 1655 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1656 && rtype != NULL
7ace3541
RH
1657 && streq (rtype, "R_ALPHA_LITUSE")
1658 && is_rela)
1659 {
1660 switch (rels[i].r_addend)
1661 {
1662 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1663 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1664 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1665 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1666 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1667 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1668 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1669 default: rtype = NULL;
1670 }
32ec8896 1671
7ace3541
RH
1672 if (rtype)
1673 printf (" (%s)", rtype);
1674 else
1675 {
1676 putchar (' ');
1677 printf (_("<unknown addend: %lx>"),
1678 (unsigned long) rels[i].r_addend);
32ec8896 1679 res = FALSE;
7ace3541
RH
1680 }
1681 }
1682 else if (symtab_index)
252b5132 1683 {
af3fc3bc 1684 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1685 {
27a45f42
AS
1686 error (_(" bad symbol index: %08lx in reloc\n"),
1687 (unsigned long) symtab_index);
32ec8896
NC
1688 res = FALSE;
1689 }
af3fc3bc 1690 else
19936277 1691 {
2cf0635d 1692 Elf_Internal_Sym * psym;
bb4d2ac2
L
1693 const char * version_string;
1694 enum versioned_symbol_info sym_info;
1695 unsigned short vna_other;
19936277 1696
af3fc3bc 1697 psym = symtab + symtab_index;
103f02d3 1698
bb4d2ac2 1699 version_string
dda8d76d 1700 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1701 strtab, strtablen,
1702 symtab_index,
1703 psym,
1704 &sym_info,
1705 &vna_other);
1706
af3fc3bc 1707 printf (" ");
171191ba 1708
d8045f23
NC
1709 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1710 {
1711 const char * name;
1712 unsigned int len;
1713 unsigned int width = is_32bit_elf ? 8 : 14;
1714
1715 /* Relocations against GNU_IFUNC symbols do not use the value
1716 of the symbol as the address to relocate against. Instead
1717 they invoke the function named by the symbol and use its
1718 result as the address for relocation.
1719
1720 To indicate this to the user, do not display the value of
1721 the symbol in the "Symbols's Value" field. Instead show
1722 its name followed by () as a hint that the symbol is
1723 invoked. */
1724
1725 if (strtab == NULL
1726 || psym->st_name == 0
1727 || psym->st_name >= strtablen)
1728 name = "??";
1729 else
1730 name = strtab + psym->st_name;
1731
1732 len = print_symbol (width, name);
bb4d2ac2
L
1733 if (version_string)
1734 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1735 version_string);
d8045f23
NC
1736 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1737 }
1738 else
1739 {
1740 print_vma (psym->st_value, LONG_HEX);
171191ba 1741
d8045f23
NC
1742 printf (is_32bit_elf ? " " : " ");
1743 }
103f02d3 1744
af3fc3bc 1745 if (psym->st_name == 0)
f1ef08cb 1746 {
2cf0635d 1747 const char * sec_name = "<null>";
f1ef08cb
AM
1748 char name_buf[40];
1749
1750 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1751 {
dda8d76d
NC
1752 if (psym->st_shndx < filedata->file_header.e_shnum)
1753 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1754 else if (psym->st_shndx == SHN_ABS)
1755 sec_name = "ABS";
1756 else if (psym->st_shndx == SHN_COMMON)
1757 sec_name = "COMMON";
dda8d76d 1758 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1759 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1760 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1761 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1762 sec_name = "SCOMMON";
dda8d76d 1763 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1764 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1765 sec_name = "SUNDEF";
dda8d76d
NC
1766 else if ((filedata->file_header.e_machine == EM_X86_64
1767 || filedata->file_header.e_machine == EM_L1OM
1768 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1769 && psym->st_shndx == SHN_X86_64_LCOMMON)
1770 sec_name = "LARGE_COMMON";
dda8d76d
NC
1771 else if (filedata->file_header.e_machine == EM_IA_64
1772 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1773 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1774 sec_name = "ANSI_COM";
dda8d76d 1775 else if (is_ia64_vms (filedata)
148b93f2
NC
1776 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1777 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1778 else
1779 {
1780 sprintf (name_buf, "<section 0x%x>",
1781 (unsigned int) psym->st_shndx);
1782 sec_name = name_buf;
1783 }
1784 }
1785 print_symbol (22, sec_name);
1786 }
af3fc3bc 1787 else if (strtab == NULL)
d79b3d50 1788 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1789 else if (psym->st_name >= strtablen)
32ec8896 1790 {
27a45f42
AS
1791 error (_("<corrupt string table index: %3ld>\n"),
1792 psym->st_name);
32ec8896
NC
1793 res = FALSE;
1794 }
af3fc3bc 1795 else
bb4d2ac2
L
1796 {
1797 print_symbol (22, strtab + psym->st_name);
1798 if (version_string)
1799 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1800 version_string);
1801 }
103f02d3 1802
af3fc3bc 1803 if (is_rela)
171191ba 1804 {
7360e63f 1805 bfd_vma off = rels[i].r_addend;
171191ba 1806
7360e63f 1807 if ((bfd_signed_vma) off < 0)
598aaa76 1808 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1809 else
598aaa76 1810 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1811 }
19936277 1812 }
252b5132 1813 }
1b228002 1814 else if (is_rela)
f7a99963 1815 {
7360e63f 1816 bfd_vma off = rels[i].r_addend;
e04d7088
L
1817
1818 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1819 if ((bfd_signed_vma) off < 0)
e04d7088
L
1820 printf ("-%" BFD_VMA_FMT "x", - off);
1821 else
1822 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1823 }
252b5132 1824
dda8d76d 1825 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1826 && rtype != NULL
1827 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1828 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1829
252b5132 1830 putchar ('\n');
2c71103e 1831
aca88567 1832#ifdef BFD64
dda8d76d 1833 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1834 {
91d6fa6a
NC
1835 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1836 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1837 const char * rtype2 = elf_mips_reloc_type (type2);
1838 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1839
2c71103e
NC
1840 printf (" Type2: ");
1841
1842 if (rtype2 == NULL)
39dbeff8
AM
1843 printf (_("unrecognized: %-7lx"),
1844 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1845 else
1846 printf ("%-17.17s", rtype2);
1847
18bd398b 1848 printf ("\n Type3: ");
2c71103e
NC
1849
1850 if (rtype3 == NULL)
39dbeff8
AM
1851 printf (_("unrecognized: %-7lx"),
1852 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1853 else
1854 printf ("%-17.17s", rtype3);
1855
53c7db4b 1856 putchar ('\n');
2c71103e 1857 }
aca88567 1858#endif /* BFD64 */
252b5132
RH
1859 }
1860
c8286bd1 1861 free (rels);
32ec8896
NC
1862
1863 return res;
252b5132
RH
1864}
1865
37c18eed
SD
1866static const char *
1867get_aarch64_dynamic_type (unsigned long type)
1868{
1869 switch (type)
1870 {
1871 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1872 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1873 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1874 default:
1875 return NULL;
1876 }
1877}
1878
252b5132 1879static const char *
d3ba0551 1880get_mips_dynamic_type (unsigned long type)
252b5132
RH
1881{
1882 switch (type)
1883 {
1884 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1885 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1886 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1887 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1888 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1889 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1890 case DT_MIPS_MSYM: return "MIPS_MSYM";
1891 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1892 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1893 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1894 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1895 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1896 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1897 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1898 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1899 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1900 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1901 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1902 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1903 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1904 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1905 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1906 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1907 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1908 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1909 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1910 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1911 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1912 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1913 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1914 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1915 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1916 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1917 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1918 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1919 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1920 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1921 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1922 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1923 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1924 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1925 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1926 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1927 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1928 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1929 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1930 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1931 default:
1932 return NULL;
1933 }
1934}
1935
9a097730 1936static const char *
d3ba0551 1937get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1938{
1939 switch (type)
1940 {
1941 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1942 default:
1943 return NULL;
1944 }
103f02d3
UD
1945}
1946
7490d522
AM
1947static const char *
1948get_ppc_dynamic_type (unsigned long type)
1949{
1950 switch (type)
1951 {
a7f2871e 1952 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1953 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1954 default:
1955 return NULL;
1956 }
1957}
1958
f1cb7e17 1959static const char *
d3ba0551 1960get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1961{
1962 switch (type)
1963 {
a7f2871e
AM
1964 case DT_PPC64_GLINK: return "PPC64_GLINK";
1965 case DT_PPC64_OPD: return "PPC64_OPD";
1966 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1967 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1968 default:
1969 return NULL;
1970 }
1971}
1972
103f02d3 1973static const char *
d3ba0551 1974get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1975{
1976 switch (type)
1977 {
1978 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1979 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1980 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1981 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1982 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1983 case DT_HP_PREINIT: return "HP_PREINIT";
1984 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1985 case DT_HP_NEEDED: return "HP_NEEDED";
1986 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1987 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1988 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1989 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1990 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1991 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1992 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1993 case DT_HP_FILTERED: return "HP_FILTERED";
1994 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1995 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1996 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1997 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1998 case DT_PLT: return "PLT";
1999 case DT_PLT_SIZE: return "PLT_SIZE";
2000 case DT_DLT: return "DLT";
2001 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2002 default:
2003 return NULL;
2004 }
2005}
9a097730 2006
ecc51f48 2007static const char *
d3ba0551 2008get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2009{
2010 switch (type)
2011 {
148b93f2
NC
2012 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2013 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2014 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2015 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2016 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2017 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2018 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2019 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2020 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2021 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2022 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2023 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2024 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2025 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2026 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2027 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2028 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2029 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2030 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2031 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2032 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2033 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2034 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2035 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2036 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2037 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2038 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2039 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2040 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2041 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2042 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2043 default:
2044 return NULL;
2045 }
2046}
2047
fd85a6a1
NC
2048static const char *
2049get_solaris_section_type (unsigned long type)
2050{
2051 switch (type)
2052 {
2053 case 0x6fffffee: return "SUNW_ancillary";
2054 case 0x6fffffef: return "SUNW_capchain";
2055 case 0x6ffffff0: return "SUNW_capinfo";
2056 case 0x6ffffff1: return "SUNW_symsort";
2057 case 0x6ffffff2: return "SUNW_tlssort";
2058 case 0x6ffffff3: return "SUNW_LDYNSYM";
2059 case 0x6ffffff4: return "SUNW_dof";
2060 case 0x6ffffff5: return "SUNW_cap";
2061 case 0x6ffffff6: return "SUNW_SIGNATURE";
2062 case 0x6ffffff7: return "SUNW_ANNOTATE";
2063 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2064 case 0x6ffffff9: return "SUNW_DEBUG";
2065 case 0x6ffffffa: return "SUNW_move";
2066 case 0x6ffffffb: return "SUNW_COMDAT";
2067 case 0x6ffffffc: return "SUNW_syminfo";
2068 case 0x6ffffffd: return "SUNW_verdef";
2069 case 0x6ffffffe: return "SUNW_verneed";
2070 case 0x6fffffff: return "SUNW_versym";
2071 case 0x70000000: return "SPARC_GOTDATA";
2072 default: return NULL;
2073 }
2074}
2075
fabcb361
RH
2076static const char *
2077get_alpha_dynamic_type (unsigned long type)
2078{
2079 switch (type)
2080 {
2081 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2082 default: return NULL;
fabcb361
RH
2083 }
2084}
2085
1c0d3aa6
NC
2086static const char *
2087get_score_dynamic_type (unsigned long type)
2088{
2089 switch (type)
2090 {
2091 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2092 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2093 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2094 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2095 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2096 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2097 default: return NULL;
1c0d3aa6
NC
2098 }
2099}
2100
40b36596
JM
2101static const char *
2102get_tic6x_dynamic_type (unsigned long type)
2103{
2104 switch (type)
2105 {
2106 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2107 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2108 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2109 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2110 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2111 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2112 default: return NULL;
40b36596
JM
2113 }
2114}
1c0d3aa6 2115
36591ba1
SL
2116static const char *
2117get_nios2_dynamic_type (unsigned long type)
2118{
2119 switch (type)
2120 {
2121 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2122 default: return NULL;
36591ba1
SL
2123 }
2124}
2125
fd85a6a1
NC
2126static const char *
2127get_solaris_dynamic_type (unsigned long type)
2128{
2129 switch (type)
2130 {
2131 case 0x6000000d: return "SUNW_AUXILIARY";
2132 case 0x6000000e: return "SUNW_RTLDINF";
2133 case 0x6000000f: return "SUNW_FILTER";
2134 case 0x60000010: return "SUNW_CAP";
2135 case 0x60000011: return "SUNW_SYMTAB";
2136 case 0x60000012: return "SUNW_SYMSZ";
2137 case 0x60000013: return "SUNW_SORTENT";
2138 case 0x60000014: return "SUNW_SYMSORT";
2139 case 0x60000015: return "SUNW_SYMSORTSZ";
2140 case 0x60000016: return "SUNW_TLSSORT";
2141 case 0x60000017: return "SUNW_TLSSORTSZ";
2142 case 0x60000018: return "SUNW_CAPINFO";
2143 case 0x60000019: return "SUNW_STRPAD";
2144 case 0x6000001a: return "SUNW_CAPCHAIN";
2145 case 0x6000001b: return "SUNW_LDMACH";
2146 case 0x6000001d: return "SUNW_CAPCHAINENT";
2147 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2148 case 0x60000021: return "SUNW_PARENT";
2149 case 0x60000023: return "SUNW_ASLR";
2150 case 0x60000025: return "SUNW_RELAX";
2151 case 0x60000029: return "SUNW_NXHEAP";
2152 case 0x6000002b: return "SUNW_NXSTACK";
2153
2154 case 0x70000001: return "SPARC_REGISTER";
2155 case 0x7ffffffd: return "AUXILIARY";
2156 case 0x7ffffffe: return "USED";
2157 case 0x7fffffff: return "FILTER";
2158
15f205b1 2159 default: return NULL;
fd85a6a1
NC
2160 }
2161}
2162
252b5132 2163static const char *
dda8d76d 2164get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2165{
e9e44622 2166 static char buff[64];
252b5132
RH
2167
2168 switch (type)
2169 {
2170 case DT_NULL: return "NULL";
2171 case DT_NEEDED: return "NEEDED";
2172 case DT_PLTRELSZ: return "PLTRELSZ";
2173 case DT_PLTGOT: return "PLTGOT";
2174 case DT_HASH: return "HASH";
2175 case DT_STRTAB: return "STRTAB";
2176 case DT_SYMTAB: return "SYMTAB";
2177 case DT_RELA: return "RELA";
2178 case DT_RELASZ: return "RELASZ";
2179 case DT_RELAENT: return "RELAENT";
2180 case DT_STRSZ: return "STRSZ";
2181 case DT_SYMENT: return "SYMENT";
2182 case DT_INIT: return "INIT";
2183 case DT_FINI: return "FINI";
2184 case DT_SONAME: return "SONAME";
2185 case DT_RPATH: return "RPATH";
2186 case DT_SYMBOLIC: return "SYMBOLIC";
2187 case DT_REL: return "REL";
2188 case DT_RELSZ: return "RELSZ";
2189 case DT_RELENT: return "RELENT";
2190 case DT_PLTREL: return "PLTREL";
2191 case DT_DEBUG: return "DEBUG";
2192 case DT_TEXTREL: return "TEXTREL";
2193 case DT_JMPREL: return "JMPREL";
2194 case DT_BIND_NOW: return "BIND_NOW";
2195 case DT_INIT_ARRAY: return "INIT_ARRAY";
2196 case DT_FINI_ARRAY: return "FINI_ARRAY";
2197 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2198 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2199 case DT_RUNPATH: return "RUNPATH";
2200 case DT_FLAGS: return "FLAGS";
2d0e6f43 2201
d1133906
NC
2202 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2203 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2204 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2205
05107a46 2206 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2207 case DT_PLTPADSZ: return "PLTPADSZ";
2208 case DT_MOVEENT: return "MOVEENT";
2209 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2210 case DT_FEATURE: return "FEATURE";
252b5132
RH
2211 case DT_POSFLAG_1: return "POSFLAG_1";
2212 case DT_SYMINSZ: return "SYMINSZ";
2213 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2214
252b5132 2215 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2216 case DT_CONFIG: return "CONFIG";
2217 case DT_DEPAUDIT: return "DEPAUDIT";
2218 case DT_AUDIT: return "AUDIT";
2219 case DT_PLTPAD: return "PLTPAD";
2220 case DT_MOVETAB: return "MOVETAB";
252b5132 2221 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2222
252b5132 2223 case DT_VERSYM: return "VERSYM";
103f02d3 2224
67a4f2b7
AO
2225 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2226 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2227 case DT_RELACOUNT: return "RELACOUNT";
2228 case DT_RELCOUNT: return "RELCOUNT";
2229 case DT_FLAGS_1: return "FLAGS_1";
2230 case DT_VERDEF: return "VERDEF";
2231 case DT_VERDEFNUM: return "VERDEFNUM";
2232 case DT_VERNEED: return "VERNEED";
2233 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2234
019148e4 2235 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2236 case DT_USED: return "USED";
2237 case DT_FILTER: return "FILTER";
103f02d3 2238
047b2264
JJ
2239 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2240 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2241 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2242 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2243 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2244 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2245
252b5132
RH
2246 default:
2247 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2248 {
2cf0635d 2249 const char * result;
103f02d3 2250
dda8d76d 2251 switch (filedata->file_header.e_machine)
252b5132 2252 {
37c18eed
SD
2253 case EM_AARCH64:
2254 result = get_aarch64_dynamic_type (type);
2255 break;
252b5132 2256 case EM_MIPS:
4fe85591 2257 case EM_MIPS_RS3_LE:
252b5132
RH
2258 result = get_mips_dynamic_type (type);
2259 break;
9a097730
RH
2260 case EM_SPARCV9:
2261 result = get_sparc64_dynamic_type (type);
2262 break;
7490d522
AM
2263 case EM_PPC:
2264 result = get_ppc_dynamic_type (type);
2265 break;
f1cb7e17
AM
2266 case EM_PPC64:
2267 result = get_ppc64_dynamic_type (type);
2268 break;
ecc51f48
NC
2269 case EM_IA_64:
2270 result = get_ia64_dynamic_type (type);
2271 break;
fabcb361
RH
2272 case EM_ALPHA:
2273 result = get_alpha_dynamic_type (type);
2274 break;
1c0d3aa6
NC
2275 case EM_SCORE:
2276 result = get_score_dynamic_type (type);
2277 break;
40b36596
JM
2278 case EM_TI_C6000:
2279 result = get_tic6x_dynamic_type (type);
2280 break;
36591ba1
SL
2281 case EM_ALTERA_NIOS2:
2282 result = get_nios2_dynamic_type (type);
2283 break;
252b5132 2284 default:
dda8d76d 2285 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2286 result = get_solaris_dynamic_type (type);
2287 else
2288 result = NULL;
252b5132
RH
2289 break;
2290 }
2291
2292 if (result != NULL)
2293 return result;
2294
e9e44622 2295 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2296 }
eec8f817 2297 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2298 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2299 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2300 {
2cf0635d 2301 const char * result;
103f02d3 2302
dda8d76d 2303 switch (filedata->file_header.e_machine)
103f02d3
UD
2304 {
2305 case EM_PARISC:
2306 result = get_parisc_dynamic_type (type);
2307 break;
148b93f2
NC
2308 case EM_IA_64:
2309 result = get_ia64_dynamic_type (type);
2310 break;
103f02d3 2311 default:
dda8d76d 2312 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2313 result = get_solaris_dynamic_type (type);
2314 else
2315 result = NULL;
103f02d3
UD
2316 break;
2317 }
2318
2319 if (result != NULL)
2320 return result;
2321
e9e44622
JJ
2322 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2323 type);
103f02d3 2324 }
252b5132 2325 else
e9e44622 2326 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2327
252b5132
RH
2328 return buff;
2329 }
2330}
2331
2332static char *
d3ba0551 2333get_file_type (unsigned e_type)
252b5132 2334{
89246a0e 2335 static char buff[64];
252b5132
RH
2336
2337 switch (e_type)
2338 {
32ec8896
NC
2339 case ET_NONE: return _("NONE (None)");
2340 case ET_REL: return _("REL (Relocatable file)");
2341 case ET_EXEC: return _("EXEC (Executable file)");
2342 case ET_DYN: return _("DYN (Shared object file)");
2343 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2344
2345 default:
2346 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2347 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2348 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2349 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2350 else
e9e44622 2351 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2352 return buff;
2353 }
2354}
2355
2356static char *
d3ba0551 2357get_machine_name (unsigned e_machine)
252b5132 2358{
b34976b6 2359 static char buff[64]; /* XXX */
252b5132
RH
2360
2361 switch (e_machine)
2362 {
55e22ca8
NC
2363 /* Please keep this switch table sorted by increasing EM_ value. */
2364 /* 0 */
c45021f2
NC
2365 case EM_NONE: return _("None");
2366 case EM_M32: return "WE32100";
2367 case EM_SPARC: return "Sparc";
2368 case EM_386: return "Intel 80386";
2369 case EM_68K: return "MC68000";
2370 case EM_88K: return "MC88000";
22abe556 2371 case EM_IAMCU: return "Intel MCU";
fb70ec17 2372 case EM_860: return "Intel 80860";
c45021f2
NC
2373 case EM_MIPS: return "MIPS R3000";
2374 case EM_S370: return "IBM System/370";
55e22ca8 2375 /* 10 */
7036c0e1 2376 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2377 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2378 case EM_PARISC: return "HPPA";
55e22ca8 2379 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2380 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2381 case EM_960: return "Intel 80960";
c45021f2 2382 case EM_PPC: return "PowerPC";
55e22ca8 2383 /* 20 */
285d1771 2384 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2385 case EM_S390_OLD:
2386 case EM_S390: return "IBM S/390";
2387 case EM_SPU: return "SPU";
2388 /* 30 */
2389 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2390 case EM_FR20: return "Fujitsu FR20";
2391 case EM_RH32: return "TRW RH32";
b34976b6 2392 case EM_MCORE: return "MCORE";
55e22ca8 2393 /* 40 */
7036c0e1
AJ
2394 case EM_ARM: return "ARM";
2395 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2396 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2397 case EM_SPARCV9: return "Sparc v9";
2398 case EM_TRICORE: return "Siemens Tricore";
584da044 2399 case EM_ARC: return "ARC";
c2dcd04e
NC
2400 case EM_H8_300: return "Renesas H8/300";
2401 case EM_H8_300H: return "Renesas H8/300H";
2402 case EM_H8S: return "Renesas H8S";
2403 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2404 /* 50 */
30800947 2405 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2406 case EM_MIPS_X: return "Stanford MIPS-X";
2407 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2408 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2409 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2410 case EM_PCP: return "Siemens PCP";
2411 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2412 case EM_NDR1: return "Denso NDR1 microprocesspr";
2413 case EM_STARCORE: return "Motorola Star*Core processor";
2414 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2415 /* 60 */
7036c0e1
AJ
2416 case EM_ST100: return "STMicroelectronics ST100 processor";
2417 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2418 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2419 case EM_PDSP: return "Sony DSP processor";
2420 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2421 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2422 case EM_FX66: return "Siemens FX66 microcontroller";
2423 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2424 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2425 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2426 /* 70 */
7036c0e1
AJ
2427 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2428 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2429 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2430 case EM_SVX: return "Silicon Graphics SVx";
2431 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2432 case EM_VAX: return "Digital VAX";
1b61cf92 2433 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2434 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2435 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2436 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2437 /* 80 */
b34976b6 2438 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2439 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2440 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2441 case EM_AVR_OLD:
2442 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2443 case EM_CYGNUS_FR30:
2444 case EM_FR30: return "Fujitsu FR30";
2445 case EM_CYGNUS_D10V:
2446 case EM_D10V: return "d10v";
2447 case EM_CYGNUS_D30V:
2448 case EM_D30V: return "d30v";
2449 case EM_CYGNUS_V850:
2450 case EM_V850: return "Renesas V850";
2451 case EM_CYGNUS_M32R:
2452 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2453 case EM_CYGNUS_MN10300:
2454 case EM_MN10300: return "mn10300";
2455 /* 90 */
2456 case EM_CYGNUS_MN10200:
2457 case EM_MN10200: return "mn10200";
2458 case EM_PJ: return "picoJava";
73589c9d 2459 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2460 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2461 case EM_XTENSA_OLD:
2462 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2463 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2464 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2465 case EM_NS32K: return "National Semiconductor 32000 series";
2466 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2467 case EM_SNP1K: return "Trebia SNP 1000 processor";
2468 /* 100 */
9abca702 2469 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2470 case EM_IP2K_OLD:
2471 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2472 case EM_MAX: return "MAX Processor";
2473 case EM_CR: return "National Semiconductor CompactRISC";
2474 case EM_F2MC16: return "Fujitsu F2MC16";
2475 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2476 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2477 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2478 case EM_SEP: return "Sharp embedded microprocessor";
2479 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2480 /* 110 */
11636f9e
JM
2481 case EM_UNICORE: return "Unicore";
2482 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2483 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2484 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2485 case EM_CRX: return "National Semiconductor CRX microprocessor";
2486 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2487 case EM_C166:
d70c5fc7 2488 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2489 case EM_M16C: return "Renesas M16C series microprocessors";
2490 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2491 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2492 /* 120 */
2493 case EM_M32C: return "Renesas M32c";
2494 /* 130 */
11636f9e
JM
2495 case EM_TSK3000: return "Altium TSK3000 core";
2496 case EM_RS08: return "Freescale RS08 embedded processor";
2497 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2498 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2499 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2500 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2501 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2502 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2503 /* 140 */
11636f9e
JM
2504 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2505 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2506 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2507 case EM_TI_PRU: return "TI PRU I/O processor";
2508 /* 160 */
11636f9e
JM
2509 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2510 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2511 case EM_R32C: return "Renesas R32C series microprocessors";
2512 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2513 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2514 case EM_8051: return "Intel 8051 and variants";
2515 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2516 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2517 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2518 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2519 /* 170 */
11636f9e
JM
2520 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2521 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2522 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2523 case EM_RX: return "Renesas RX";
a3c62988 2524 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2525 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2526 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2527 case EM_CR16:
2528 case EM_MICROBLAZE:
2529 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2530 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2531 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2532 /* 180 */
2533 case EM_L1OM: return "Intel L1OM";
2534 case EM_K1OM: return "Intel K1OM";
2535 case EM_INTEL182: return "Intel (reserved)";
2536 case EM_AARCH64: return "AArch64";
2537 case EM_ARM184: return "ARM (reserved)";
2538 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2539 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2540 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2541 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2542 /* 190 */
11636f9e 2543 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2544 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2545 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2546 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2547 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2548 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2549 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2550 case EM_RL78: return "Renesas RL78";
6d913794 2551 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2552 case EM_78K0R: return "Renesas 78K0R";
2553 /* 200 */
6d913794 2554 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2555 case EM_BA1: return "Beyond BA1 CPU architecture";
2556 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2557 case EM_XCORE: return "XMOS xCORE processor family";
2558 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2559 /* 210 */
6d913794
NC
2560 case EM_KM32: return "KM211 KM32 32-bit processor";
2561 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2562 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2563 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2564 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2565 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2566 case EM_COGE: return "Cognitive Smart Memory Processor";
2567 case EM_COOL: return "Bluechip Systems CoolEngine";
2568 case EM_NORC: return "Nanoradio Optimized RISC";
2569 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2570 /* 220 */
15f205b1 2571 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2572 case EM_VISIUM: return "CDS VISIUMcore processor";
2573 case EM_FT32: return "FTDI Chip FT32";
2574 case EM_MOXIE: return "Moxie";
2575 case EM_AMDGPU: return "AMD GPU";
2576 case EM_RISCV: return "RISC-V";
2577 case EM_LANAI: return "Lanai 32-bit processor";
2578 case EM_BPF: return "Linux BPF";
fe944acf 2579 case EM_NFP: return "Netronome Flow Processor";
55e22ca8
NC
2580
2581 /* Large numbers... */
2582 case EM_MT: return "Morpho Techologies MT processor";
2583 case EM_ALPHA: return "Alpha";
2584 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2585 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2586 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2587 case EM_IQ2000: return "Vitesse IQ2000";
2588 case EM_M32C_OLD:
2589 case EM_NIOS32: return "Altera Nios";
2590 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2591 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2592 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2593 case EM_S12Z: return "Freescale S12Z";
b8891f8d 2594 case EM_CSKY: return "C-SKY";
55e22ca8 2595
252b5132 2596 default:
35d9dd2f 2597 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2598 return buff;
2599 }
2600}
2601
a9522a21
AB
2602static void
2603decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2604{
2605 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2606 other compilers don't a specific architecture type in the e_flags, and
2607 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2608 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2609 architectures.
2610
2611 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2612 but also sets a specific architecture type in the e_flags field.
2613
2614 However, when decoding the flags we don't worry if we see an
2615 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2616 ARCEM architecture type. */
2617
2618 switch (e_flags & EF_ARC_MACH_MSK)
2619 {
2620 /* We only expect these to occur for EM_ARC_COMPACT2. */
2621 case EF_ARC_CPU_ARCV2EM:
2622 strcat (buf, ", ARC EM");
2623 break;
2624 case EF_ARC_CPU_ARCV2HS:
2625 strcat (buf, ", ARC HS");
2626 break;
2627
2628 /* We only expect these to occur for EM_ARC_COMPACT. */
2629 case E_ARC_MACH_ARC600:
2630 strcat (buf, ", ARC600");
2631 break;
2632 case E_ARC_MACH_ARC601:
2633 strcat (buf, ", ARC601");
2634 break;
2635 case E_ARC_MACH_ARC700:
2636 strcat (buf, ", ARC700");
2637 break;
2638
2639 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2640 new ELF with new architecture being read by an old version of
2641 readelf, or (c) An ELF built with non-GNU compiler that does not
2642 set the architecture in the e_flags. */
2643 default:
2644 if (e_machine == EM_ARC_COMPACT)
2645 strcat (buf, ", Unknown ARCompact");
2646 else
2647 strcat (buf, ", Unknown ARC");
2648 break;
2649 }
2650
2651 switch (e_flags & EF_ARC_OSABI_MSK)
2652 {
2653 case E_ARC_OSABI_ORIG:
2654 strcat (buf, ", (ABI:legacy)");
2655 break;
2656 case E_ARC_OSABI_V2:
2657 strcat (buf, ", (ABI:v2)");
2658 break;
2659 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2660 case E_ARC_OSABI_V3:
2661 strcat (buf, ", v3 no-legacy-syscalls ABI");
2662 break;
53a346d8
CZ
2663 case E_ARC_OSABI_V4:
2664 strcat (buf, ", v4 ABI");
2665 break;
a9522a21
AB
2666 default:
2667 strcat (buf, ", unrecognised ARC OSABI flag");
2668 break;
2669 }
2670}
2671
f3485b74 2672static void
d3ba0551 2673decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2674{
2675 unsigned eabi;
32ec8896 2676 bfd_boolean unknown = FALSE;
f3485b74
NC
2677
2678 eabi = EF_ARM_EABI_VERSION (e_flags);
2679 e_flags &= ~ EF_ARM_EABIMASK;
2680
2681 /* Handle "generic" ARM flags. */
2682 if (e_flags & EF_ARM_RELEXEC)
2683 {
2684 strcat (buf, ", relocatable executable");
2685 e_flags &= ~ EF_ARM_RELEXEC;
2686 }
76da6bbe 2687
18a20338
CL
2688 if (e_flags & EF_ARM_PIC)
2689 {
2690 strcat (buf, ", position independent");
2691 e_flags &= ~ EF_ARM_PIC;
2692 }
2693
f3485b74
NC
2694 /* Now handle EABI specific flags. */
2695 switch (eabi)
2696 {
2697 default:
2c71103e 2698 strcat (buf, ", <unrecognized EABI>");
f3485b74 2699 if (e_flags)
32ec8896 2700 unknown = TRUE;
f3485b74
NC
2701 break;
2702
2703 case EF_ARM_EABI_VER1:
a5bcd848 2704 strcat (buf, ", Version1 EABI");
f3485b74
NC
2705 while (e_flags)
2706 {
2707 unsigned flag;
76da6bbe 2708
f3485b74
NC
2709 /* Process flags one bit at a time. */
2710 flag = e_flags & - e_flags;
2711 e_flags &= ~ flag;
76da6bbe 2712
f3485b74
NC
2713 switch (flag)
2714 {
a5bcd848 2715 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2716 strcat (buf, ", sorted symbol tables");
2717 break;
76da6bbe 2718
f3485b74 2719 default:
32ec8896 2720 unknown = TRUE;
f3485b74
NC
2721 break;
2722 }
2723 }
2724 break;
76da6bbe 2725
a5bcd848
PB
2726 case EF_ARM_EABI_VER2:
2727 strcat (buf, ", Version2 EABI");
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_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2739 strcat (buf, ", sorted symbol tables");
2740 break;
2741
2742 case EF_ARM_DYNSYMSUSESEGIDX:
2743 strcat (buf, ", dynamic symbols use segment index");
2744 break;
2745
2746 case EF_ARM_MAPSYMSFIRST:
2747 strcat (buf, ", mapping symbols precede others");
2748 break;
2749
2750 default:
32ec8896 2751 unknown = TRUE;
a5bcd848
PB
2752 break;
2753 }
2754 }
2755 break;
2756
d507cf36
PB
2757 case EF_ARM_EABI_VER3:
2758 strcat (buf, ", Version3 EABI");
8cb51566
PB
2759 break;
2760
2761 case EF_ARM_EABI_VER4:
2762 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2763 while (e_flags)
2764 {
2765 unsigned flag;
2766
2767 /* Process flags one bit at a time. */
2768 flag = e_flags & - e_flags;
2769 e_flags &= ~ flag;
2770
2771 switch (flag)
2772 {
2773 case EF_ARM_BE8:
2774 strcat (buf, ", BE8");
2775 break;
2776
2777 case EF_ARM_LE8:
2778 strcat (buf, ", LE8");
2779 break;
2780
2781 default:
32ec8896 2782 unknown = TRUE;
3bfcb652
NC
2783 break;
2784 }
3bfcb652
NC
2785 }
2786 break;
3a4a14e9
PB
2787
2788 case EF_ARM_EABI_VER5:
2789 strcat (buf, ", Version5 EABI");
d507cf36
PB
2790 while (e_flags)
2791 {
2792 unsigned flag;
2793
2794 /* Process flags one bit at a time. */
2795 flag = e_flags & - e_flags;
2796 e_flags &= ~ flag;
2797
2798 switch (flag)
2799 {
2800 case EF_ARM_BE8:
2801 strcat (buf, ", BE8");
2802 break;
2803
2804 case EF_ARM_LE8:
2805 strcat (buf, ", LE8");
2806 break;
2807
3bfcb652
NC
2808 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2809 strcat (buf, ", soft-float ABI");
2810 break;
2811
2812 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2813 strcat (buf, ", hard-float ABI");
2814 break;
2815
d507cf36 2816 default:
32ec8896 2817 unknown = TRUE;
d507cf36
PB
2818 break;
2819 }
2820 }
2821 break;
2822
f3485b74 2823 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2824 strcat (buf, ", GNU EABI");
f3485b74
NC
2825 while (e_flags)
2826 {
2827 unsigned flag;
76da6bbe 2828
f3485b74
NC
2829 /* Process flags one bit at a time. */
2830 flag = e_flags & - e_flags;
2831 e_flags &= ~ flag;
76da6bbe 2832
f3485b74
NC
2833 switch (flag)
2834 {
a5bcd848 2835 case EF_ARM_INTERWORK:
f3485b74
NC
2836 strcat (buf, ", interworking enabled");
2837 break;
76da6bbe 2838
a5bcd848 2839 case EF_ARM_APCS_26:
f3485b74
NC
2840 strcat (buf, ", uses APCS/26");
2841 break;
76da6bbe 2842
a5bcd848 2843 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2844 strcat (buf, ", uses APCS/float");
2845 break;
76da6bbe 2846
a5bcd848 2847 case EF_ARM_PIC:
f3485b74
NC
2848 strcat (buf, ", position independent");
2849 break;
76da6bbe 2850
a5bcd848 2851 case EF_ARM_ALIGN8:
f3485b74
NC
2852 strcat (buf, ", 8 bit structure alignment");
2853 break;
76da6bbe 2854
a5bcd848 2855 case EF_ARM_NEW_ABI:
f3485b74
NC
2856 strcat (buf, ", uses new ABI");
2857 break;
76da6bbe 2858
a5bcd848 2859 case EF_ARM_OLD_ABI:
f3485b74
NC
2860 strcat (buf, ", uses old ABI");
2861 break;
76da6bbe 2862
a5bcd848 2863 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2864 strcat (buf, ", software FP");
2865 break;
76da6bbe 2866
90e01f86
ILT
2867 case EF_ARM_VFP_FLOAT:
2868 strcat (buf, ", VFP");
2869 break;
2870
fde78edd
NC
2871 case EF_ARM_MAVERICK_FLOAT:
2872 strcat (buf, ", Maverick FP");
2873 break;
2874
f3485b74 2875 default:
32ec8896 2876 unknown = TRUE;
f3485b74
NC
2877 break;
2878 }
2879 }
2880 }
f3485b74
NC
2881
2882 if (unknown)
2b692964 2883 strcat (buf,_(", <unknown>"));
f3485b74
NC
2884}
2885
343433df
AB
2886static void
2887decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2888{
2889 --size; /* Leave space for null terminator. */
2890
2891 switch (e_flags & EF_AVR_MACH)
2892 {
2893 case E_AVR_MACH_AVR1:
2894 strncat (buf, ", avr:1", size);
2895 break;
2896 case E_AVR_MACH_AVR2:
2897 strncat (buf, ", avr:2", size);
2898 break;
2899 case E_AVR_MACH_AVR25:
2900 strncat (buf, ", avr:25", size);
2901 break;
2902 case E_AVR_MACH_AVR3:
2903 strncat (buf, ", avr:3", size);
2904 break;
2905 case E_AVR_MACH_AVR31:
2906 strncat (buf, ", avr:31", size);
2907 break;
2908 case E_AVR_MACH_AVR35:
2909 strncat (buf, ", avr:35", size);
2910 break;
2911 case E_AVR_MACH_AVR4:
2912 strncat (buf, ", avr:4", size);
2913 break;
2914 case E_AVR_MACH_AVR5:
2915 strncat (buf, ", avr:5", size);
2916 break;
2917 case E_AVR_MACH_AVR51:
2918 strncat (buf, ", avr:51", size);
2919 break;
2920 case E_AVR_MACH_AVR6:
2921 strncat (buf, ", avr:6", size);
2922 break;
2923 case E_AVR_MACH_AVRTINY:
2924 strncat (buf, ", avr:100", size);
2925 break;
2926 case E_AVR_MACH_XMEGA1:
2927 strncat (buf, ", avr:101", size);
2928 break;
2929 case E_AVR_MACH_XMEGA2:
2930 strncat (buf, ", avr:102", size);
2931 break;
2932 case E_AVR_MACH_XMEGA3:
2933 strncat (buf, ", avr:103", size);
2934 break;
2935 case E_AVR_MACH_XMEGA4:
2936 strncat (buf, ", avr:104", size);
2937 break;
2938 case E_AVR_MACH_XMEGA5:
2939 strncat (buf, ", avr:105", size);
2940 break;
2941 case E_AVR_MACH_XMEGA6:
2942 strncat (buf, ", avr:106", size);
2943 break;
2944 case E_AVR_MACH_XMEGA7:
2945 strncat (buf, ", avr:107", size);
2946 break;
2947 default:
2948 strncat (buf, ", avr:<unknown>", size);
2949 break;
2950 }
2951
2952 size -= strlen (buf);
2953 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2954 strncat (buf, ", link-relax", size);
2955}
2956
35c08157
KLC
2957static void
2958decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2959{
2960 unsigned abi;
2961 unsigned arch;
2962 unsigned config;
2963 unsigned version;
32ec8896
NC
2964 bfd_boolean has_fpu = FALSE;
2965 unsigned int r = 0;
35c08157
KLC
2966
2967 static const char *ABI_STRINGS[] =
2968 {
2969 "ABI v0", /* use r5 as return register; only used in N1213HC */
2970 "ABI v1", /* use r0 as return register */
2971 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2972 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2973 "AABI",
2974 "ABI2 FP+"
35c08157
KLC
2975 };
2976 static const char *VER_STRINGS[] =
2977 {
2978 "Andes ELF V1.3 or older",
2979 "Andes ELF V1.3.1",
2980 "Andes ELF V1.4"
2981 };
2982 static const char *ARCH_STRINGS[] =
2983 {
2984 "",
2985 "Andes Star v1.0",
2986 "Andes Star v2.0",
2987 "Andes Star v3.0",
2988 "Andes Star v3.0m"
2989 };
2990
2991 abi = EF_NDS_ABI & e_flags;
2992 arch = EF_NDS_ARCH & e_flags;
2993 config = EF_NDS_INST & e_flags;
2994 version = EF_NDS32_ELF_VERSION & e_flags;
2995
2996 memset (buf, 0, size);
2997
2998 switch (abi)
2999 {
3000 case E_NDS_ABI_V0:
3001 case E_NDS_ABI_V1:
3002 case E_NDS_ABI_V2:
3003 case E_NDS_ABI_V2FP:
3004 case E_NDS_ABI_AABI:
40c7a7cb 3005 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3006 /* In case there are holes in the array. */
3007 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3008 break;
3009
3010 default:
3011 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3012 break;
3013 }
3014
3015 switch (version)
3016 {
3017 case E_NDS32_ELF_VER_1_2:
3018 case E_NDS32_ELF_VER_1_3:
3019 case E_NDS32_ELF_VER_1_4:
3020 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3021 break;
3022
3023 default:
3024 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3025 break;
3026 }
3027
3028 if (E_NDS_ABI_V0 == abi)
3029 {
3030 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3031 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3032 if (arch == E_NDS_ARCH_STAR_V1_0)
3033 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3034 return;
3035 }
3036
3037 switch (arch)
3038 {
3039 case E_NDS_ARCH_STAR_V1_0:
3040 case E_NDS_ARCH_STAR_V2_0:
3041 case E_NDS_ARCH_STAR_V3_0:
3042 case E_NDS_ARCH_STAR_V3_M:
3043 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3044 break;
3045
3046 default:
3047 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3048 /* ARCH version determines how the e_flags are interpreted.
3049 If it is unknown, we cannot proceed. */
3050 return;
3051 }
3052
3053 /* Newer ABI; Now handle architecture specific flags. */
3054 if (arch == E_NDS_ARCH_STAR_V1_0)
3055 {
3056 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3057 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3058
3059 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3060 r += snprintf (buf + r, size -r, ", MAC");
3061
3062 if (config & E_NDS32_HAS_DIV_INST)
3063 r += snprintf (buf + r, size -r, ", DIV");
3064
3065 if (config & E_NDS32_HAS_16BIT_INST)
3066 r += snprintf (buf + r, size -r, ", 16b");
3067 }
3068 else
3069 {
3070 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3071 {
3072 if (version <= E_NDS32_ELF_VER_1_3)
3073 r += snprintf (buf + r, size -r, ", [B8]");
3074 else
3075 r += snprintf (buf + r, size -r, ", EX9");
3076 }
3077
3078 if (config & E_NDS32_HAS_MAC_DX_INST)
3079 r += snprintf (buf + r, size -r, ", MAC_DX");
3080
3081 if (config & E_NDS32_HAS_DIV_DX_INST)
3082 r += snprintf (buf + r, size -r, ", DIV_DX");
3083
3084 if (config & E_NDS32_HAS_16BIT_INST)
3085 {
3086 if (version <= E_NDS32_ELF_VER_1_3)
3087 r += snprintf (buf + r, size -r, ", 16b");
3088 else
3089 r += snprintf (buf + r, size -r, ", IFC");
3090 }
3091 }
3092
3093 if (config & E_NDS32_HAS_EXT_INST)
3094 r += snprintf (buf + r, size -r, ", PERF1");
3095
3096 if (config & E_NDS32_HAS_EXT2_INST)
3097 r += snprintf (buf + r, size -r, ", PERF2");
3098
3099 if (config & E_NDS32_HAS_FPU_INST)
3100 {
32ec8896 3101 has_fpu = TRUE;
35c08157
KLC
3102 r += snprintf (buf + r, size -r, ", FPU_SP");
3103 }
3104
3105 if (config & E_NDS32_HAS_FPU_DP_INST)
3106 {
32ec8896 3107 has_fpu = TRUE;
35c08157
KLC
3108 r += snprintf (buf + r, size -r, ", FPU_DP");
3109 }
3110
3111 if (config & E_NDS32_HAS_FPU_MAC_INST)
3112 {
32ec8896 3113 has_fpu = TRUE;
35c08157
KLC
3114 r += snprintf (buf + r, size -r, ", FPU_MAC");
3115 }
3116
3117 if (has_fpu)
3118 {
3119 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3120 {
3121 case E_NDS32_FPU_REG_8SP_4DP:
3122 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3123 break;
3124 case E_NDS32_FPU_REG_16SP_8DP:
3125 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3126 break;
3127 case E_NDS32_FPU_REG_32SP_16DP:
3128 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3129 break;
3130 case E_NDS32_FPU_REG_32SP_32DP:
3131 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3132 break;
3133 }
3134 }
3135
3136 if (config & E_NDS32_HAS_AUDIO_INST)
3137 r += snprintf (buf + r, size -r, ", AUDIO");
3138
3139 if (config & E_NDS32_HAS_STRING_INST)
3140 r += snprintf (buf + r, size -r, ", STR");
3141
3142 if (config & E_NDS32_HAS_REDUCED_REGS)
3143 r += snprintf (buf + r, size -r, ", 16REG");
3144
3145 if (config & E_NDS32_HAS_VIDEO_INST)
3146 {
3147 if (version <= E_NDS32_ELF_VER_1_3)
3148 r += snprintf (buf + r, size -r, ", VIDEO");
3149 else
3150 r += snprintf (buf + r, size -r, ", SATURATION");
3151 }
3152
3153 if (config & E_NDS32_HAS_ENCRIPT_INST)
3154 r += snprintf (buf + r, size -r, ", ENCRP");
3155
3156 if (config & E_NDS32_HAS_L2C_INST)
3157 r += snprintf (buf + r, size -r, ", L2C");
3158}
3159
252b5132 3160static char *
dda8d76d 3161get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3162{
b34976b6 3163 static char buf[1024];
252b5132
RH
3164
3165 buf[0] = '\0';
76da6bbe 3166
252b5132
RH
3167 if (e_flags)
3168 {
3169 switch (e_machine)
3170 {
3171 default:
3172 break;
3173
886a2506 3174 case EM_ARC_COMPACT2:
886a2506 3175 case EM_ARC_COMPACT:
a9522a21
AB
3176 decode_ARC_machine_flags (e_flags, e_machine, buf);
3177 break;
886a2506 3178
f3485b74
NC
3179 case EM_ARM:
3180 decode_ARM_machine_flags (e_flags, buf);
3181 break;
76da6bbe 3182
343433df
AB
3183 case EM_AVR:
3184 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3185 break;
3186
781303ce
MF
3187 case EM_BLACKFIN:
3188 if (e_flags & EF_BFIN_PIC)
3189 strcat (buf, ", PIC");
3190
3191 if (e_flags & EF_BFIN_FDPIC)
3192 strcat (buf, ", FDPIC");
3193
3194 if (e_flags & EF_BFIN_CODE_IN_L1)
3195 strcat (buf, ", code in L1");
3196
3197 if (e_flags & EF_BFIN_DATA_IN_L1)
3198 strcat (buf, ", data in L1");
3199
3200 break;
3201
ec2dfb42
AO
3202 case EM_CYGNUS_FRV:
3203 switch (e_flags & EF_FRV_CPU_MASK)
3204 {
3205 case EF_FRV_CPU_GENERIC:
3206 break;
3207
3208 default:
3209 strcat (buf, ", fr???");
3210 break;
57346661 3211
ec2dfb42
AO
3212 case EF_FRV_CPU_FR300:
3213 strcat (buf, ", fr300");
3214 break;
3215
3216 case EF_FRV_CPU_FR400:
3217 strcat (buf, ", fr400");
3218 break;
3219 case EF_FRV_CPU_FR405:
3220 strcat (buf, ", fr405");
3221 break;
3222
3223 case EF_FRV_CPU_FR450:
3224 strcat (buf, ", fr450");
3225 break;
3226
3227 case EF_FRV_CPU_FR500:
3228 strcat (buf, ", fr500");
3229 break;
3230 case EF_FRV_CPU_FR550:
3231 strcat (buf, ", fr550");
3232 break;
3233
3234 case EF_FRV_CPU_SIMPLE:
3235 strcat (buf, ", simple");
3236 break;
3237 case EF_FRV_CPU_TOMCAT:
3238 strcat (buf, ", tomcat");
3239 break;
3240 }
1c877e87 3241 break;
ec2dfb42 3242
53c7db4b 3243 case EM_68K:
425c6cb0 3244 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3245 strcat (buf, ", m68000");
425c6cb0 3246 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3247 strcat (buf, ", cpu32");
3248 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3249 strcat (buf, ", fido_a");
425c6cb0 3250 else
266abb8f 3251 {
2cf0635d
NC
3252 char const * isa = _("unknown");
3253 char const * mac = _("unknown mac");
3254 char const * additional = NULL;
0112cd26 3255
c694fd50 3256 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3257 {
c694fd50 3258 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3259 isa = "A";
3260 additional = ", nodiv";
3261 break;
c694fd50 3262 case EF_M68K_CF_ISA_A:
266abb8f
NS
3263 isa = "A";
3264 break;
c694fd50 3265 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3266 isa = "A+";
3267 break;
c694fd50 3268 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3269 isa = "B";
3270 additional = ", nousp";
3271 break;
c694fd50 3272 case EF_M68K_CF_ISA_B:
266abb8f
NS
3273 isa = "B";
3274 break;
f608cd77
NS
3275 case EF_M68K_CF_ISA_C:
3276 isa = "C";
3277 break;
3278 case EF_M68K_CF_ISA_C_NODIV:
3279 isa = "C";
3280 additional = ", nodiv";
3281 break;
266abb8f
NS
3282 }
3283 strcat (buf, ", cf, isa ");
3284 strcat (buf, isa);
0b2e31dc
NS
3285 if (additional)
3286 strcat (buf, additional);
c694fd50 3287 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3288 strcat (buf, ", float");
c694fd50 3289 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3290 {
3291 case 0:
3292 mac = NULL;
3293 break;
c694fd50 3294 case EF_M68K_CF_MAC:
266abb8f
NS
3295 mac = "mac";
3296 break;
c694fd50 3297 case EF_M68K_CF_EMAC:
266abb8f
NS
3298 mac = "emac";
3299 break;
f608cd77
NS
3300 case EF_M68K_CF_EMAC_B:
3301 mac = "emac_b";
3302 break;
266abb8f
NS
3303 }
3304 if (mac)
3305 {
3306 strcat (buf, ", ");
3307 strcat (buf, mac);
3308 }
266abb8f 3309 }
53c7db4b 3310 break;
33c63f9d 3311
153a2776
NC
3312 case EM_CYGNUS_MEP:
3313 switch (e_flags & EF_MEP_CPU_MASK)
3314 {
3315 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3316 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3317 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3318 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3319 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3320 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3321 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3322 }
3323
3324 switch (e_flags & EF_MEP_COP_MASK)
3325 {
3326 case EF_MEP_COP_NONE: break;
3327 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3328 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3329 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3330 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3331 default: strcat (buf, _("<unknown MeP copro type>")); break;
3332 }
3333
3334 if (e_flags & EF_MEP_LIBRARY)
3335 strcat (buf, ", Built for Library");
3336
3337 if (e_flags & EF_MEP_INDEX_MASK)
3338 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3339 e_flags & EF_MEP_INDEX_MASK);
3340
3341 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3342 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3343 e_flags & ~ EF_MEP_ALL_FLAGS);
3344 break;
3345
252b5132
RH
3346 case EM_PPC:
3347 if (e_flags & EF_PPC_EMB)
3348 strcat (buf, ", emb");
3349
3350 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3351 strcat (buf, _(", relocatable"));
252b5132
RH
3352
3353 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3354 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3355 break;
3356
ee67d69a
AM
3357 case EM_PPC64:
3358 if (e_flags & EF_PPC64_ABI)
3359 {
3360 char abi[] = ", abiv0";
3361
3362 abi[6] += e_flags & EF_PPC64_ABI;
3363 strcat (buf, abi);
3364 }
3365 break;
3366
708e2187
NC
3367 case EM_V800:
3368 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3369 strcat (buf, ", RH850 ABI");
0b4362b0 3370
708e2187
NC
3371 if (e_flags & EF_V800_850E3)
3372 strcat (buf, ", V3 architecture");
3373
3374 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3375 strcat (buf, ", FPU not used");
3376
3377 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3378 strcat (buf, ", regmode: COMMON");
3379
3380 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3381 strcat (buf, ", r4 not used");
3382
3383 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3384 strcat (buf, ", r30 not used");
3385
3386 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3387 strcat (buf, ", r5 not used");
3388
3389 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3390 strcat (buf, ", r2 not used");
3391
3392 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3393 {
3394 switch (e_flags & - e_flags)
3395 {
3396 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3397 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3398 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3399 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3400 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3401 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3402 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3403 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3404 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3405 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3406 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3407 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3408 default: break;
3409 }
3410 }
3411 break;
3412
2b0337b0 3413 case EM_V850:
252b5132
RH
3414 case EM_CYGNUS_V850:
3415 switch (e_flags & EF_V850_ARCH)
3416 {
78c8d46c
NC
3417 case E_V850E3V5_ARCH:
3418 strcat (buf, ", v850e3v5");
3419 break;
1cd986c5
NC
3420 case E_V850E2V3_ARCH:
3421 strcat (buf, ", v850e2v3");
3422 break;
3423 case E_V850E2_ARCH:
3424 strcat (buf, ", v850e2");
3425 break;
3426 case E_V850E1_ARCH:
3427 strcat (buf, ", v850e1");
8ad30312 3428 break;
252b5132
RH
3429 case E_V850E_ARCH:
3430 strcat (buf, ", v850e");
3431 break;
252b5132
RH
3432 case E_V850_ARCH:
3433 strcat (buf, ", v850");
3434 break;
3435 default:
2b692964 3436 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3437 break;
3438 }
3439 break;
3440
2b0337b0 3441 case EM_M32R:
252b5132
RH
3442 case EM_CYGNUS_M32R:
3443 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3444 strcat (buf, ", m32r");
252b5132
RH
3445 break;
3446
3447 case EM_MIPS:
4fe85591 3448 case EM_MIPS_RS3_LE:
252b5132
RH
3449 if (e_flags & EF_MIPS_NOREORDER)
3450 strcat (buf, ", noreorder");
3451
3452 if (e_flags & EF_MIPS_PIC)
3453 strcat (buf, ", pic");
3454
3455 if (e_flags & EF_MIPS_CPIC)
3456 strcat (buf, ", cpic");
3457
d1bdd336
TS
3458 if (e_flags & EF_MIPS_UCODE)
3459 strcat (buf, ", ugen_reserved");
3460
252b5132
RH
3461 if (e_flags & EF_MIPS_ABI2)
3462 strcat (buf, ", abi2");
3463
43521d43
TS
3464 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3465 strcat (buf, ", odk first");
3466
a5d22d2a
TS
3467 if (e_flags & EF_MIPS_32BITMODE)
3468 strcat (buf, ", 32bitmode");
3469
ba92f887
MR
3470 if (e_flags & EF_MIPS_NAN2008)
3471 strcat (buf, ", nan2008");
3472
fef1b0b3
SE
3473 if (e_flags & EF_MIPS_FP64)
3474 strcat (buf, ", fp64");
3475
156c2f8b
NC
3476 switch ((e_flags & EF_MIPS_MACH))
3477 {
3478 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3479 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3480 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3481 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3482 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3483 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3484 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3485 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3486 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3487 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3488 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3489 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3490 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3491 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3492 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3493 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3494 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3495 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3496 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3497 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3498 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3499 case 0:
3500 /* We simply ignore the field in this case to avoid confusion:
3501 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3502 extension. */
3503 break;
2b692964 3504 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3505 }
43521d43
TS
3506
3507 switch ((e_flags & EF_MIPS_ABI))
3508 {
3509 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3510 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3511 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3512 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3513 case 0:
3514 /* We simply ignore the field in this case to avoid confusion:
3515 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3516 This means it is likely to be an o32 file, but not for
3517 sure. */
3518 break;
2b692964 3519 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3520 }
3521
3522 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3523 strcat (buf, ", mdmx");
3524
3525 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3526 strcat (buf, ", mips16");
3527
df58fc94
RS
3528 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3529 strcat (buf, ", micromips");
3530
43521d43
TS
3531 switch ((e_flags & EF_MIPS_ARCH))
3532 {
3533 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3534 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3535 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3536 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3537 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3538 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3539 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3540 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3541 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3542 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3543 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3544 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3545 }
252b5132 3546 break;
351b4b40 3547
35c08157
KLC
3548 case EM_NDS32:
3549 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3550 break;
3551
fe944acf
FT
3552 case EM_NFP:
3553 switch (EF_NFP_MACH (e_flags))
3554 {
3555 case E_NFP_MACH_3200:
3556 strcat (buf, ", NFP-32xx");
3557 break;
3558 case E_NFP_MACH_6000:
3559 strcat (buf, ", NFP-6xxx");
3560 break;
3561 }
3562 break;
3563
e23eba97
NC
3564 case EM_RISCV:
3565 if (e_flags & EF_RISCV_RVC)
3566 strcat (buf, ", RVC");
2922d21d 3567
7f999549
JW
3568 if (e_flags & EF_RISCV_RVE)
3569 strcat (buf, ", RVE");
3570
2922d21d
AW
3571 switch (e_flags & EF_RISCV_FLOAT_ABI)
3572 {
3573 case EF_RISCV_FLOAT_ABI_SOFT:
3574 strcat (buf, ", soft-float ABI");
3575 break;
3576
3577 case EF_RISCV_FLOAT_ABI_SINGLE:
3578 strcat (buf, ", single-float ABI");
3579 break;
3580
3581 case EF_RISCV_FLOAT_ABI_DOUBLE:
3582 strcat (buf, ", double-float ABI");
3583 break;
3584
3585 case EF_RISCV_FLOAT_ABI_QUAD:
3586 strcat (buf, ", quad-float ABI");
3587 break;
3588 }
e23eba97
NC
3589 break;
3590
ccde1100
AO
3591 case EM_SH:
3592 switch ((e_flags & EF_SH_MACH_MASK))
3593 {
3594 case EF_SH1: strcat (buf, ", sh1"); break;
3595 case EF_SH2: strcat (buf, ", sh2"); break;
3596 case EF_SH3: strcat (buf, ", sh3"); break;
3597 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3598 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3599 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3600 case EF_SH3E: strcat (buf, ", sh3e"); break;
3601 case EF_SH4: strcat (buf, ", sh4"); break;
3602 case EF_SH5: strcat (buf, ", sh5"); break;
3603 case EF_SH2E: strcat (buf, ", sh2e"); break;
3604 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3605 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3606 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3607 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3608 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3609 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3610 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3611 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3612 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3613 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3614 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3615 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3616 }
3617
cec6a5b8
MR
3618 if (e_flags & EF_SH_PIC)
3619 strcat (buf, ", pic");
3620
3621 if (e_flags & EF_SH_FDPIC)
3622 strcat (buf, ", fdpic");
ccde1100 3623 break;
948f632f 3624
73589c9d
CS
3625 case EM_OR1K:
3626 if (e_flags & EF_OR1K_NODELAY)
3627 strcat (buf, ", no delay");
3628 break;
57346661 3629
351b4b40
RH
3630 case EM_SPARCV9:
3631 if (e_flags & EF_SPARC_32PLUS)
3632 strcat (buf, ", v8+");
3633
3634 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3635 strcat (buf, ", ultrasparcI");
3636
3637 if (e_flags & EF_SPARC_SUN_US3)
3638 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3639
3640 if (e_flags & EF_SPARC_HAL_R1)
3641 strcat (buf, ", halr1");
3642
3643 if (e_flags & EF_SPARC_LEDATA)
3644 strcat (buf, ", ledata");
3645
3646 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3647 strcat (buf, ", tso");
3648
3649 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3650 strcat (buf, ", pso");
3651
3652 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3653 strcat (buf, ", rmo");
3654 break;
7d466069 3655
103f02d3
UD
3656 case EM_PARISC:
3657 switch (e_flags & EF_PARISC_ARCH)
3658 {
3659 case EFA_PARISC_1_0:
3660 strcpy (buf, ", PA-RISC 1.0");
3661 break;
3662 case EFA_PARISC_1_1:
3663 strcpy (buf, ", PA-RISC 1.1");
3664 break;
3665 case EFA_PARISC_2_0:
3666 strcpy (buf, ", PA-RISC 2.0");
3667 break;
3668 default:
3669 break;
3670 }
3671 if (e_flags & EF_PARISC_TRAPNIL)
3672 strcat (buf, ", trapnil");
3673 if (e_flags & EF_PARISC_EXT)
3674 strcat (buf, ", ext");
3675 if (e_flags & EF_PARISC_LSB)
3676 strcat (buf, ", lsb");
3677 if (e_flags & EF_PARISC_WIDE)
3678 strcat (buf, ", wide");
3679 if (e_flags & EF_PARISC_NO_KABP)
3680 strcat (buf, ", no kabp");
3681 if (e_flags & EF_PARISC_LAZYSWAP)
3682 strcat (buf, ", lazyswap");
30800947 3683 break;
76da6bbe 3684
7d466069 3685 case EM_PJ:
2b0337b0 3686 case EM_PJ_OLD:
7d466069
ILT
3687 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3688 strcat (buf, ", new calling convention");
3689
3690 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3691 strcat (buf, ", gnu calling convention");
3692 break;
4d6ed7c8
NC
3693
3694 case EM_IA_64:
3695 if ((e_flags & EF_IA_64_ABI64))
3696 strcat (buf, ", 64-bit");
3697 else
3698 strcat (buf, ", 32-bit");
3699 if ((e_flags & EF_IA_64_REDUCEDFP))
3700 strcat (buf, ", reduced fp model");
3701 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3702 strcat (buf, ", no function descriptors, constant gp");
3703 else if ((e_flags & EF_IA_64_CONS_GP))
3704 strcat (buf, ", constant gp");
3705 if ((e_flags & EF_IA_64_ABSOLUTE))
3706 strcat (buf, ", absolute");
dda8d76d 3707 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3708 {
3709 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3710 strcat (buf, ", vms_linkages");
3711 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3712 {
3713 case EF_IA_64_VMS_COMCOD_SUCCESS:
3714 break;
3715 case EF_IA_64_VMS_COMCOD_WARNING:
3716 strcat (buf, ", warning");
3717 break;
3718 case EF_IA_64_VMS_COMCOD_ERROR:
3719 strcat (buf, ", error");
3720 break;
3721 case EF_IA_64_VMS_COMCOD_ABORT:
3722 strcat (buf, ", abort");
3723 break;
3724 default:
bee0ee85
NC
3725 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3726 e_flags & EF_IA_64_VMS_COMCOD);
3727 strcat (buf, ", <unknown>");
28f997cf
TG
3728 }
3729 }
4d6ed7c8 3730 break;
179d3252
JT
3731
3732 case EM_VAX:
3733 if ((e_flags & EF_VAX_NONPIC))
3734 strcat (buf, ", non-PIC");
3735 if ((e_flags & EF_VAX_DFLOAT))
3736 strcat (buf, ", D-Float");
3737 if ((e_flags & EF_VAX_GFLOAT))
3738 strcat (buf, ", G-Float");
3739 break;
c7927a3c 3740
619ed720
EB
3741 case EM_VISIUM:
3742 if (e_flags & EF_VISIUM_ARCH_MCM)
3743 strcat (buf, ", mcm");
3744 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3745 strcat (buf, ", mcm24");
3746 if (e_flags & EF_VISIUM_ARCH_GR6)
3747 strcat (buf, ", gr6");
3748 break;
3749
4046d87a 3750 case EM_RL78:
1740ba0c
NC
3751 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3752 {
3753 case E_FLAG_RL78_ANY_CPU: break;
3754 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3755 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3756 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3757 }
856ea05c
KP
3758 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3759 strcat (buf, ", 64-bit doubles");
4046d87a 3760 break;
0b4362b0 3761
c7927a3c
NC
3762 case EM_RX:
3763 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3764 strcat (buf, ", 64-bit doubles");
3765 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3766 strcat (buf, ", dsp");
d4cb0ea0 3767 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3768 strcat (buf, ", pid");
708e2187
NC
3769 if (e_flags & E_FLAG_RX_ABI)
3770 strcat (buf, ", RX ABI");
3525236c
NC
3771 if (e_flags & E_FLAG_RX_SINSNS_SET)
3772 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3773 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3774 if (e_flags & E_FLAG_RX_V2)
3775 strcat (buf, ", V2");
f87673e0
YS
3776 if (e_flags & E_FLAG_RX_V3)
3777 strcat (buf, ", V3");
d4cb0ea0 3778 break;
55786da2
AK
3779
3780 case EM_S390:
3781 if (e_flags & EF_S390_HIGH_GPRS)
3782 strcat (buf, ", highgprs");
d4cb0ea0 3783 break;
40b36596
JM
3784
3785 case EM_TI_C6000:
3786 if ((e_flags & EF_C6000_REL))
3787 strcat (buf, ", relocatable module");
d4cb0ea0 3788 break;
13761a11
NC
3789
3790 case EM_MSP430:
3791 strcat (buf, _(": architecture variant: "));
3792 switch (e_flags & EF_MSP430_MACH)
3793 {
3794 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3795 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3796 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3797 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3798 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3799 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3800 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3801 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3802 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3803 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3804 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3805 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3806 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3807 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3808 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3809 default:
3810 strcat (buf, _(": unknown")); break;
3811 }
3812
3813 if (e_flags & ~ EF_MSP430_MACH)
3814 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3815 break;
3816
3817 case EM_Z80:
3818 switch (e_flags & EF_Z80_MACH_MSK)
3819 {
3820 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3821 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3822 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3823 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3824 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3825 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3826 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3827 default:
3828 strcat (buf, _(", unknown")); break;
3829 }
3830 break;
252b5132
RH
3831 }
3832 }
3833
3834 return buf;
3835}
3836
252b5132 3837static const char *
dda8d76d 3838get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3839{
3840 static char buff[32];
3841
3842 switch (osabi)
3843 {
3844 case ELFOSABI_NONE: return "UNIX - System V";
3845 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3846 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3847 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3848 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3849 case ELFOSABI_AIX: return "UNIX - AIX";
3850 case ELFOSABI_IRIX: return "UNIX - IRIX";
3851 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3852 case ELFOSABI_TRU64: return "UNIX - TRU64";
3853 case ELFOSABI_MODESTO: return "Novell - Modesto";
3854 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3855 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3856 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3857 case ELFOSABI_AROS: return "AROS";
11636f9e 3858 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3859 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3860 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3861 default:
40b36596 3862 if (osabi >= 64)
dda8d76d 3863 switch (filedata->file_header.e_machine)
40b36596
JM
3864 {
3865 case EM_ARM:
3866 switch (osabi)
3867 {
3868 case ELFOSABI_ARM: return "ARM";
18a20338 3869 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3870 default:
3871 break;
3872 }
3873 break;
3874
3875 case EM_MSP430:
3876 case EM_MSP430_OLD:
619ed720 3877 case EM_VISIUM:
40b36596
JM
3878 switch (osabi)
3879 {
3880 case ELFOSABI_STANDALONE: return _("Standalone App");
3881 default:
3882 break;
3883 }
3884 break;
3885
3886 case EM_TI_C6000:
3887 switch (osabi)
3888 {
3889 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3890 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3891 default:
3892 break;
3893 }
3894 break;
3895
3896 default:
3897 break;
3898 }
e9e44622 3899 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3900 return buff;
3901 }
3902}
3903
a06ea964
NC
3904static const char *
3905get_aarch64_segment_type (unsigned long type)
3906{
3907 switch (type)
3908 {
32ec8896
NC
3909 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3910 default: return NULL;
a06ea964 3911 }
a06ea964
NC
3912}
3913
b294bdf8
MM
3914static const char *
3915get_arm_segment_type (unsigned long type)
3916{
3917 switch (type)
3918 {
32ec8896
NC
3919 case PT_ARM_EXIDX: return "EXIDX";
3920 default: return NULL;
b294bdf8 3921 }
b294bdf8
MM
3922}
3923
b4cbbe8f
AK
3924static const char *
3925get_s390_segment_type (unsigned long type)
3926{
3927 switch (type)
3928 {
3929 case PT_S390_PGSTE: return "S390_PGSTE";
3930 default: return NULL;
3931 }
3932}
3933
d3ba0551
AM
3934static const char *
3935get_mips_segment_type (unsigned long type)
252b5132
RH
3936{
3937 switch (type)
3938 {
32ec8896
NC
3939 case PT_MIPS_REGINFO: return "REGINFO";
3940 case PT_MIPS_RTPROC: return "RTPROC";
3941 case PT_MIPS_OPTIONS: return "OPTIONS";
3942 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3943 default: return NULL;
252b5132 3944 }
252b5132
RH
3945}
3946
103f02d3 3947static const char *
d3ba0551 3948get_parisc_segment_type (unsigned long type)
103f02d3
UD
3949{
3950 switch (type)
3951 {
103f02d3
UD
3952 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3953 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3954 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3955 default: return NULL;
103f02d3 3956 }
103f02d3
UD
3957}
3958
4d6ed7c8 3959static const char *
d3ba0551 3960get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3961{
3962 switch (type)
3963 {
3964 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3965 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3966 default: return NULL;
4d6ed7c8 3967 }
4d6ed7c8
NC
3968}
3969
40b36596
JM
3970static const char *
3971get_tic6x_segment_type (unsigned long type)
3972{
3973 switch (type)
3974 {
32ec8896
NC
3975 case PT_C6000_PHATTR: return "C6000_PHATTR";
3976 default: return NULL;
40b36596 3977 }
40b36596
JM
3978}
3979
df3a023b
AM
3980static const char *
3981get_hpux_segment_type (unsigned long type, unsigned e_machine)
3982{
3983 if (e_machine == EM_PARISC)
3984 switch (type)
3985 {
3986 case PT_HP_TLS: return "HP_TLS";
3987 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3988 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3989 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3990 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3991 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3992 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3993 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3994 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3995 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3996 case PT_HP_PARALLEL: return "HP_PARALLEL";
3997 case PT_HP_FASTBIND: return "HP_FASTBIND";
3998 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3999 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4000 case PT_HP_STACK: return "HP_STACK";
4001 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4002 default: return NULL;
4003 }
4004
4005 if (e_machine == EM_IA_64)
4006 switch (type)
4007 {
4008 case PT_HP_TLS: return "HP_TLS";
4009 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4010 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4011 case PT_IA_64_HP_STACK: return "HP_STACK";
4012 default: return NULL;
4013 }
4014
4015 return NULL;
4016}
4017
5522f910
NC
4018static const char *
4019get_solaris_segment_type (unsigned long type)
4020{
4021 switch (type)
4022 {
4023 case 0x6464e550: return "PT_SUNW_UNWIND";
4024 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4025 case 0x6ffffff7: return "PT_LOSUNW";
4026 case 0x6ffffffa: return "PT_SUNWBSS";
4027 case 0x6ffffffb: return "PT_SUNWSTACK";
4028 case 0x6ffffffc: return "PT_SUNWDTRACE";
4029 case 0x6ffffffd: return "PT_SUNWCAP";
4030 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4031 default: return NULL;
5522f910
NC
4032 }
4033}
4034
252b5132 4035static const char *
dda8d76d 4036get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4037{
b34976b6 4038 static char buff[32];
252b5132
RH
4039
4040 switch (p_type)
4041 {
b34976b6
AM
4042 case PT_NULL: return "NULL";
4043 case PT_LOAD: return "LOAD";
252b5132 4044 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4045 case PT_INTERP: return "INTERP";
4046 case PT_NOTE: return "NOTE";
4047 case PT_SHLIB: return "SHLIB";
4048 case PT_PHDR: return "PHDR";
13ae64f3 4049 case PT_TLS: return "TLS";
32ec8896 4050 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4051 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4052 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4053 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4054
252b5132 4055 default:
df3a023b 4056 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4057 {
2cf0635d 4058 const char * result;
103f02d3 4059
dda8d76d 4060 switch (filedata->file_header.e_machine)
252b5132 4061 {
a06ea964
NC
4062 case EM_AARCH64:
4063 result = get_aarch64_segment_type (p_type);
4064 break;
b294bdf8
MM
4065 case EM_ARM:
4066 result = get_arm_segment_type (p_type);
4067 break;
252b5132 4068 case EM_MIPS:
4fe85591 4069 case EM_MIPS_RS3_LE:
252b5132
RH
4070 result = get_mips_segment_type (p_type);
4071 break;
103f02d3
UD
4072 case EM_PARISC:
4073 result = get_parisc_segment_type (p_type);
4074 break;
4d6ed7c8
NC
4075 case EM_IA_64:
4076 result = get_ia64_segment_type (p_type);
4077 break;
40b36596
JM
4078 case EM_TI_C6000:
4079 result = get_tic6x_segment_type (p_type);
4080 break;
b4cbbe8f
AK
4081 case EM_S390:
4082 case EM_S390_OLD:
4083 result = get_s390_segment_type (p_type);
4084 break;
252b5132
RH
4085 default:
4086 result = NULL;
4087 break;
4088 }
103f02d3 4089
252b5132
RH
4090 if (result != NULL)
4091 return result;
103f02d3 4092
1a9ccd70 4093 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4094 }
4095 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4096 {
df3a023b 4097 const char * result = NULL;
103f02d3 4098
df3a023b 4099 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4100 {
df3a023b
AM
4101 case ELFOSABI_GNU:
4102 case ELFOSABI_FREEBSD:
4103 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4104 {
4105 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4106 result = buff;
4107 }
103f02d3 4108 break;
df3a023b
AM
4109 case ELFOSABI_HPUX:
4110 result = get_hpux_segment_type (p_type,
4111 filedata->file_header.e_machine);
4112 break;
4113 case ELFOSABI_SOLARIS:
4114 result = get_solaris_segment_type (p_type);
00428cca 4115 break;
103f02d3 4116 default:
103f02d3
UD
4117 break;
4118 }
103f02d3
UD
4119 if (result != NULL)
4120 return result;
4121
1a9ccd70 4122 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4123 }
252b5132 4124 else
e9e44622 4125 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4126
4127 return buff;
4128 }
4129}
4130
53a346d8
CZ
4131static const char *
4132get_arc_section_type_name (unsigned int sh_type)
4133{
4134 switch (sh_type)
4135 {
4136 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4137 default:
4138 break;
4139 }
4140 return NULL;
4141}
4142
252b5132 4143static const char *
d3ba0551 4144get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4145{
4146 switch (sh_type)
4147 {
b34976b6
AM
4148 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4149 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4150 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4151 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4152 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4153 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4154 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4155 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4156 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4157 case SHT_MIPS_RELD: return "MIPS_RELD";
4158 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4159 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4160 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4161 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4162 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4163 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4164 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4165 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4166 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4167 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4168 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4169 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4170 case SHT_MIPS_LINE: return "MIPS_LINE";
4171 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4172 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4173 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4174 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4175 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4176 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4177 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4178 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4179 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4180 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4181 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4182 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4183 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4184 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4185 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4186 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4187 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4188 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4189 default:
4190 break;
4191 }
4192 return NULL;
4193}
4194
103f02d3 4195static const char *
d3ba0551 4196get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4197{
4198 switch (sh_type)
4199 {
4200 case SHT_PARISC_EXT: return "PARISC_EXT";
4201 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4202 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4203 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4204 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4205 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4206 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4207 default: return NULL;
103f02d3 4208 }
103f02d3
UD
4209}
4210
4d6ed7c8 4211static const char *
dda8d76d 4212get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4213{
18bd398b 4214 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4215 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4216 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4217
4d6ed7c8
NC
4218 switch (sh_type)
4219 {
148b93f2
NC
4220 case SHT_IA_64_EXT: return "IA_64_EXT";
4221 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4222 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4223 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4224 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4225 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4226 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4227 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4228 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4229 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4230 default:
4231 break;
4232 }
4233 return NULL;
4234}
4235
d2b2c203
DJ
4236static const char *
4237get_x86_64_section_type_name (unsigned int sh_type)
4238{
4239 switch (sh_type)
4240 {
4241 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4242 default: return NULL;
d2b2c203 4243 }
d2b2c203
DJ
4244}
4245
a06ea964
NC
4246static const char *
4247get_aarch64_section_type_name (unsigned int sh_type)
4248{
4249 switch (sh_type)
4250 {
32ec8896
NC
4251 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4252 default: return NULL;
a06ea964 4253 }
a06ea964
NC
4254}
4255
40a18ebd
NC
4256static const char *
4257get_arm_section_type_name (unsigned int sh_type)
4258{
4259 switch (sh_type)
4260 {
7f6fed87
NC
4261 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4262 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4263 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4264 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4265 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4266 default: return NULL;
40a18ebd 4267 }
40a18ebd
NC
4268}
4269
40b36596
JM
4270static const char *
4271get_tic6x_section_type_name (unsigned int sh_type)
4272{
4273 switch (sh_type)
4274 {
32ec8896
NC
4275 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4276 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4277 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4278 case SHT_TI_ICODE: return "TI_ICODE";
4279 case SHT_TI_XREF: return "TI_XREF";
4280 case SHT_TI_HANDLER: return "TI_HANDLER";
4281 case SHT_TI_INITINFO: return "TI_INITINFO";
4282 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4283 default: return NULL;
40b36596 4284 }
40b36596
JM
4285}
4286
13761a11
NC
4287static const char *
4288get_msp430x_section_type_name (unsigned int sh_type)
4289{
4290 switch (sh_type)
4291 {
32ec8896
NC
4292 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4293 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4294 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4295 default: return NULL;
13761a11
NC
4296 }
4297}
4298
fe944acf
FT
4299static const char *
4300get_nfp_section_type_name (unsigned int sh_type)
4301{
4302 switch (sh_type)
4303 {
4304 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4305 case SHT_NFP_INITREG: return "NFP_INITREG";
4306 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4307 default: return NULL;
4308 }
4309}
4310
685080f2
NC
4311static const char *
4312get_v850_section_type_name (unsigned int sh_type)
4313{
4314 switch (sh_type)
4315 {
32ec8896
NC
4316 case SHT_V850_SCOMMON: return "V850 Small Common";
4317 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4318 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4319 case SHT_RENESAS_IOP: return "RENESAS IOP";
4320 case SHT_RENESAS_INFO: return "RENESAS INFO";
4321 default: return NULL;
685080f2
NC
4322 }
4323}
4324
2dc8dd17
JW
4325static const char *
4326get_riscv_section_type_name (unsigned int sh_type)
4327{
4328 switch (sh_type)
4329 {
4330 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4331 default: return NULL;
4332 }
4333}
4334
252b5132 4335static const char *
dda8d76d 4336get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4337{
b34976b6 4338 static char buff[32];
9fb71ee4 4339 const char * result;
252b5132
RH
4340
4341 switch (sh_type)
4342 {
4343 case SHT_NULL: return "NULL";
4344 case SHT_PROGBITS: return "PROGBITS";
4345 case SHT_SYMTAB: return "SYMTAB";
4346 case SHT_STRTAB: return "STRTAB";
4347 case SHT_RELA: return "RELA";
4348 case SHT_HASH: return "HASH";
4349 case SHT_DYNAMIC: return "DYNAMIC";
4350 case SHT_NOTE: return "NOTE";
4351 case SHT_NOBITS: return "NOBITS";
4352 case SHT_REL: return "REL";
4353 case SHT_SHLIB: return "SHLIB";
4354 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4355 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4356 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4357 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4358 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4359 case SHT_GROUP: return "GROUP";
67ce483b 4360 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4361 case SHT_GNU_verdef: return "VERDEF";
4362 case SHT_GNU_verneed: return "VERNEED";
4363 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4364 case 0x6ffffff0: return "VERSYM";
4365 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4366 case 0x7ffffffd: return "AUXILIARY";
4367 case 0x7fffffff: return "FILTER";
047b2264 4368 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4369
4370 default:
4371 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4372 {
dda8d76d 4373 switch (filedata->file_header.e_machine)
252b5132 4374 {
53a346d8
CZ
4375 case EM_ARC:
4376 case EM_ARC_COMPACT:
4377 case EM_ARC_COMPACT2:
4378 result = get_arc_section_type_name (sh_type);
4379 break;
252b5132 4380 case EM_MIPS:
4fe85591 4381 case EM_MIPS_RS3_LE:
252b5132
RH
4382 result = get_mips_section_type_name (sh_type);
4383 break;
103f02d3
UD
4384 case EM_PARISC:
4385 result = get_parisc_section_type_name (sh_type);
4386 break;
4d6ed7c8 4387 case EM_IA_64:
dda8d76d 4388 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4389 break;
d2b2c203 4390 case EM_X86_64:
8a9036a4 4391 case EM_L1OM:
7a9068fe 4392 case EM_K1OM:
d2b2c203
DJ
4393 result = get_x86_64_section_type_name (sh_type);
4394 break;
a06ea964
NC
4395 case EM_AARCH64:
4396 result = get_aarch64_section_type_name (sh_type);
4397 break;
40a18ebd
NC
4398 case EM_ARM:
4399 result = get_arm_section_type_name (sh_type);
4400 break;
40b36596
JM
4401 case EM_TI_C6000:
4402 result = get_tic6x_section_type_name (sh_type);
4403 break;
13761a11
NC
4404 case EM_MSP430:
4405 result = get_msp430x_section_type_name (sh_type);
4406 break;
fe944acf
FT
4407 case EM_NFP:
4408 result = get_nfp_section_type_name (sh_type);
4409 break;
685080f2
NC
4410 case EM_V800:
4411 case EM_V850:
4412 case EM_CYGNUS_V850:
4413 result = get_v850_section_type_name (sh_type);
4414 break;
2dc8dd17
JW
4415 case EM_RISCV:
4416 result = get_riscv_section_type_name (sh_type);
4417 break;
252b5132
RH
4418 default:
4419 result = NULL;
4420 break;
4421 }
4422
4423 if (result != NULL)
4424 return result;
4425
9fb71ee4 4426 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4427 }
4428 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4429 {
dda8d76d 4430 switch (filedata->file_header.e_machine)
148b93f2
NC
4431 {
4432 case EM_IA_64:
dda8d76d 4433 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4434 break;
4435 default:
dda8d76d 4436 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4437 result = get_solaris_section_type (sh_type);
4438 else
1b4b80bf
NC
4439 {
4440 switch (sh_type)
4441 {
4442 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4443 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4444 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4445 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4446 default:
4447 result = NULL;
4448 break;
4449 }
4450 }
148b93f2
NC
4451 break;
4452 }
4453
4454 if (result != NULL)
4455 return result;
4456
9fb71ee4 4457 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4458 }
252b5132 4459 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4460 {
dda8d76d 4461 switch (filedata->file_header.e_machine)
685080f2
NC
4462 {
4463 case EM_V800:
4464 case EM_V850:
4465 case EM_CYGNUS_V850:
9fb71ee4 4466 result = get_v850_section_type_name (sh_type);
a9fb83be 4467 break;
685080f2 4468 default:
9fb71ee4 4469 result = NULL;
685080f2
NC
4470 break;
4471 }
4472
9fb71ee4
NC
4473 if (result != NULL)
4474 return result;
4475
4476 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4477 }
252b5132 4478 else
a7dbfd1c
NC
4479 /* This message is probably going to be displayed in a 15
4480 character wide field, so put the hex value first. */
4481 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4482
252b5132
RH
4483 return buff;
4484 }
4485}
4486
79bc120c
NC
4487enum long_option_values
4488{
4489 OPTION_DEBUG_DUMP = 512,
4490 OPTION_DYN_SYMS,
4491 OPTION_DWARF_DEPTH,
4492 OPTION_DWARF_START,
4493 OPTION_DWARF_CHECK,
4494 OPTION_CTF_DUMP,
4495 OPTION_CTF_PARENT,
4496 OPTION_CTF_SYMBOLS,
4497 OPTION_CTF_STRINGS,
4498 OPTION_WITH_SYMBOL_VERSIONS,
4499 OPTION_RECURSE_LIMIT,
4500 OPTION_NO_RECURSE_LIMIT,
4501 OPTION_NO_DEMANGLING
4502};
2979dc34 4503
85b1c36d 4504static struct option options[] =
252b5132 4505{
79bc120c
NC
4506 /* Note - This table is alpha-sorted on the 'val'
4507 field in order to make adding new options easier. */
4508 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4509 {"all", no_argument, 0, 'a'},
79bc120c
NC
4510 {"demangle", optional_argument, 0, 'C'},
4511 {"archive-index", no_argument, 0, 'c'},
4512 {"use-dynamic", no_argument, 0, 'D'},
4513 {"dynamic", no_argument, 0, 'd'},
b34976b6 4514 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4515 {"section-groups", no_argument, 0, 'g'},
4516 {"help", no_argument, 0, 'H'},
4517 {"file-header", no_argument, 0, 'h'},
b34976b6 4518 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4519 {"lint", no_argument, 0, 'L'},
4520 {"enable-checks", no_argument, 0, 'L'},
4521 {"program-headers", no_argument, 0, 'l'},
b34976b6 4522 {"segments", no_argument, 0, 'l'},
595cf52e 4523 {"full-section-name",no_argument, 0, 'N'},
79bc120c
NC
4524 {"notes", no_argument, 0, 'n'},
4525 {"string-dump", required_argument, 0, 'p'},
4526 {"relocated-dump", required_argument, 0, 'R'},
4527 {"relocs", no_argument, 0, 'r'},
4528 {"section-headers", no_argument, 0, 'S'},
4529 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4530 {"symbols", no_argument, 0, 's'},
4531 {"syms", no_argument, 0, 's'},
79bc120c
NC
4532 {"silent-truncation",no_argument, 0, 'T'},
4533 {"section-details", no_argument, 0, 't'},
09c11c86 4534 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4535 {"version-info", no_argument, 0, 'V'},
4536 {"version", no_argument, 0, 'v'},
4537 {"wide", no_argument, 0, 'W'},
b34976b6 4538 {"hex-dump", required_argument, 0, 'x'},
0e602686 4539 {"decompress", no_argument, 0, 'z'},
252b5132 4540
79bc120c
NC
4541 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4542 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4543 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4544 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4545 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
4546 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4547 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4548 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4549 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4550#ifdef ENABLE_LIBCTF
d344b407 4551 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4552 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4553 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4554 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4555#endif
7d9813f1 4556
b34976b6 4557 {0, no_argument, 0, 0}
252b5132
RH
4558};
4559
4560static void
2cf0635d 4561usage (FILE * stream)
252b5132 4562{
92f01d61
JM
4563 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4564 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4565 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4566 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4567 -h --file-header Display the ELF file header\n\
4568 -l --program-headers Display the program headers\n\
4569 --segments An alias for --program-headers\n\
4570 -S --section-headers Display the sections' header\n\
4571 --sections An alias for --section-headers\n\
f5842774 4572 -g --section-groups Display the section groups\n\
5477e8a0 4573 -t --section-details Display the section details\n\
8b53311e
NC
4574 -e --headers Equivalent to: -h -l -S\n\
4575 -s --syms Display the symbol table\n\
3f08eb35 4576 --symbols An alias for --syms\n\
1b513401 4577 --dyn-syms Display the dynamic symbol table\n\
79bc120c
NC
4578 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4579 The STYLE, if specified, can be `auto' (the default),\n\
4580 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
4581 or `gnat'\n\
4582 --no-demangle Do not demangle low-level symbol names. (This is the default)\n\
4583 --recurse-limit Enable a demangling recursion limit. (This is the default)\n\
4584 --no-recurse-limit Disable a demangling recursion limit\n\
8b53311e
NC
4585 -n --notes Display the core notes (if present)\n\
4586 -r --relocs Display the relocations (if present)\n\
4587 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4588 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4589 -V --version-info Display the version sections (if present)\n\
1b31d05e 4590 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4591 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4592 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4593 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4594 -x --hex-dump=<number|name>\n\
4595 Dump the contents of section <number|name> as bytes\n\
4596 -p --string-dump=<number|name>\n\
4597 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4598 -R --relocated-dump=<number|name>\n\
4599 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4600 -z --decompress Decompress section before dumping it\n\
e4b7104b 4601 -w[lLiaprmfFsoORtUuTgAckK] or\n\
1ed06042 4602 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
e4b7104b 4603 =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
657d0d47 4604 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4605 =addr,=cu_index,=links,=follow-links]\n\
4606 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4607 fprintf (stream, _("\
4608 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4609 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4610 or deeper\n"));
094e34f2 4611#ifdef ENABLE_LIBCTF
7d9813f1
NA
4612 fprintf (stream, _("\
4613 --ctf=<number|name> Display CTF info from section <number|name>\n\
4614 --ctf-parent=<number|name>\n\
4615 Use section <number|name> as the CTF parent\n\n\
4616 --ctf-symbols=<number|name>\n\
4617 Use section <number|name> as the CTF external symtab\n\n\
4618 --ctf-strings=<number|name>\n\
4619 Use section <number|name> as the CTF external strtab\n\n"));
094e34f2 4620#endif
7d9813f1 4621
252b5132 4622#ifdef SUPPORT_DISASSEMBLY
92f01d61 4623 fprintf (stream, _("\
09c11c86
NC
4624 -i --instruction-dump=<number|name>\n\
4625 Disassemble the contents of section <number|name>\n"));
252b5132 4626#endif
92f01d61 4627 fprintf (stream, _("\
8b53311e
NC
4628 -I --histogram Display histogram of bucket list lengths\n\
4629 -W --wide Allow output width to exceed 80 characters\n\
0942c7ab 4630 -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
07012eee 4631 @<file> Read options from <file>\n\
8b53311e
NC
4632 -H --help Display this information\n\
4633 -v --version Display the version number of readelf\n"));
1118d252 4634
92f01d61
JM
4635 if (REPORT_BUGS_TO[0] && stream == stdout)
4636 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4637
92f01d61 4638 exit (stream == stdout ? 0 : 1);
252b5132
RH
4639}
4640
18bd398b
NC
4641/* Record the fact that the user wants the contents of section number
4642 SECTION to be displayed using the method(s) encoded as flags bits
4643 in TYPE. Note, TYPE can be zero if we are creating the array for
4644 the first time. */
4645
252b5132 4646static void
6431e409
AM
4647request_dump_bynumber (struct dump_data *dumpdata,
4648 unsigned int section, dump_type type)
252b5132 4649{
6431e409 4650 if (section >= dumpdata->num_dump_sects)
252b5132 4651 {
2cf0635d 4652 dump_type * new_dump_sects;
252b5132 4653
3f5e193b 4654 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4655 sizeof (* new_dump_sects));
252b5132
RH
4656
4657 if (new_dump_sects == NULL)
591a748a 4658 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4659 else
4660 {
6431e409 4661 if (dumpdata->dump_sects)
21b65bac
NC
4662 {
4663 /* Copy current flag settings. */
6431e409
AM
4664 memcpy (new_dump_sects, dumpdata->dump_sects,
4665 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4666
6431e409 4667 free (dumpdata->dump_sects);
21b65bac 4668 }
252b5132 4669
6431e409
AM
4670 dumpdata->dump_sects = new_dump_sects;
4671 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4672 }
4673 }
4674
6431e409
AM
4675 if (dumpdata->dump_sects)
4676 dumpdata->dump_sects[section] |= type;
252b5132
RH
4677}
4678
aef1f6d0
DJ
4679/* Request a dump by section name. */
4680
4681static void
2cf0635d 4682request_dump_byname (const char * section, dump_type type)
aef1f6d0 4683{
2cf0635d 4684 struct dump_list_entry * new_request;
aef1f6d0 4685
3f5e193b
NC
4686 new_request = (struct dump_list_entry *)
4687 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4688 if (!new_request)
591a748a 4689 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4690
4691 new_request->name = strdup (section);
4692 if (!new_request->name)
591a748a 4693 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4694
4695 new_request->type = type;
4696
4697 new_request->next = dump_sects_byname;
4698 dump_sects_byname = new_request;
4699}
4700
cf13d699 4701static inline void
6431e409 4702request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4703{
4704 int section;
4705 char * cp;
4706
4707 do_dump++;
4708 section = strtoul (optarg, & cp, 0);
4709
4710 if (! *cp && section >= 0)
6431e409 4711 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4712 else
4713 request_dump_byname (optarg, type);
4714}
4715
252b5132 4716static void
6431e409 4717parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4718{
4719 int c;
4720
4721 if (argc < 2)
92f01d61 4722 usage (stderr);
252b5132
RH
4723
4724 while ((c = getopt_long
79bc120c 4725 (argc, argv, "ACDHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4726 {
252b5132
RH
4727 switch (c)
4728 {
4729 case 0:
4730 /* Long options. */
4731 break;
4732 case 'H':
92f01d61 4733 usage (stdout);
252b5132
RH
4734 break;
4735
4736 case 'a':
32ec8896
NC
4737 do_syms = TRUE;
4738 do_reloc = TRUE;
4739 do_unwind = TRUE;
4740 do_dynamic = TRUE;
4741 do_header = TRUE;
4742 do_sections = TRUE;
4743 do_section_groups = TRUE;
4744 do_segments = TRUE;
4745 do_version = TRUE;
4746 do_histogram = TRUE;
4747 do_arch = TRUE;
4748 do_notes = TRUE;
252b5132 4749 break;
79bc120c 4750
f5842774 4751 case 'g':
32ec8896 4752 do_section_groups = TRUE;
f5842774 4753 break;
5477e8a0 4754 case 't':
595cf52e 4755 case 'N':
32ec8896
NC
4756 do_sections = TRUE;
4757 do_section_details = TRUE;
595cf52e 4758 break;
252b5132 4759 case 'e':
32ec8896
NC
4760 do_header = TRUE;
4761 do_sections = TRUE;
4762 do_segments = TRUE;
252b5132 4763 break;
a952a375 4764 case 'A':
32ec8896 4765 do_arch = TRUE;
a952a375 4766 break;
252b5132 4767 case 'D':
32ec8896 4768 do_using_dynamic = TRUE;
252b5132
RH
4769 break;
4770 case 'r':
32ec8896 4771 do_reloc = TRUE;
252b5132 4772 break;
4d6ed7c8 4773 case 'u':
32ec8896 4774 do_unwind = TRUE;
4d6ed7c8 4775 break;
252b5132 4776 case 'h':
32ec8896 4777 do_header = TRUE;
252b5132
RH
4778 break;
4779 case 'l':
32ec8896 4780 do_segments = TRUE;
252b5132
RH
4781 break;
4782 case 's':
32ec8896 4783 do_syms = TRUE;
252b5132
RH
4784 break;
4785 case 'S':
32ec8896 4786 do_sections = TRUE;
252b5132
RH
4787 break;
4788 case 'd':
32ec8896 4789 do_dynamic = TRUE;
252b5132 4790 break;
a952a375 4791 case 'I':
32ec8896 4792 do_histogram = TRUE;
a952a375 4793 break;
779fe533 4794 case 'n':
32ec8896 4795 do_notes = TRUE;
779fe533 4796 break;
4145f1d5 4797 case 'c':
32ec8896 4798 do_archive_index = TRUE;
4145f1d5 4799 break;
1b513401
NC
4800 case 'L':
4801 do_checks = TRUE;
4802 break;
252b5132 4803 case 'x':
6431e409 4804 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4805 break;
09c11c86 4806 case 'p':
6431e409 4807 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4808 break;
4809 case 'R':
6431e409 4810 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4811 break;
0e602686 4812 case 'z':
32ec8896 4813 decompress_dumps = TRUE;
0e602686 4814 break;
252b5132 4815 case 'w':
32ec8896 4816 do_dump = TRUE;
252b5132 4817 if (optarg == 0)
613ff48b 4818 {
32ec8896 4819 do_debugging = TRUE;
613ff48b
CC
4820 dwarf_select_sections_all ();
4821 }
252b5132
RH
4822 else
4823 {
32ec8896 4824 do_debugging = FALSE;
4cb93e3b 4825 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4826 }
4827 break;
2979dc34 4828 case OPTION_DEBUG_DUMP:
32ec8896 4829 do_dump = TRUE;
2979dc34 4830 if (optarg == 0)
32ec8896 4831 do_debugging = TRUE;
2979dc34
JJ
4832 else
4833 {
32ec8896 4834 do_debugging = FALSE;
4cb93e3b 4835 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4836 }
4837 break;
fd2f0033
TT
4838 case OPTION_DWARF_DEPTH:
4839 {
4840 char *cp;
4841
4842 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4843 }
4844 break;
4845 case OPTION_DWARF_START:
4846 {
4847 char *cp;
4848
4849 dwarf_start_die = strtoul (optarg, & cp, 0);
4850 }
4851 break;
4723351a 4852 case OPTION_DWARF_CHECK:
32ec8896 4853 dwarf_check = TRUE;
4723351a 4854 break;
7d9813f1
NA
4855 case OPTION_CTF_DUMP:
4856 do_ctf = TRUE;
6431e409 4857 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4858 break;
4859 case OPTION_CTF_SYMBOLS:
df16e041 4860 free (dump_ctf_symtab_name);
7d9813f1
NA
4861 dump_ctf_symtab_name = strdup (optarg);
4862 break;
4863 case OPTION_CTF_STRINGS:
df16e041 4864 free (dump_ctf_strtab_name);
7d9813f1
NA
4865 dump_ctf_strtab_name = strdup (optarg);
4866 break;
4867 case OPTION_CTF_PARENT:
df16e041 4868 free (dump_ctf_parent_name);
7d9813f1
NA
4869 dump_ctf_parent_name = strdup (optarg);
4870 break;
2c610e4b 4871 case OPTION_DYN_SYMS:
32ec8896 4872 do_dyn_syms = TRUE;
2c610e4b 4873 break;
252b5132
RH
4874#ifdef SUPPORT_DISASSEMBLY
4875 case 'i':
6431e409 4876 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4877 break;
252b5132
RH
4878#endif
4879 case 'v':
4880 print_version (program_name);
4881 break;
4882 case 'V':
32ec8896 4883 do_version = TRUE;
252b5132 4884 break;
d974e256 4885 case 'W':
32ec8896 4886 do_wide = TRUE;
d974e256 4887 break;
0942c7ab
NC
4888 case 'T':
4889 do_not_show_symbol_truncation = TRUE;
4890 break;
79bc120c
NC
4891 case 'C':
4892 do_demangle = TRUE;
4893 if (optarg != NULL)
4894 {
4895 enum demangling_styles style;
4896
4897 style = cplus_demangle_name_to_style (optarg);
4898 if (style == unknown_demangling)
4899 error (_("unknown demangling style `%s'"), optarg);
4900
4901 cplus_demangle_set_style (style);
4902 }
4903 break;
4904 case OPTION_NO_DEMANGLING:
4905 do_demangle = FALSE;
4906 break;
4907 case OPTION_RECURSE_LIMIT:
4908 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
4909 break;
4910 case OPTION_NO_RECURSE_LIMIT:
4911 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
4912 break;
4913 case OPTION_WITH_SYMBOL_VERSIONS:
4914 /* Ignored for backward compatibility. */
4915 break;
4916
252b5132 4917 default:
252b5132
RH
4918 /* xgettext:c-format */
4919 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4920 /* Fall through. */
252b5132 4921 case '?':
92f01d61 4922 usage (stderr);
252b5132
RH
4923 }
4924 }
4925
4d6ed7c8 4926 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4927 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4928 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4929 && !do_section_groups && !do_archive_index
4930 && !do_dyn_syms)
1b513401
NC
4931 {
4932 if (do_checks)
4933 {
4934 check_all = TRUE;
4935 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = TRUE;
4936 do_segments = do_header = do_dump = do_version = TRUE;
4937 do_histogram = do_debugging = do_arch = do_notes = TRUE;
4938 do_section_groups = do_archive_index = do_dyn_syms = TRUE;
4939 }
4940 else
4941 usage (stderr);
4942 }
252b5132
RH
4943}
4944
4945static const char *
d3ba0551 4946get_elf_class (unsigned int elf_class)
252b5132 4947{
b34976b6 4948 static char buff[32];
103f02d3 4949
252b5132
RH
4950 switch (elf_class)
4951 {
4952 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4953 case ELFCLASS32: return "ELF32";
4954 case ELFCLASS64: return "ELF64";
ab5e7794 4955 default:
e9e44622 4956 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4957 return buff;
252b5132
RH
4958 }
4959}
4960
4961static const char *
d3ba0551 4962get_data_encoding (unsigned int encoding)
252b5132 4963{
b34976b6 4964 static char buff[32];
103f02d3 4965
252b5132
RH
4966 switch (encoding)
4967 {
4968 case ELFDATANONE: return _("none");
33c63f9d
CM
4969 case ELFDATA2LSB: return _("2's complement, little endian");
4970 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4971 default:
e9e44622 4972 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4973 return buff;
252b5132
RH
4974 }
4975}
4976
dda8d76d 4977/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4978
32ec8896 4979static bfd_boolean
dda8d76d 4980process_file_header (Filedata * filedata)
252b5132 4981{
dda8d76d
NC
4982 Elf_Internal_Ehdr * header = & filedata->file_header;
4983
4984 if ( header->e_ident[EI_MAG0] != ELFMAG0
4985 || header->e_ident[EI_MAG1] != ELFMAG1
4986 || header->e_ident[EI_MAG2] != ELFMAG2
4987 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4988 {
4989 error
4990 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4991 return FALSE;
252b5132
RH
4992 }
4993
955ff7fc 4994 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 4995
252b5132
RH
4996 if (do_header)
4997 {
32ec8896 4998 unsigned i;
252b5132
RH
4999
5000 printf (_("ELF Header:\n"));
5001 printf (_(" Magic: "));
b34976b6 5002 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5003 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5004 printf ("\n");
5005 printf (_(" Class: %s\n"),
dda8d76d 5006 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5007 printf (_(" Data: %s\n"),
dda8d76d 5008 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5009 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5010 header->e_ident[EI_VERSION],
5011 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5012 ? _(" (current)")
dda8d76d 5013 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5014 ? _(" <unknown>")
789be9f7 5015 : "")));
252b5132 5016 printf (_(" OS/ABI: %s\n"),
dda8d76d 5017 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5018 printf (_(" ABI Version: %d\n"),
dda8d76d 5019 header->e_ident[EI_ABIVERSION]);
252b5132 5020 printf (_(" Type: %s\n"),
dda8d76d 5021 get_file_type (header->e_type));
252b5132 5022 printf (_(" Machine: %s\n"),
dda8d76d 5023 get_machine_name (header->e_machine));
252b5132 5024 printf (_(" Version: 0x%lx\n"),
e8a64888 5025 header->e_version);
76da6bbe 5026
f7a99963 5027 printf (_(" Entry point address: "));
e8a64888 5028 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5029 printf (_("\n Start of program headers: "));
e8a64888 5030 print_vma (header->e_phoff, DEC);
f7a99963 5031 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5032 print_vma (header->e_shoff, DEC);
f7a99963 5033 printf (_(" (bytes into file)\n"));
76da6bbe 5034
252b5132 5035 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5036 header->e_flags,
dda8d76d 5037 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5038 printf (_(" Size of this header: %u (bytes)\n"),
5039 header->e_ehsize);
5040 printf (_(" Size of program headers: %u (bytes)\n"),
5041 header->e_phentsize);
5042 printf (_(" Number of program headers: %u"),
5043 header->e_phnum);
dda8d76d
NC
5044 if (filedata->section_headers != NULL
5045 && header->e_phnum == PN_XNUM
5046 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5047 {
5048 header->e_phnum = filedata->section_headers[0].sh_info;
5049 printf (" (%u)", header->e_phnum);
5050 }
2046a35d 5051 putc ('\n', stdout);
e8a64888
AM
5052 printf (_(" Size of section headers: %u (bytes)\n"),
5053 header->e_shentsize);
5054 printf (_(" Number of section headers: %u"),
5055 header->e_shnum);
dda8d76d 5056 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5057 {
5058 header->e_shnum = filedata->section_headers[0].sh_size;
5059 printf (" (%u)", header->e_shnum);
5060 }
560f3c1c 5061 putc ('\n', stdout);
e8a64888
AM
5062 printf (_(" Section header string table index: %u"),
5063 header->e_shstrndx);
dda8d76d
NC
5064 if (filedata->section_headers != NULL
5065 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5066 {
5067 header->e_shstrndx = filedata->section_headers[0].sh_link;
5068 printf (" (%u)", header->e_shstrndx);
5069 }
5070 if (header->e_shstrndx != SHN_UNDEF
5071 && header->e_shstrndx >= header->e_shnum)
5072 {
5073 header->e_shstrndx = SHN_UNDEF;
5074 printf (_(" <corrupt: out of range>"));
5075 }
560f3c1c
AM
5076 putc ('\n', stdout);
5077 }
5078
dda8d76d 5079 if (filedata->section_headers != NULL)
560f3c1c 5080 {
dda8d76d
NC
5081 if (header->e_phnum == PN_XNUM
5082 && filedata->section_headers[0].sh_info != 0)
5083 header->e_phnum = filedata->section_headers[0].sh_info;
5084 if (header->e_shnum == SHN_UNDEF)
5085 header->e_shnum = filedata->section_headers[0].sh_size;
5086 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5087 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5088 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5089 header->e_shstrndx = SHN_UNDEF;
5090 free (filedata->section_headers);
5091 filedata->section_headers = NULL;
252b5132 5092 }
103f02d3 5093
32ec8896 5094 return TRUE;
9ea033b2
NC
5095}
5096
dda8d76d
NC
5097/* Read in the program headers from FILEDATA and store them in PHEADERS.
5098 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5099
e0a31db1 5100static bfd_boolean
dda8d76d 5101get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5102{
2cf0635d
NC
5103 Elf32_External_Phdr * phdrs;
5104 Elf32_External_Phdr * external;
5105 Elf_Internal_Phdr * internal;
b34976b6 5106 unsigned int i;
dda8d76d
NC
5107 unsigned int size = filedata->file_header.e_phentsize;
5108 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5109
5110 /* PR binutils/17531: Cope with unexpected section header sizes. */
5111 if (size == 0 || num == 0)
5112 return FALSE;
5113 if (size < sizeof * phdrs)
5114 {
5115 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5116 return FALSE;
5117 }
5118 if (size > sizeof * phdrs)
5119 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5120
dda8d76d 5121 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5122 size, num, _("program headers"));
5123 if (phdrs == NULL)
5124 return FALSE;
9ea033b2 5125
91d6fa6a 5126 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5127 i < filedata->file_header.e_phnum;
b34976b6 5128 i++, internal++, external++)
252b5132 5129 {
9ea033b2
NC
5130 internal->p_type = BYTE_GET (external->p_type);
5131 internal->p_offset = BYTE_GET (external->p_offset);
5132 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5133 internal->p_paddr = BYTE_GET (external->p_paddr);
5134 internal->p_filesz = BYTE_GET (external->p_filesz);
5135 internal->p_memsz = BYTE_GET (external->p_memsz);
5136 internal->p_flags = BYTE_GET (external->p_flags);
5137 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5138 }
5139
9ea033b2 5140 free (phdrs);
e0a31db1 5141 return TRUE;
252b5132
RH
5142}
5143
dda8d76d
NC
5144/* Read in the program headers from FILEDATA and store them in PHEADERS.
5145 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5146
e0a31db1 5147static bfd_boolean
dda8d76d 5148get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5149{
2cf0635d
NC
5150 Elf64_External_Phdr * phdrs;
5151 Elf64_External_Phdr * external;
5152 Elf_Internal_Phdr * internal;
b34976b6 5153 unsigned int i;
dda8d76d
NC
5154 unsigned int size = filedata->file_header.e_phentsize;
5155 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5156
5157 /* PR binutils/17531: Cope with unexpected section header sizes. */
5158 if (size == 0 || num == 0)
5159 return FALSE;
5160 if (size < sizeof * phdrs)
5161 {
5162 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5163 return FALSE;
5164 }
5165 if (size > sizeof * phdrs)
5166 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5167
dda8d76d 5168 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5169 size, num, _("program headers"));
a6e9f9df 5170 if (!phdrs)
e0a31db1 5171 return FALSE;
9ea033b2 5172
91d6fa6a 5173 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5174 i < filedata->file_header.e_phnum;
b34976b6 5175 i++, internal++, external++)
9ea033b2
NC
5176 {
5177 internal->p_type = BYTE_GET (external->p_type);
5178 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5179 internal->p_offset = BYTE_GET (external->p_offset);
5180 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5181 internal->p_paddr = BYTE_GET (external->p_paddr);
5182 internal->p_filesz = BYTE_GET (external->p_filesz);
5183 internal->p_memsz = BYTE_GET (external->p_memsz);
5184 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5185 }
5186
5187 free (phdrs);
e0a31db1 5188 return TRUE;
9ea033b2 5189}
252b5132 5190
32ec8896 5191/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5192
32ec8896 5193static bfd_boolean
dda8d76d 5194get_program_headers (Filedata * filedata)
d93f0186 5195{
2cf0635d 5196 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5197
5198 /* Check cache of prior read. */
dda8d76d 5199 if (filedata->program_headers != NULL)
32ec8896 5200 return TRUE;
d93f0186 5201
82156ab7
NC
5202 /* Be kind to memory checkers by looking for
5203 e_phnum values which we know must be invalid. */
dda8d76d 5204 if (filedata->file_header.e_phnum
82156ab7 5205 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5206 >= filedata->file_size)
82156ab7
NC
5207 {
5208 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5209 filedata->file_header.e_phnum);
82156ab7
NC
5210 return FALSE;
5211 }
d93f0186 5212
dda8d76d 5213 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5214 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5215 if (phdrs == NULL)
5216 {
8b73c356 5217 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5218 filedata->file_header.e_phnum);
32ec8896 5219 return FALSE;
d93f0186
NC
5220 }
5221
5222 if (is_32bit_elf
dda8d76d
NC
5223 ? get_32bit_program_headers (filedata, phdrs)
5224 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5225 {
dda8d76d 5226 filedata->program_headers = phdrs;
32ec8896 5227 return TRUE;
d93f0186
NC
5228 }
5229
5230 free (phdrs);
32ec8896 5231 return FALSE;
d93f0186
NC
5232}
5233
32ec8896 5234/* Returns TRUE if the program headers were loaded. */
2f62977e 5235
32ec8896 5236static bfd_boolean
dda8d76d 5237process_program_headers (Filedata * filedata)
252b5132 5238{
2cf0635d 5239 Elf_Internal_Phdr * segment;
b34976b6 5240 unsigned int i;
1a9ccd70 5241 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5242
978c4450
AM
5243 filedata->dynamic_addr = 0;
5244 filedata->dynamic_size = 0;
663f67df 5245
dda8d76d 5246 if (filedata->file_header.e_phnum == 0)
252b5132 5247 {
82f2dbf7 5248 /* PR binutils/12467. */
dda8d76d 5249 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5250 {
5251 warn (_("possibly corrupt ELF header - it has a non-zero program"
5252 " header offset, but no program headers\n"));
5253 return FALSE;
5254 }
82f2dbf7 5255 else if (do_segments)
252b5132 5256 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5257 return TRUE;
252b5132
RH
5258 }
5259
5260 if (do_segments && !do_header)
5261 {
dda8d76d
NC
5262 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5263 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5264 printf (ngettext ("There is %d program header, starting at offset %s\n",
5265 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5266 filedata->file_header.e_phnum),
5267 filedata->file_header.e_phnum,
5268 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5269 }
5270
dda8d76d 5271 if (! get_program_headers (filedata))
6b4bf3bc 5272 return TRUE;
103f02d3 5273
252b5132
RH
5274 if (do_segments)
5275 {
dda8d76d 5276 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5277 printf (_("\nProgram Headers:\n"));
5278 else
5279 printf (_("\nProgram Headers:\n"));
76da6bbe 5280
f7a99963
NC
5281 if (is_32bit_elf)
5282 printf
5283 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5284 else if (do_wide)
5285 printf
5286 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5287 else
5288 {
5289 printf
5290 (_(" Type Offset VirtAddr PhysAddr\n"));
5291 printf
5292 (_(" FileSiz MemSiz Flags Align\n"));
5293 }
252b5132
RH
5294 }
5295
dda8d76d
NC
5296 for (i = 0, segment = filedata->program_headers;
5297 i < filedata->file_header.e_phnum;
b34976b6 5298 i++, segment++)
252b5132
RH
5299 {
5300 if (do_segments)
5301 {
dda8d76d 5302 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5303
5304 if (is_32bit_elf)
5305 {
5306 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5307 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5308 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5309 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5310 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5311 printf ("%c%c%c ",
5312 (segment->p_flags & PF_R ? 'R' : ' '),
5313 (segment->p_flags & PF_W ? 'W' : ' '),
5314 (segment->p_flags & PF_X ? 'E' : ' '));
5315 printf ("%#lx", (unsigned long) segment->p_align);
5316 }
d974e256
JJ
5317 else if (do_wide)
5318 {
5319 if ((unsigned long) segment->p_offset == segment->p_offset)
5320 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5321 else
5322 {
5323 print_vma (segment->p_offset, FULL_HEX);
5324 putchar (' ');
5325 }
5326
5327 print_vma (segment->p_vaddr, FULL_HEX);
5328 putchar (' ');
5329 print_vma (segment->p_paddr, FULL_HEX);
5330 putchar (' ');
5331
5332 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5333 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5334 else
5335 {
5336 print_vma (segment->p_filesz, FULL_HEX);
5337 putchar (' ');
5338 }
5339
5340 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5341 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5342 else
5343 {
f48e6c45 5344 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5345 }
5346
5347 printf (" %c%c%c ",
5348 (segment->p_flags & PF_R ? 'R' : ' '),
5349 (segment->p_flags & PF_W ? 'W' : ' '),
5350 (segment->p_flags & PF_X ? 'E' : ' '));
5351
5352 if ((unsigned long) segment->p_align == segment->p_align)
5353 printf ("%#lx", (unsigned long) segment->p_align);
5354 else
5355 {
5356 print_vma (segment->p_align, PREFIX_HEX);
5357 }
5358 }
f7a99963
NC
5359 else
5360 {
5361 print_vma (segment->p_offset, FULL_HEX);
5362 putchar (' ');
5363 print_vma (segment->p_vaddr, FULL_HEX);
5364 putchar (' ');
5365 print_vma (segment->p_paddr, FULL_HEX);
5366 printf ("\n ");
5367 print_vma (segment->p_filesz, FULL_HEX);
5368 putchar (' ');
5369 print_vma (segment->p_memsz, FULL_HEX);
5370 printf (" %c%c%c ",
5371 (segment->p_flags & PF_R ? 'R' : ' '),
5372 (segment->p_flags & PF_W ? 'W' : ' '),
5373 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5374 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5375 }
252b5132 5376
1a9ccd70
NC
5377 putc ('\n', stdout);
5378 }
f54498b4 5379
252b5132
RH
5380 switch (segment->p_type)
5381 {
1a9ccd70 5382 case PT_LOAD:
502d895c
NC
5383#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5384 required by the ELF standard, several programs, including the Linux
5385 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5386 if (previous_load
5387 && previous_load->p_vaddr > segment->p_vaddr)
5388 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5389#endif
1a9ccd70
NC
5390 if (segment->p_memsz < segment->p_filesz)
5391 error (_("the segment's file size is larger than its memory size\n"));
5392 previous_load = segment;
5393 break;
5394
5395 case PT_PHDR:
5396 /* PR 20815 - Verify that the program header is loaded into memory. */
5397 if (i > 0 && previous_load != NULL)
5398 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5399 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5400 {
5401 unsigned int j;
5402
dda8d76d 5403 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5404 {
5405 Elf_Internal_Phdr *load = filedata->program_headers + j;
5406 if (load->p_type == PT_LOAD
5407 && load->p_offset <= segment->p_offset
5408 && (load->p_offset + load->p_filesz
5409 >= segment->p_offset + segment->p_filesz)
5410 && load->p_vaddr <= segment->p_vaddr
5411 && (load->p_vaddr + load->p_filesz
5412 >= segment->p_vaddr + segment->p_filesz))
5413 break;
5414 }
dda8d76d 5415 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5416 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5417 }
5418 break;
5419
252b5132 5420 case PT_DYNAMIC:
978c4450 5421 if (filedata->dynamic_addr)
252b5132
RH
5422 error (_("more than one dynamic segment\n"));
5423
20737c13
AM
5424 /* By default, assume that the .dynamic section is the first
5425 section in the DYNAMIC segment. */
978c4450
AM
5426 filedata->dynamic_addr = segment->p_offset;
5427 filedata->dynamic_size = segment->p_filesz;
20737c13 5428
b2d38a17
NC
5429 /* Try to locate the .dynamic section. If there is
5430 a section header table, we can easily locate it. */
dda8d76d 5431 if (filedata->section_headers != NULL)
b2d38a17 5432 {
2cf0635d 5433 Elf_Internal_Shdr * sec;
b2d38a17 5434
dda8d76d 5435 sec = find_section (filedata, ".dynamic");
89fac5e3 5436 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5437 {
28f997cf
TG
5438 /* A corresponding .dynamic section is expected, but on
5439 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5440 if (!is_ia64_vms (filedata))
28f997cf 5441 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5442 break;
5443 }
5444
42bb2e33 5445 if (sec->sh_type == SHT_NOBITS)
20737c13 5446 {
978c4450 5447 filedata->dynamic_size = 0;
20737c13
AM
5448 break;
5449 }
42bb2e33 5450
978c4450
AM
5451 filedata->dynamic_addr = sec->sh_offset;
5452 filedata->dynamic_size = sec->sh_size;
b2d38a17 5453
8ac10c5b
L
5454 /* The PT_DYNAMIC segment, which is used by the run-time
5455 loader, should exactly match the .dynamic section. */
5456 if (do_checks
5457 && (filedata->dynamic_addr != segment->p_offset
5458 || filedata->dynamic_size != segment->p_filesz))
5459 warn (_("\
5460the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5461 }
39e224f6
MW
5462
5463 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5464 segment. Check this after matching against the section headers
5465 so we don't warn on debuginfo file (which have NOBITS .dynamic
5466 sections). */
978c4450
AM
5467 if (filedata->dynamic_addr > filedata->file_size
5468 || (filedata->dynamic_size
5469 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5470 {
5471 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5472 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5473 }
252b5132
RH
5474 break;
5475
5476 case PT_INTERP:
978c4450
AM
5477 if (fseek (filedata->handle,
5478 filedata->archive_file_offset + (long) segment->p_offset,
fb52b2f4 5479 SEEK_SET))
252b5132
RH
5480 error (_("Unable to find program interpreter name\n"));
5481 else
5482 {
f8eae8b2 5483 char fmt [32];
9495b2e6 5484 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5485
5486 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5487 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5488
978c4450
AM
5489 filedata->program_interpreter[0] = 0;
5490 if (fscanf (filedata->handle, fmt,
5491 filedata->program_interpreter) <= 0)
7bd7b3ef 5492 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5493
5494 if (do_segments)
f54498b4 5495 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5496 filedata->program_interpreter);
252b5132
RH
5497 }
5498 break;
5499 }
252b5132
RH
5500 }
5501
dda8d76d
NC
5502 if (do_segments
5503 && filedata->section_headers != NULL
5504 && filedata->string_table != NULL)
252b5132
RH
5505 {
5506 printf (_("\n Section to Segment mapping:\n"));
5507 printf (_(" Segment Sections...\n"));
5508
dda8d76d 5509 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5510 {
9ad5cbcf 5511 unsigned int j;
2cf0635d 5512 Elf_Internal_Shdr * section;
252b5132 5513
dda8d76d
NC
5514 segment = filedata->program_headers + i;
5515 section = filedata->section_headers + 1;
252b5132
RH
5516
5517 printf (" %2.2d ", i);
5518
dda8d76d 5519 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5520 {
f4638467
AM
5521 if (!ELF_TBSS_SPECIAL (section, segment)
5522 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5523 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5524 }
5525
5526 putc ('\n',stdout);
5527 }
5528 }
5529
32ec8896 5530 return TRUE;
252b5132
RH
5531}
5532
5533
d93f0186
NC
5534/* Find the file offset corresponding to VMA by using the program headers. */
5535
5536static long
dda8d76d 5537offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5538{
2cf0635d 5539 Elf_Internal_Phdr * seg;
d93f0186 5540
dda8d76d 5541 if (! get_program_headers (filedata))
d93f0186
NC
5542 {
5543 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5544 return (long) vma;
5545 }
5546
dda8d76d
NC
5547 for (seg = filedata->program_headers;
5548 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5549 ++seg)
5550 {
5551 if (seg->p_type != PT_LOAD)
5552 continue;
5553
5554 if (vma >= (seg->p_vaddr & -seg->p_align)
5555 && vma + size <= seg->p_vaddr + seg->p_filesz)
5556 return vma - seg->p_vaddr + seg->p_offset;
5557 }
5558
5559 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5560 (unsigned long) vma);
d93f0186
NC
5561 return (long) vma;
5562}
5563
5564
dda8d76d
NC
5565/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5566 If PROBE is true, this is just a probe and we do not generate any error
5567 messages if the load fails. */
049b0c3a
NC
5568
5569static bfd_boolean
dda8d76d 5570get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5571{
2cf0635d
NC
5572 Elf32_External_Shdr * shdrs;
5573 Elf_Internal_Shdr * internal;
dda8d76d
NC
5574 unsigned int i;
5575 unsigned int size = filedata->file_header.e_shentsize;
5576 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5577
5578 /* PR binutils/17531: Cope with unexpected section header sizes. */
5579 if (size == 0 || num == 0)
5580 return FALSE;
5581 if (size < sizeof * shdrs)
5582 {
5583 if (! probe)
5584 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5585 return FALSE;
5586 }
5587 if (!probe && size > sizeof * shdrs)
5588 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5589
dda8d76d 5590 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5591 size, num,
5592 probe ? NULL : _("section headers"));
5593 if (shdrs == NULL)
5594 return FALSE;
252b5132 5595
dda8d76d
NC
5596 free (filedata->section_headers);
5597 filedata->section_headers = (Elf_Internal_Shdr *)
5598 cmalloc (num, sizeof (Elf_Internal_Shdr));
5599 if (filedata->section_headers == NULL)
252b5132 5600 {
049b0c3a 5601 if (!probe)
8b73c356 5602 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5603 free (shdrs);
049b0c3a 5604 return FALSE;
252b5132
RH
5605 }
5606
dda8d76d 5607 for (i = 0, internal = filedata->section_headers;
560f3c1c 5608 i < num;
b34976b6 5609 i++, internal++)
252b5132
RH
5610 {
5611 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5612 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5613 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5614 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5615 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5616 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5617 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5618 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5619 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5620 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5621 if (!probe && internal->sh_link > num)
5622 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5623 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5624 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5625 }
5626
5627 free (shdrs);
049b0c3a 5628 return TRUE;
252b5132
RH
5629}
5630
dda8d76d
NC
5631/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5632
049b0c3a 5633static bfd_boolean
dda8d76d 5634get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5635{
dda8d76d
NC
5636 Elf64_External_Shdr * shdrs;
5637 Elf_Internal_Shdr * internal;
5638 unsigned int i;
5639 unsigned int size = filedata->file_header.e_shentsize;
5640 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5641
5642 /* PR binutils/17531: Cope with unexpected section header sizes. */
5643 if (size == 0 || num == 0)
5644 return FALSE;
dda8d76d 5645
049b0c3a
NC
5646 if (size < sizeof * shdrs)
5647 {
5648 if (! probe)
5649 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5650 return FALSE;
5651 }
dda8d76d 5652
049b0c3a
NC
5653 if (! probe && size > sizeof * shdrs)
5654 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5655
dda8d76d
NC
5656 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5657 filedata->file_header.e_shoff,
049b0c3a
NC
5658 size, num,
5659 probe ? NULL : _("section headers"));
5660 if (shdrs == NULL)
5661 return FALSE;
9ea033b2 5662
dda8d76d
NC
5663 free (filedata->section_headers);
5664 filedata->section_headers = (Elf_Internal_Shdr *)
5665 cmalloc (num, sizeof (Elf_Internal_Shdr));
5666 if (filedata->section_headers == NULL)
9ea033b2 5667 {
049b0c3a 5668 if (! probe)
8b73c356 5669 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5670 free (shdrs);
049b0c3a 5671 return FALSE;
9ea033b2
NC
5672 }
5673
dda8d76d 5674 for (i = 0, internal = filedata->section_headers;
560f3c1c 5675 i < num;
b34976b6 5676 i++, internal++)
9ea033b2
NC
5677 {
5678 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5679 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5680 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5681 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5682 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5683 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5684 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5685 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5686 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5687 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5688 if (!probe && internal->sh_link > num)
5689 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5690 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5691 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5692 }
5693
5694 free (shdrs);
049b0c3a 5695 return TRUE;
9ea033b2
NC
5696}
5697
252b5132 5698static Elf_Internal_Sym *
dda8d76d
NC
5699get_32bit_elf_symbols (Filedata * filedata,
5700 Elf_Internal_Shdr * section,
5701 unsigned long * num_syms_return)
252b5132 5702{
ba5cdace 5703 unsigned long number = 0;
dd24e3da 5704 Elf32_External_Sym * esyms = NULL;
ba5cdace 5705 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5706 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5707 Elf_Internal_Sym * psym;
b34976b6 5708 unsigned int j;
e3d39609 5709 elf_section_list * entry;
252b5132 5710
c9c1d674
EG
5711 if (section->sh_size == 0)
5712 {
5713 if (num_syms_return != NULL)
5714 * num_syms_return = 0;
5715 return NULL;
5716 }
5717
dd24e3da 5718 /* Run some sanity checks first. */
c9c1d674 5719 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5720 {
c9c1d674 5721 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5722 printable_section_name (filedata, section),
5723 (unsigned long) section->sh_entsize);
ba5cdace 5724 goto exit_point;
dd24e3da
NC
5725 }
5726
dda8d76d 5727 if (section->sh_size > filedata->file_size)
f54498b4
NC
5728 {
5729 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5730 printable_section_name (filedata, section),
5731 (unsigned long) section->sh_size);
f54498b4
NC
5732 goto exit_point;
5733 }
5734
dd24e3da
NC
5735 number = section->sh_size / section->sh_entsize;
5736
5737 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5738 {
c9c1d674 5739 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5740 (unsigned long) section->sh_size,
dda8d76d 5741 printable_section_name (filedata, section),
8066deb1 5742 (unsigned long) section->sh_entsize);
ba5cdace 5743 goto exit_point;
dd24e3da
NC
5744 }
5745
dda8d76d 5746 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5747 section->sh_size, _("symbols"));
dd24e3da 5748 if (esyms == NULL)
ba5cdace 5749 goto exit_point;
252b5132 5750
e3d39609 5751 shndx = NULL;
978c4450 5752 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5753 {
5754 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5755 continue;
5756
5757 if (shndx != NULL)
5758 {
5759 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5760 free (shndx);
5761 }
5762
5763 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5764 entry->hdr->sh_offset,
5765 1, entry->hdr->sh_size,
5766 _("symbol table section indices"));
5767 if (shndx == NULL)
5768 goto exit_point;
5769
5770 /* PR17531: file: heap-buffer-overflow */
5771 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5772 {
5773 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5774 printable_section_name (filedata, entry->hdr),
5775 (unsigned long) entry->hdr->sh_size,
5776 (unsigned long) section->sh_size);
5777 goto exit_point;
c9c1d674 5778 }
e3d39609 5779 }
9ad5cbcf 5780
3f5e193b 5781 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5782
5783 if (isyms == NULL)
5784 {
8b73c356
NC
5785 error (_("Out of memory reading %lu symbols\n"),
5786 (unsigned long) number);
dd24e3da 5787 goto exit_point;
252b5132
RH
5788 }
5789
dd24e3da 5790 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5791 {
5792 psym->st_name = BYTE_GET (esyms[j].st_name);
5793 psym->st_value = BYTE_GET (esyms[j].st_value);
5794 psym->st_size = BYTE_GET (esyms[j].st_size);
5795 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5796 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5797 psym->st_shndx
5798 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5799 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5800 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5801 psym->st_info = BYTE_GET (esyms[j].st_info);
5802 psym->st_other = BYTE_GET (esyms[j].st_other);
5803 }
5804
dd24e3da 5805 exit_point:
e3d39609
NC
5806 free (shndx);
5807 free (esyms);
252b5132 5808
ba5cdace
NC
5809 if (num_syms_return != NULL)
5810 * num_syms_return = isyms == NULL ? 0 : number;
5811
252b5132
RH
5812 return isyms;
5813}
5814
9ea033b2 5815static Elf_Internal_Sym *
dda8d76d
NC
5816get_64bit_elf_symbols (Filedata * filedata,
5817 Elf_Internal_Shdr * section,
5818 unsigned long * num_syms_return)
9ea033b2 5819{
ba5cdace
NC
5820 unsigned long number = 0;
5821 Elf64_External_Sym * esyms = NULL;
5822 Elf_External_Sym_Shndx * shndx = NULL;
5823 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5824 Elf_Internal_Sym * psym;
b34976b6 5825 unsigned int j;
e3d39609 5826 elf_section_list * entry;
9ea033b2 5827
c9c1d674
EG
5828 if (section->sh_size == 0)
5829 {
5830 if (num_syms_return != NULL)
5831 * num_syms_return = 0;
5832 return NULL;
5833 }
5834
dd24e3da 5835 /* Run some sanity checks first. */
c9c1d674 5836 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5837 {
c9c1d674 5838 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5839 printable_section_name (filedata, section),
8066deb1 5840 (unsigned long) section->sh_entsize);
ba5cdace 5841 goto exit_point;
dd24e3da
NC
5842 }
5843
dda8d76d 5844 if (section->sh_size > filedata->file_size)
f54498b4
NC
5845 {
5846 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5847 printable_section_name (filedata, section),
8066deb1 5848 (unsigned long) section->sh_size);
f54498b4
NC
5849 goto exit_point;
5850 }
5851
dd24e3da
NC
5852 number = section->sh_size / section->sh_entsize;
5853
5854 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5855 {
c9c1d674 5856 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5857 (unsigned long) section->sh_size,
dda8d76d 5858 printable_section_name (filedata, section),
8066deb1 5859 (unsigned long) section->sh_entsize);
ba5cdace 5860 goto exit_point;
dd24e3da
NC
5861 }
5862
dda8d76d 5863 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5864 section->sh_size, _("symbols"));
a6e9f9df 5865 if (!esyms)
ba5cdace 5866 goto exit_point;
9ea033b2 5867
e3d39609 5868 shndx = NULL;
978c4450 5869 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5870 {
5871 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5872 continue;
5873
5874 if (shndx != NULL)
5875 {
5876 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5877 free (shndx);
c9c1d674 5878 }
e3d39609
NC
5879
5880 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5881 entry->hdr->sh_offset,
5882 1, entry->hdr->sh_size,
5883 _("symbol table section indices"));
5884 if (shndx == NULL)
5885 goto exit_point;
5886
5887 /* PR17531: file: heap-buffer-overflow */
5888 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5889 {
5890 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5891 printable_section_name (filedata, entry->hdr),
5892 (unsigned long) entry->hdr->sh_size,
5893 (unsigned long) section->sh_size);
5894 goto exit_point;
5895 }
5896 }
9ad5cbcf 5897
3f5e193b 5898 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5899
5900 if (isyms == NULL)
5901 {
8b73c356
NC
5902 error (_("Out of memory reading %lu symbols\n"),
5903 (unsigned long) number);
ba5cdace 5904 goto exit_point;
9ea033b2
NC
5905 }
5906
ba5cdace 5907 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5908 {
5909 psym->st_name = BYTE_GET (esyms[j].st_name);
5910 psym->st_info = BYTE_GET (esyms[j].st_info);
5911 psym->st_other = BYTE_GET (esyms[j].st_other);
5912 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5913
4fbb74a6 5914 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5915 psym->st_shndx
5916 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5917 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5918 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5919
66543521
AM
5920 psym->st_value = BYTE_GET (esyms[j].st_value);
5921 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5922 }
5923
ba5cdace 5924 exit_point:
e3d39609
NC
5925 free (shndx);
5926 free (esyms);
ba5cdace
NC
5927
5928 if (num_syms_return != NULL)
5929 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5930
5931 return isyms;
5932}
5933
d1133906 5934static const char *
dda8d76d 5935get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5936{
5477e8a0 5937 static char buff[1024];
2cf0635d 5938 char * p = buff;
32ec8896
NC
5939 unsigned int field_size = is_32bit_elf ? 8 : 16;
5940 signed int sindex;
5941 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5942 bfd_vma os_flags = 0;
5943 bfd_vma proc_flags = 0;
5944 bfd_vma unknown_flags = 0;
148b93f2 5945 static const struct
5477e8a0 5946 {
2cf0635d 5947 const char * str;
32ec8896 5948 unsigned int len;
5477e8a0
L
5949 }
5950 flags [] =
5951 {
cfcac11d
NC
5952 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5953 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5954 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5955 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5956 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5957 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5958 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5959 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5960 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5961 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5962 /* IA-64 specific. */
5963 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5964 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5965 /* IA-64 OpenVMS specific. */
5966 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5967 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5968 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5969 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5970 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5971 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5972 /* Generic. */
cfcac11d 5973 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5974 /* SPARC specific. */
77115a4a 5975 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5976 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5977 /* ARM specific. */
5978 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5979 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5980 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5981 /* GNU specific. */
5982 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5983 /* VLE specific. */
5984 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5985 };
5986
5987 if (do_section_details)
5988 {
8d5ff12c
L
5989 sprintf (buff, "[%*.*lx]: ",
5990 field_size, field_size, (unsigned long) sh_flags);
5991 p += field_size + 4;
5477e8a0 5992 }
76da6bbe 5993
d1133906
NC
5994 while (sh_flags)
5995 {
5996 bfd_vma flag;
5997
5998 flag = sh_flags & - sh_flags;
5999 sh_flags &= ~ flag;
76da6bbe 6000
5477e8a0 6001 if (do_section_details)
d1133906 6002 {
5477e8a0
L
6003 switch (flag)
6004 {
91d6fa6a
NC
6005 case SHF_WRITE: sindex = 0; break;
6006 case SHF_ALLOC: sindex = 1; break;
6007 case SHF_EXECINSTR: sindex = 2; break;
6008 case SHF_MERGE: sindex = 3; break;
6009 case SHF_STRINGS: sindex = 4; break;
6010 case SHF_INFO_LINK: sindex = 5; break;
6011 case SHF_LINK_ORDER: sindex = 6; break;
6012 case SHF_OS_NONCONFORMING: sindex = 7; break;
6013 case SHF_GROUP: sindex = 8; break;
6014 case SHF_TLS: sindex = 9; break;
18ae9cc1 6015 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6016 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 6017 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 6018
5477e8a0 6019 default:
91d6fa6a 6020 sindex = -1;
dda8d76d 6021 switch (filedata->file_header.e_machine)
148b93f2 6022 {
cfcac11d 6023 case EM_IA_64:
148b93f2 6024 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6025 sindex = 10;
148b93f2 6026 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6027 sindex = 11;
148b93f2 6028#ifdef BFD64
dda8d76d 6029 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6030 switch (flag)
6031 {
91d6fa6a
NC
6032 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6033 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6034 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6035 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6036 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6037 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6038 default: break;
6039 }
6040#endif
cfcac11d
NC
6041 break;
6042
caa83f8b 6043 case EM_386:
22abe556 6044 case EM_IAMCU:
caa83f8b 6045 case EM_X86_64:
7f502d6c 6046 case EM_L1OM:
7a9068fe 6047 case EM_K1OM:
cfcac11d
NC
6048 case EM_OLD_SPARCV9:
6049 case EM_SPARC32PLUS:
6050 case EM_SPARCV9:
6051 case EM_SPARC:
18ae9cc1 6052 if (flag == SHF_ORDERED)
91d6fa6a 6053 sindex = 19;
cfcac11d 6054 break;
ac4c9b04
MG
6055
6056 case EM_ARM:
6057 switch (flag)
6058 {
6059 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6060 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6061 case SHF_COMDEF: sindex = 23; break;
6062 default: break;
6063 }
6064 break;
83eef883
AFB
6065 case EM_PPC:
6066 if (flag == SHF_PPC_VLE)
6067 sindex = 25;
6068 break;
ac4c9b04 6069
cfcac11d
NC
6070 default:
6071 break;
148b93f2 6072 }
5477e8a0
L
6073 }
6074
91d6fa6a 6075 if (sindex != -1)
5477e8a0 6076 {
8d5ff12c
L
6077 if (p != buff + field_size + 4)
6078 {
6079 if (size < (10 + 2))
bee0ee85
NC
6080 {
6081 warn (_("Internal error: not enough buffer room for section flag info"));
6082 return _("<unknown>");
6083 }
8d5ff12c
L
6084 size -= 2;
6085 *p++ = ',';
6086 *p++ = ' ';
6087 }
6088
91d6fa6a
NC
6089 size -= flags [sindex].len;
6090 p = stpcpy (p, flags [sindex].str);
5477e8a0 6091 }
3b22753a 6092 else if (flag & SHF_MASKOS)
8d5ff12c 6093 os_flags |= flag;
d1133906 6094 else if (flag & SHF_MASKPROC)
8d5ff12c 6095 proc_flags |= flag;
d1133906 6096 else
8d5ff12c 6097 unknown_flags |= flag;
5477e8a0
L
6098 }
6099 else
6100 {
6101 switch (flag)
6102 {
6103 case SHF_WRITE: *p = 'W'; break;
6104 case SHF_ALLOC: *p = 'A'; break;
6105 case SHF_EXECINSTR: *p = 'X'; break;
6106 case SHF_MERGE: *p = 'M'; break;
6107 case SHF_STRINGS: *p = 'S'; break;
6108 case SHF_INFO_LINK: *p = 'I'; break;
6109 case SHF_LINK_ORDER: *p = 'L'; break;
6110 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6111 case SHF_GROUP: *p = 'G'; break;
6112 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6113 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6114 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 6115 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
6116
6117 default:
dda8d76d
NC
6118 if ((filedata->file_header.e_machine == EM_X86_64
6119 || filedata->file_header.e_machine == EM_L1OM
6120 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6121 && flag == SHF_X86_64_LARGE)
6122 *p = 'l';
dda8d76d 6123 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6124 && flag == SHF_ARM_PURECODE)
91f68a68 6125 *p = 'y';
dda8d76d 6126 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
6127 && flag == SHF_PPC_VLE)
6128 *p = 'v';
5477e8a0
L
6129 else if (flag & SHF_MASKOS)
6130 {
6131 *p = 'o';
6132 sh_flags &= ~ SHF_MASKOS;
6133 }
6134 else if (flag & SHF_MASKPROC)
6135 {
6136 *p = 'p';
6137 sh_flags &= ~ SHF_MASKPROC;
6138 }
6139 else
6140 *p = 'x';
6141 break;
6142 }
6143 p++;
d1133906
NC
6144 }
6145 }
76da6bbe 6146
8d5ff12c
L
6147 if (do_section_details)
6148 {
6149 if (os_flags)
6150 {
6151 size -= 5 + field_size;
6152 if (p != buff + field_size + 4)
6153 {
6154 if (size < (2 + 1))
bee0ee85
NC
6155 {
6156 warn (_("Internal error: not enough buffer room for section flag info"));
6157 return _("<unknown>");
6158 }
8d5ff12c
L
6159 size -= 2;
6160 *p++ = ',';
6161 *p++ = ' ';
6162 }
6163 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6164 (unsigned long) os_flags);
6165 p += 5 + field_size;
6166 }
6167 if (proc_flags)
6168 {
6169 size -= 7 + field_size;
6170 if (p != buff + field_size + 4)
6171 {
6172 if (size < (2 + 1))
bee0ee85
NC
6173 {
6174 warn (_("Internal error: not enough buffer room for section flag info"));
6175 return _("<unknown>");
6176 }
8d5ff12c
L
6177 size -= 2;
6178 *p++ = ',';
6179 *p++ = ' ';
6180 }
6181 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6182 (unsigned long) proc_flags);
6183 p += 7 + field_size;
6184 }
6185 if (unknown_flags)
6186 {
6187 size -= 10 + field_size;
6188 if (p != buff + field_size + 4)
6189 {
6190 if (size < (2 + 1))
bee0ee85
NC
6191 {
6192 warn (_("Internal error: not enough buffer room for section flag info"));
6193 return _("<unknown>");
6194 }
8d5ff12c
L
6195 size -= 2;
6196 *p++ = ',';
6197 *p++ = ' ';
6198 }
2b692964 6199 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6200 (unsigned long) unknown_flags);
6201 p += 10 + field_size;
6202 }
6203 }
6204
e9e44622 6205 *p = '\0';
d1133906
NC
6206 return buff;
6207}
6208
5844b465 6209static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6210get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6211{
6212 if (is_32bit_elf)
6213 {
6214 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6215
ebdf1ebf
NC
6216 if (size < sizeof (* echdr))
6217 {
6218 error (_("Compressed section is too small even for a compression header\n"));
6219 return 0;
6220 }
6221
77115a4a
L
6222 chdr->ch_type = BYTE_GET (echdr->ch_type);
6223 chdr->ch_size = BYTE_GET (echdr->ch_size);
6224 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6225 return sizeof (*echdr);
6226 }
6227 else
6228 {
6229 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6230
ebdf1ebf
NC
6231 if (size < sizeof (* echdr))
6232 {
6233 error (_("Compressed section is too small even for a compression header\n"));
6234 return 0;
6235 }
6236
77115a4a
L
6237 chdr->ch_type = BYTE_GET (echdr->ch_type);
6238 chdr->ch_size = BYTE_GET (echdr->ch_size);
6239 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6240 return sizeof (*echdr);
6241 }
6242}
6243
32ec8896 6244static bfd_boolean
dda8d76d 6245process_section_headers (Filedata * filedata)
252b5132 6246{
2cf0635d 6247 Elf_Internal_Shdr * section;
b34976b6 6248 unsigned int i;
252b5132 6249
8fb879cd 6250 free (filedata->section_headers);
dda8d76d 6251 filedata->section_headers = NULL;
978c4450
AM
6252 free (filedata->dynamic_symbols);
6253 filedata->dynamic_symbols = NULL;
6254 filedata->num_dynamic_syms = 0;
6255 free (filedata->dynamic_strings);
6256 filedata->dynamic_strings = NULL;
6257 filedata->dynamic_strings_length = 0;
6258 free (filedata->dynamic_syminfo);
6259 filedata->dynamic_syminfo = NULL;
6260 while (filedata->symtab_shndx_list != NULL)
8ff66993 6261 {
978c4450
AM
6262 elf_section_list *next = filedata->symtab_shndx_list->next;
6263 free (filedata->symtab_shndx_list);
6264 filedata->symtab_shndx_list = next;
8ff66993 6265 }
252b5132 6266
dda8d76d 6267 if (filedata->file_header.e_shnum == 0)
252b5132 6268 {
82f2dbf7 6269 /* PR binutils/12467. */
dda8d76d 6270 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6271 {
6272 warn (_("possibly corrupt ELF file header - it has a non-zero"
6273 " section header offset, but no section headers\n"));
6274 return FALSE;
6275 }
82f2dbf7 6276 else if (do_sections)
252b5132
RH
6277 printf (_("\nThere are no sections in this file.\n"));
6278
32ec8896 6279 return TRUE;
252b5132
RH
6280 }
6281
6282 if (do_sections && !do_header)
d3a49aa8
AM
6283 printf (ngettext ("There is %d section header, "
6284 "starting at offset 0x%lx:\n",
6285 "There are %d section headers, "
6286 "starting at offset 0x%lx:\n",
dda8d76d
NC
6287 filedata->file_header.e_shnum),
6288 filedata->file_header.e_shnum,
6289 (unsigned long) filedata->file_header.e_shoff);
252b5132 6290
9ea033b2
NC
6291 if (is_32bit_elf)
6292 {
dda8d76d 6293 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6294 return FALSE;
6295 }
6296 else
6297 {
dda8d76d 6298 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6299 return FALSE;
9ea033b2 6300 }
252b5132
RH
6301
6302 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6303 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6304 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6305 {
dda8d76d 6306 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6307
c256ffe7
JJ
6308 if (section->sh_size != 0)
6309 {
dda8d76d
NC
6310 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6311 1, section->sh_size,
6312 _("string table"));
0de14b54 6313
dda8d76d 6314 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6315 }
252b5132
RH
6316 }
6317
6318 /* Scan the sections for the dynamic symbol table
e3c8793a 6319 and dynamic string table and debug sections. */
89fac5e3 6320 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6321 switch (filedata->file_header.e_machine)
89fac5e3
RS
6322 {
6323 case EM_MIPS:
6324 case EM_MIPS_RS3_LE:
6325 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6326 FDE addresses. However, the ABI also has a semi-official ILP32
6327 variant for which the normal FDE address size rules apply.
6328
6329 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6330 section, where XX is the size of longs in bits. Unfortunately,
6331 earlier compilers provided no way of distinguishing ILP32 objects
6332 from LP64 objects, so if there's any doubt, we should assume that
6333 the official LP64 form is being used. */
dda8d76d
NC
6334 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6335 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6336 eh_addr_size = 8;
6337 break;
0f56a26a
DD
6338
6339 case EM_H8_300:
6340 case EM_H8_300H:
dda8d76d 6341 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6342 {
6343 case E_H8_MACH_H8300:
6344 case E_H8_MACH_H8300HN:
6345 case E_H8_MACH_H8300SN:
6346 case E_H8_MACH_H8300SXN:
6347 eh_addr_size = 2;
6348 break;
6349 case E_H8_MACH_H8300H:
6350 case E_H8_MACH_H8300S:
6351 case E_H8_MACH_H8300SX:
6352 eh_addr_size = 4;
6353 break;
6354 }
f4236fe4
DD
6355 break;
6356
ff7eeb89 6357 case EM_M32C_OLD:
f4236fe4 6358 case EM_M32C:
dda8d76d 6359 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6360 {
6361 case EF_M32C_CPU_M16C:
6362 eh_addr_size = 2;
6363 break;
6364 }
6365 break;
89fac5e3
RS
6366 }
6367
76ca31c0
NC
6368#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6369 do \
6370 { \
6371 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6372 if (section->sh_entsize != expected_entsize) \
9dd3a467 6373 { \
76ca31c0
NC
6374 char buf[40]; \
6375 sprintf_vma (buf, section->sh_entsize); \
6376 /* Note: coded this way so that there is a single string for \
6377 translation. */ \
6378 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6379 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6380 (unsigned) expected_entsize); \
9dd3a467 6381 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6382 } \
6383 } \
08d8fa11 6384 while (0)
9dd3a467
NC
6385
6386#define CHECK_ENTSIZE(section, i, type) \
1b513401 6387 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6388 sizeof (Elf64_External_##type))
6389
dda8d76d
NC
6390 for (i = 0, section = filedata->section_headers;
6391 i < filedata->file_header.e_shnum;
b34976b6 6392 i++, section++)
252b5132 6393 {
2cf0635d 6394 char * name = SECTION_NAME (section);
252b5132 6395
1b513401
NC
6396 /* Run some sanity checks on the headers and
6397 possibly fill in some file data as well. */
6398 switch (section->sh_type)
252b5132 6399 {
1b513401 6400 case SHT_DYNSYM:
978c4450 6401 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6402 {
6403 error (_("File contains multiple dynamic symbol tables\n"));
6404 continue;
6405 }
6406
08d8fa11 6407 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6408 filedata->dynamic_symbols
6409 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6410 filedata->dynamic_symtab_section = section;
1b513401
NC
6411 break;
6412
6413 case SHT_STRTAB:
6414 if (streq (name, ".dynstr"))
252b5132 6415 {
1b513401
NC
6416 if (filedata->dynamic_strings != NULL)
6417 {
6418 error (_("File contains multiple dynamic string tables\n"));
6419 continue;
6420 }
6421
6422 filedata->dynamic_strings
6423 = (char *) get_data (NULL, filedata, section->sh_offset,
6424 1, section->sh_size, _("dynamic strings"));
6425 filedata->dynamic_strings_length
6426 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6427 filedata->dynamic_strtab_section = section;
252b5132 6428 }
1b513401
NC
6429 break;
6430
6431 case SHT_SYMTAB_SHNDX:
6432 {
6433 elf_section_list * entry = xmalloc (sizeof * entry);
6434
6435 entry->hdr = section;
6436 entry->next = filedata->symtab_shndx_list;
6437 filedata->symtab_shndx_list = entry;
6438 }
6439 break;
6440
6441 case SHT_SYMTAB:
6442 CHECK_ENTSIZE (section, i, Sym);
6443 break;
6444
6445 case SHT_GROUP:
6446 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6447 break;
252b5132 6448
1b513401
NC
6449 case SHT_REL:
6450 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6451 if (do_checks && section->sh_size == 0)
1b513401
NC
6452 warn (_("Section '%s': zero-sized relocation section\n"), name);
6453 break;
6454
6455 case SHT_RELA:
6456 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6457 if (do_checks && section->sh_size == 0)
1b513401
NC
6458 warn (_("Section '%s': zero-sized relocation section\n"), name);
6459 break;
6460
6461 case SHT_NOTE:
6462 case SHT_PROGBITS:
546cb2d8
NC
6463 /* Having a zero sized section is not illegal according to the
6464 ELF standard, but it might be an indication that something
6465 is wrong. So issue a warning if we are running in lint mode. */
6466 if (do_checks && section->sh_size == 0)
1b513401
NC
6467 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6468 break;
6469
6470 default:
6471 break;
6472 }
6473
6474 if ((do_debugging || do_debug_info || do_debug_abbrevs
6475 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6476 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e4b7104b 6477 || do_debug_str || do_debug_str_offsets || do_debug_loc || do_debug_ranges
1b513401
NC
6478 || do_debug_addr || do_debug_cu_index || do_debug_links)
6479 && (const_strneq (name, ".debug_")
6480 || const_strneq (name, ".zdebug_")))
252b5132 6481 {
1b315056
CS
6482 if (name[1] == 'z')
6483 name += sizeof (".zdebug_") - 1;
6484 else
6485 name += sizeof (".debug_") - 1;
252b5132
RH
6486
6487 if (do_debugging
4723351a
CC
6488 || (do_debug_info && const_strneq (name, "info"))
6489 || (do_debug_info && const_strneq (name, "types"))
6490 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6491 || (do_debug_lines && strcmp (name, "line") == 0)
6492 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6493 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6494 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6495 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6496 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6497 || (do_debug_aranges && const_strneq (name, "aranges"))
6498 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6499 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6500 || (do_debug_frames && const_strneq (name, "frame"))
6501 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6502 || (do_debug_macinfo && const_strneq (name, "macro"))
6503 || (do_debug_str && const_strneq (name, "str"))
e4b7104b 6504 || (do_debug_str_offsets && const_strneq (name, "str_offsets"))
4723351a 6505 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6506 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6507 || (do_debug_addr && const_strneq (name, "addr"))
6508 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6509 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6510 )
6431e409 6511 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6512 }
a262ae96 6513 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6514 else if ((do_debugging || do_debug_info)
0112cd26 6515 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6516 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6517 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6518 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6519 else if (do_gdb_index && (streq (name, ".gdb_index")
6520 || streq (name, ".debug_names")))
6431e409 6521 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6522 /* Trace sections for Itanium VMS. */
6523 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6524 || do_trace_aranges)
6525 && const_strneq (name, ".trace_"))
6526 {
6527 name += sizeof (".trace_") - 1;
6528
6529 if (do_debugging
6530 || (do_trace_info && streq (name, "info"))
6531 || (do_trace_abbrevs && streq (name, "abbrev"))
6532 || (do_trace_aranges && streq (name, "aranges"))
6533 )
6431e409 6534 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6535 }
dda8d76d
NC
6536 else if ((do_debugging || do_debug_links)
6537 && (const_strneq (name, ".gnu_debuglink")
6538 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6539 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6540 }
6541
6542 if (! do_sections)
32ec8896 6543 return TRUE;
252b5132 6544
dda8d76d 6545 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6546 printf (_("\nSection Headers:\n"));
6547 else
6548 printf (_("\nSection Header:\n"));
76da6bbe 6549
f7a99963 6550 if (is_32bit_elf)
595cf52e 6551 {
5477e8a0 6552 if (do_section_details)
595cf52e
L
6553 {
6554 printf (_(" [Nr] Name\n"));
5477e8a0 6555 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6556 }
6557 else
6558 printf
6559 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6560 }
d974e256 6561 else if (do_wide)
595cf52e 6562 {
5477e8a0 6563 if (do_section_details)
595cf52e
L
6564 {
6565 printf (_(" [Nr] Name\n"));
5477e8a0 6566 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6567 }
6568 else
6569 printf
6570 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6571 }
f7a99963
NC
6572 else
6573 {
5477e8a0 6574 if (do_section_details)
595cf52e
L
6575 {
6576 printf (_(" [Nr] Name\n"));
5477e8a0
L
6577 printf (_(" Type Address Offset Link\n"));
6578 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6579 }
6580 else
6581 {
6582 printf (_(" [Nr] Name Type Address Offset\n"));
6583 printf (_(" Size EntSize Flags Link Info Align\n"));
6584 }
f7a99963 6585 }
252b5132 6586
5477e8a0
L
6587 if (do_section_details)
6588 printf (_(" Flags\n"));
6589
dda8d76d
NC
6590 for (i = 0, section = filedata->section_headers;
6591 i < filedata->file_header.e_shnum;
b34976b6 6592 i++, section++)
252b5132 6593 {
dd905818
NC
6594 /* Run some sanity checks on the section header. */
6595
6596 /* Check the sh_link field. */
6597 switch (section->sh_type)
6598 {
285e3f99
AM
6599 case SHT_REL:
6600 case SHT_RELA:
6601 if (section->sh_link == 0
6602 && (filedata->file_header.e_type == ET_EXEC
6603 || filedata->file_header.e_type == ET_DYN))
6604 /* A dynamic relocation section where all entries use a
6605 zero symbol index need not specify a symtab section. */
6606 break;
6607 /* Fall through. */
dd905818
NC
6608 case SHT_SYMTAB_SHNDX:
6609 case SHT_GROUP:
6610 case SHT_HASH:
6611 case SHT_GNU_HASH:
6612 case SHT_GNU_versym:
285e3f99 6613 if (section->sh_link == 0
dda8d76d
NC
6614 || section->sh_link >= filedata->file_header.e_shnum
6615 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6616 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6617 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6618 i, section->sh_link);
6619 break;
6620
6621 case SHT_DYNAMIC:
6622 case SHT_SYMTAB:
6623 case SHT_DYNSYM:
6624 case SHT_GNU_verneed:
6625 case SHT_GNU_verdef:
6626 case SHT_GNU_LIBLIST:
285e3f99 6627 if (section->sh_link == 0
dda8d76d
NC
6628 || section->sh_link >= filedata->file_header.e_shnum
6629 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6630 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6631 i, section->sh_link);
6632 break;
6633
6634 case SHT_INIT_ARRAY:
6635 case SHT_FINI_ARRAY:
6636 case SHT_PREINIT_ARRAY:
6637 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6638 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6639 i, section->sh_link);
6640 break;
6641
6642 default:
6643 /* FIXME: Add support for target specific section types. */
6644#if 0 /* Currently we do not check other section types as there are too
6645 many special cases. Stab sections for example have a type
6646 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6647 section. */
6648 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6649 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6650 i, section->sh_link);
6651#endif
6652 break;
6653 }
6654
6655 /* Check the sh_info field. */
6656 switch (section->sh_type)
6657 {
6658 case SHT_REL:
6659 case SHT_RELA:
285e3f99
AM
6660 if (section->sh_info == 0
6661 && (filedata->file_header.e_type == ET_EXEC
6662 || filedata->file_header.e_type == ET_DYN))
6663 /* Dynamic relocations apply to segments, so they do not
6664 need to specify the section they relocate. */
6665 break;
6666 if (section->sh_info == 0
dda8d76d
NC
6667 || section->sh_info >= filedata->file_header.e_shnum
6668 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6669 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6670 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6671 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6672 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6673 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6674 /* FIXME: Are other section types valid ? */
dda8d76d 6675 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6676 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6677 i, section->sh_info);
dd905818
NC
6678 break;
6679
6680 case SHT_DYNAMIC:
6681 case SHT_HASH:
6682 case SHT_SYMTAB_SHNDX:
6683 case SHT_INIT_ARRAY:
6684 case SHT_FINI_ARRAY:
6685 case SHT_PREINIT_ARRAY:
6686 if (section->sh_info != 0)
6687 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6688 i, section->sh_info);
6689 break;
6690
6691 case SHT_GROUP:
6692 case SHT_SYMTAB:
6693 case SHT_DYNSYM:
6694 /* A symbol index - we assume that it is valid. */
6695 break;
6696
6697 default:
6698 /* FIXME: Add support for target specific section types. */
6699 if (section->sh_type == SHT_NOBITS)
6700 /* NOBITS section headers with non-zero sh_info fields can be
6701 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6702 information. The stripped sections have their headers
6703 preserved but their types set to SHT_NOBITS. So do not check
6704 this type of section. */
dd905818
NC
6705 ;
6706 else if (section->sh_flags & SHF_INFO_LINK)
6707 {
dda8d76d 6708 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6709 warn (_("[%2u]: Expected link to another section in info field"), i);
6710 }
a91e1603
L
6711 else if (section->sh_type < SHT_LOOS
6712 && (section->sh_flags & SHF_GNU_MBIND) == 0
6713 && section->sh_info != 0)
dd905818
NC
6714 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6715 i, section->sh_info);
6716 break;
6717 }
6718
3e6b6445 6719 /* Check the sh_size field. */
dda8d76d 6720 if (section->sh_size > filedata->file_size
3e6b6445
NC
6721 && section->sh_type != SHT_NOBITS
6722 && section->sh_type != SHT_NULL
6723 && section->sh_type < SHT_LOOS)
6724 warn (_("Size of section %u is larger than the entire file!\n"), i);
6725
7bfd842d 6726 printf (" [%2u] ", i);
5477e8a0 6727 if (do_section_details)
dda8d76d 6728 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6729 else
74e1a04b 6730 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6731
ea52a088 6732 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6733 get_section_type_name (filedata, section->sh_type));
0b4362b0 6734
f7a99963
NC
6735 if (is_32bit_elf)
6736 {
cfcac11d
NC
6737 const char * link_too_big = NULL;
6738
f7a99963 6739 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6740
f7a99963
NC
6741 printf ( " %6.6lx %6.6lx %2.2lx",
6742 (unsigned long) section->sh_offset,
6743 (unsigned long) section->sh_size,
6744 (unsigned long) section->sh_entsize);
d1133906 6745
5477e8a0
L
6746 if (do_section_details)
6747 fputs (" ", stdout);
6748 else
dda8d76d 6749 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6750
dda8d76d 6751 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6752 {
6753 link_too_big = "";
6754 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6755 an error but it can have special values in Solaris binaries. */
dda8d76d 6756 switch (filedata->file_header.e_machine)
cfcac11d 6757 {
caa83f8b 6758 case EM_386:
22abe556 6759 case EM_IAMCU:
caa83f8b 6760 case EM_X86_64:
7f502d6c 6761 case EM_L1OM:
7a9068fe 6762 case EM_K1OM:
cfcac11d
NC
6763 case EM_OLD_SPARCV9:
6764 case EM_SPARC32PLUS:
6765 case EM_SPARCV9:
6766 case EM_SPARC:
6767 if (section->sh_link == (SHN_BEFORE & 0xffff))
6768 link_too_big = "BEFORE";
6769 else if (section->sh_link == (SHN_AFTER & 0xffff))
6770 link_too_big = "AFTER";
6771 break;
6772 default:
6773 break;
6774 }
6775 }
6776
6777 if (do_section_details)
6778 {
6779 if (link_too_big != NULL && * link_too_big)
6780 printf ("<%s> ", link_too_big);
6781 else
6782 printf ("%2u ", section->sh_link);
6783 printf ("%3u %2lu\n", section->sh_info,
6784 (unsigned long) section->sh_addralign);
6785 }
6786 else
6787 printf ("%2u %3u %2lu\n",
6788 section->sh_link,
6789 section->sh_info,
6790 (unsigned long) section->sh_addralign);
6791
6792 if (link_too_big && ! * link_too_big)
6793 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6794 i, section->sh_link);
f7a99963 6795 }
d974e256
JJ
6796 else if (do_wide)
6797 {
6798 print_vma (section->sh_addr, LONG_HEX);
6799
6800 if ((long) section->sh_offset == section->sh_offset)
6801 printf (" %6.6lx", (unsigned long) section->sh_offset);
6802 else
6803 {
6804 putchar (' ');
6805 print_vma (section->sh_offset, LONG_HEX);
6806 }
6807
6808 if ((unsigned long) section->sh_size == section->sh_size)
6809 printf (" %6.6lx", (unsigned long) section->sh_size);
6810 else
6811 {
6812 putchar (' ');
6813 print_vma (section->sh_size, LONG_HEX);
6814 }
6815
6816 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6817 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6818 else
6819 {
6820 putchar (' ');
6821 print_vma (section->sh_entsize, LONG_HEX);
6822 }
6823
5477e8a0
L
6824 if (do_section_details)
6825 fputs (" ", stdout);
6826 else
dda8d76d 6827 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6828
72de5009 6829 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6830
6831 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6832 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6833 else
6834 {
6835 print_vma (section->sh_addralign, DEC);
6836 putchar ('\n');
6837 }
6838 }
5477e8a0 6839 else if (do_section_details)
595cf52e 6840 {
55cc53e9 6841 putchar (' ');
595cf52e
L
6842 print_vma (section->sh_addr, LONG_HEX);
6843 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6844 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6845 else
6846 {
6847 printf (" ");
6848 print_vma (section->sh_offset, LONG_HEX);
6849 }
72de5009 6850 printf (" %u\n ", section->sh_link);
595cf52e 6851 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6852 putchar (' ');
595cf52e
L
6853 print_vma (section->sh_entsize, LONG_HEX);
6854
72de5009
AM
6855 printf (" %-16u %lu\n",
6856 section->sh_info,
595cf52e
L
6857 (unsigned long) section->sh_addralign);
6858 }
f7a99963
NC
6859 else
6860 {
6861 putchar (' ');
6862 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6863 if ((long) section->sh_offset == section->sh_offset)
6864 printf (" %8.8lx", (unsigned long) section->sh_offset);
6865 else
6866 {
6867 printf (" ");
6868 print_vma (section->sh_offset, LONG_HEX);
6869 }
f7a99963
NC
6870 printf ("\n ");
6871 print_vma (section->sh_size, LONG_HEX);
6872 printf (" ");
6873 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6874
dda8d76d 6875 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6876
72de5009
AM
6877 printf (" %2u %3u %lu\n",
6878 section->sh_link,
6879 section->sh_info,
f7a99963
NC
6880 (unsigned long) section->sh_addralign);
6881 }
5477e8a0
L
6882
6883 if (do_section_details)
77115a4a 6884 {
dda8d76d 6885 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6886 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6887 {
6888 /* Minimum section size is 12 bytes for 32-bit compression
6889 header + 12 bytes for compressed data header. */
6890 unsigned char buf[24];
d8024a91 6891
77115a4a 6892 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6893 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6894 sizeof (buf), _("compression header")))
6895 {
6896 Elf_Internal_Chdr chdr;
d8024a91 6897
5844b465
NC
6898 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
6899 printf (_(" [<corrupt>]\n"));
77115a4a 6900 else
5844b465
NC
6901 {
6902 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6903 printf (" ZLIB, ");
6904 else
6905 printf (_(" [<unknown>: 0x%x], "),
6906 chdr.ch_type);
6907 print_vma (chdr.ch_size, LONG_HEX);
6908 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6909 }
77115a4a
L
6910 }
6911 }
6912 }
252b5132
RH
6913 }
6914
5477e8a0 6915 if (!do_section_details)
3dbcc61d 6916 {
9fb71ee4
NC
6917 /* The ordering of the letters shown here matches the ordering of the
6918 corresponding SHF_xxx values, and hence the order in which these
6919 letters will be displayed to the user. */
6920 printf (_("Key to Flags:\n\
6921 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6922 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6923 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6924 if (filedata->file_header.e_machine == EM_X86_64
6925 || filedata->file_header.e_machine == EM_L1OM
6926 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6927 printf (_("l (large), "));
dda8d76d 6928 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6929 printf (_("y (purecode), "));
dda8d76d 6930 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6931 printf (_("v (VLE), "));
9fb71ee4 6932 printf ("p (processor specific)\n");
0b4362b0 6933 }
d1133906 6934
32ec8896 6935 return TRUE;
252b5132
RH
6936}
6937
28d13567
AM
6938static bfd_boolean
6939get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
6940 Elf_Internal_Sym **symtab, unsigned long *nsyms,
6941 char **strtab, unsigned long *strtablen)
6942{
6943 *strtab = NULL;
6944 *strtablen = 0;
6945 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
6946
6947 if (*symtab == NULL)
6948 return FALSE;
6949
6950 if (symsec->sh_link != 0)
6951 {
6952 Elf_Internal_Shdr *strsec;
6953
6954 if (symsec->sh_link >= filedata->file_header.e_shnum)
6955 {
6956 error (_("Bad sh_link in symbol table section\n"));
6957 free (*symtab);
6958 *symtab = NULL;
6959 *nsyms = 0;
6960 return FALSE;
6961 }
6962
6963 strsec = filedata->section_headers + symsec->sh_link;
6964
6965 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
6966 1, strsec->sh_size, _("string table"));
6967 if (*strtab == NULL)
6968 {
6969 free (*symtab);
6970 *symtab = NULL;
6971 *nsyms = 0;
6972 return FALSE;
6973 }
6974 *strtablen = strsec->sh_size;
6975 }
6976 return TRUE;
6977}
6978
f5842774
L
6979static const char *
6980get_group_flags (unsigned int flags)
6981{
1449284b 6982 static char buff[128];
220453ec 6983
6d913794
NC
6984 if (flags == 0)
6985 return "";
6986 else if (flags == GRP_COMDAT)
6987 return "COMDAT ";
f5842774 6988
89246a0e
AM
6989 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
6990 flags,
6991 flags & GRP_MASKOS ? _("<OS specific>") : "",
6992 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
6993 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
6994 ? _("<unknown>") : ""));
6d913794 6995
f5842774
L
6996 return buff;
6997}
6998
32ec8896 6999static bfd_boolean
dda8d76d 7000process_section_groups (Filedata * filedata)
f5842774 7001{
2cf0635d 7002 Elf_Internal_Shdr * section;
f5842774 7003 unsigned int i;
2cf0635d
NC
7004 struct group * group;
7005 Elf_Internal_Shdr * symtab_sec;
7006 Elf_Internal_Shdr * strtab_sec;
7007 Elf_Internal_Sym * symtab;
ba5cdace 7008 unsigned long num_syms;
2cf0635d 7009 char * strtab;
c256ffe7 7010 size_t strtab_size;
d1f5c6e3
L
7011
7012 /* Don't process section groups unless needed. */
7013 if (!do_unwind && !do_section_groups)
32ec8896 7014 return TRUE;
f5842774 7015
dda8d76d 7016 if (filedata->file_header.e_shnum == 0)
f5842774
L
7017 {
7018 if (do_section_groups)
82f2dbf7 7019 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 7020
32ec8896 7021 return TRUE;
f5842774
L
7022 }
7023
dda8d76d 7024 if (filedata->section_headers == NULL)
f5842774
L
7025 {
7026 error (_("Section headers are not available!\n"));
fa1908fd 7027 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 7028 return FALSE;
f5842774
L
7029 }
7030
978c4450
AM
7031 filedata->section_headers_groups
7032 = (struct group **) calloc (filedata->file_header.e_shnum,
7033 sizeof (struct group *));
e4b17d5c 7034
978c4450 7035 if (filedata->section_headers_groups == NULL)
e4b17d5c 7036 {
8b73c356 7037 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7038 filedata->file_header.e_shnum);
32ec8896 7039 return FALSE;
e4b17d5c
L
7040 }
7041
f5842774 7042 /* Scan the sections for the group section. */
978c4450 7043 filedata->group_count = 0;
dda8d76d
NC
7044 for (i = 0, section = filedata->section_headers;
7045 i < filedata->file_header.e_shnum;
f5842774 7046 i++, section++)
e4b17d5c 7047 if (section->sh_type == SHT_GROUP)
978c4450 7048 filedata->group_count++;
e4b17d5c 7049
978c4450 7050 if (filedata->group_count == 0)
d1f5c6e3
L
7051 {
7052 if (do_section_groups)
7053 printf (_("\nThere are no section groups in this file.\n"));
7054
32ec8896 7055 return TRUE;
d1f5c6e3
L
7056 }
7057
978c4450
AM
7058 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7059 sizeof (struct group));
e4b17d5c 7060
978c4450 7061 if (filedata->section_groups == NULL)
e4b17d5c 7062 {
8b73c356 7063 error (_("Out of memory reading %lu groups\n"),
978c4450 7064 (unsigned long) filedata->group_count);
32ec8896 7065 return FALSE;
e4b17d5c
L
7066 }
7067
d1f5c6e3
L
7068 symtab_sec = NULL;
7069 strtab_sec = NULL;
7070 symtab = NULL;
ba5cdace 7071 num_syms = 0;
d1f5c6e3 7072 strtab = NULL;
c256ffe7 7073 strtab_size = 0;
978c4450 7074 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7075 i < filedata->file_header.e_shnum;
e4b17d5c 7076 i++, section++)
f5842774
L
7077 {
7078 if (section->sh_type == SHT_GROUP)
7079 {
dda8d76d 7080 const char * name = printable_section_name (filedata, section);
74e1a04b 7081 const char * group_name;
2cf0635d
NC
7082 unsigned char * start;
7083 unsigned char * indices;
f5842774 7084 unsigned int entry, j, size;
2cf0635d
NC
7085 Elf_Internal_Shdr * sec;
7086 Elf_Internal_Sym * sym;
f5842774
L
7087
7088 /* Get the symbol table. */
dda8d76d
NC
7089 if (section->sh_link >= filedata->file_header.e_shnum
7090 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7091 != SHT_SYMTAB))
f5842774
L
7092 {
7093 error (_("Bad sh_link in group section `%s'\n"), name);
7094 continue;
7095 }
d1f5c6e3
L
7096
7097 if (symtab_sec != sec)
7098 {
7099 symtab_sec = sec;
9db70fc3 7100 free (symtab);
dda8d76d 7101 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7102 }
f5842774 7103
dd24e3da
NC
7104 if (symtab == NULL)
7105 {
7106 error (_("Corrupt header in group section `%s'\n"), name);
7107 continue;
7108 }
7109
ba5cdace
NC
7110 if (section->sh_info >= num_syms)
7111 {
7112 error (_("Bad sh_info in group section `%s'\n"), name);
7113 continue;
7114 }
7115
f5842774
L
7116 sym = symtab + section->sh_info;
7117
7118 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7119 {
4fbb74a6 7120 if (sym->st_shndx == 0
dda8d76d 7121 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7122 {
7123 error (_("Bad sh_info in group section `%s'\n"), name);
7124 continue;
7125 }
ba2685cc 7126
dda8d76d 7127 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7 7128 strtab_sec = NULL;
9db70fc3 7129 free (strtab);
f5842774 7130 strtab = NULL;
c256ffe7 7131 strtab_size = 0;
f5842774
L
7132 }
7133 else
7134 {
7135 /* Get the string table. */
dda8d76d 7136 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7137 {
7138 strtab_sec = NULL;
9db70fc3 7139 free (strtab);
c256ffe7
JJ
7140 strtab = NULL;
7141 strtab_size = 0;
7142 }
7143 else if (strtab_sec
dda8d76d 7144 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7145 {
7146 strtab_sec = sec;
9db70fc3 7147 free (strtab);
071436c6 7148
dda8d76d 7149 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7150 1, strtab_sec->sh_size,
7151 _("string table"));
c256ffe7 7152 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7153 }
c256ffe7 7154 group_name = sym->st_name < strtab_size
2b692964 7155 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7156 }
7157
c9c1d674
EG
7158 /* PR 17531: file: loop. */
7159 if (section->sh_entsize > section->sh_size)
7160 {
7161 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7162 printable_section_name (filedata, section),
8066deb1
AM
7163 (unsigned long) section->sh_entsize,
7164 (unsigned long) section->sh_size);
61dd8e19 7165 continue;
c9c1d674
EG
7166 }
7167
dda8d76d 7168 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7169 1, section->sh_size,
7170 _("section data"));
59245841
NC
7171 if (start == NULL)
7172 continue;
f5842774
L
7173
7174 indices = start;
7175 size = (section->sh_size / section->sh_entsize) - 1;
7176 entry = byte_get (indices, 4);
7177 indices += 4;
e4b17d5c
L
7178
7179 if (do_section_groups)
7180 {
2b692964 7181 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7182 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7183
e4b17d5c
L
7184 printf (_(" [Index] Name\n"));
7185 }
7186
7187 group->group_index = i;
7188
f5842774
L
7189 for (j = 0; j < size; j++)
7190 {
2cf0635d 7191 struct group_list * g;
e4b17d5c 7192
f5842774
L
7193 entry = byte_get (indices, 4);
7194 indices += 4;
7195
dda8d76d 7196 if (entry >= filedata->file_header.e_shnum)
391cb864 7197 {
57028622
NC
7198 static unsigned num_group_errors = 0;
7199
7200 if (num_group_errors ++ < 10)
7201 {
7202 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7203 entry, i, filedata->file_header.e_shnum - 1);
57028622 7204 if (num_group_errors == 10)
67ce483b 7205 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7206 }
391cb864
L
7207 continue;
7208 }
391cb864 7209
978c4450 7210 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7211 {
d1f5c6e3
L
7212 if (entry)
7213 {
57028622
NC
7214 static unsigned num_errs = 0;
7215
7216 if (num_errs ++ < 10)
7217 {
7218 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7219 entry, i,
978c4450 7220 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7221 if (num_errs == 10)
7222 warn (_("Further error messages about already contained group sections suppressed\n"));
7223 }
d1f5c6e3
L
7224 continue;
7225 }
7226 else
7227 {
7228 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7229 section group. We just warn it the first time
d1f5c6e3 7230 and ignore it afterwards. */
32ec8896 7231 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7232 if (!warned)
7233 {
7234 error (_("section 0 in group section [%5u]\n"),
978c4450 7235 filedata->section_headers_groups [entry]->group_index);
32ec8896 7236 warned = TRUE;
d1f5c6e3
L
7237 }
7238 }
e4b17d5c
L
7239 }
7240
978c4450 7241 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7242
7243 if (do_section_groups)
7244 {
dda8d76d
NC
7245 sec = filedata->section_headers + entry;
7246 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7247 }
7248
3f5e193b 7249 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7250 g->section_index = entry;
7251 g->next = group->root;
7252 group->root = g;
f5842774
L
7253 }
7254
9db70fc3 7255 free (start);
e4b17d5c
L
7256
7257 group++;
f5842774
L
7258 }
7259 }
7260
9db70fc3
AM
7261 free (symtab);
7262 free (strtab);
32ec8896 7263 return TRUE;
f5842774
L
7264}
7265
28f997cf
TG
7266/* Data used to display dynamic fixups. */
7267
7268struct ia64_vms_dynfixup
7269{
7270 bfd_vma needed_ident; /* Library ident number. */
7271 bfd_vma needed; /* Index in the dstrtab of the library name. */
7272 bfd_vma fixup_needed; /* Index of the library. */
7273 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7274 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7275};
7276
7277/* Data used to display dynamic relocations. */
7278
7279struct ia64_vms_dynimgrela
7280{
7281 bfd_vma img_rela_cnt; /* Number of relocations. */
7282 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7283};
7284
7285/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7286 library). */
7287
32ec8896 7288static bfd_boolean
dda8d76d
NC
7289dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7290 struct ia64_vms_dynfixup * fixup,
7291 const char * strtab,
7292 unsigned int strtab_sz)
28f997cf 7293{
32ec8896 7294 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7295 long i;
32ec8896 7296 const char * lib_name;
28f997cf 7297
978c4450
AM
7298 imfs = get_data (NULL, filedata,
7299 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7300 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7301 _("dynamic section image fixups"));
7302 if (!imfs)
32ec8896 7303 return FALSE;
28f997cf
TG
7304
7305 if (fixup->needed < strtab_sz)
7306 lib_name = strtab + fixup->needed;
7307 else
7308 {
32ec8896 7309 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7310 (unsigned long) fixup->needed);
28f997cf
TG
7311 lib_name = "???";
7312 }
736990c4 7313
28f997cf
TG
7314 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7315 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7316 printf
7317 (_("Seg Offset Type SymVec DataType\n"));
7318
7319 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7320 {
7321 unsigned int type;
7322 const char *rtype;
7323
7324 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7325 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7326 type = BYTE_GET (imfs [i].type);
7327 rtype = elf_ia64_reloc_type (type);
7328 if (rtype == NULL)
7329 printf (" 0x%08x ", type);
7330 else
7331 printf (" %-32s ", rtype);
7332 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7333 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7334 }
7335
7336 free (imfs);
32ec8896 7337 return TRUE;
28f997cf
TG
7338}
7339
7340/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7341
32ec8896 7342static bfd_boolean
dda8d76d 7343dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7344{
7345 Elf64_External_VMS_IMAGE_RELA *imrs;
7346 long i;
7347
978c4450
AM
7348 imrs = get_data (NULL, filedata,
7349 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7350 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7351 _("dynamic section image relocations"));
28f997cf 7352 if (!imrs)
32ec8896 7353 return FALSE;
28f997cf
TG
7354
7355 printf (_("\nImage relocs\n"));
7356 printf
7357 (_("Seg Offset Type Addend Seg Sym Off\n"));
7358
7359 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7360 {
7361 unsigned int type;
7362 const char *rtype;
7363
7364 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7365 printf ("%08" BFD_VMA_FMT "x ",
7366 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7367 type = BYTE_GET (imrs [i].type);
7368 rtype = elf_ia64_reloc_type (type);
7369 if (rtype == NULL)
7370 printf ("0x%08x ", type);
7371 else
7372 printf ("%-31s ", rtype);
7373 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7374 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7375 printf ("%08" BFD_VMA_FMT "x\n",
7376 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7377 }
7378
7379 free (imrs);
32ec8896 7380 return TRUE;
28f997cf
TG
7381}
7382
7383/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7384
32ec8896 7385static bfd_boolean
dda8d76d 7386process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7387{
7388 struct ia64_vms_dynfixup fixup;
7389 struct ia64_vms_dynimgrela imgrela;
7390 Elf_Internal_Dyn *entry;
28f997cf
TG
7391 bfd_vma strtab_off = 0;
7392 bfd_vma strtab_sz = 0;
7393 char *strtab = NULL;
32ec8896 7394 bfd_boolean res = TRUE;
28f997cf
TG
7395
7396 memset (&fixup, 0, sizeof (fixup));
7397 memset (&imgrela, 0, sizeof (imgrela));
7398
7399 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7400 for (entry = filedata->dynamic_section;
7401 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7402 entry++)
7403 {
7404 switch (entry->d_tag)
7405 {
7406 case DT_IA_64_VMS_STRTAB_OFFSET:
7407 strtab_off = entry->d_un.d_val;
7408 break;
7409 case DT_STRSZ:
7410 strtab_sz = entry->d_un.d_val;
7411 if (strtab == NULL)
978c4450
AM
7412 strtab = get_data (NULL, filedata,
7413 filedata->dynamic_addr + strtab_off,
28f997cf 7414 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7415 if (strtab == NULL)
7416 strtab_sz = 0;
28f997cf
TG
7417 break;
7418
7419 case DT_IA_64_VMS_NEEDED_IDENT:
7420 fixup.needed_ident = entry->d_un.d_val;
7421 break;
7422 case DT_NEEDED:
7423 fixup.needed = entry->d_un.d_val;
7424 break;
7425 case DT_IA_64_VMS_FIXUP_NEEDED:
7426 fixup.fixup_needed = entry->d_un.d_val;
7427 break;
7428 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7429 fixup.fixup_rela_cnt = entry->d_un.d_val;
7430 break;
7431 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7432 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7433 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7434 res = FALSE;
28f997cf 7435 break;
28f997cf
TG
7436 case DT_IA_64_VMS_IMG_RELA_CNT:
7437 imgrela.img_rela_cnt = entry->d_un.d_val;
7438 break;
7439 case DT_IA_64_VMS_IMG_RELA_OFF:
7440 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7441 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7442 res = FALSE;
28f997cf
TG
7443 break;
7444
7445 default:
7446 break;
7447 }
7448 }
7449
9db70fc3 7450 free (strtab);
28f997cf
TG
7451
7452 return res;
7453}
7454
85b1c36d 7455static struct
566b0d53 7456{
2cf0635d 7457 const char * name;
566b0d53
L
7458 int reloc;
7459 int size;
7460 int rela;
32ec8896
NC
7461}
7462 dynamic_relocations [] =
566b0d53 7463{
32ec8896
NC
7464 { "REL", DT_REL, DT_RELSZ, FALSE },
7465 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7466 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7467};
7468
252b5132 7469/* Process the reloc section. */
18bd398b 7470
32ec8896 7471static bfd_boolean
dda8d76d 7472process_relocs (Filedata * filedata)
252b5132 7473{
b34976b6
AM
7474 unsigned long rel_size;
7475 unsigned long rel_offset;
252b5132 7476
252b5132 7477 if (!do_reloc)
32ec8896 7478 return TRUE;
252b5132
RH
7479
7480 if (do_using_dynamic)
7481 {
32ec8896 7482 int is_rela;
2cf0635d 7483 const char * name;
32ec8896 7484 bfd_boolean has_dynamic_reloc;
566b0d53 7485 unsigned int i;
0de14b54 7486
32ec8896 7487 has_dynamic_reloc = FALSE;
252b5132 7488
566b0d53 7489 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7490 {
566b0d53
L
7491 is_rela = dynamic_relocations [i].rela;
7492 name = dynamic_relocations [i].name;
978c4450
AM
7493 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7494 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7495
32ec8896
NC
7496 if (rel_size)
7497 has_dynamic_reloc = TRUE;
566b0d53
L
7498
7499 if (is_rela == UNKNOWN)
aa903cfb 7500 {
566b0d53 7501 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7502 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7503 {
7504 case DT_REL:
7505 is_rela = FALSE;
7506 break;
7507 case DT_RELA:
7508 is_rela = TRUE;
7509 break;
7510 }
aa903cfb 7511 }
252b5132 7512
566b0d53
L
7513 if (rel_size)
7514 {
7515 printf
7516 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7517 name, rel_offset, rel_size);
252b5132 7518
dda8d76d
NC
7519 dump_relocations (filedata,
7520 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7521 rel_size,
978c4450
AM
7522 filedata->dynamic_symbols,
7523 filedata->num_dynamic_syms,
7524 filedata->dynamic_strings,
7525 filedata->dynamic_strings_length,
32ec8896 7526 is_rela, TRUE /* is_dynamic */);
566b0d53 7527 }
252b5132 7528 }
566b0d53 7529
dda8d76d
NC
7530 if (is_ia64_vms (filedata))
7531 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7532 has_dynamic_reloc = TRUE;
28f997cf 7533
566b0d53 7534 if (! has_dynamic_reloc)
252b5132
RH
7535 printf (_("\nThere are no dynamic relocations in this file.\n"));
7536 }
7537 else
7538 {
2cf0635d 7539 Elf_Internal_Shdr * section;
b34976b6 7540 unsigned long i;
32ec8896 7541 bfd_boolean found = FALSE;
252b5132 7542
dda8d76d
NC
7543 for (i = 0, section = filedata->section_headers;
7544 i < filedata->file_header.e_shnum;
b34976b6 7545 i++, section++)
252b5132
RH
7546 {
7547 if ( section->sh_type != SHT_RELA
7548 && section->sh_type != SHT_REL)
7549 continue;
7550
7551 rel_offset = section->sh_offset;
7552 rel_size = section->sh_size;
7553
7554 if (rel_size)
7555 {
b34976b6 7556 int is_rela;
d3a49aa8 7557 unsigned long num_rela;
103f02d3 7558
252b5132
RH
7559 printf (_("\nRelocation section "));
7560
dda8d76d 7561 if (filedata->string_table == NULL)
19936277 7562 printf ("%d", section->sh_name);
252b5132 7563 else
dda8d76d 7564 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7565
d3a49aa8
AM
7566 num_rela = rel_size / section->sh_entsize;
7567 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7568 " at offset 0x%lx contains %lu entries:\n",
7569 num_rela),
7570 rel_offset, num_rela);
252b5132 7571
d79b3d50
NC
7572 is_rela = section->sh_type == SHT_RELA;
7573
4fbb74a6 7574 if (section->sh_link != 0
dda8d76d 7575 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7576 {
2cf0635d
NC
7577 Elf_Internal_Shdr * symsec;
7578 Elf_Internal_Sym * symtab;
d79b3d50 7579 unsigned long nsyms;
c256ffe7 7580 unsigned long strtablen = 0;
2cf0635d 7581 char * strtab = NULL;
57346661 7582
dda8d76d 7583 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7584 if (symsec->sh_type != SHT_SYMTAB
7585 && symsec->sh_type != SHT_DYNSYM)
7586 continue;
7587
28d13567
AM
7588 if (!get_symtab (filedata, symsec,
7589 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7590 continue;
252b5132 7591
dda8d76d 7592 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7593 symtab, nsyms, strtab, strtablen,
7594 is_rela,
7595 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7596 free (strtab);
d79b3d50
NC
7597 free (symtab);
7598 }
7599 else
dda8d76d 7600 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7601 NULL, 0, NULL, 0, is_rela,
7602 FALSE /* is_dynamic */);
252b5132 7603
32ec8896 7604 found = TRUE;
252b5132
RH
7605 }
7606 }
7607
7608 if (! found)
45ac8f4f
NC
7609 {
7610 /* Users sometimes forget the -D option, so try to be helpful. */
7611 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7612 {
978c4450 7613 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f
NC
7614 {
7615 printf (_("\nThere are no static relocations in this file."));
7616 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7617
7618 break;
7619 }
7620 }
7621 if (i == ARRAY_SIZE (dynamic_relocations))
7622 printf (_("\nThere are no relocations in this file.\n"));
7623 }
252b5132
RH
7624 }
7625
32ec8896 7626 return TRUE;
252b5132
RH
7627}
7628
4d6ed7c8
NC
7629/* An absolute address consists of a section and an offset. If the
7630 section is NULL, the offset itself is the address, otherwise, the
7631 address equals to LOAD_ADDRESS(section) + offset. */
7632
7633struct absaddr
948f632f
DA
7634{
7635 unsigned short section;
7636 bfd_vma offset;
7637};
4d6ed7c8 7638
948f632f
DA
7639/* Find the nearest symbol at or below ADDR. Returns the symbol
7640 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7641
4d6ed7c8 7642static void
dda8d76d
NC
7643find_symbol_for_address (Filedata * filedata,
7644 Elf_Internal_Sym * symtab,
7645 unsigned long nsyms,
7646 const char * strtab,
7647 unsigned long strtab_size,
7648 struct absaddr addr,
7649 const char ** symname,
7650 bfd_vma * offset)
4d6ed7c8 7651{
d3ba0551 7652 bfd_vma dist = 0x100000;
2cf0635d 7653 Elf_Internal_Sym * sym;
948f632f
DA
7654 Elf_Internal_Sym * beg;
7655 Elf_Internal_Sym * end;
2cf0635d 7656 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7657
0b6ae522 7658 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7659 beg = symtab;
7660 end = symtab + nsyms;
0b6ae522 7661
948f632f 7662 while (beg < end)
4d6ed7c8 7663 {
948f632f
DA
7664 bfd_vma value;
7665
7666 sym = beg + (end - beg) / 2;
0b6ae522 7667
948f632f 7668 value = sym->st_value;
0b6ae522
DJ
7669 REMOVE_ARCH_BITS (value);
7670
948f632f 7671 if (sym->st_name != 0
4d6ed7c8 7672 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7673 && addr.offset >= value
7674 && addr.offset - value < dist)
4d6ed7c8
NC
7675 {
7676 best = sym;
0b6ae522 7677 dist = addr.offset - value;
4d6ed7c8
NC
7678 if (!dist)
7679 break;
7680 }
948f632f
DA
7681
7682 if (addr.offset < value)
7683 end = sym;
7684 else
7685 beg = sym + 1;
4d6ed7c8 7686 }
1b31d05e 7687
4d6ed7c8
NC
7688 if (best)
7689 {
57346661 7690 *symname = (best->st_name >= strtab_size
2b692964 7691 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7692 *offset = dist;
7693 return;
7694 }
1b31d05e 7695
4d6ed7c8
NC
7696 *symname = NULL;
7697 *offset = addr.offset;
7698}
7699
32ec8896 7700static /* signed */ int
948f632f
DA
7701symcmp (const void *p, const void *q)
7702{
7703 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7704 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7705
7706 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7707}
7708
7709/* Process the unwind section. */
7710
7711#include "unwind-ia64.h"
7712
7713struct ia64_unw_table_entry
7714{
7715 struct absaddr start;
7716 struct absaddr end;
7717 struct absaddr info;
7718};
7719
7720struct ia64_unw_aux_info
7721{
32ec8896
NC
7722 struct ia64_unw_table_entry * table; /* Unwind table. */
7723 unsigned long table_len; /* Length of unwind table. */
7724 unsigned char * info; /* Unwind info. */
7725 unsigned long info_size; /* Size of unwind info. */
7726 bfd_vma info_addr; /* Starting address of unwind info. */
7727 bfd_vma seg_base; /* Starting address of segment. */
7728 Elf_Internal_Sym * symtab; /* The symbol table. */
7729 unsigned long nsyms; /* Number of symbols. */
7730 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7731 unsigned long nfuns; /* Number of entries in funtab. */
7732 char * strtab; /* The string table. */
7733 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7734};
7735
32ec8896 7736static bfd_boolean
dda8d76d 7737dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7738{
2cf0635d 7739 struct ia64_unw_table_entry * tp;
948f632f 7740 unsigned long j, nfuns;
4d6ed7c8 7741 int in_body;
32ec8896 7742 bfd_boolean res = TRUE;
7036c0e1 7743
948f632f
DA
7744 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7745 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7746 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7747 aux->funtab[nfuns++] = aux->symtab[j];
7748 aux->nfuns = nfuns;
7749 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7750
4d6ed7c8
NC
7751 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7752 {
7753 bfd_vma stamp;
7754 bfd_vma offset;
2cf0635d
NC
7755 const unsigned char * dp;
7756 const unsigned char * head;
53774b7e 7757 const unsigned char * end;
2cf0635d 7758 const char * procname;
4d6ed7c8 7759
dda8d76d 7760 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7761 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7762
7763 fputs ("\n<", stdout);
7764
7765 if (procname)
7766 {
7767 fputs (procname, stdout);
7768
7769 if (offset)
7770 printf ("+%lx", (unsigned long) offset);
7771 }
7772
7773 fputs (">: [", stdout);
7774 print_vma (tp->start.offset, PREFIX_HEX);
7775 fputc ('-', stdout);
7776 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7777 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7778 (unsigned long) (tp->info.offset - aux->seg_base));
7779
53774b7e
NC
7780 /* PR 17531: file: 86232b32. */
7781 if (aux->info == NULL)
7782 continue;
7783
97c0a079
AM
7784 offset = tp->info.offset;
7785 if (tp->info.section)
7786 {
7787 if (tp->info.section >= filedata->file_header.e_shnum)
7788 {
7789 warn (_("Invalid section %u in table entry %ld\n"),
7790 tp->info.section, (long) (tp - aux->table));
7791 res = FALSE;
7792 continue;
7793 }
7794 offset += filedata->section_headers[tp->info.section].sh_addr;
7795 }
7796 offset -= aux->info_addr;
53774b7e 7797 /* PR 17531: file: 0997b4d1. */
90679903
AM
7798 if (offset >= aux->info_size
7799 || aux->info_size - offset < 8)
53774b7e
NC
7800 {
7801 warn (_("Invalid offset %lx in table entry %ld\n"),
7802 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7803 res = FALSE;
53774b7e
NC
7804 continue;
7805 }
7806
97c0a079 7807 head = aux->info + offset;
a4a00738 7808 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7809
86f55779 7810 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7811 (unsigned) UNW_VER (stamp),
7812 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7813 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7814 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7815 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7816
7817 if (UNW_VER (stamp) != 1)
7818 {
2b692964 7819 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7820 continue;
7821 }
7822
7823 in_body = 0;
53774b7e
NC
7824 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7825 /* PR 17531: file: 16ceda89. */
7826 if (end > aux->info + aux->info_size)
7827 end = aux->info + aux->info_size;
7828 for (dp = head + 8; dp < end;)
b4477bc8 7829 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7830 }
948f632f
DA
7831
7832 free (aux->funtab);
32ec8896
NC
7833
7834 return res;
4d6ed7c8
NC
7835}
7836
53774b7e 7837static bfd_boolean
dda8d76d
NC
7838slurp_ia64_unwind_table (Filedata * filedata,
7839 struct ia64_unw_aux_info * aux,
7840 Elf_Internal_Shdr * sec)
4d6ed7c8 7841{
89fac5e3 7842 unsigned long size, nrelas, i;
2cf0635d
NC
7843 Elf_Internal_Phdr * seg;
7844 struct ia64_unw_table_entry * tep;
7845 Elf_Internal_Shdr * relsec;
7846 Elf_Internal_Rela * rela;
7847 Elf_Internal_Rela * rp;
7848 unsigned char * table;
7849 unsigned char * tp;
7850 Elf_Internal_Sym * sym;
7851 const char * relname;
4d6ed7c8 7852
53774b7e
NC
7853 aux->table_len = 0;
7854
4d6ed7c8
NC
7855 /* First, find the starting address of the segment that includes
7856 this section: */
7857
dda8d76d 7858 if (filedata->file_header.e_phnum)
4d6ed7c8 7859 {
dda8d76d 7860 if (! get_program_headers (filedata))
53774b7e 7861 return FALSE;
4d6ed7c8 7862
dda8d76d
NC
7863 for (seg = filedata->program_headers;
7864 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7865 ++seg)
4d6ed7c8
NC
7866 {
7867 if (seg->p_type != PT_LOAD)
7868 continue;
7869
7870 if (sec->sh_addr >= seg->p_vaddr
7871 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7872 {
7873 aux->seg_base = seg->p_vaddr;
7874 break;
7875 }
7876 }
4d6ed7c8
NC
7877 }
7878
7879 /* Second, build the unwind table from the contents of the unwind section: */
7880 size = sec->sh_size;
dda8d76d 7881 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7882 _("unwind table"));
a6e9f9df 7883 if (!table)
53774b7e 7884 return FALSE;
4d6ed7c8 7885
53774b7e 7886 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7887 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7888 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7889 tep = aux->table;
53774b7e
NC
7890
7891 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7892 {
7893 tep->start.section = SHN_UNDEF;
7894 tep->end.section = SHN_UNDEF;
7895 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7896 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7897 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7898 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7899 tep->start.offset += aux->seg_base;
7900 tep->end.offset += aux->seg_base;
7901 tep->info.offset += aux->seg_base;
7902 }
7903 free (table);
7904
41e92641 7905 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7906 for (relsec = filedata->section_headers;
7907 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7908 ++relsec)
7909 {
7910 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7911 || relsec->sh_info >= filedata->file_header.e_shnum
7912 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7913 continue;
7914
dda8d76d 7915 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7916 & rela, & nrelas))
53774b7e
NC
7917 {
7918 free (aux->table);
7919 aux->table = NULL;
7920 aux->table_len = 0;
7921 return FALSE;
7922 }
4d6ed7c8
NC
7923
7924 for (rp = rela; rp < rela + nrelas; ++rp)
7925 {
4770fb94 7926 unsigned int sym_ndx;
726bd37d
AM
7927 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
7928 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 7929
82b1b41b
NC
7930 /* PR 17531: file: 9fa67536. */
7931 if (relname == NULL)
7932 {
726bd37d 7933 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
7934 continue;
7935 }
948f632f 7936
0112cd26 7937 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7938 {
82b1b41b 7939 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7940 continue;
7941 }
7942
89fac5e3 7943 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7944
53774b7e
NC
7945 /* PR 17531: file: 5bc8d9bf. */
7946 if (i >= aux->table_len)
7947 {
7948 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7949 continue;
7950 }
7951
4770fb94
AM
7952 sym_ndx = get_reloc_symindex (rp->r_info);
7953 if (sym_ndx >= aux->nsyms)
7954 {
7955 warn (_("Skipping reloc with invalid symbol index: %u\n"),
7956 sym_ndx);
7957 continue;
7958 }
7959 sym = aux->symtab + sym_ndx;
7960
53774b7e 7961 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7962 {
7963 case 0:
7964 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7965 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7966 break;
7967 case 1:
7968 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7969 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7970 break;
7971 case 2:
7972 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7973 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7974 break;
7975 default:
7976 break;
7977 }
7978 }
7979
7980 free (rela);
7981 }
7982
53774b7e 7983 return TRUE;
4d6ed7c8
NC
7984}
7985
32ec8896 7986static bfd_boolean
dda8d76d 7987ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7988{
2cf0635d
NC
7989 Elf_Internal_Shdr * sec;
7990 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 7991 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7992 struct ia64_unw_aux_info aux;
32ec8896 7993 bfd_boolean res = TRUE;
f1467e33 7994
4d6ed7c8
NC
7995 memset (& aux, 0, sizeof (aux));
7996
dda8d76d 7997 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7998 {
28d13567 7999 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8000 {
28d13567 8001 if (aux.symtab)
4082ef84 8002 {
28d13567
AM
8003 error (_("Multiple symbol tables encountered\n"));
8004 free (aux.symtab);
8005 aux.symtab = NULL;
4082ef84 8006 free (aux.strtab);
28d13567 8007 aux.strtab = NULL;
4082ef84 8008 }
28d13567
AM
8009 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8010 &aux.strtab, &aux.strtab_size))
8011 return FALSE;
4d6ed7c8
NC
8012 }
8013 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8014 unwcount++;
8015 }
8016
8017 if (!unwcount)
8018 printf (_("\nThere are no unwind sections in this file.\n"));
8019
8020 while (unwcount-- > 0)
8021 {
2cf0635d 8022 char * suffix;
579f31ac
JJ
8023 size_t len, len2;
8024
dda8d76d
NC
8025 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8026 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8027 if (sec->sh_type == SHT_IA_64_UNWIND)
8028 {
8029 unwsec = sec;
8030 break;
8031 }
4082ef84
NC
8032 /* We have already counted the number of SHT_IA64_UNWIND
8033 sections so the loop above should never fail. */
8034 assert (unwsec != NULL);
579f31ac
JJ
8035
8036 unwstart = i + 1;
8037 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8038
e4b17d5c
L
8039 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8040 {
8041 /* We need to find which section group it is in. */
4082ef84 8042 struct group_list * g;
e4b17d5c 8043
978c4450
AM
8044 if (filedata->section_headers_groups == NULL
8045 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8046 i = filedata->file_header.e_shnum;
4082ef84 8047 else
e4b17d5c 8048 {
978c4450 8049 g = filedata->section_headers_groups[i]->root;
18bd398b 8050
4082ef84
NC
8051 for (; g != NULL; g = g->next)
8052 {
dda8d76d 8053 sec = filedata->section_headers + g->section_index;
e4b17d5c 8054
4082ef84
NC
8055 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
8056 break;
8057 }
8058
8059 if (g == NULL)
dda8d76d 8060 i = filedata->file_header.e_shnum;
4082ef84 8061 }
e4b17d5c 8062 }
18bd398b 8063 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 8064 {
18bd398b 8065 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8066 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8067 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8068 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8069 ++i, ++sec)
18bd398b
NC
8070 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
8071 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8072 break;
8073 }
8074 else
8075 {
8076 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8077 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8078 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8079 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8080 suffix = "";
18bd398b 8081 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 8082 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8083 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8084 ++i, ++sec)
18bd398b
NC
8085 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
8086 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8087 break;
8088 }
8089
dda8d76d 8090 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8091 {
8092 printf (_("\nCould not find unwind info section for "));
8093
dda8d76d 8094 if (filedata->string_table == NULL)
579f31ac
JJ
8095 printf ("%d", unwsec->sh_name);
8096 else
dda8d76d 8097 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8098 }
8099 else
4d6ed7c8 8100 {
4d6ed7c8 8101 aux.info_addr = sec->sh_addr;
dda8d76d 8102 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8103 sec->sh_size,
8104 _("unwind info"));
59245841 8105 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8106
579f31ac 8107 printf (_("\nUnwind section "));
4d6ed7c8 8108
dda8d76d 8109 if (filedata->string_table == NULL)
579f31ac
JJ
8110 printf ("%d", unwsec->sh_name);
8111 else
dda8d76d 8112 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8113
579f31ac 8114 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8115 (unsigned long) unwsec->sh_offset,
89fac5e3 8116 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8117
dda8d76d 8118 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8119 && aux.table_len > 0)
dda8d76d 8120 dump_ia64_unwind (filedata, & aux);
579f31ac 8121
9db70fc3
AM
8122 free ((char *) aux.table);
8123 free ((char *) aux.info);
579f31ac
JJ
8124 aux.table = NULL;
8125 aux.info = NULL;
8126 }
4d6ed7c8 8127 }
4d6ed7c8 8128
9db70fc3
AM
8129 free (aux.symtab);
8130 free ((char *) aux.strtab);
32ec8896
NC
8131
8132 return res;
4d6ed7c8
NC
8133}
8134
3f5e193b 8135struct hppa_unw_table_entry
32ec8896
NC
8136{
8137 struct absaddr start;
8138 struct absaddr end;
8139 unsigned int Cannot_unwind:1; /* 0 */
8140 unsigned int Millicode:1; /* 1 */
8141 unsigned int Millicode_save_sr0:1; /* 2 */
8142 unsigned int Region_description:2; /* 3..4 */
8143 unsigned int reserved1:1; /* 5 */
8144 unsigned int Entry_SR:1; /* 6 */
8145 unsigned int Entry_FR:4; /* Number saved 7..10 */
8146 unsigned int Entry_GR:5; /* Number saved 11..15 */
8147 unsigned int Args_stored:1; /* 16 */
8148 unsigned int Variable_Frame:1; /* 17 */
8149 unsigned int Separate_Package_Body:1; /* 18 */
8150 unsigned int Frame_Extension_Millicode:1; /* 19 */
8151 unsigned int Stack_Overflow_Check:1; /* 20 */
8152 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8153 unsigned int Ada_Region:1; /* 22 */
8154 unsigned int cxx_info:1; /* 23 */
8155 unsigned int cxx_try_catch:1; /* 24 */
8156 unsigned int sched_entry_seq:1; /* 25 */
8157 unsigned int reserved2:1; /* 26 */
8158 unsigned int Save_SP:1; /* 27 */
8159 unsigned int Save_RP:1; /* 28 */
8160 unsigned int Save_MRP_in_frame:1; /* 29 */
8161 unsigned int extn_ptr_defined:1; /* 30 */
8162 unsigned int Cleanup_defined:1; /* 31 */
8163
8164 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8165 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8166 unsigned int Large_frame:1; /* 2 */
8167 unsigned int Pseudo_SP_Set:1; /* 3 */
8168 unsigned int reserved4:1; /* 4 */
8169 unsigned int Total_frame_size:27; /* 5..31 */
8170};
3f5e193b 8171
57346661 8172struct hppa_unw_aux_info
948f632f 8173{
32ec8896
NC
8174 struct hppa_unw_table_entry * table; /* Unwind table. */
8175 unsigned long table_len; /* Length of unwind table. */
8176 bfd_vma seg_base; /* Starting address of segment. */
8177 Elf_Internal_Sym * symtab; /* The symbol table. */
8178 unsigned long nsyms; /* Number of symbols. */
8179 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8180 unsigned long nfuns; /* Number of entries in funtab. */
8181 char * strtab; /* The string table. */
8182 unsigned long strtab_size; /* Size of string table. */
948f632f 8183};
57346661 8184
32ec8896 8185static bfd_boolean
dda8d76d 8186dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8187{
2cf0635d 8188 struct hppa_unw_table_entry * tp;
948f632f 8189 unsigned long j, nfuns;
32ec8896 8190 bfd_boolean res = TRUE;
948f632f
DA
8191
8192 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8193 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8194 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8195 aux->funtab[nfuns++] = aux->symtab[j];
8196 aux->nfuns = nfuns;
8197 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8198
57346661
AM
8199 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8200 {
8201 bfd_vma offset;
2cf0635d 8202 const char * procname;
57346661 8203
dda8d76d 8204 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8205 aux->strtab_size, tp->start, &procname,
8206 &offset);
8207
8208 fputs ("\n<", stdout);
8209
8210 if (procname)
8211 {
8212 fputs (procname, stdout);
8213
8214 if (offset)
8215 printf ("+%lx", (unsigned long) offset);
8216 }
8217
8218 fputs (">: [", stdout);
8219 print_vma (tp->start.offset, PREFIX_HEX);
8220 fputc ('-', stdout);
8221 print_vma (tp->end.offset, PREFIX_HEX);
8222 printf ("]\n\t");
8223
18bd398b
NC
8224#define PF(_m) if (tp->_m) printf (#_m " ");
8225#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8226 PF(Cannot_unwind);
8227 PF(Millicode);
8228 PF(Millicode_save_sr0);
18bd398b 8229 /* PV(Region_description); */
57346661
AM
8230 PF(Entry_SR);
8231 PV(Entry_FR);
8232 PV(Entry_GR);
8233 PF(Args_stored);
8234 PF(Variable_Frame);
8235 PF(Separate_Package_Body);
8236 PF(Frame_Extension_Millicode);
8237 PF(Stack_Overflow_Check);
8238 PF(Two_Instruction_SP_Increment);
8239 PF(Ada_Region);
8240 PF(cxx_info);
8241 PF(cxx_try_catch);
8242 PF(sched_entry_seq);
8243 PF(Save_SP);
8244 PF(Save_RP);
8245 PF(Save_MRP_in_frame);
8246 PF(extn_ptr_defined);
8247 PF(Cleanup_defined);
8248 PF(MPE_XL_interrupt_marker);
8249 PF(HP_UX_interrupt_marker);
8250 PF(Large_frame);
8251 PF(Pseudo_SP_Set);
8252 PV(Total_frame_size);
8253#undef PF
8254#undef PV
8255 }
8256
18bd398b 8257 printf ("\n");
948f632f
DA
8258
8259 free (aux->funtab);
32ec8896
NC
8260
8261 return res;
57346661
AM
8262}
8263
32ec8896 8264static bfd_boolean
dda8d76d
NC
8265slurp_hppa_unwind_table (Filedata * filedata,
8266 struct hppa_unw_aux_info * aux,
8267 Elf_Internal_Shdr * sec)
57346661 8268{
1c0751b2 8269 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8270 Elf_Internal_Phdr * seg;
8271 struct hppa_unw_table_entry * tep;
8272 Elf_Internal_Shdr * relsec;
8273 Elf_Internal_Rela * rela;
8274 Elf_Internal_Rela * rp;
8275 unsigned char * table;
8276 unsigned char * tp;
8277 Elf_Internal_Sym * sym;
8278 const char * relname;
57346661 8279
57346661
AM
8280 /* First, find the starting address of the segment that includes
8281 this section. */
dda8d76d 8282 if (filedata->file_header.e_phnum)
57346661 8283 {
dda8d76d 8284 if (! get_program_headers (filedata))
32ec8896 8285 return FALSE;
57346661 8286
dda8d76d
NC
8287 for (seg = filedata->program_headers;
8288 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8289 ++seg)
8290 {
8291 if (seg->p_type != PT_LOAD)
8292 continue;
8293
8294 if (sec->sh_addr >= seg->p_vaddr
8295 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8296 {
8297 aux->seg_base = seg->p_vaddr;
8298 break;
8299 }
8300 }
8301 }
8302
8303 /* Second, build the unwind table from the contents of the unwind
8304 section. */
8305 size = sec->sh_size;
dda8d76d 8306 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8307 _("unwind table"));
57346661 8308 if (!table)
32ec8896 8309 return FALSE;
57346661 8310
1c0751b2
DA
8311 unw_ent_size = 16;
8312 nentries = size / unw_ent_size;
8313 size = unw_ent_size * nentries;
57346661 8314
e3fdc001 8315 aux->table_len = nentries;
3f5e193b
NC
8316 tep = aux->table = (struct hppa_unw_table_entry *)
8317 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8318
1c0751b2 8319 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8320 {
8321 unsigned int tmp1, tmp2;
8322
8323 tep->start.section = SHN_UNDEF;
8324 tep->end.section = SHN_UNDEF;
8325
1c0751b2
DA
8326 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8327 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8328 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8329 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8330
8331 tep->start.offset += aux->seg_base;
8332 tep->end.offset += aux->seg_base;
57346661
AM
8333
8334 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8335 tep->Millicode = (tmp1 >> 30) & 0x1;
8336 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8337 tep->Region_description = (tmp1 >> 27) & 0x3;
8338 tep->reserved1 = (tmp1 >> 26) & 0x1;
8339 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8340 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8341 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8342 tep->Args_stored = (tmp1 >> 15) & 0x1;
8343 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8344 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8345 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8346 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8347 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8348 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8349 tep->cxx_info = (tmp1 >> 8) & 0x1;
8350 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8351 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8352 tep->reserved2 = (tmp1 >> 5) & 0x1;
8353 tep->Save_SP = (tmp1 >> 4) & 0x1;
8354 tep->Save_RP = (tmp1 >> 3) & 0x1;
8355 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8356 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8357 tep->Cleanup_defined = tmp1 & 0x1;
8358
8359 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8360 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8361 tep->Large_frame = (tmp2 >> 29) & 0x1;
8362 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8363 tep->reserved4 = (tmp2 >> 27) & 0x1;
8364 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8365 }
8366 free (table);
8367
8368 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8369 for (relsec = filedata->section_headers;
8370 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8371 ++relsec)
8372 {
8373 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8374 || relsec->sh_info >= filedata->file_header.e_shnum
8375 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8376 continue;
8377
dda8d76d 8378 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8379 & rela, & nrelas))
32ec8896 8380 return FALSE;
57346661
AM
8381
8382 for (rp = rela; rp < rela + nrelas; ++rp)
8383 {
4770fb94 8384 unsigned int sym_ndx;
726bd37d
AM
8385 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8386 relname = elf_hppa_reloc_type (r_type);
57346661 8387
726bd37d
AM
8388 if (relname == NULL)
8389 {
8390 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8391 continue;
8392 }
8393
57346661 8394 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8395 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8396 {
726bd37d 8397 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8398 continue;
8399 }
8400
8401 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8402 if (i >= aux->table_len)
8403 {
8404 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8405 continue;
8406 }
57346661 8407
4770fb94
AM
8408 sym_ndx = get_reloc_symindex (rp->r_info);
8409 if (sym_ndx >= aux->nsyms)
8410 {
8411 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8412 sym_ndx);
8413 continue;
8414 }
8415 sym = aux->symtab + sym_ndx;
8416
43f6cd05 8417 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8418 {
8419 case 0:
8420 aux->table[i].start.section = sym->st_shndx;
1e456d54 8421 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8422 break;
8423 case 1:
8424 aux->table[i].end.section = sym->st_shndx;
1e456d54 8425 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8426 break;
8427 default:
8428 break;
8429 }
8430 }
8431
8432 free (rela);
8433 }
8434
32ec8896 8435 return TRUE;
57346661
AM
8436}
8437
32ec8896 8438static bfd_boolean
dda8d76d 8439hppa_process_unwind (Filedata * filedata)
57346661 8440{
57346661 8441 struct hppa_unw_aux_info aux;
2cf0635d 8442 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8443 Elf_Internal_Shdr * sec;
18bd398b 8444 unsigned long i;
32ec8896 8445 bfd_boolean res = TRUE;
57346661 8446
dda8d76d 8447 if (filedata->string_table == NULL)
32ec8896 8448 return FALSE;
1b31d05e
NC
8449
8450 memset (& aux, 0, sizeof (aux));
57346661 8451
dda8d76d 8452 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8453 {
28d13567 8454 if (sec->sh_type == SHT_SYMTAB)
57346661 8455 {
28d13567 8456 if (aux.symtab)
4082ef84 8457 {
28d13567
AM
8458 error (_("Multiple symbol tables encountered\n"));
8459 free (aux.symtab);
8460 aux.symtab = NULL;
4082ef84 8461 free (aux.strtab);
28d13567 8462 aux.strtab = NULL;
4082ef84 8463 }
28d13567
AM
8464 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8465 &aux.strtab, &aux.strtab_size))
8466 return FALSE;
57346661 8467 }
18bd398b 8468 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8469 unwsec = sec;
8470 }
8471
8472 if (!unwsec)
8473 printf (_("\nThere are no unwind sections in this file.\n"));
8474
dda8d76d 8475 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8476 {
18bd398b 8477 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8478 {
43f6cd05 8479 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8480
d3a49aa8
AM
8481 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8482 "contains %lu entry:\n",
8483 "\nUnwind section '%s' at offset 0x%lx "
8484 "contains %lu entries:\n",
8485 num_unwind),
dda8d76d 8486 printable_section_name (filedata, sec),
57346661 8487 (unsigned long) sec->sh_offset,
d3a49aa8 8488 num_unwind);
57346661 8489
dda8d76d 8490 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8491 res = FALSE;
66b09c7e
S
8492
8493 if (res && aux.table_len > 0)
32ec8896 8494 {
dda8d76d 8495 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8496 res = FALSE;
8497 }
57346661 8498
9db70fc3 8499 free ((char *) aux.table);
57346661
AM
8500 aux.table = NULL;
8501 }
8502 }
8503
9db70fc3
AM
8504 free (aux.symtab);
8505 free ((char *) aux.strtab);
32ec8896
NC
8506
8507 return res;
57346661
AM
8508}
8509
0b6ae522
DJ
8510struct arm_section
8511{
a734115a
NC
8512 unsigned char * data; /* The unwind data. */
8513 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8514 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8515 unsigned long nrelas; /* The number of relocations. */
8516 unsigned int rel_type; /* REL or RELA ? */
8517 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8518};
8519
8520struct arm_unw_aux_info
8521{
dda8d76d 8522 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8523 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8524 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8525 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8526 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8527 char * strtab; /* The file's string table. */
8528 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8529};
8530
8531static const char *
dda8d76d
NC
8532arm_print_vma_and_name (Filedata * filedata,
8533 struct arm_unw_aux_info * aux,
8534 bfd_vma fn,
8535 struct absaddr addr)
0b6ae522
DJ
8536{
8537 const char *procname;
8538 bfd_vma sym_offset;
8539
8540 if (addr.section == SHN_UNDEF)
8541 addr.offset = fn;
8542
dda8d76d 8543 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8544 aux->strtab_size, addr, &procname,
8545 &sym_offset);
8546
8547 print_vma (fn, PREFIX_HEX);
8548
8549 if (procname)
8550 {
8551 fputs (" <", stdout);
8552 fputs (procname, stdout);
8553
8554 if (sym_offset)
8555 printf ("+0x%lx", (unsigned long) sym_offset);
8556 fputc ('>', stdout);
8557 }
8558
8559 return procname;
8560}
8561
8562static void
8563arm_free_section (struct arm_section *arm_sec)
8564{
9db70fc3
AM
8565 free (arm_sec->data);
8566 free (arm_sec->rela);
0b6ae522
DJ
8567}
8568
a734115a
NC
8569/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8570 cached section and install SEC instead.
8571 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8572 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8573 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8574 relocation's offset in ADDR.
1b31d05e
NC
8575 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8576 into the string table of the symbol associated with the reloc. If no
8577 reloc was applied store -1 there.
8578 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8579
8580static bfd_boolean
dda8d76d
NC
8581get_unwind_section_word (Filedata * filedata,
8582 struct arm_unw_aux_info * aux,
1b31d05e
NC
8583 struct arm_section * arm_sec,
8584 Elf_Internal_Shdr * sec,
8585 bfd_vma word_offset,
8586 unsigned int * wordp,
8587 struct absaddr * addr,
8588 bfd_vma * sym_name)
0b6ae522
DJ
8589{
8590 Elf_Internal_Rela *rp;
8591 Elf_Internal_Sym *sym;
8592 const char * relname;
8593 unsigned int word;
8594 bfd_boolean wrapped;
8595
e0a31db1
NC
8596 if (sec == NULL || arm_sec == NULL)
8597 return FALSE;
8598
0b6ae522
DJ
8599 addr->section = SHN_UNDEF;
8600 addr->offset = 0;
8601
1b31d05e
NC
8602 if (sym_name != NULL)
8603 *sym_name = (bfd_vma) -1;
8604
a734115a 8605 /* If necessary, update the section cache. */
0b6ae522
DJ
8606 if (sec != arm_sec->sec)
8607 {
8608 Elf_Internal_Shdr *relsec;
8609
8610 arm_free_section (arm_sec);
8611
8612 arm_sec->sec = sec;
dda8d76d 8613 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8614 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8615 arm_sec->rela = NULL;
8616 arm_sec->nrelas = 0;
8617
dda8d76d
NC
8618 for (relsec = filedata->section_headers;
8619 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8620 ++relsec)
8621 {
dda8d76d
NC
8622 if (relsec->sh_info >= filedata->file_header.e_shnum
8623 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8624 /* PR 15745: Check the section type as well. */
8625 || (relsec->sh_type != SHT_REL
8626 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8627 continue;
8628
a734115a 8629 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8630 if (relsec->sh_type == SHT_REL)
8631 {
dda8d76d 8632 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8633 relsec->sh_size,
8634 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8635 return FALSE;
0b6ae522 8636 }
1ae40aa4 8637 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8638 {
dda8d76d 8639 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8640 relsec->sh_size,
8641 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8642 return FALSE;
0b6ae522 8643 }
1ae40aa4 8644 break;
0b6ae522
DJ
8645 }
8646
8647 arm_sec->next_rela = arm_sec->rela;
8648 }
8649
a734115a 8650 /* If there is no unwind data we can do nothing. */
0b6ae522 8651 if (arm_sec->data == NULL)
a734115a 8652 return FALSE;
0b6ae522 8653
e0a31db1 8654 /* If the offset is invalid then fail. */
f32ba729
NC
8655 if (/* PR 21343 *//* PR 18879 */
8656 sec->sh_size < 4
8657 || word_offset > (sec->sh_size - 4)
1a915552 8658 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8659 return FALSE;
8660
a734115a 8661 /* Get the word at the required offset. */
0b6ae522
DJ
8662 word = byte_get (arm_sec->data + word_offset, 4);
8663
0eff7165
NC
8664 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8665 if (arm_sec->rela == NULL)
8666 {
8667 * wordp = word;
8668 return TRUE;
8669 }
8670
a734115a 8671 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8672 wrapped = FALSE;
8673 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8674 {
8675 bfd_vma prelval, offset;
8676
8677 if (rp->r_offset > word_offset && !wrapped)
8678 {
8679 rp = arm_sec->rela;
8680 wrapped = TRUE;
8681 }
8682 if (rp->r_offset > word_offset)
8683 break;
8684
8685 if (rp->r_offset & 3)
8686 {
8687 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8688 (unsigned long) rp->r_offset);
8689 continue;
8690 }
8691
8692 if (rp->r_offset < word_offset)
8693 continue;
8694
74e1a04b
NC
8695 /* PR 17531: file: 027-161405-0.004 */
8696 if (aux->symtab == NULL)
8697 continue;
8698
0b6ae522
DJ
8699 if (arm_sec->rel_type == SHT_REL)
8700 {
8701 offset = word & 0x7fffffff;
8702 if (offset & 0x40000000)
8703 offset |= ~ (bfd_vma) 0x7fffffff;
8704 }
a734115a 8705 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8706 offset = rp->r_addend;
a734115a 8707 else
74e1a04b
NC
8708 {
8709 error (_("Unknown section relocation type %d encountered\n"),
8710 arm_sec->rel_type);
8711 break;
8712 }
0b6ae522 8713
071436c6
NC
8714 /* PR 17531 file: 027-1241568-0.004. */
8715 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8716 {
8717 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8718 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8719 break;
8720 }
8721
8722 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8723 offset += sym->st_value;
8724 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8725
a734115a 8726 /* Check that we are processing the expected reloc type. */
dda8d76d 8727 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8728 {
8729 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8730 if (relname == NULL)
8731 {
8732 warn (_("Skipping unknown ARM relocation type: %d\n"),
8733 (int) ELF32_R_TYPE (rp->r_info));
8734 continue;
8735 }
a734115a
NC
8736
8737 if (streq (relname, "R_ARM_NONE"))
8738 continue;
0b4362b0 8739
a734115a
NC
8740 if (! streq (relname, "R_ARM_PREL31"))
8741 {
071436c6 8742 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8743 continue;
8744 }
8745 }
dda8d76d 8746 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8747 {
8748 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8749 if (relname == NULL)
8750 {
8751 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8752 (int) ELF32_R_TYPE (rp->r_info));
8753 continue;
8754 }
0b4362b0 8755
a734115a
NC
8756 if (streq (relname, "R_C6000_NONE"))
8757 continue;
8758
8759 if (! streq (relname, "R_C6000_PREL31"))
8760 {
071436c6 8761 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8762 continue;
8763 }
8764
8765 prelval >>= 1;
8766 }
8767 else
74e1a04b
NC
8768 {
8769 /* This function currently only supports ARM and TI unwinders. */
8770 warn (_("Only TI and ARM unwinders are currently supported\n"));
8771 break;
8772 }
fa197c1c 8773
0b6ae522
DJ
8774 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8775 addr->section = sym->st_shndx;
8776 addr->offset = offset;
74e1a04b 8777
1b31d05e
NC
8778 if (sym_name)
8779 * sym_name = sym->st_name;
0b6ae522
DJ
8780 break;
8781 }
8782
8783 *wordp = word;
8784 arm_sec->next_rela = rp;
8785
a734115a 8786 return TRUE;
0b6ae522
DJ
8787}
8788
a734115a
NC
8789static const char *tic6x_unwind_regnames[16] =
8790{
0b4362b0
RM
8791 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8792 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8793 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8794};
fa197c1c 8795
0b6ae522 8796static void
fa197c1c 8797decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8798{
fa197c1c
PB
8799 int i;
8800
8801 for (i = 12; mask; mask >>= 1, i--)
8802 {
8803 if (mask & 1)
8804 {
8805 fputs (tic6x_unwind_regnames[i], stdout);
8806 if (mask > 1)
8807 fputs (", ", stdout);
8808 }
8809 }
8810}
0b6ae522
DJ
8811
8812#define ADVANCE \
8813 if (remaining == 0 && more_words) \
8814 { \
8815 data_offset += 4; \
dda8d76d 8816 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8817 data_offset, & word, & addr, NULL)) \
32ec8896 8818 return FALSE; \
0b6ae522
DJ
8819 remaining = 4; \
8820 more_words--; \
8821 } \
8822
8823#define GET_OP(OP) \
8824 ADVANCE; \
8825 if (remaining) \
8826 { \
8827 remaining--; \
8828 (OP) = word >> 24; \
8829 word <<= 8; \
8830 } \
8831 else \
8832 { \
2b692964 8833 printf (_("[Truncated opcode]\n")); \
32ec8896 8834 return FALSE; \
0b6ae522 8835 } \
cc5914eb 8836 printf ("0x%02x ", OP)
0b6ae522 8837
32ec8896 8838static bfd_boolean
dda8d76d
NC
8839decode_arm_unwind_bytecode (Filedata * filedata,
8840 struct arm_unw_aux_info * aux,
948f632f
DA
8841 unsigned int word,
8842 unsigned int remaining,
8843 unsigned int more_words,
8844 bfd_vma data_offset,
8845 Elf_Internal_Shdr * data_sec,
8846 struct arm_section * data_arm_sec)
fa197c1c
PB
8847{
8848 struct absaddr addr;
32ec8896 8849 bfd_boolean res = TRUE;
0b6ae522
DJ
8850
8851 /* Decode the unwinding instructions. */
8852 while (1)
8853 {
8854 unsigned int op, op2;
8855
8856 ADVANCE;
8857 if (remaining == 0)
8858 break;
8859 remaining--;
8860 op = word >> 24;
8861 word <<= 8;
8862
cc5914eb 8863 printf (" 0x%02x ", op);
0b6ae522
DJ
8864
8865 if ((op & 0xc0) == 0x00)
8866 {
8867 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8868
cc5914eb 8869 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8870 }
8871 else if ((op & 0xc0) == 0x40)
8872 {
8873 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8874
cc5914eb 8875 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8876 }
8877 else if ((op & 0xf0) == 0x80)
8878 {
8879 GET_OP (op2);
8880 if (op == 0x80 && op2 == 0)
8881 printf (_("Refuse to unwind"));
8882 else
8883 {
8884 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8885 bfd_boolean first = TRUE;
0b6ae522 8886 int i;
2b692964 8887
0b6ae522
DJ
8888 printf ("pop {");
8889 for (i = 0; i < 12; i++)
8890 if (mask & (1 << i))
8891 {
8892 if (first)
32ec8896 8893 first = FALSE;
0b6ae522
DJ
8894 else
8895 printf (", ");
8896 printf ("r%d", 4 + i);
8897 }
8898 printf ("}");
8899 }
8900 }
8901 else if ((op & 0xf0) == 0x90)
8902 {
8903 if (op == 0x9d || op == 0x9f)
8904 printf (_(" [Reserved]"));
8905 else
cc5914eb 8906 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8907 }
8908 else if ((op & 0xf0) == 0xa0)
8909 {
8910 int end = 4 + (op & 0x07);
32ec8896 8911 bfd_boolean first = TRUE;
0b6ae522 8912 int i;
61865e30 8913
0b6ae522
DJ
8914 printf (" pop {");
8915 for (i = 4; i <= end; i++)
8916 {
8917 if (first)
32ec8896 8918 first = FALSE;
0b6ae522
DJ
8919 else
8920 printf (", ");
8921 printf ("r%d", i);
8922 }
8923 if (op & 0x08)
8924 {
1b31d05e 8925 if (!first)
0b6ae522
DJ
8926 printf (", ");
8927 printf ("r14");
8928 }
8929 printf ("}");
8930 }
8931 else if (op == 0xb0)
8932 printf (_(" finish"));
8933 else if (op == 0xb1)
8934 {
8935 GET_OP (op2);
8936 if (op2 == 0 || (op2 & 0xf0) != 0)
8937 printf (_("[Spare]"));
8938 else
8939 {
8940 unsigned int mask = op2 & 0x0f;
32ec8896 8941 bfd_boolean first = TRUE;
0b6ae522 8942 int i;
61865e30 8943
0b6ae522
DJ
8944 printf ("pop {");
8945 for (i = 0; i < 12; i++)
8946 if (mask & (1 << i))
8947 {
8948 if (first)
32ec8896 8949 first = FALSE;
0b6ae522
DJ
8950 else
8951 printf (", ");
8952 printf ("r%d", i);
8953 }
8954 printf ("}");
8955 }
8956 }
8957 else if (op == 0xb2)
8958 {
b115cf96 8959 unsigned char buf[9];
0b6ae522
DJ
8960 unsigned int i, len;
8961 unsigned long offset;
61865e30 8962
b115cf96 8963 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8964 {
8965 GET_OP (buf[i]);
8966 if ((buf[i] & 0x80) == 0)
8967 break;
8968 }
4082ef84 8969 if (i == sizeof (buf))
32ec8896 8970 {
27a45f42 8971 error (_("corrupt change to vsp\n"));
32ec8896
NC
8972 res = FALSE;
8973 }
4082ef84
NC
8974 else
8975 {
cd30bcef 8976 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
8977 assert (len == i + 1);
8978 offset = offset * 4 + 0x204;
8979 printf ("vsp = vsp + %ld", offset);
8980 }
0b6ae522 8981 }
61865e30 8982 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8983 {
61865e30
NC
8984 unsigned int first, last;
8985
8986 GET_OP (op2);
8987 first = op2 >> 4;
8988 last = op2 & 0x0f;
8989 if (op == 0xc8)
8990 first = first + 16;
8991 printf ("pop {D%d", first);
8992 if (last)
8993 printf ("-D%d", first + last);
8994 printf ("}");
8995 }
8996 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8997 {
8998 unsigned int count = op & 0x07;
8999
9000 printf ("pop {D8");
9001 if (count)
9002 printf ("-D%d", 8 + count);
9003 printf ("}");
9004 }
9005 else if (op >= 0xc0 && op <= 0xc5)
9006 {
9007 unsigned int count = op & 0x07;
9008
9009 printf (" pop {wR10");
9010 if (count)
9011 printf ("-wR%d", 10 + count);
9012 printf ("}");
9013 }
9014 else if (op == 0xc6)
9015 {
9016 unsigned int first, last;
9017
9018 GET_OP (op2);
9019 first = op2 >> 4;
9020 last = op2 & 0x0f;
9021 printf ("pop {wR%d", first);
9022 if (last)
9023 printf ("-wR%d", first + last);
9024 printf ("}");
9025 }
9026 else if (op == 0xc7)
9027 {
9028 GET_OP (op2);
9029 if (op2 == 0 || (op2 & 0xf0) != 0)
9030 printf (_("[Spare]"));
0b6ae522
DJ
9031 else
9032 {
61865e30 9033 unsigned int mask = op2 & 0x0f;
32ec8896 9034 bfd_boolean first = TRUE;
61865e30
NC
9035 int i;
9036
9037 printf ("pop {");
9038 for (i = 0; i < 4; i++)
9039 if (mask & (1 << i))
9040 {
9041 if (first)
32ec8896 9042 first = FALSE;
61865e30
NC
9043 else
9044 printf (", ");
9045 printf ("wCGR%d", i);
9046 }
9047 printf ("}");
0b6ae522
DJ
9048 }
9049 }
61865e30 9050 else
32ec8896
NC
9051 {
9052 printf (_(" [unsupported opcode]"));
9053 res = FALSE;
9054 }
9055
0b6ae522
DJ
9056 printf ("\n");
9057 }
32ec8896
NC
9058
9059 return res;
fa197c1c
PB
9060}
9061
32ec8896 9062static bfd_boolean
dda8d76d
NC
9063decode_tic6x_unwind_bytecode (Filedata * filedata,
9064 struct arm_unw_aux_info * aux,
948f632f
DA
9065 unsigned int word,
9066 unsigned int remaining,
9067 unsigned int more_words,
9068 bfd_vma data_offset,
9069 Elf_Internal_Shdr * data_sec,
9070 struct arm_section * data_arm_sec)
fa197c1c
PB
9071{
9072 struct absaddr addr;
9073
9074 /* Decode the unwinding instructions. */
9075 while (1)
9076 {
9077 unsigned int op, op2;
9078
9079 ADVANCE;
9080 if (remaining == 0)
9081 break;
9082 remaining--;
9083 op = word >> 24;
9084 word <<= 8;
9085
9cf03b7e 9086 printf (" 0x%02x ", op);
fa197c1c
PB
9087
9088 if ((op & 0xc0) == 0x00)
9089 {
9090 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9091 printf (" sp = sp + %d", offset);
fa197c1c
PB
9092 }
9093 else if ((op & 0xc0) == 0x80)
9094 {
9095 GET_OP (op2);
9096 if (op == 0x80 && op2 == 0)
9097 printf (_("Refuse to unwind"));
9098 else
9099 {
9100 unsigned int mask = ((op & 0x1f) << 8) | op2;
9101 if (op & 0x20)
9102 printf ("pop compact {");
9103 else
9104 printf ("pop {");
9105
9106 decode_tic6x_unwind_regmask (mask);
9107 printf("}");
9108 }
9109 }
9110 else if ((op & 0xf0) == 0xc0)
9111 {
9112 unsigned int reg;
9113 unsigned int nregs;
9114 unsigned int i;
9115 const char *name;
a734115a
NC
9116 struct
9117 {
32ec8896
NC
9118 unsigned int offset;
9119 unsigned int reg;
fa197c1c
PB
9120 } regpos[16];
9121
9122 /* Scan entire instruction first so that GET_OP output is not
9123 interleaved with disassembly. */
9124 nregs = 0;
9125 for (i = 0; nregs < (op & 0xf); i++)
9126 {
9127 GET_OP (op2);
9128 reg = op2 >> 4;
9129 if (reg != 0xf)
9130 {
9131 regpos[nregs].offset = i * 2;
9132 regpos[nregs].reg = reg;
9133 nregs++;
9134 }
9135
9136 reg = op2 & 0xf;
9137 if (reg != 0xf)
9138 {
9139 regpos[nregs].offset = i * 2 + 1;
9140 regpos[nregs].reg = reg;
9141 nregs++;
9142 }
9143 }
9144
9145 printf (_("pop frame {"));
18344509 9146 if (nregs == 0)
fa197c1c 9147 {
18344509
NC
9148 printf (_("*corrupt* - no registers specified"));
9149 }
9150 else
9151 {
9152 reg = nregs - 1;
9153 for (i = i * 2; i > 0; i--)
fa197c1c 9154 {
18344509
NC
9155 if (regpos[reg].offset == i - 1)
9156 {
9157 name = tic6x_unwind_regnames[regpos[reg].reg];
9158 if (reg > 0)
9159 reg--;
9160 }
9161 else
9162 name = _("[pad]");
fa197c1c 9163
18344509
NC
9164 fputs (name, stdout);
9165 if (i > 1)
9166 printf (", ");
9167 }
fa197c1c
PB
9168 }
9169
9170 printf ("}");
9171 }
9172 else if (op == 0xd0)
9173 printf (" MOV FP, SP");
9174 else if (op == 0xd1)
9175 printf (" __c6xabi_pop_rts");
9176 else if (op == 0xd2)
9177 {
9178 unsigned char buf[9];
9179 unsigned int i, len;
9180 unsigned long offset;
a734115a 9181
fa197c1c
PB
9182 for (i = 0; i < sizeof (buf); i++)
9183 {
9184 GET_OP (buf[i]);
9185 if ((buf[i] & 0x80) == 0)
9186 break;
9187 }
0eff7165
NC
9188 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9189 if (i == sizeof (buf))
9190 {
0eff7165 9191 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9192 return FALSE;
0eff7165 9193 }
948f632f 9194
cd30bcef 9195 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9196 assert (len == i + 1);
9197 offset = offset * 8 + 0x408;
9198 printf (_("sp = sp + %ld"), offset);
9199 }
9200 else if ((op & 0xf0) == 0xe0)
9201 {
9202 if ((op & 0x0f) == 7)
9203 printf (" RETURN");
9204 else
9205 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9206 }
9207 else
9208 {
9209 printf (_(" [unsupported opcode]"));
9210 }
9211 putchar ('\n');
9212 }
32ec8896
NC
9213
9214 return TRUE;
fa197c1c
PB
9215}
9216
9217static bfd_vma
dda8d76d 9218arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9219{
9220 bfd_vma offset;
9221
9222 offset = word & 0x7fffffff;
9223 if (offset & 0x40000000)
9224 offset |= ~ (bfd_vma) 0x7fffffff;
9225
dda8d76d 9226 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9227 offset <<= 1;
9228
9229 return offset + where;
9230}
9231
32ec8896 9232static bfd_boolean
dda8d76d
NC
9233decode_arm_unwind (Filedata * filedata,
9234 struct arm_unw_aux_info * aux,
1b31d05e
NC
9235 unsigned int word,
9236 unsigned int remaining,
9237 bfd_vma data_offset,
9238 Elf_Internal_Shdr * data_sec,
9239 struct arm_section * data_arm_sec)
fa197c1c
PB
9240{
9241 int per_index;
9242 unsigned int more_words = 0;
37e14bc3 9243 struct absaddr addr;
1b31d05e 9244 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9245 bfd_boolean res = TRUE;
fa197c1c
PB
9246
9247 if (remaining == 0)
9248 {
1b31d05e
NC
9249 /* Fetch the first word.
9250 Note - when decoding an object file the address extracted
9251 here will always be 0. So we also pass in the sym_name
9252 parameter so that we can find the symbol associated with
9253 the personality routine. */
dda8d76d 9254 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9255 & word, & addr, & sym_name))
32ec8896 9256 return FALSE;
1b31d05e 9257
fa197c1c
PB
9258 remaining = 4;
9259 }
c93dbb25
CZ
9260 else
9261 {
9262 addr.section = SHN_UNDEF;
9263 addr.offset = 0;
9264 }
fa197c1c
PB
9265
9266 if ((word & 0x80000000) == 0)
9267 {
9268 /* Expand prel31 for personality routine. */
9269 bfd_vma fn;
9270 const char *procname;
9271
dda8d76d 9272 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9273 printf (_(" Personality routine: "));
1b31d05e
NC
9274 if (fn == 0
9275 && addr.section == SHN_UNDEF && addr.offset == 0
9276 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9277 {
9278 procname = aux->strtab + sym_name;
9279 print_vma (fn, PREFIX_HEX);
9280 if (procname)
9281 {
9282 fputs (" <", stdout);
9283 fputs (procname, stdout);
9284 fputc ('>', stdout);
9285 }
9286 }
9287 else
dda8d76d 9288 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9289 fputc ('\n', stdout);
9290
9291 /* The GCC personality routines use the standard compact
9292 encoding, starting with one byte giving the number of
9293 words. */
9294 if (procname != NULL
9295 && (const_strneq (procname, "__gcc_personality_v0")
9296 || const_strneq (procname, "__gxx_personality_v0")
9297 || const_strneq (procname, "__gcj_personality_v0")
9298 || const_strneq (procname, "__gnu_objc_personality_v0")))
9299 {
9300 remaining = 0;
9301 more_words = 1;
9302 ADVANCE;
9303 if (!remaining)
9304 {
9305 printf (_(" [Truncated data]\n"));
32ec8896 9306 return FALSE;
fa197c1c
PB
9307 }
9308 more_words = word >> 24;
9309 word <<= 8;
9310 remaining--;
9311 per_index = -1;
9312 }
9313 else
32ec8896 9314 return TRUE;
fa197c1c
PB
9315 }
9316 else
9317 {
1b31d05e 9318 /* ARM EHABI Section 6.3:
0b4362b0 9319
1b31d05e 9320 An exception-handling table entry for the compact model looks like:
0b4362b0 9321
1b31d05e
NC
9322 31 30-28 27-24 23-0
9323 -- ----- ----- ----
9324 1 0 index Data for personalityRoutine[index] */
9325
dda8d76d 9326 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9327 && (word & 0x70000000))
32ec8896
NC
9328 {
9329 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9330 res = FALSE;
9331 }
1b31d05e 9332
fa197c1c 9333 per_index = (word >> 24) & 0x7f;
1b31d05e 9334 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9335 if (per_index == 0)
9336 {
9337 more_words = 0;
9338 word <<= 8;
9339 remaining--;
9340 }
9341 else if (per_index < 3)
9342 {
9343 more_words = (word >> 16) & 0xff;
9344 word <<= 16;
9345 remaining -= 2;
9346 }
9347 }
9348
dda8d76d 9349 switch (filedata->file_header.e_machine)
fa197c1c
PB
9350 {
9351 case EM_ARM:
9352 if (per_index < 3)
9353 {
dda8d76d 9354 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9355 data_offset, data_sec, data_arm_sec))
9356 res = FALSE;
fa197c1c
PB
9357 }
9358 else
1b31d05e
NC
9359 {
9360 warn (_("Unknown ARM compact model index encountered\n"));
9361 printf (_(" [reserved]\n"));
32ec8896 9362 res = FALSE;
1b31d05e 9363 }
fa197c1c
PB
9364 break;
9365
9366 case EM_TI_C6000:
9367 if (per_index < 3)
9368 {
dda8d76d 9369 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9370 data_offset, data_sec, data_arm_sec))
9371 res = FALSE;
fa197c1c
PB
9372 }
9373 else if (per_index < 5)
9374 {
9375 if (((word >> 17) & 0x7f) == 0x7f)
9376 printf (_(" Restore stack from frame pointer\n"));
9377 else
9378 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9379 printf (_(" Registers restored: "));
9380 if (per_index == 4)
9381 printf (" (compact) ");
9382 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9383 putchar ('\n');
9384 printf (_(" Return register: %s\n"),
9385 tic6x_unwind_regnames[word & 0xf]);
9386 }
9387 else
1b31d05e 9388 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9389 break;
9390
9391 default:
74e1a04b 9392 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9393 filedata->file_header.e_machine);
32ec8896 9394 res = FALSE;
fa197c1c 9395 }
0b6ae522
DJ
9396
9397 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9398
9399 return res;
0b6ae522
DJ
9400}
9401
32ec8896 9402static bfd_boolean
dda8d76d
NC
9403dump_arm_unwind (Filedata * filedata,
9404 struct arm_unw_aux_info * aux,
9405 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9406{
9407 struct arm_section exidx_arm_sec, extab_arm_sec;
9408 unsigned int i, exidx_len;
948f632f 9409 unsigned long j, nfuns;
32ec8896 9410 bfd_boolean res = TRUE;
0b6ae522
DJ
9411
9412 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9413 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9414 exidx_len = exidx_sec->sh_size / 8;
9415
948f632f
DA
9416 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9417 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9418 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9419 aux->funtab[nfuns++] = aux->symtab[j];
9420 aux->nfuns = nfuns;
9421 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9422
0b6ae522
DJ
9423 for (i = 0; i < exidx_len; i++)
9424 {
9425 unsigned int exidx_fn, exidx_entry;
9426 struct absaddr fn_addr, entry_addr;
9427 bfd_vma fn;
9428
9429 fputc ('\n', stdout);
9430
dda8d76d 9431 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9432 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9433 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9434 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9435 {
948f632f 9436 free (aux->funtab);
1b31d05e
NC
9437 arm_free_section (& exidx_arm_sec);
9438 arm_free_section (& extab_arm_sec);
32ec8896 9439 return FALSE;
0b6ae522
DJ
9440 }
9441
83c257ca
NC
9442 /* ARM EHABI, Section 5:
9443 An index table entry consists of 2 words.
9444 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9445 if (exidx_fn & 0x80000000)
32ec8896
NC
9446 {
9447 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9448 res = FALSE;
9449 }
83c257ca 9450
dda8d76d 9451 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9452
dda8d76d 9453 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9454 fputs (": ", stdout);
9455
9456 if (exidx_entry == 1)
9457 {
9458 print_vma (exidx_entry, PREFIX_HEX);
9459 fputs (" [cantunwind]\n", stdout);
9460 }
9461 else if (exidx_entry & 0x80000000)
9462 {
9463 print_vma (exidx_entry, PREFIX_HEX);
9464 fputc ('\n', stdout);
dda8d76d 9465 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9466 }
9467 else
9468 {
8f73510c 9469 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9470 Elf_Internal_Shdr *table_sec;
9471
9472 fputs ("@", stdout);
dda8d76d 9473 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9474 print_vma (table, PREFIX_HEX);
9475 printf ("\n");
9476
9477 /* Locate the matching .ARM.extab. */
9478 if (entry_addr.section != SHN_UNDEF
dda8d76d 9479 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9480 {
dda8d76d 9481 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9482 table_offset = entry_addr.offset;
1a915552
NC
9483 /* PR 18879 */
9484 if (table_offset > table_sec->sh_size
9485 || ((bfd_signed_vma) table_offset) < 0)
9486 {
9487 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9488 (unsigned long) table_offset,
dda8d76d 9489 printable_section_name (filedata, table_sec));
32ec8896 9490 res = FALSE;
1a915552
NC
9491 continue;
9492 }
0b6ae522
DJ
9493 }
9494 else
9495 {
dda8d76d 9496 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9497 if (table_sec != NULL)
9498 table_offset = table - table_sec->sh_addr;
9499 }
32ec8896 9500
0b6ae522
DJ
9501 if (table_sec == NULL)
9502 {
9503 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9504 (unsigned long) table);
32ec8896 9505 res = FALSE;
0b6ae522
DJ
9506 continue;
9507 }
32ec8896 9508
dda8d76d 9509 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9510 &extab_arm_sec))
9511 res = FALSE;
0b6ae522
DJ
9512 }
9513 }
9514
9515 printf ("\n");
9516
948f632f 9517 free (aux->funtab);
0b6ae522
DJ
9518 arm_free_section (&exidx_arm_sec);
9519 arm_free_section (&extab_arm_sec);
32ec8896
NC
9520
9521 return res;
0b6ae522
DJ
9522}
9523
fa197c1c 9524/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9525
32ec8896 9526static bfd_boolean
dda8d76d 9527arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9528{
9529 struct arm_unw_aux_info aux;
9530 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9531 Elf_Internal_Shdr *sec;
9532 unsigned long i;
fa197c1c 9533 unsigned int sec_type;
32ec8896 9534 bfd_boolean res = TRUE;
0b6ae522 9535
dda8d76d 9536 switch (filedata->file_header.e_machine)
fa197c1c
PB
9537 {
9538 case EM_ARM:
9539 sec_type = SHT_ARM_EXIDX;
9540 break;
9541
9542 case EM_TI_C6000:
9543 sec_type = SHT_C6000_UNWIND;
9544 break;
9545
0b4362b0 9546 default:
74e1a04b 9547 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9548 filedata->file_header.e_machine);
32ec8896 9549 return FALSE;
fa197c1c
PB
9550 }
9551
dda8d76d 9552 if (filedata->string_table == NULL)
32ec8896 9553 return FALSE;
1b31d05e
NC
9554
9555 memset (& aux, 0, sizeof (aux));
dda8d76d 9556 aux.filedata = filedata;
0b6ae522 9557
dda8d76d 9558 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9559 {
28d13567 9560 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9561 {
28d13567 9562 if (aux.symtab)
74e1a04b 9563 {
28d13567
AM
9564 error (_("Multiple symbol tables encountered\n"));
9565 free (aux.symtab);
9566 aux.symtab = NULL;
74e1a04b 9567 free (aux.strtab);
28d13567 9568 aux.strtab = NULL;
74e1a04b 9569 }
28d13567
AM
9570 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9571 &aux.strtab, &aux.strtab_size))
9572 return FALSE;
0b6ae522 9573 }
fa197c1c 9574 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9575 unwsec = sec;
9576 }
9577
1b31d05e 9578 if (unwsec == NULL)
0b6ae522 9579 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9580 else
dda8d76d 9581 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9582 {
9583 if (sec->sh_type == sec_type)
9584 {
d3a49aa8
AM
9585 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9586 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9587 "contains %lu entry:\n",
9588 "\nUnwind section '%s' at offset 0x%lx "
9589 "contains %lu entries:\n",
9590 num_unwind),
dda8d76d 9591 printable_section_name (filedata, sec),
1b31d05e 9592 (unsigned long) sec->sh_offset,
d3a49aa8 9593 num_unwind);
0b6ae522 9594
dda8d76d 9595 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9596 res = FALSE;
1b31d05e
NC
9597 }
9598 }
0b6ae522 9599
9db70fc3
AM
9600 free (aux.symtab);
9601 free ((char *) aux.strtab);
32ec8896
NC
9602
9603 return res;
0b6ae522
DJ
9604}
9605
32ec8896 9606static bfd_boolean
dda8d76d 9607process_unwind (Filedata * filedata)
57346661 9608{
2cf0635d
NC
9609 struct unwind_handler
9610 {
32ec8896 9611 unsigned int machtype;
dda8d76d 9612 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9613 } handlers[] =
9614 {
0b6ae522 9615 { EM_ARM, arm_process_unwind },
57346661
AM
9616 { EM_IA_64, ia64_process_unwind },
9617 { EM_PARISC, hppa_process_unwind },
fa197c1c 9618 { EM_TI_C6000, arm_process_unwind },
32ec8896 9619 { 0, NULL }
57346661
AM
9620 };
9621 int i;
9622
9623 if (!do_unwind)
32ec8896 9624 return TRUE;
57346661
AM
9625
9626 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9627 if (filedata->file_header.e_machine == handlers[i].machtype)
9628 return handlers[i].handler (filedata);
57346661 9629
1b31d05e 9630 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9631 get_machine_name (filedata->file_header.e_machine));
32ec8896 9632 return TRUE;
57346661
AM
9633}
9634
37c18eed
SD
9635static void
9636dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9637{
9638 switch (entry->d_tag)
9639 {
9640 case DT_AARCH64_BTI_PLT:
1dbade74 9641 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9642 break;
9643 default:
9644 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9645 break;
9646 }
9647 putchar ('\n');
9648}
9649
252b5132 9650static void
978c4450 9651dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9652{
9653 switch (entry->d_tag)
9654 {
9655 case DT_MIPS_FLAGS:
9656 if (entry->d_un.d_val == 0)
4b68bca3 9657 printf (_("NONE"));
252b5132
RH
9658 else
9659 {
9660 static const char * opts[] =
9661 {
9662 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9663 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9664 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9665 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9666 "RLD_ORDER_SAFE"
9667 };
9668 unsigned int cnt;
32ec8896 9669 bfd_boolean first = TRUE;
2b692964 9670
60bca95a 9671 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9672 if (entry->d_un.d_val & (1 << cnt))
9673 {
9674 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9675 first = FALSE;
252b5132 9676 }
252b5132
RH
9677 }
9678 break;
103f02d3 9679
252b5132 9680 case DT_MIPS_IVERSION:
978c4450
AM
9681 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9682 printf (_("Interface Version: %s"),
9683 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9684 else
76ca31c0
NC
9685 {
9686 char buf[40];
9687 sprintf_vma (buf, entry->d_un.d_ptr);
9688 /* Note: coded this way so that there is a single string for translation. */
9689 printf (_("<corrupt: %s>"), buf);
9690 }
252b5132 9691 break;
103f02d3 9692
252b5132
RH
9693 case DT_MIPS_TIME_STAMP:
9694 {
d5b07ef4 9695 char timebuf[128];
2cf0635d 9696 struct tm * tmp;
91d6fa6a 9697 time_t atime = entry->d_un.d_val;
82b1b41b 9698
91d6fa6a 9699 tmp = gmtime (&atime);
82b1b41b
NC
9700 /* PR 17531: file: 6accc532. */
9701 if (tmp == NULL)
9702 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9703 else
9704 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9705 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9706 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9707 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9708 }
9709 break;
103f02d3 9710
252b5132
RH
9711 case DT_MIPS_RLD_VERSION:
9712 case DT_MIPS_LOCAL_GOTNO:
9713 case DT_MIPS_CONFLICTNO:
9714 case DT_MIPS_LIBLISTNO:
9715 case DT_MIPS_SYMTABNO:
9716 case DT_MIPS_UNREFEXTNO:
9717 case DT_MIPS_HIPAGENO:
9718 case DT_MIPS_DELTA_CLASS_NO:
9719 case DT_MIPS_DELTA_INSTANCE_NO:
9720 case DT_MIPS_DELTA_RELOC_NO:
9721 case DT_MIPS_DELTA_SYM_NO:
9722 case DT_MIPS_DELTA_CLASSSYM_NO:
9723 case DT_MIPS_COMPACT_SIZE:
c69075ac 9724 print_vma (entry->d_un.d_val, DEC);
252b5132 9725 break;
103f02d3 9726
f16a9783 9727 case DT_MIPS_XHASH:
978c4450
AM
9728 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9729 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9730 /* Falls through. */
9731
103f02d3 9732 default:
4b68bca3 9733 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9734 }
4b68bca3 9735 putchar ('\n');
103f02d3
UD
9736}
9737
103f02d3 9738static void
2cf0635d 9739dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9740{
9741 switch (entry->d_tag)
9742 {
9743 case DT_HP_DLD_FLAGS:
9744 {
9745 static struct
9746 {
9747 long int bit;
2cf0635d 9748 const char * str;
5e220199
NC
9749 }
9750 flags[] =
9751 {
9752 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9753 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9754 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9755 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9756 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9757 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9758 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9759 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9760 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9761 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9762 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9763 { DT_HP_GST, "HP_GST" },
9764 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9765 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9766 { DT_HP_NODELETE, "HP_NODELETE" },
9767 { DT_HP_GROUP, "HP_GROUP" },
9768 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9769 };
32ec8896 9770 bfd_boolean first = TRUE;
5e220199 9771 size_t cnt;
f7a99963 9772 bfd_vma val = entry->d_un.d_val;
103f02d3 9773
60bca95a 9774 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9775 if (val & flags[cnt].bit)
30800947
NC
9776 {
9777 if (! first)
9778 putchar (' ');
9779 fputs (flags[cnt].str, stdout);
32ec8896 9780 first = FALSE;
30800947
NC
9781 val ^= flags[cnt].bit;
9782 }
76da6bbe 9783
103f02d3 9784 if (val != 0 || first)
f7a99963
NC
9785 {
9786 if (! first)
9787 putchar (' ');
9788 print_vma (val, HEX);
9789 }
103f02d3
UD
9790 }
9791 break;
76da6bbe 9792
252b5132 9793 default:
f7a99963
NC
9794 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9795 break;
252b5132 9796 }
35b1837e 9797 putchar ('\n');
252b5132
RH
9798}
9799
28f997cf
TG
9800#ifdef BFD64
9801
9802/* VMS vs Unix time offset and factor. */
9803
9804#define VMS_EPOCH_OFFSET 35067168000000000LL
9805#define VMS_GRANULARITY_FACTOR 10000000
9806
9807/* Display a VMS time in a human readable format. */
9808
9809static void
9810print_vms_time (bfd_int64_t vmstime)
9811{
9812 struct tm *tm;
9813 time_t unxtime;
9814
9815 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9816 tm = gmtime (&unxtime);
9817 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9818 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9819 tm->tm_hour, tm->tm_min, tm->tm_sec);
9820}
9821#endif /* BFD64 */
9822
ecc51f48 9823static void
2cf0635d 9824dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9825{
9826 switch (entry->d_tag)
9827 {
0de14b54 9828 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9829 /* First 3 slots reserved. */
ecc51f48
NC
9830 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9831 printf (" -- ");
9832 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9833 break;
9834
28f997cf
TG
9835 case DT_IA_64_VMS_LINKTIME:
9836#ifdef BFD64
9837 print_vms_time (entry->d_un.d_val);
9838#endif
9839 break;
9840
9841 case DT_IA_64_VMS_LNKFLAGS:
9842 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9843 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9844 printf (" CALL_DEBUG");
9845 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9846 printf (" NOP0BUFS");
9847 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9848 printf (" P0IMAGE");
9849 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9850 printf (" MKTHREADS");
9851 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9852 printf (" UPCALLS");
9853 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9854 printf (" IMGSTA");
9855 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9856 printf (" INITIALIZE");
9857 if (entry->d_un.d_val & VMS_LF_MAIN)
9858 printf (" MAIN");
9859 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9860 printf (" EXE_INIT");
9861 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9862 printf (" TBK_IN_IMG");
9863 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9864 printf (" DBG_IN_IMG");
9865 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9866 printf (" TBK_IN_DSF");
9867 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9868 printf (" DBG_IN_DSF");
9869 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9870 printf (" SIGNATURES");
9871 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9872 printf (" REL_SEG_OFF");
9873 break;
9874
bdf4d63a
JJ
9875 default:
9876 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9877 break;
ecc51f48 9878 }
bdf4d63a 9879 putchar ('\n');
ecc51f48
NC
9880}
9881
32ec8896 9882static bfd_boolean
dda8d76d 9883get_32bit_dynamic_section (Filedata * filedata)
252b5132 9884{
2cf0635d
NC
9885 Elf32_External_Dyn * edyn;
9886 Elf32_External_Dyn * ext;
9887 Elf_Internal_Dyn * entry;
103f02d3 9888
978c4450
AM
9889 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
9890 filedata->dynamic_addr, 1,
9891 filedata->dynamic_size,
9892 _("dynamic section"));
a6e9f9df 9893 if (!edyn)
32ec8896 9894 return FALSE;
103f02d3 9895
071436c6
NC
9896 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9897 might not have the luxury of section headers. Look for the DT_NULL
9898 terminator to determine the number of entries. */
978c4450
AM
9899 for (ext = edyn, filedata->dynamic_nent = 0;
9900 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9901 ext++)
9902 {
978c4450 9903 filedata->dynamic_nent++;
ba2685cc
AM
9904 if (BYTE_GET (ext->d_tag) == DT_NULL)
9905 break;
9906 }
252b5132 9907
978c4450
AM
9908 filedata->dynamic_section
9909 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9910 if (filedata->dynamic_section == NULL)
252b5132 9911 {
8b73c356 9912 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9913 (unsigned long) filedata->dynamic_nent);
9ea033b2 9914 free (edyn);
32ec8896 9915 return FALSE;
9ea033b2 9916 }
252b5132 9917
978c4450
AM
9918 for (ext = edyn, entry = filedata->dynamic_section;
9919 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9920 ext++, entry++)
9ea033b2 9921 {
fb514b26
AM
9922 entry->d_tag = BYTE_GET (ext->d_tag);
9923 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9924 }
9925
9ea033b2
NC
9926 free (edyn);
9927
32ec8896 9928 return TRUE;
9ea033b2
NC
9929}
9930
32ec8896 9931static bfd_boolean
dda8d76d 9932get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9933{
2cf0635d
NC
9934 Elf64_External_Dyn * edyn;
9935 Elf64_External_Dyn * ext;
9936 Elf_Internal_Dyn * entry;
103f02d3 9937
071436c6 9938 /* Read in the data. */
978c4450
AM
9939 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
9940 filedata->dynamic_addr, 1,
9941 filedata->dynamic_size,
9942 _("dynamic section"));
a6e9f9df 9943 if (!edyn)
32ec8896 9944 return FALSE;
103f02d3 9945
071436c6
NC
9946 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9947 might not have the luxury of section headers. Look for the DT_NULL
9948 terminator to determine the number of entries. */
978c4450 9949 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 9950 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 9951 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9952 ext++)
9953 {
978c4450 9954 filedata->dynamic_nent++;
66543521 9955 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9956 break;
9957 }
252b5132 9958
978c4450
AM
9959 filedata->dynamic_section
9960 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9961 if (filedata->dynamic_section == NULL)
252b5132 9962 {
8b73c356 9963 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9964 (unsigned long) filedata->dynamic_nent);
252b5132 9965 free (edyn);
32ec8896 9966 return FALSE;
252b5132
RH
9967 }
9968
071436c6 9969 /* Convert from external to internal formats. */
978c4450
AM
9970 for (ext = edyn, entry = filedata->dynamic_section;
9971 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9972 ext++, entry++)
252b5132 9973 {
66543521
AM
9974 entry->d_tag = BYTE_GET (ext->d_tag);
9975 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9976 }
9977
9978 free (edyn);
9979
32ec8896 9980 return TRUE;
9ea033b2
NC
9981}
9982
e9e44622
JJ
9983static void
9984print_dynamic_flags (bfd_vma flags)
d1133906 9985{
32ec8896 9986 bfd_boolean first = TRUE;
13ae64f3 9987
d1133906
NC
9988 while (flags)
9989 {
9990 bfd_vma flag;
9991
9992 flag = flags & - flags;
9993 flags &= ~ flag;
9994
e9e44622 9995 if (first)
32ec8896 9996 first = FALSE;
e9e44622
JJ
9997 else
9998 putc (' ', stdout);
13ae64f3 9999
d1133906
NC
10000 switch (flag)
10001 {
e9e44622
JJ
10002 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10003 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10004 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10005 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10006 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10007 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10008 }
10009 }
e9e44622 10010 puts ("");
d1133906
NC
10011}
10012
10ca4b04
L
10013static bfd_vma *
10014get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10015{
10016 unsigned char * e_data;
10017 bfd_vma * i_data;
10018
10019 /* If the size_t type is smaller than the bfd_size_type, eg because
10020 you are building a 32-bit tool on a 64-bit host, then make sure
10021 that when (number) is cast to (size_t) no information is lost. */
10022 if (sizeof (size_t) < sizeof (bfd_size_type)
10023 && (bfd_size_type) ((size_t) number) != number)
10024 {
10025 error (_("Size truncation prevents reading %s elements of size %u\n"),
10026 bfd_vmatoa ("u", number), ent_size);
10027 return NULL;
10028 }
10029
10030 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10031 attempting to allocate memory when the read is bound to fail. */
10032 if (ent_size * number > filedata->file_size)
10033 {
10034 error (_("Invalid number of dynamic entries: %s\n"),
10035 bfd_vmatoa ("u", number));
10036 return NULL;
10037 }
10038
10039 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10040 if (e_data == NULL)
10041 {
10042 error (_("Out of memory reading %s dynamic entries\n"),
10043 bfd_vmatoa ("u", number));
10044 return NULL;
10045 }
10046
10047 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10048 {
10049 error (_("Unable to read in %s bytes of dynamic data\n"),
10050 bfd_vmatoa ("u", number * ent_size));
10051 free (e_data);
10052 return NULL;
10053 }
10054
10055 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10056 if (i_data == NULL)
10057 {
10058 error (_("Out of memory allocating space for %s dynamic entries\n"),
10059 bfd_vmatoa ("u", number));
10060 free (e_data);
10061 return NULL;
10062 }
10063
10064 while (number--)
10065 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10066
10067 free (e_data);
10068
10069 return i_data;
10070}
10071
10072static unsigned long
10073get_num_dynamic_syms (Filedata * filedata)
10074{
10075 unsigned long num_of_syms = 0;
10076
10077 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10078 return num_of_syms;
10079
978c4450 10080 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10081 {
10082 unsigned char nb[8];
10083 unsigned char nc[8];
10084 unsigned int hash_ent_size = 4;
10085
10086 if ((filedata->file_header.e_machine == EM_ALPHA
10087 || filedata->file_header.e_machine == EM_S390
10088 || filedata->file_header.e_machine == EM_S390_OLD)
10089 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10090 hash_ent_size = 8;
10091
10092 if (fseek (filedata->handle,
978c4450
AM
10093 (filedata->archive_file_offset
10094 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10095 sizeof nb + sizeof nc)),
10096 SEEK_SET))
10097 {
10098 error (_("Unable to seek to start of dynamic information\n"));
10099 goto no_hash;
10100 }
10101
10102 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10103 {
10104 error (_("Failed to read in number of buckets\n"));
10105 goto no_hash;
10106 }
10107
10108 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10109 {
10110 error (_("Failed to read in number of chains\n"));
10111 goto no_hash;
10112 }
10113
978c4450
AM
10114 filedata->nbuckets = byte_get (nb, hash_ent_size);
10115 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10116
2482f306
AM
10117 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10118 {
10119 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10120 hash_ent_size);
10121 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10122 hash_ent_size);
001890e1 10123
2482f306
AM
10124 if (filedata->buckets != NULL && filedata->chains != NULL)
10125 num_of_syms = filedata->nchains;
10126 }
ceb9bf11 10127 no_hash:
10ca4b04
L
10128 if (num_of_syms == 0)
10129 {
9db70fc3
AM
10130 free (filedata->buckets);
10131 filedata->buckets = NULL;
10132 free (filedata->chains);
10133 filedata->chains = NULL;
978c4450 10134 filedata->nbuckets = 0;
10ca4b04
L
10135 }
10136 }
10137
978c4450 10138 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10139 {
10140 unsigned char nb[16];
10141 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10142 bfd_vma buckets_vma;
10143 unsigned long hn;
10ca4b04
L
10144
10145 if (fseek (filedata->handle,
978c4450
AM
10146 (filedata->archive_file_offset
10147 + offset_from_vma (filedata,
10148 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10149 sizeof nb)),
10150 SEEK_SET))
10151 {
10152 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10153 goto no_gnu_hash;
10154 }
10155
10156 if (fread (nb, 16, 1, filedata->handle) != 1)
10157 {
10158 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10159 goto no_gnu_hash;
10160 }
10161
978c4450
AM
10162 filedata->ngnubuckets = byte_get (nb, 4);
10163 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10164 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10165 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10166 if (is_32bit_elf)
10167 buckets_vma += bitmaskwords * 4;
10168 else
10169 buckets_vma += bitmaskwords * 8;
10170
10171 if (fseek (filedata->handle,
978c4450 10172 (filedata->archive_file_offset
10ca4b04
L
10173 + offset_from_vma (filedata, buckets_vma, 4)),
10174 SEEK_SET))
10175 {
10176 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10177 goto no_gnu_hash;
10178 }
10179
978c4450
AM
10180 filedata->gnubuckets
10181 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10182
978c4450 10183 if (filedata->gnubuckets == NULL)
90837ea7 10184 goto no_gnu_hash;
10ca4b04 10185
978c4450
AM
10186 for (i = 0; i < filedata->ngnubuckets; i++)
10187 if (filedata->gnubuckets[i] != 0)
10ca4b04 10188 {
978c4450 10189 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10190 goto no_gnu_hash;
10ca4b04 10191
978c4450
AM
10192 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10193 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10194 }
10195
10196 if (maxchain == 0xffffffff)
90837ea7 10197 goto no_gnu_hash;
10ca4b04 10198
978c4450 10199 maxchain -= filedata->gnusymidx;
10ca4b04
L
10200
10201 if (fseek (filedata->handle,
978c4450
AM
10202 (filedata->archive_file_offset
10203 + offset_from_vma (filedata,
10204 buckets_vma + 4 * (filedata->ngnubuckets
10205 + maxchain),
10206 4)),
10ca4b04
L
10207 SEEK_SET))
10208 {
10209 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10210 goto no_gnu_hash;
10211 }
10212
10213 do
10214 {
10215 if (fread (nb, 4, 1, filedata->handle) != 1)
10216 {
10217 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10218 goto no_gnu_hash;
10219 }
10220
10221 if (maxchain + 1 == 0)
90837ea7 10222 goto no_gnu_hash;
10ca4b04
L
10223
10224 ++maxchain;
10225 }
10226 while ((byte_get (nb, 4) & 1) == 0);
10227
10228 if (fseek (filedata->handle,
978c4450
AM
10229 (filedata->archive_file_offset
10230 + offset_from_vma (filedata, (buckets_vma
10231 + 4 * filedata->ngnubuckets),
10232 4)),
10ca4b04
L
10233 SEEK_SET))
10234 {
10235 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10236 goto no_gnu_hash;
10237 }
10238
978c4450
AM
10239 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10240 filedata->ngnuchains = maxchain;
10ca4b04 10241
978c4450 10242 if (filedata->gnuchains == NULL)
90837ea7 10243 goto no_gnu_hash;
10ca4b04 10244
978c4450 10245 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10246 {
10247 if (fseek (filedata->handle,
978c4450 10248 (filedata->archive_file_offset
10ca4b04 10249 + offset_from_vma (filedata, (buckets_vma
978c4450 10250 + 4 * (filedata->ngnubuckets
10ca4b04
L
10251 + maxchain)), 4)),
10252 SEEK_SET))
10253 {
10254 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10255 goto no_gnu_hash;
10256 }
10257
978c4450 10258 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10259 if (filedata->mipsxlat == NULL)
10260 goto no_gnu_hash;
10ca4b04
L
10261 }
10262
978c4450
AM
10263 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10264 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10265 {
978c4450
AM
10266 bfd_vma si = filedata->gnubuckets[hn];
10267 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10268
10269 do
10270 {
978c4450 10271 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10272 {
c31ab5a0
AM
10273 if (off < filedata->ngnuchains
10274 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10275 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10276 }
10277 else
10278 {
10279 if (si >= num_of_syms)
10280 num_of_syms = si + 1;
10281 }
10282 si++;
10283 }
978c4450
AM
10284 while (off < filedata->ngnuchains
10285 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10286 }
10287
90837ea7 10288 if (num_of_syms == 0)
10ca4b04 10289 {
90837ea7 10290 no_gnu_hash:
9db70fc3
AM
10291 free (filedata->mipsxlat);
10292 filedata->mipsxlat = NULL;
10293 free (filedata->gnuchains);
10294 filedata->gnuchains = NULL;
10295 free (filedata->gnubuckets);
10296 filedata->gnubuckets = NULL;
978c4450
AM
10297 filedata->ngnubuckets = 0;
10298 filedata->ngnuchains = 0;
10ca4b04
L
10299 }
10300 }
10301
10302 return num_of_syms;
10303}
10304
b2d38a17
NC
10305/* Parse and display the contents of the dynamic section. */
10306
32ec8896 10307static bfd_boolean
dda8d76d 10308process_dynamic_section (Filedata * filedata)
9ea033b2 10309{
2cf0635d 10310 Elf_Internal_Dyn * entry;
9ea033b2 10311
978c4450 10312 if (filedata->dynamic_size == 0)
9ea033b2
NC
10313 {
10314 if (do_dynamic)
b2d38a17 10315 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 10316
32ec8896 10317 return TRUE;
9ea033b2
NC
10318 }
10319
10320 if (is_32bit_elf)
10321 {
dda8d76d 10322 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10323 return FALSE;
10324 }
10325 else
10326 {
dda8d76d 10327 if (! get_64bit_dynamic_section (filedata))
32ec8896 10328 return FALSE;
9ea033b2 10329 }
9ea033b2 10330
252b5132 10331 /* Find the appropriate symbol table. */
978c4450 10332 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10333 {
2482f306
AM
10334 unsigned long num_of_syms;
10335
978c4450
AM
10336 for (entry = filedata->dynamic_section;
10337 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10338 ++entry)
10ca4b04 10339 if (entry->d_tag == DT_SYMTAB)
978c4450 10340 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10341 else if (entry->d_tag == DT_SYMENT)
978c4450 10342 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10343 else if (entry->d_tag == DT_HASH)
978c4450 10344 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10345 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10346 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10347 else if ((filedata->file_header.e_machine == EM_MIPS
10348 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10349 && entry->d_tag == DT_MIPS_XHASH)
10350 {
978c4450
AM
10351 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10352 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10353 }
252b5132 10354
2482f306
AM
10355 num_of_syms = get_num_dynamic_syms (filedata);
10356
10357 if (num_of_syms != 0
10358 && filedata->dynamic_symbols == NULL
10359 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10360 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10361 {
10362 Elf_Internal_Phdr *seg;
2482f306 10363 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10364
2482f306
AM
10365 if (! get_program_headers (filedata))
10366 {
10367 error (_("Cannot interpret virtual addresses "
10368 "without program headers.\n"));
10369 return FALSE;
10370 }
252b5132 10371
2482f306
AM
10372 for (seg = filedata->program_headers;
10373 seg < filedata->program_headers + filedata->file_header.e_phnum;
10374 ++seg)
10375 {
10376 if (seg->p_type != PT_LOAD)
10377 continue;
252b5132 10378
2482f306
AM
10379 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10380 {
10381 /* See PR 21379 for a reproducer. */
10382 error (_("Invalid PT_LOAD entry\n"));
10383 return FALSE;
10384 }
252b5132 10385
2482f306
AM
10386 if (vma >= (seg->p_vaddr & -seg->p_align)
10387 && vma < seg->p_vaddr + seg->p_filesz)
10388 {
10389 /* Since we do not know how big the symbol table is,
10390 we default to reading in up to the end of PT_LOAD
10391 segment and processing that. This is overkill, I
10392 know, but it should work. */
10393 Elf_Internal_Shdr section;
10394 section.sh_offset = (vma - seg->p_vaddr
10395 + seg->p_offset);
10396 section.sh_size = (num_of_syms
10397 * filedata->dynamic_info[DT_SYMENT]);
10398 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10399
10400 if (do_checks
10401 && filedata->dynamic_symtab_section != NULL
10402 && ((filedata->dynamic_symtab_section->sh_offset
10403 != section.sh_offset)
10404 || (filedata->dynamic_symtab_section->sh_size
10405 != section.sh_size)
10406 || (filedata->dynamic_symtab_section->sh_entsize
10407 != section.sh_entsize)))
10408 warn (_("\
10409the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10410
2482f306
AM
10411 section.sh_name = filedata->string_table_length;
10412 filedata->dynamic_symbols
10413 = GET_ELF_SYMBOLS (filedata, &section,
10414 &filedata->num_dynamic_syms);
10415 if (filedata->dynamic_symbols == NULL
10416 || filedata->num_dynamic_syms != num_of_syms)
10417 {
10418 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10419 return FALSE;
10420 }
10421 break;
10422 }
10423 }
10424 }
10425 }
252b5132
RH
10426
10427 /* Similarly find a string table. */
978c4450
AM
10428 if (filedata->dynamic_strings == NULL)
10429 for (entry = filedata->dynamic_section;
10430 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10431 ++entry)
10432 {
10433 if (entry->d_tag == DT_STRTAB)
978c4450 10434 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10435
10ca4b04 10436 if (entry->d_tag == DT_STRSZ)
978c4450 10437 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10438
978c4450
AM
10439 if (filedata->dynamic_info[DT_STRTAB]
10440 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10441 {
10442 unsigned long offset;
978c4450 10443 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10444
10445 offset = offset_from_vma (filedata,
978c4450 10446 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10447 str_tab_len);
8ac10c5b
L
10448 if (do_checks
10449 && filedata->dynamic_strtab_section
10450 && ((filedata->dynamic_strtab_section->sh_offset
10451 != (file_ptr) offset)
10452 || (filedata->dynamic_strtab_section->sh_size
10453 != str_tab_len)))
10454 warn (_("\
10455the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10456
978c4450
AM
10457 filedata->dynamic_strings
10458 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10459 _("dynamic string table"));
10460 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10461 {
10462 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10463 break;
10464 }
e3d39609 10465
978c4450 10466 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10467 break;
10468 }
10469 }
252b5132
RH
10470
10471 /* And find the syminfo section if available. */
978c4450 10472 if (filedata->dynamic_syminfo == NULL)
252b5132 10473 {
3e8bba36 10474 unsigned long syminsz = 0;
252b5132 10475
978c4450
AM
10476 for (entry = filedata->dynamic_section;
10477 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10478 ++entry)
252b5132
RH
10479 {
10480 if (entry->d_tag == DT_SYMINENT)
10481 {
10482 /* Note: these braces are necessary to avoid a syntax
10483 error from the SunOS4 C compiler. */
049b0c3a
NC
10484 /* PR binutils/17531: A corrupt file can trigger this test.
10485 So do not use an assert, instead generate an error message. */
10486 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10487 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10488 (int) entry->d_un.d_val);
252b5132
RH
10489 }
10490 else if (entry->d_tag == DT_SYMINSZ)
10491 syminsz = entry->d_un.d_val;
10492 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10493 filedata->dynamic_syminfo_offset
10494 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10495 }
10496
978c4450 10497 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10498 {
2cf0635d
NC
10499 Elf_External_Syminfo * extsyminfo;
10500 Elf_External_Syminfo * extsym;
10501 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10502
10503 /* There is a syminfo section. Read the data. */
3f5e193b 10504 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10505 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10506 1, syminsz, _("symbol information"));
a6e9f9df 10507 if (!extsyminfo)
32ec8896 10508 return FALSE;
252b5132 10509
978c4450 10510 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10511 {
10512 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10513 free (filedata->dynamic_syminfo);
e3d39609 10514 }
978c4450
AM
10515 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10516 if (filedata->dynamic_syminfo == NULL)
252b5132 10517 {
2482f306
AM
10518 error (_("Out of memory allocating %lu bytes "
10519 "for dynamic symbol info\n"),
8b73c356 10520 (unsigned long) syminsz);
32ec8896 10521 return FALSE;
252b5132
RH
10522 }
10523
2482f306
AM
10524 filedata->dynamic_syminfo_nent
10525 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10526 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10527 syminfo < (filedata->dynamic_syminfo
10528 + filedata->dynamic_syminfo_nent);
86dba8ee 10529 ++syminfo, ++extsym)
252b5132 10530 {
86dba8ee
AM
10531 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10532 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10533 }
10534
10535 free (extsyminfo);
10536 }
10537 }
10538
978c4450 10539 if (do_dynamic && filedata->dynamic_addr)
d3a49aa8
AM
10540 printf (ngettext ("\nDynamic section at offset 0x%lx "
10541 "contains %lu entry:\n",
10542 "\nDynamic section at offset 0x%lx "
10543 "contains %lu entries:\n",
978c4450
AM
10544 filedata->dynamic_nent),
10545 filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent);
252b5132
RH
10546 if (do_dynamic)
10547 printf (_(" Tag Type Name/Value\n"));
10548
978c4450
AM
10549 for (entry = filedata->dynamic_section;
10550 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10551 entry++)
252b5132
RH
10552 {
10553 if (do_dynamic)
f7a99963 10554 {
2cf0635d 10555 const char * dtype;
e699b9ff 10556
f7a99963
NC
10557 putchar (' ');
10558 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10559 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10560 printf (" (%s)%*s", dtype,
32ec8896 10561 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10562 }
252b5132
RH
10563
10564 switch (entry->d_tag)
10565 {
d1133906
NC
10566 case DT_FLAGS:
10567 if (do_dynamic)
e9e44622 10568 print_dynamic_flags (entry->d_un.d_val);
d1133906 10569 break;
76da6bbe 10570
252b5132
RH
10571 case DT_AUXILIARY:
10572 case DT_FILTER:
019148e4
L
10573 case DT_CONFIG:
10574 case DT_DEPAUDIT:
10575 case DT_AUDIT:
252b5132
RH
10576 if (do_dynamic)
10577 {
019148e4 10578 switch (entry->d_tag)
b34976b6 10579 {
019148e4
L
10580 case DT_AUXILIARY:
10581 printf (_("Auxiliary library"));
10582 break;
10583
10584 case DT_FILTER:
10585 printf (_("Filter library"));
10586 break;
10587
b34976b6 10588 case DT_CONFIG:
019148e4
L
10589 printf (_("Configuration file"));
10590 break;
10591
10592 case DT_DEPAUDIT:
10593 printf (_("Dependency audit library"));
10594 break;
10595
10596 case DT_AUDIT:
10597 printf (_("Audit library"));
10598 break;
10599 }
252b5132 10600
978c4450
AM
10601 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10602 printf (": [%s]\n",
10603 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10604 else
f7a99963
NC
10605 {
10606 printf (": ");
10607 print_vma (entry->d_un.d_val, PREFIX_HEX);
10608 putchar ('\n');
10609 }
252b5132
RH
10610 }
10611 break;
10612
dcefbbbd 10613 case DT_FEATURE:
252b5132
RH
10614 if (do_dynamic)
10615 {
10616 printf (_("Flags:"));
86f55779 10617
252b5132
RH
10618 if (entry->d_un.d_val == 0)
10619 printf (_(" None\n"));
10620 else
10621 {
10622 unsigned long int val = entry->d_un.d_val;
86f55779 10623
252b5132
RH
10624 if (val & DTF_1_PARINIT)
10625 {
10626 printf (" PARINIT");
10627 val ^= DTF_1_PARINIT;
10628 }
dcefbbbd
L
10629 if (val & DTF_1_CONFEXP)
10630 {
10631 printf (" CONFEXP");
10632 val ^= DTF_1_CONFEXP;
10633 }
252b5132
RH
10634 if (val != 0)
10635 printf (" %lx", val);
10636 puts ("");
10637 }
10638 }
10639 break;
10640
10641 case DT_POSFLAG_1:
10642 if (do_dynamic)
10643 {
10644 printf (_("Flags:"));
86f55779 10645
252b5132
RH
10646 if (entry->d_un.d_val == 0)
10647 printf (_(" None\n"));
10648 else
10649 {
10650 unsigned long int val = entry->d_un.d_val;
86f55779 10651
252b5132
RH
10652 if (val & DF_P1_LAZYLOAD)
10653 {
10654 printf (" LAZYLOAD");
10655 val ^= DF_P1_LAZYLOAD;
10656 }
10657 if (val & DF_P1_GROUPPERM)
10658 {
10659 printf (" GROUPPERM");
10660 val ^= DF_P1_GROUPPERM;
10661 }
10662 if (val != 0)
10663 printf (" %lx", val);
10664 puts ("");
10665 }
10666 }
10667 break;
10668
10669 case DT_FLAGS_1:
10670 if (do_dynamic)
10671 {
10672 printf (_("Flags:"));
10673 if (entry->d_un.d_val == 0)
10674 printf (_(" None\n"));
10675 else
10676 {
10677 unsigned long int val = entry->d_un.d_val;
86f55779 10678
252b5132
RH
10679 if (val & DF_1_NOW)
10680 {
10681 printf (" NOW");
10682 val ^= DF_1_NOW;
10683 }
10684 if (val & DF_1_GLOBAL)
10685 {
10686 printf (" GLOBAL");
10687 val ^= DF_1_GLOBAL;
10688 }
10689 if (val & DF_1_GROUP)
10690 {
10691 printf (" GROUP");
10692 val ^= DF_1_GROUP;
10693 }
10694 if (val & DF_1_NODELETE)
10695 {
10696 printf (" NODELETE");
10697 val ^= DF_1_NODELETE;
10698 }
10699 if (val & DF_1_LOADFLTR)
10700 {
10701 printf (" LOADFLTR");
10702 val ^= DF_1_LOADFLTR;
10703 }
10704 if (val & DF_1_INITFIRST)
10705 {
10706 printf (" INITFIRST");
10707 val ^= DF_1_INITFIRST;
10708 }
10709 if (val & DF_1_NOOPEN)
10710 {
10711 printf (" NOOPEN");
10712 val ^= DF_1_NOOPEN;
10713 }
10714 if (val & DF_1_ORIGIN)
10715 {
10716 printf (" ORIGIN");
10717 val ^= DF_1_ORIGIN;
10718 }
10719 if (val & DF_1_DIRECT)
10720 {
10721 printf (" DIRECT");
10722 val ^= DF_1_DIRECT;
10723 }
10724 if (val & DF_1_TRANS)
10725 {
10726 printf (" TRANS");
10727 val ^= DF_1_TRANS;
10728 }
10729 if (val & DF_1_INTERPOSE)
10730 {
10731 printf (" INTERPOSE");
10732 val ^= DF_1_INTERPOSE;
10733 }
f7db6139 10734 if (val & DF_1_NODEFLIB)
dcefbbbd 10735 {
f7db6139
L
10736 printf (" NODEFLIB");
10737 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10738 }
10739 if (val & DF_1_NODUMP)
10740 {
10741 printf (" NODUMP");
10742 val ^= DF_1_NODUMP;
10743 }
34b60028 10744 if (val & DF_1_CONFALT)
dcefbbbd 10745 {
34b60028
L
10746 printf (" CONFALT");
10747 val ^= DF_1_CONFALT;
10748 }
10749 if (val & DF_1_ENDFILTEE)
10750 {
10751 printf (" ENDFILTEE");
10752 val ^= DF_1_ENDFILTEE;
10753 }
10754 if (val & DF_1_DISPRELDNE)
10755 {
10756 printf (" DISPRELDNE");
10757 val ^= DF_1_DISPRELDNE;
10758 }
10759 if (val & DF_1_DISPRELPND)
10760 {
10761 printf (" DISPRELPND");
10762 val ^= DF_1_DISPRELPND;
10763 }
10764 if (val & DF_1_NODIRECT)
10765 {
10766 printf (" NODIRECT");
10767 val ^= DF_1_NODIRECT;
10768 }
10769 if (val & DF_1_IGNMULDEF)
10770 {
10771 printf (" IGNMULDEF");
10772 val ^= DF_1_IGNMULDEF;
10773 }
10774 if (val & DF_1_NOKSYMS)
10775 {
10776 printf (" NOKSYMS");
10777 val ^= DF_1_NOKSYMS;
10778 }
10779 if (val & DF_1_NOHDR)
10780 {
10781 printf (" NOHDR");
10782 val ^= DF_1_NOHDR;
10783 }
10784 if (val & DF_1_EDITED)
10785 {
10786 printf (" EDITED");
10787 val ^= DF_1_EDITED;
10788 }
10789 if (val & DF_1_NORELOC)
10790 {
10791 printf (" NORELOC");
10792 val ^= DF_1_NORELOC;
10793 }
10794 if (val & DF_1_SYMINTPOSE)
10795 {
10796 printf (" SYMINTPOSE");
10797 val ^= DF_1_SYMINTPOSE;
10798 }
10799 if (val & DF_1_GLOBAUDIT)
10800 {
10801 printf (" GLOBAUDIT");
10802 val ^= DF_1_GLOBAUDIT;
10803 }
10804 if (val & DF_1_SINGLETON)
10805 {
10806 printf (" SINGLETON");
10807 val ^= DF_1_SINGLETON;
dcefbbbd 10808 }
5c383f02
RO
10809 if (val & DF_1_STUB)
10810 {
10811 printf (" STUB");
10812 val ^= DF_1_STUB;
10813 }
10814 if (val & DF_1_PIE)
10815 {
10816 printf (" PIE");
10817 val ^= DF_1_PIE;
10818 }
b1202ffa
L
10819 if (val & DF_1_KMOD)
10820 {
10821 printf (" KMOD");
10822 val ^= DF_1_KMOD;
10823 }
10824 if (val & DF_1_WEAKFILTER)
10825 {
10826 printf (" WEAKFILTER");
10827 val ^= DF_1_WEAKFILTER;
10828 }
10829 if (val & DF_1_NOCOMMON)
10830 {
10831 printf (" NOCOMMON");
10832 val ^= DF_1_NOCOMMON;
10833 }
252b5132
RH
10834 if (val != 0)
10835 printf (" %lx", val);
10836 puts ("");
10837 }
10838 }
10839 break;
10840
10841 case DT_PLTREL:
978c4450 10842 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10843 if (do_dynamic)
dda8d76d 10844 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10845 break;
10846
10847 case DT_NULL :
10848 case DT_NEEDED :
10849 case DT_PLTGOT :
10850 case DT_HASH :
10851 case DT_STRTAB :
10852 case DT_SYMTAB :
10853 case DT_RELA :
10854 case DT_INIT :
10855 case DT_FINI :
10856 case DT_SONAME :
10857 case DT_RPATH :
10858 case DT_SYMBOLIC:
10859 case DT_REL :
10860 case DT_DEBUG :
10861 case DT_TEXTREL :
10862 case DT_JMPREL :
019148e4 10863 case DT_RUNPATH :
978c4450 10864 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
10865
10866 if (do_dynamic)
10867 {
2cf0635d 10868 char * name;
252b5132 10869
978c4450
AM
10870 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10871 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10872 else
d79b3d50 10873 name = NULL;
252b5132
RH
10874
10875 if (name)
10876 {
10877 switch (entry->d_tag)
10878 {
10879 case DT_NEEDED:
10880 printf (_("Shared library: [%s]"), name);
10881
978c4450 10882 if (streq (name, filedata->program_interpreter))
f7a99963 10883 printf (_(" program interpreter"));
252b5132
RH
10884 break;
10885
10886 case DT_SONAME:
f7a99963 10887 printf (_("Library soname: [%s]"), name);
252b5132
RH
10888 break;
10889
10890 case DT_RPATH:
f7a99963 10891 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10892 break;
10893
019148e4
L
10894 case DT_RUNPATH:
10895 printf (_("Library runpath: [%s]"), name);
10896 break;
10897
252b5132 10898 default:
f7a99963
NC
10899 print_vma (entry->d_un.d_val, PREFIX_HEX);
10900 break;
252b5132
RH
10901 }
10902 }
10903 else
f7a99963
NC
10904 print_vma (entry->d_un.d_val, PREFIX_HEX);
10905
10906 putchar ('\n');
252b5132
RH
10907 }
10908 break;
10909
10910 case DT_PLTRELSZ:
10911 case DT_RELASZ :
10912 case DT_STRSZ :
10913 case DT_RELSZ :
10914 case DT_RELAENT :
10915 case DT_SYMENT :
10916 case DT_RELENT :
978c4450 10917 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10918 /* Fall through. */
252b5132
RH
10919 case DT_PLTPADSZ:
10920 case DT_MOVEENT :
10921 case DT_MOVESZ :
10922 case DT_INIT_ARRAYSZ:
10923 case DT_FINI_ARRAYSZ:
047b2264
JJ
10924 case DT_GNU_CONFLICTSZ:
10925 case DT_GNU_LIBLISTSZ:
252b5132 10926 if (do_dynamic)
f7a99963
NC
10927 {
10928 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10929 printf (_(" (bytes)\n"));
f7a99963 10930 }
252b5132
RH
10931 break;
10932
10933 case DT_VERDEFNUM:
10934 case DT_VERNEEDNUM:
10935 case DT_RELACOUNT:
10936 case DT_RELCOUNT:
10937 if (do_dynamic)
f7a99963
NC
10938 {
10939 print_vma (entry->d_un.d_val, UNSIGNED);
10940 putchar ('\n');
10941 }
252b5132
RH
10942 break;
10943
10944 case DT_SYMINSZ:
10945 case DT_SYMINENT:
10946 case DT_SYMINFO:
10947 case DT_USED:
10948 case DT_INIT_ARRAY:
10949 case DT_FINI_ARRAY:
10950 if (do_dynamic)
10951 {
d79b3d50 10952 if (entry->d_tag == DT_USED
978c4450 10953 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 10954 {
978c4450 10955 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10956
b34976b6 10957 if (*name)
252b5132
RH
10958 {
10959 printf (_("Not needed object: [%s]\n"), name);
10960 break;
10961 }
10962 }
103f02d3 10963
f7a99963
NC
10964 print_vma (entry->d_un.d_val, PREFIX_HEX);
10965 putchar ('\n');
252b5132
RH
10966 }
10967 break;
10968
10969 case DT_BIND_NOW:
10970 /* The value of this entry is ignored. */
35b1837e
AM
10971 if (do_dynamic)
10972 putchar ('\n');
252b5132 10973 break;
103f02d3 10974
047b2264
JJ
10975 case DT_GNU_PRELINKED:
10976 if (do_dynamic)
10977 {
2cf0635d 10978 struct tm * tmp;
91d6fa6a 10979 time_t atime = entry->d_un.d_val;
047b2264 10980
91d6fa6a 10981 tmp = gmtime (&atime);
071436c6
NC
10982 /* PR 17533 file: 041-1244816-0.004. */
10983 if (tmp == NULL)
5a2cbcf4
L
10984 printf (_("<corrupt time val: %lx"),
10985 (unsigned long) atime);
071436c6
NC
10986 else
10987 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10988 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10989 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10990
10991 }
10992 break;
10993
fdc90cb4 10994 case DT_GNU_HASH:
978c4450 10995 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
10996 if (do_dynamic)
10997 {
10998 print_vma (entry->d_un.d_val, PREFIX_HEX);
10999 putchar ('\n');
11000 }
11001 break;
11002
252b5132
RH
11003 default:
11004 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11005 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11006 = entry->d_un.d_val;
252b5132
RH
11007
11008 if (do_dynamic)
11009 {
dda8d76d 11010 switch (filedata->file_header.e_machine)
252b5132 11011 {
37c18eed
SD
11012 case EM_AARCH64:
11013 dynamic_section_aarch64_val (entry);
11014 break;
252b5132 11015 case EM_MIPS:
4fe85591 11016 case EM_MIPS_RS3_LE:
978c4450 11017 dynamic_section_mips_val (filedata, entry);
252b5132 11018 break;
103f02d3 11019 case EM_PARISC:
b2d38a17 11020 dynamic_section_parisc_val (entry);
103f02d3 11021 break;
ecc51f48 11022 case EM_IA_64:
b2d38a17 11023 dynamic_section_ia64_val (entry);
ecc51f48 11024 break;
252b5132 11025 default:
f7a99963
NC
11026 print_vma (entry->d_un.d_val, PREFIX_HEX);
11027 putchar ('\n');
252b5132
RH
11028 }
11029 }
11030 break;
11031 }
11032 }
11033
32ec8896 11034 return TRUE;
252b5132
RH
11035}
11036
11037static char *
d3ba0551 11038get_ver_flags (unsigned int flags)
252b5132 11039{
6d4f21f6 11040 static char buff[128];
252b5132
RH
11041
11042 buff[0] = 0;
11043
11044 if (flags == 0)
11045 return _("none");
11046
11047 if (flags & VER_FLG_BASE)
7bb1ad17 11048 strcat (buff, "BASE");
252b5132
RH
11049
11050 if (flags & VER_FLG_WEAK)
11051 {
11052 if (flags & VER_FLG_BASE)
7bb1ad17 11053 strcat (buff, " | ");
252b5132 11054
7bb1ad17 11055 strcat (buff, "WEAK");
252b5132
RH
11056 }
11057
44ec90b9
RO
11058 if (flags & VER_FLG_INFO)
11059 {
11060 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11061 strcat (buff, " | ");
44ec90b9 11062
7bb1ad17 11063 strcat (buff, "INFO");
44ec90b9
RO
11064 }
11065
11066 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11067 {
11068 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11069 strcat (buff, " | ");
11070
11071 strcat (buff, _("<unknown>"));
11072 }
252b5132
RH
11073
11074 return buff;
11075}
11076
11077/* Display the contents of the version sections. */
98fb390a 11078
32ec8896 11079static bfd_boolean
dda8d76d 11080process_version_sections (Filedata * filedata)
252b5132 11081{
2cf0635d 11082 Elf_Internal_Shdr * section;
b34976b6 11083 unsigned i;
32ec8896 11084 bfd_boolean found = FALSE;
252b5132
RH
11085
11086 if (! do_version)
32ec8896 11087 return TRUE;
252b5132 11088
dda8d76d
NC
11089 for (i = 0, section = filedata->section_headers;
11090 i < filedata->file_header.e_shnum;
b34976b6 11091 i++, section++)
252b5132
RH
11092 {
11093 switch (section->sh_type)
11094 {
11095 case SHT_GNU_verdef:
11096 {
2cf0635d 11097 Elf_External_Verdef * edefs;
452bf675
AM
11098 unsigned long idx;
11099 unsigned long cnt;
2cf0635d 11100 char * endbuf;
252b5132 11101
32ec8896 11102 found = TRUE;
252b5132 11103
d3a49aa8
AM
11104 printf (ngettext ("\nVersion definition section '%s' "
11105 "contains %u entry:\n",
11106 "\nVersion definition section '%s' "
11107 "contains %u entries:\n",
11108 section->sh_info),
dda8d76d 11109 printable_section_name (filedata, section),
74e1a04b 11110 section->sh_info);
252b5132 11111
ae9ac79e 11112 printf (_(" Addr: 0x"));
252b5132 11113 printf_vma (section->sh_addr);
233f82cf 11114 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11115 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11116 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11117
3f5e193b 11118 edefs = (Elf_External_Verdef *)
dda8d76d 11119 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11120 _("version definition section"));
a6e9f9df
AM
11121 if (!edefs)
11122 break;
59245841 11123 endbuf = (char *) edefs + section->sh_size;
252b5132 11124
1445030f 11125 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11126 {
2cf0635d
NC
11127 char * vstart;
11128 Elf_External_Verdef * edef;
b34976b6 11129 Elf_Internal_Verdef ent;
2cf0635d 11130 Elf_External_Verdaux * eaux;
b34976b6 11131 Elf_Internal_Verdaux aux;
452bf675 11132 unsigned long isum;
b34976b6 11133 int j;
103f02d3 11134
252b5132 11135 vstart = ((char *) edefs) + idx;
54806181
AM
11136 if (vstart + sizeof (*edef) > endbuf)
11137 break;
252b5132
RH
11138
11139 edef = (Elf_External_Verdef *) vstart;
11140
11141 ent.vd_version = BYTE_GET (edef->vd_version);
11142 ent.vd_flags = BYTE_GET (edef->vd_flags);
11143 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11144 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11145 ent.vd_hash = BYTE_GET (edef->vd_hash);
11146 ent.vd_aux = BYTE_GET (edef->vd_aux);
11147 ent.vd_next = BYTE_GET (edef->vd_next);
11148
452bf675 11149 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11150 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11151
11152 printf (_(" Index: %d Cnt: %d "),
11153 ent.vd_ndx, ent.vd_cnt);
11154
452bf675 11155 /* Check for overflow. */
1445030f 11156 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11157 break;
11158
252b5132
RH
11159 vstart += ent.vd_aux;
11160
1445030f
AM
11161 if (vstart + sizeof (*eaux) > endbuf)
11162 break;
252b5132
RH
11163 eaux = (Elf_External_Verdaux *) vstart;
11164
11165 aux.vda_name = BYTE_GET (eaux->vda_name);
11166 aux.vda_next = BYTE_GET (eaux->vda_next);
11167
978c4450
AM
11168 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11169 printf (_("Name: %s\n"),
11170 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11171 else
11172 printf (_("Name index: %ld\n"), aux.vda_name);
11173
11174 isum = idx + ent.vd_aux;
11175
b34976b6 11176 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11177 {
1445030f
AM
11178 if (aux.vda_next < sizeof (*eaux)
11179 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11180 {
11181 warn (_("Invalid vda_next field of %lx\n"),
11182 aux.vda_next);
11183 j = ent.vd_cnt;
11184 break;
11185 }
dd24e3da 11186 /* Check for overflow. */
7e26601c 11187 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11188 break;
11189
252b5132
RH
11190 isum += aux.vda_next;
11191 vstart += aux.vda_next;
11192
54806181
AM
11193 if (vstart + sizeof (*eaux) > endbuf)
11194 break;
1445030f 11195 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11196
11197 aux.vda_name = BYTE_GET (eaux->vda_name);
11198 aux.vda_next = BYTE_GET (eaux->vda_next);
11199
978c4450 11200 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11201 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11202 isum, j,
11203 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11204 else
452bf675 11205 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11206 isum, j, aux.vda_name);
11207 }
dd24e3da 11208
54806181
AM
11209 if (j < ent.vd_cnt)
11210 printf (_(" Version def aux past end of section\n"));
252b5132 11211
c9f02c3e
MR
11212 /* PR 17531:
11213 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11214 if (ent.vd_next < sizeof (*edef)
11215 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11216 {
11217 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11218 cnt = section->sh_info;
11219 break;
11220 }
452bf675 11221 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11222 break;
11223
252b5132
RH
11224 idx += ent.vd_next;
11225 }
dd24e3da 11226
54806181
AM
11227 if (cnt < section->sh_info)
11228 printf (_(" Version definition past end of section\n"));
252b5132
RH
11229
11230 free (edefs);
11231 }
11232 break;
103f02d3 11233
252b5132
RH
11234 case SHT_GNU_verneed:
11235 {
2cf0635d 11236 Elf_External_Verneed * eneed;
452bf675
AM
11237 unsigned long idx;
11238 unsigned long cnt;
2cf0635d 11239 char * endbuf;
252b5132 11240
32ec8896 11241 found = TRUE;
252b5132 11242
d3a49aa8
AM
11243 printf (ngettext ("\nVersion needs section '%s' "
11244 "contains %u entry:\n",
11245 "\nVersion needs section '%s' "
11246 "contains %u entries:\n",
11247 section->sh_info),
dda8d76d 11248 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11249
11250 printf (_(" Addr: 0x"));
11251 printf_vma (section->sh_addr);
72de5009 11252 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11253 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11254 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11255
dda8d76d 11256 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11257 section->sh_offset, 1,
11258 section->sh_size,
9cf03b7e 11259 _("Version Needs section"));
a6e9f9df
AM
11260 if (!eneed)
11261 break;
59245841 11262 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11263
11264 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11265 {
2cf0635d 11266 Elf_External_Verneed * entry;
b34976b6 11267 Elf_Internal_Verneed ent;
452bf675 11268 unsigned long isum;
b34976b6 11269 int j;
2cf0635d 11270 char * vstart;
252b5132
RH
11271
11272 vstart = ((char *) eneed) + idx;
54806181
AM
11273 if (vstart + sizeof (*entry) > endbuf)
11274 break;
252b5132
RH
11275
11276 entry = (Elf_External_Verneed *) vstart;
11277
11278 ent.vn_version = BYTE_GET (entry->vn_version);
11279 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11280 ent.vn_file = BYTE_GET (entry->vn_file);
11281 ent.vn_aux = BYTE_GET (entry->vn_aux);
11282 ent.vn_next = BYTE_GET (entry->vn_next);
11283
452bf675 11284 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11285
978c4450
AM
11286 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11287 printf (_(" File: %s"),
11288 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11289 else
11290 printf (_(" File: %lx"), ent.vn_file);
11291
11292 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11293
dd24e3da 11294 /* Check for overflow. */
7e26601c 11295 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11296 break;
252b5132
RH
11297 vstart += ent.vn_aux;
11298
11299 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11300 {
2cf0635d 11301 Elf_External_Vernaux * eaux;
b34976b6 11302 Elf_Internal_Vernaux aux;
252b5132 11303
54806181
AM
11304 if (vstart + sizeof (*eaux) > endbuf)
11305 break;
252b5132
RH
11306 eaux = (Elf_External_Vernaux *) vstart;
11307
11308 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11309 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11310 aux.vna_other = BYTE_GET (eaux->vna_other);
11311 aux.vna_name = BYTE_GET (eaux->vna_name);
11312 aux.vna_next = BYTE_GET (eaux->vna_next);
11313
978c4450 11314 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11315 printf (_(" %#06lx: Name: %s"),
978c4450 11316 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11317 else
452bf675 11318 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11319 isum, aux.vna_name);
11320
11321 printf (_(" Flags: %s Version: %d\n"),
11322 get_ver_flags (aux.vna_flags), aux.vna_other);
11323
1445030f
AM
11324 if (aux.vna_next < sizeof (*eaux)
11325 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11326 {
11327 warn (_("Invalid vna_next field of %lx\n"),
11328 aux.vna_next);
11329 j = ent.vn_cnt;
11330 break;
11331 }
1445030f
AM
11332 /* Check for overflow. */
11333 if (aux.vna_next > (size_t) (endbuf - vstart))
11334 break;
252b5132
RH
11335 isum += aux.vna_next;
11336 vstart += aux.vna_next;
11337 }
9cf03b7e 11338
54806181 11339 if (j < ent.vn_cnt)
9cf03b7e 11340 warn (_("Missing Version Needs auxillary information\n"));
252b5132 11341
1445030f
AM
11342 if (ent.vn_next < sizeof (*entry)
11343 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11344 {
452bf675 11345 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11346 cnt = section->sh_info;
11347 break;
11348 }
1445030f
AM
11349 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11350 break;
252b5132
RH
11351 idx += ent.vn_next;
11352 }
9cf03b7e 11353
54806181 11354 if (cnt < section->sh_info)
9cf03b7e 11355 warn (_("Missing Version Needs information\n"));
103f02d3 11356
252b5132
RH
11357 free (eneed);
11358 }
11359 break;
11360
11361 case SHT_GNU_versym:
11362 {
2cf0635d 11363 Elf_Internal_Shdr * link_section;
8b73c356
NC
11364 size_t total;
11365 unsigned int cnt;
2cf0635d
NC
11366 unsigned char * edata;
11367 unsigned short * data;
11368 char * strtab;
11369 Elf_Internal_Sym * symbols;
11370 Elf_Internal_Shdr * string_sec;
ba5cdace 11371 unsigned long num_syms;
d3ba0551 11372 long off;
252b5132 11373
dda8d76d 11374 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11375 break;
11376
dda8d76d 11377 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11378 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11379
dda8d76d 11380 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11381 break;
11382
32ec8896 11383 found = TRUE;
252b5132 11384
dda8d76d 11385 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11386 if (symbols == NULL)
11387 break;
252b5132 11388
dda8d76d 11389 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11390
dda8d76d 11391 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11392 string_sec->sh_size,
11393 _("version string table"));
a6e9f9df 11394 if (!strtab)
0429c154
MS
11395 {
11396 free (symbols);
11397 break;
11398 }
252b5132 11399
d3a49aa8
AM
11400 printf (ngettext ("\nVersion symbols section '%s' "
11401 "contains %lu entry:\n",
11402 "\nVersion symbols section '%s' "
11403 "contains %lu entries:\n",
11404 total),
dda8d76d 11405 printable_section_name (filedata, section), (unsigned long) total);
252b5132 11406
ae9ac79e 11407 printf (_(" Addr: 0x"));
252b5132 11408 printf_vma (section->sh_addr);
72de5009 11409 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11410 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11411 printable_section_name (filedata, link_section));
252b5132 11412
dda8d76d 11413 off = offset_from_vma (filedata,
978c4450 11414 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11415 total * sizeof (short));
95099889
AM
11416 edata = (unsigned char *) get_data (NULL, filedata, off,
11417 sizeof (short), total,
11418 _("version symbol data"));
a6e9f9df
AM
11419 if (!edata)
11420 {
11421 free (strtab);
0429c154 11422 free (symbols);
a6e9f9df
AM
11423 break;
11424 }
252b5132 11425
3f5e193b 11426 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11427
11428 for (cnt = total; cnt --;)
b34976b6
AM
11429 data[cnt] = byte_get (edata + cnt * sizeof (short),
11430 sizeof (short));
252b5132
RH
11431
11432 free (edata);
11433
11434 for (cnt = 0; cnt < total; cnt += 4)
11435 {
11436 int j, nn;
ab273396
AM
11437 char *name;
11438 char *invalid = _("*invalid*");
252b5132
RH
11439
11440 printf (" %03x:", cnt);
11441
11442 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11443 switch (data[cnt + j])
252b5132
RH
11444 {
11445 case 0:
11446 fputs (_(" 0 (*local*) "), stdout);
11447 break;
11448
11449 case 1:
11450 fputs (_(" 1 (*global*) "), stdout);
11451 break;
11452
11453 default:
c244d050
NC
11454 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11455 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11456
dd24e3da 11457 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11458 array, break to avoid an out-of-bounds read. */
11459 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11460 {
11461 warn (_("invalid index into symbol array\n"));
11462 break;
11463 }
11464
ab273396 11465 name = NULL;
978c4450 11466 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11467 {
b34976b6
AM
11468 Elf_Internal_Verneed ivn;
11469 unsigned long offset;
252b5132 11470
d93f0186 11471 offset = offset_from_vma
978c4450
AM
11472 (filedata,
11473 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11474 sizeof (Elf_External_Verneed));
252b5132 11475
b34976b6 11476 do
252b5132 11477 {
b34976b6
AM
11478 Elf_Internal_Vernaux ivna;
11479 Elf_External_Verneed evn;
11480 Elf_External_Vernaux evna;
11481 unsigned long a_off;
252b5132 11482
dda8d76d 11483 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11484 _("version need")) == NULL)
11485 break;
0b4362b0 11486
252b5132
RH
11487 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11488 ivn.vn_next = BYTE_GET (evn.vn_next);
11489
11490 a_off = offset + ivn.vn_aux;
11491
11492 do
11493 {
dda8d76d 11494 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11495 1, _("version need aux (2)")) == NULL)
11496 {
11497 ivna.vna_next = 0;
11498 ivna.vna_other = 0;
11499 }
11500 else
11501 {
11502 ivna.vna_next = BYTE_GET (evna.vna_next);
11503 ivna.vna_other = BYTE_GET (evna.vna_other);
11504 }
252b5132
RH
11505
11506 a_off += ivna.vna_next;
11507 }
b34976b6 11508 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11509 && ivna.vna_next != 0);
11510
b34976b6 11511 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11512 {
11513 ivna.vna_name = BYTE_GET (evna.vna_name);
11514
54806181 11515 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11516 name = invalid;
54806181
AM
11517 else
11518 name = strtab + ivna.vna_name;
252b5132
RH
11519 break;
11520 }
11521
11522 offset += ivn.vn_next;
11523 }
11524 while (ivn.vn_next);
11525 }
00d93f34 11526
ab273396 11527 if (data[cnt + j] != 0x8001
978c4450 11528 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11529 {
b34976b6
AM
11530 Elf_Internal_Verdef ivd;
11531 Elf_External_Verdef evd;
11532 unsigned long offset;
252b5132 11533
d93f0186 11534 offset = offset_from_vma
978c4450
AM
11535 (filedata,
11536 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11537 sizeof evd);
252b5132
RH
11538
11539 do
11540 {
dda8d76d 11541 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11542 _("version def")) == NULL)
11543 {
11544 ivd.vd_next = 0;
948f632f 11545 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11546 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11547 break;
59245841
NC
11548 }
11549 else
11550 {
11551 ivd.vd_next = BYTE_GET (evd.vd_next);
11552 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11553 }
252b5132
RH
11554
11555 offset += ivd.vd_next;
11556 }
c244d050 11557 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11558 && ivd.vd_next != 0);
11559
c244d050 11560 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11561 {
b34976b6
AM
11562 Elf_External_Verdaux evda;
11563 Elf_Internal_Verdaux ivda;
252b5132
RH
11564
11565 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11566
dda8d76d 11567 if (get_data (&evda, filedata,
59245841
NC
11568 offset - ivd.vd_next + ivd.vd_aux,
11569 sizeof (evda), 1,
11570 _("version def aux")) == NULL)
11571 break;
252b5132
RH
11572
11573 ivda.vda_name = BYTE_GET (evda.vda_name);
11574
54806181 11575 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11576 name = invalid;
11577 else if (name != NULL && name != invalid)
11578 name = _("*both*");
54806181
AM
11579 else
11580 name = strtab + ivda.vda_name;
252b5132
RH
11581 }
11582 }
ab273396
AM
11583 if (name != NULL)
11584 nn += printf ("(%s%-*s",
11585 name,
11586 12 - (int) strlen (name),
11587 ")");
252b5132
RH
11588
11589 if (nn < 18)
11590 printf ("%*c", 18 - nn, ' ');
11591 }
11592
11593 putchar ('\n');
11594 }
11595
11596 free (data);
11597 free (strtab);
11598 free (symbols);
11599 }
11600 break;
103f02d3 11601
252b5132
RH
11602 default:
11603 break;
11604 }
11605 }
11606
11607 if (! found)
11608 printf (_("\nNo version information found in this file.\n"));
11609
32ec8896 11610 return TRUE;
252b5132
RH
11611}
11612
d1133906 11613static const char *
dda8d76d 11614get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11615{
89246a0e 11616 static char buff[64];
252b5132
RH
11617
11618 switch (binding)
11619 {
b34976b6
AM
11620 case STB_LOCAL: return "LOCAL";
11621 case STB_GLOBAL: return "GLOBAL";
11622 case STB_WEAK: return "WEAK";
252b5132
RH
11623 default:
11624 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11625 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11626 binding);
252b5132 11627 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11628 {
11629 if (binding == STB_GNU_UNIQUE
df3a023b 11630 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11631 return "UNIQUE";
11632 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11633 }
252b5132 11634 else
e9e44622 11635 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11636 return buff;
11637 }
11638}
11639
d1133906 11640static const char *
dda8d76d 11641get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11642{
89246a0e 11643 static char buff[64];
252b5132
RH
11644
11645 switch (type)
11646 {
b34976b6
AM
11647 case STT_NOTYPE: return "NOTYPE";
11648 case STT_OBJECT: return "OBJECT";
11649 case STT_FUNC: return "FUNC";
11650 case STT_SECTION: return "SECTION";
11651 case STT_FILE: return "FILE";
11652 case STT_COMMON: return "COMMON";
11653 case STT_TLS: return "TLS";
15ab5209
DB
11654 case STT_RELC: return "RELC";
11655 case STT_SRELC: return "SRELC";
252b5132
RH
11656 default:
11657 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11658 {
dda8d76d 11659 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11660 return "THUMB_FUNC";
103f02d3 11661
dda8d76d 11662 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11663 return "REGISTER";
11664
dda8d76d 11665 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11666 return "PARISC_MILLI";
11667
e9e44622 11668 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11669 }
252b5132 11670 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11671 {
dda8d76d 11672 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11673 {
11674 if (type == STT_HP_OPAQUE)
11675 return "HP_OPAQUE";
11676 if (type == STT_HP_STUB)
11677 return "HP_STUB";
11678 }
11679
d8045f23 11680 if (type == STT_GNU_IFUNC
dda8d76d 11681 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11682 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11683 return "IFUNC";
11684
e9e44622 11685 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11686 }
252b5132 11687 else
e9e44622 11688 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11689 return buff;
11690 }
11691}
11692
d1133906 11693static const char *
d3ba0551 11694get_symbol_visibility (unsigned int visibility)
d1133906
NC
11695{
11696 switch (visibility)
11697 {
b34976b6
AM
11698 case STV_DEFAULT: return "DEFAULT";
11699 case STV_INTERNAL: return "INTERNAL";
11700 case STV_HIDDEN: return "HIDDEN";
d1133906 11701 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11702 default:
27a45f42 11703 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11704 return _("<unknown>");
d1133906
NC
11705 }
11706}
11707
2057d69d
CZ
11708static const char *
11709get_alpha_symbol_other (unsigned int other)
9abca702 11710{
2057d69d
CZ
11711 switch (other)
11712 {
11713 case STO_ALPHA_NOPV: return "NOPV";
11714 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11715 default:
27a45f42 11716 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11717 return _("<unknown>");
9abca702 11718 }
2057d69d
CZ
11719}
11720
fd85a6a1
NC
11721static const char *
11722get_solaris_symbol_visibility (unsigned int visibility)
11723{
11724 switch (visibility)
11725 {
11726 case 4: return "EXPORTED";
11727 case 5: return "SINGLETON";
11728 case 6: return "ELIMINATE";
11729 default: return get_symbol_visibility (visibility);
11730 }
11731}
11732
2301ed1c
SN
11733static const char *
11734get_aarch64_symbol_other (unsigned int other)
11735{
11736 static char buf[32];
11737
11738 if (other & STO_AARCH64_VARIANT_PCS)
11739 {
11740 other &= ~STO_AARCH64_VARIANT_PCS;
11741 if (other == 0)
11742 return "VARIANT_PCS";
11743 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
11744 return buf;
11745 }
11746 return NULL;
11747}
11748
5e2b0d47
NC
11749static const char *
11750get_mips_symbol_other (unsigned int other)
11751{
11752 switch (other)
11753 {
32ec8896
NC
11754 case STO_OPTIONAL: return "OPTIONAL";
11755 case STO_MIPS_PLT: return "MIPS PLT";
11756 case STO_MIPS_PIC: return "MIPS PIC";
11757 case STO_MICROMIPS: return "MICROMIPS";
11758 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11759 case STO_MIPS16: return "MIPS16";
11760 default: return NULL;
5e2b0d47
NC
11761 }
11762}
11763
28f997cf 11764static const char *
dda8d76d 11765get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11766{
dda8d76d 11767 if (is_ia64_vms (filedata))
28f997cf
TG
11768 {
11769 static char res[32];
11770
11771 res[0] = 0;
11772
11773 /* Function types is for images and .STB files only. */
dda8d76d 11774 switch (filedata->file_header.e_type)
28f997cf
TG
11775 {
11776 case ET_DYN:
11777 case ET_EXEC:
11778 switch (VMS_ST_FUNC_TYPE (other))
11779 {
11780 case VMS_SFT_CODE_ADDR:
11781 strcat (res, " CA");
11782 break;
11783 case VMS_SFT_SYMV_IDX:
11784 strcat (res, " VEC");
11785 break;
11786 case VMS_SFT_FD:
11787 strcat (res, " FD");
11788 break;
11789 case VMS_SFT_RESERVE:
11790 strcat (res, " RSV");
11791 break;
11792 default:
bee0ee85
NC
11793 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11794 VMS_ST_FUNC_TYPE (other));
11795 strcat (res, " <unknown>");
11796 break;
28f997cf
TG
11797 }
11798 break;
11799 default:
11800 break;
11801 }
11802 switch (VMS_ST_LINKAGE (other))
11803 {
11804 case VMS_STL_IGNORE:
11805 strcat (res, " IGN");
11806 break;
11807 case VMS_STL_RESERVE:
11808 strcat (res, " RSV");
11809 break;
11810 case VMS_STL_STD:
11811 strcat (res, " STD");
11812 break;
11813 case VMS_STL_LNK:
11814 strcat (res, " LNK");
11815 break;
11816 default:
bee0ee85
NC
11817 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11818 VMS_ST_LINKAGE (other));
11819 strcat (res, " <unknown>");
11820 break;
28f997cf
TG
11821 }
11822
11823 if (res[0] != 0)
11824 return res + 1;
11825 else
11826 return res;
11827 }
11828 return NULL;
11829}
11830
6911b7dc
AM
11831static const char *
11832get_ppc64_symbol_other (unsigned int other)
11833{
14732552
AM
11834 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11835 return NULL;
11836
11837 other >>= STO_PPC64_LOCAL_BIT;
11838 if (other <= 6)
6911b7dc 11839 {
89246a0e 11840 static char buf[64];
14732552
AM
11841 if (other >= 2)
11842 other = ppc64_decode_local_entry (other);
11843 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11844 return buf;
11845 }
11846 return NULL;
11847}
11848
5e2b0d47 11849static const char *
dda8d76d 11850get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11851{
11852 const char * result = NULL;
89246a0e 11853 static char buff [64];
5e2b0d47
NC
11854
11855 if (other == 0)
11856 return "";
11857
dda8d76d 11858 switch (filedata->file_header.e_machine)
5e2b0d47 11859 {
2057d69d
CZ
11860 case EM_ALPHA:
11861 result = get_alpha_symbol_other (other);
11862 break;
2301ed1c
SN
11863 case EM_AARCH64:
11864 result = get_aarch64_symbol_other (other);
11865 break;
5e2b0d47
NC
11866 case EM_MIPS:
11867 result = get_mips_symbol_other (other);
28f997cf
TG
11868 break;
11869 case EM_IA_64:
dda8d76d 11870 result = get_ia64_symbol_other (filedata, other);
28f997cf 11871 break;
6911b7dc
AM
11872 case EM_PPC64:
11873 result = get_ppc64_symbol_other (other);
11874 break;
5e2b0d47 11875 default:
fd85a6a1 11876 result = NULL;
5e2b0d47
NC
11877 break;
11878 }
11879
11880 if (result)
11881 return result;
11882
11883 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11884 return buff;
11885}
11886
d1133906 11887static const char *
dda8d76d 11888get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11889{
b34976b6 11890 static char buff[32];
5cf1065c 11891
252b5132
RH
11892 switch (type)
11893 {
b34976b6
AM
11894 case SHN_UNDEF: return "UND";
11895 case SHN_ABS: return "ABS";
11896 case SHN_COMMON: return "COM";
252b5132 11897 default:
9ce701e2 11898 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
11899 && filedata->file_header.e_machine == EM_IA_64
11900 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
11901 return "ANSI_COM";
11902 else if ((filedata->file_header.e_machine == EM_X86_64
11903 || filedata->file_header.e_machine == EM_L1OM
11904 || filedata->file_header.e_machine == EM_K1OM)
11905 && type == SHN_X86_64_LCOMMON)
11906 return "LARGE_COM";
11907 else if ((type == SHN_MIPS_SCOMMON
11908 && filedata->file_header.e_machine == EM_MIPS)
11909 || (type == SHN_TIC6X_SCOMMON
11910 && filedata->file_header.e_machine == EM_TI_C6000))
11911 return "SCOM";
11912 else if (type == SHN_MIPS_SUNDEFINED
11913 && filedata->file_header.e_machine == EM_MIPS)
11914 return "SUND";
11915 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
11916 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
11917 else if (type >= SHN_LOOS && type <= SHN_HIOS)
11918 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11919 else if (type >= SHN_LORESERVE)
11920 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
11921 else if (filedata->file_header.e_shnum != 0
11922 && type >= filedata->file_header.e_shnum)
11923 sprintf (buff, _("bad section index[%3d]"), type);
11924 else
11925 sprintf (buff, "%3d", type);
11926 break;
fd85a6a1
NC
11927 }
11928
10ca4b04 11929 return buff;
6bd1a22c
L
11930}
11931
bb4d2ac2 11932static const char *
dda8d76d 11933get_symbol_version_string (Filedata * filedata,
1449284b
NC
11934 bfd_boolean is_dynsym,
11935 const char * strtab,
11936 unsigned long int strtab_size,
11937 unsigned int si,
11938 Elf_Internal_Sym * psym,
11939 enum versioned_symbol_info * sym_info,
11940 unsigned short * vna_other)
bb4d2ac2 11941{
ab273396
AM
11942 unsigned char data[2];
11943 unsigned short vers_data;
11944 unsigned long offset;
7a815dd5 11945 unsigned short max_vd_ndx;
bb4d2ac2 11946
ab273396 11947 if (!is_dynsym
978c4450 11948 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 11949 return NULL;
bb4d2ac2 11950
978c4450
AM
11951 offset = offset_from_vma (filedata,
11952 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11953 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11954
dda8d76d 11955 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11956 sizeof (data), 1, _("version data")) == NULL)
11957 return NULL;
11958
11959 vers_data = byte_get (data, 2);
bb4d2ac2 11960
1f6f5dba 11961 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11962 return NULL;
bb4d2ac2 11963
0b8b7609 11964 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
11965 max_vd_ndx = 0;
11966
ab273396
AM
11967 /* Usually we'd only see verdef for defined symbols, and verneed for
11968 undefined symbols. However, symbols defined by the linker in
11969 .dynbss for variables copied from a shared library in order to
11970 avoid text relocations are defined yet have verneed. We could
11971 use a heuristic to detect the special case, for example, check
11972 for verneed first on symbols defined in SHT_NOBITS sections, but
11973 it is simpler and more reliable to just look for both verdef and
11974 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11975
ab273396
AM
11976 if (psym->st_shndx != SHN_UNDEF
11977 && vers_data != 0x8001
978c4450 11978 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
11979 {
11980 Elf_Internal_Verdef ivd;
11981 Elf_Internal_Verdaux ivda;
11982 Elf_External_Verdaux evda;
11983 unsigned long off;
bb4d2ac2 11984
dda8d76d 11985 off = offset_from_vma (filedata,
978c4450 11986 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
11987 sizeof (Elf_External_Verdef));
11988
11989 do
bb4d2ac2 11990 {
ab273396
AM
11991 Elf_External_Verdef evd;
11992
dda8d76d 11993 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11994 _("version def")) == NULL)
11995 {
11996 ivd.vd_ndx = 0;
11997 ivd.vd_aux = 0;
11998 ivd.vd_next = 0;
1f6f5dba 11999 ivd.vd_flags = 0;
ab273396
AM
12000 }
12001 else
bb4d2ac2 12002 {
ab273396
AM
12003 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12004 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12005 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12006 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12007 }
bb4d2ac2 12008
7a815dd5
L
12009 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12010 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12011
ab273396
AM
12012 off += ivd.vd_next;
12013 }
12014 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12015
ab273396
AM
12016 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12017 {
9abca702 12018 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12019 return NULL;
12020
ab273396
AM
12021 off -= ivd.vd_next;
12022 off += ivd.vd_aux;
bb4d2ac2 12023
dda8d76d 12024 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12025 _("version def aux")) != NULL)
12026 {
12027 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12028
ab273396 12029 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12030 return (ivda.vda_name < strtab_size
12031 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12032 }
12033 }
12034 }
bb4d2ac2 12035
978c4450 12036 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12037 {
12038 Elf_External_Verneed evn;
12039 Elf_Internal_Verneed ivn;
12040 Elf_Internal_Vernaux ivna;
bb4d2ac2 12041
dda8d76d 12042 offset = offset_from_vma (filedata,
978c4450 12043 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12044 sizeof evn);
12045 do
12046 {
12047 unsigned long vna_off;
bb4d2ac2 12048
dda8d76d 12049 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12050 _("version need")) == NULL)
12051 {
12052 ivna.vna_next = 0;
12053 ivna.vna_other = 0;
12054 ivna.vna_name = 0;
12055 break;
12056 }
bb4d2ac2 12057
ab273396
AM
12058 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12059 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12060
ab273396 12061 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12062
ab273396
AM
12063 do
12064 {
12065 Elf_External_Vernaux evna;
bb4d2ac2 12066
dda8d76d 12067 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12068 _("version need aux (3)")) == NULL)
bb4d2ac2 12069 {
ab273396
AM
12070 ivna.vna_next = 0;
12071 ivna.vna_other = 0;
12072 ivna.vna_name = 0;
bb4d2ac2 12073 }
bb4d2ac2 12074 else
bb4d2ac2 12075 {
ab273396
AM
12076 ivna.vna_other = BYTE_GET (evna.vna_other);
12077 ivna.vna_next = BYTE_GET (evna.vna_next);
12078 ivna.vna_name = BYTE_GET (evna.vna_name);
12079 }
bb4d2ac2 12080
ab273396
AM
12081 vna_off += ivna.vna_next;
12082 }
12083 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12084
ab273396
AM
12085 if (ivna.vna_other == vers_data)
12086 break;
bb4d2ac2 12087
ab273396
AM
12088 offset += ivn.vn_next;
12089 }
12090 while (ivn.vn_next != 0);
bb4d2ac2 12091
ab273396
AM
12092 if (ivna.vna_other == vers_data)
12093 {
12094 *sym_info = symbol_undefined;
12095 *vna_other = ivna.vna_other;
12096 return (ivna.vna_name < strtab_size
12097 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12098 }
7a815dd5
L
12099 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12100 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12101 return _("<corrupt>");
bb4d2ac2 12102 }
ab273396 12103 return NULL;
bb4d2ac2
L
12104}
12105
10ca4b04
L
12106static void
12107print_dynamic_symbol (Filedata *filedata, unsigned long si,
12108 Elf_Internal_Sym *symtab,
12109 Elf_Internal_Shdr *section,
12110 char *strtab, size_t strtab_size)
252b5132 12111{
10ca4b04
L
12112 const char *version_string;
12113 enum versioned_symbol_info sym_info;
12114 unsigned short vna_other;
12115 Elf_Internal_Sym *psym = symtab + si;
0942c7ab 12116
10ca4b04
L
12117 printf ("%6ld: ", si);
12118 print_vma (psym->st_value, LONG_HEX);
12119 putchar (' ');
12120 print_vma (psym->st_size, DEC_5);
12121 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12122 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12123 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12124 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12125 else
252b5132 12126 {
10ca4b04 12127 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12128
10ca4b04
L
12129 printf (" %-7s", get_symbol_visibility (vis));
12130 /* Check to see if any other bits in the st_other field are set.
12131 Note - displaying this information disrupts the layout of the
12132 table being generated, but for the moment this case is very rare. */
12133 if (psym->st_other ^ vis)
12134 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12135 }
10ca4b04 12136 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab
NC
12137
12138 bfd_boolean is_valid = VALID_SYMBOL_NAME (strtab, strtab_size,
12139 psym->st_name);
12140 const char * sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
10ca4b04
L
12141
12142 version_string
12143 = get_symbol_version_string (filedata,
12144 (section == NULL
12145 || section->sh_type == SHT_DYNSYM),
12146 strtab, strtab_size, si,
12147 psym, &sym_info, &vna_other);
0942c7ab
NC
12148
12149 int len_avail = 21;
12150 if (! do_wide && version_string != NULL)
12151 {
ddb43bab 12152 char buffer[16];
0942c7ab 12153
ddb43bab 12154 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12155
12156 if (sym_info == symbol_undefined)
12157 len_avail -= sprintf (buffer," (%d)", vna_other);
12158 else if (sym_info != symbol_hidden)
12159 len_avail -= 1;
12160 }
12161
12162 print_symbol (len_avail, sstr);
12163
10ca4b04
L
12164 if (version_string)
12165 {
12166 if (sym_info == symbol_undefined)
12167 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12168 else
10ca4b04
L
12169 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12170 version_string);
12171 }
6bd1a22c 12172
10ca4b04 12173 putchar ('\n');
6bd1a22c 12174
10ca4b04
L
12175 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12176 && section != NULL
12177 && si >= section->sh_info
12178 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12179 && filedata->file_header.e_machine != EM_MIPS
12180 /* Solaris binaries have been found to violate this requirement as
12181 well. Not sure if this is a bug or an ABI requirement. */
12182 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12183 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12184 si, printable_section_name (filedata, section), section->sh_info);
12185}
f16a9783 12186
10ca4b04
L
12187/* Dump the symbol table. */
12188static bfd_boolean
12189process_symbol_table (Filedata * filedata)
12190{
12191 Elf_Internal_Shdr * section;
f16a9783 12192
10ca4b04
L
12193 if (!do_syms && !do_dyn_syms && !do_histogram)
12194 return TRUE;
6bd1a22c 12195
978c4450 12196 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12197 && do_syms
12198 && do_using_dynamic
978c4450
AM
12199 && filedata->dynamic_strings != NULL
12200 && filedata->dynamic_symbols != NULL)
6bd1a22c 12201 {
10ca4b04 12202 unsigned long si;
6bd1a22c 12203
10ca4b04
L
12204 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12205 "\nSymbol table for image contains %lu entries:\n",
978c4450
AM
12206 filedata->num_dynamic_syms),
12207 filedata->num_dynamic_syms);
10ca4b04
L
12208 if (is_32bit_elf)
12209 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12210 else
12211 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12212
978c4450
AM
12213 for (si = 0; si < filedata->num_dynamic_syms; si++)
12214 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12215 filedata->dynamic_strings,
12216 filedata->dynamic_strings_length);
252b5132 12217 }
8b73c356 12218 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12219 && filedata->section_headers != NULL)
252b5132 12220 {
b34976b6 12221 unsigned int i;
252b5132 12222
dda8d76d
NC
12223 for (i = 0, section = filedata->section_headers;
12224 i < filedata->file_header.e_shnum;
252b5132
RH
12225 i++, section++)
12226 {
2cf0635d 12227 char * strtab = NULL;
c256ffe7 12228 unsigned long int strtab_size = 0;
2cf0635d 12229 Elf_Internal_Sym * symtab;
ef3df110 12230 unsigned long si, num_syms;
252b5132 12231
2c610e4b
L
12232 if ((section->sh_type != SHT_SYMTAB
12233 && section->sh_type != SHT_DYNSYM)
12234 || (!do_syms
12235 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12236 continue;
12237
dd24e3da
NC
12238 if (section->sh_entsize == 0)
12239 {
12240 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12241 printable_section_name (filedata, section));
dd24e3da
NC
12242 continue;
12243 }
12244
d3a49aa8
AM
12245 num_syms = section->sh_size / section->sh_entsize;
12246 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12247 "\nSymbol table '%s' contains %lu entries:\n",
12248 num_syms),
dda8d76d 12249 printable_section_name (filedata, section),
d3a49aa8 12250 num_syms);
dd24e3da 12251
f7a99963 12252 if (is_32bit_elf)
ca47b30c 12253 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12254 else
ca47b30c 12255 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12256
dda8d76d 12257 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12258 if (symtab == NULL)
12259 continue;
12260
dda8d76d 12261 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12262 {
dda8d76d
NC
12263 strtab = filedata->string_table;
12264 strtab_size = filedata->string_table_length;
c256ffe7 12265 }
dda8d76d 12266 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12267 {
2cf0635d 12268 Elf_Internal_Shdr * string_sec;
252b5132 12269
dda8d76d 12270 string_sec = filedata->section_headers + section->sh_link;
252b5132 12271
dda8d76d 12272 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12273 1, string_sec->sh_size,
12274 _("string table"));
c256ffe7 12275 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12276 }
12277
10ca4b04
L
12278 for (si = 0; si < num_syms; si++)
12279 print_dynamic_symbol (filedata, si, symtab, section,
12280 strtab, strtab_size);
252b5132
RH
12281
12282 free (symtab);
dda8d76d 12283 if (strtab != filedata->string_table)
252b5132
RH
12284 free (strtab);
12285 }
12286 }
12287 else if (do_syms)
12288 printf
12289 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12290
978c4450 12291 if (do_histogram && filedata->buckets != NULL)
252b5132 12292 {
2cf0635d
NC
12293 unsigned long * lengths;
12294 unsigned long * counts;
66543521
AM
12295 unsigned long hn;
12296 bfd_vma si;
12297 unsigned long maxlength = 0;
12298 unsigned long nzero_counts = 0;
12299 unsigned long nsyms = 0;
6bd6a03d 12300 char *visited;
252b5132 12301
d3a49aa8
AM
12302 printf (ngettext ("\nHistogram for bucket list length "
12303 "(total of %lu bucket):\n",
12304 "\nHistogram for bucket list length "
12305 "(total of %lu buckets):\n",
978c4450
AM
12306 (unsigned long) filedata->nbuckets),
12307 (unsigned long) filedata->nbuckets);
252b5132 12308
978c4450
AM
12309 lengths = (unsigned long *) calloc (filedata->nbuckets,
12310 sizeof (*lengths));
252b5132
RH
12311 if (lengths == NULL)
12312 {
8b73c356 12313 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12314 goto err_out;
252b5132 12315 }
978c4450
AM
12316 visited = xcmalloc (filedata->nchains, 1);
12317 memset (visited, 0, filedata->nchains);
8b73c356
NC
12318
12319 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12320 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12321 {
978c4450 12322 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12323 {
b34976b6 12324 ++nsyms;
252b5132 12325 if (maxlength < ++lengths[hn])
b34976b6 12326 ++maxlength;
978c4450 12327 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12328 {
12329 error (_("histogram chain is corrupt\n"));
12330 break;
12331 }
12332 visited[si] = 1;
252b5132
RH
12333 }
12334 }
6bd6a03d 12335 free (visited);
252b5132 12336
3f5e193b 12337 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12338 if (counts == NULL)
12339 {
b2e951ec 12340 free (lengths);
8b73c356 12341 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12342 goto err_out;
252b5132
RH
12343 }
12344
978c4450 12345 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12346 ++counts[lengths[hn]];
252b5132 12347
978c4450 12348 if (filedata->nbuckets > 0)
252b5132 12349 {
66543521
AM
12350 unsigned long i;
12351 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12352 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12353 for (i = 1; i <= maxlength; ++i)
103f02d3 12354 {
66543521
AM
12355 nzero_counts += counts[i] * i;
12356 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12357 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12358 (nzero_counts * 100.0) / nsyms);
12359 }
252b5132
RH
12360 }
12361
12362 free (counts);
12363 free (lengths);
12364 }
12365
978c4450
AM
12366 free (filedata->buckets);
12367 filedata->buckets = NULL;
12368 filedata->nbuckets = 0;
12369 free (filedata->chains);
12370 filedata->chains = NULL;
252b5132 12371
978c4450 12372 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 12373 {
2cf0635d
NC
12374 unsigned long * lengths;
12375 unsigned long * counts;
fdc90cb4
JJ
12376 unsigned long hn;
12377 unsigned long maxlength = 0;
12378 unsigned long nzero_counts = 0;
12379 unsigned long nsyms = 0;
fdc90cb4 12380
f16a9783 12381 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12382 "(total of %lu bucket):\n",
f16a9783 12383 "\nHistogram for `%s' bucket list length "
d3a49aa8 12384 "(total of %lu buckets):\n",
978c4450
AM
12385 (unsigned long) filedata->ngnubuckets),
12386 GNU_HASH_SECTION_NAME (filedata),
12387 (unsigned long) filedata->ngnubuckets);
8b73c356 12388
978c4450
AM
12389 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
12390 sizeof (*lengths));
fdc90cb4
JJ
12391 if (lengths == NULL)
12392 {
8b73c356 12393 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12394 goto err_out;
fdc90cb4
JJ
12395 }
12396
fdc90cb4
JJ
12397 printf (_(" Length Number %% of total Coverage\n"));
12398
978c4450
AM
12399 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12400 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
12401 {
12402 bfd_vma off, length = 1;
12403
978c4450 12404 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 12405 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
12406 off < filedata->ngnuchains
12407 && (filedata->gnuchains[off] & 1) == 0;
071436c6 12408 ++off)
fdc90cb4
JJ
12409 ++length;
12410 lengths[hn] = length;
12411 if (length > maxlength)
12412 maxlength = length;
12413 nsyms += length;
12414 }
12415
3f5e193b 12416 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12417 if (counts == NULL)
12418 {
b2e951ec 12419 free (lengths);
8b73c356 12420 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12421 goto err_out;
fdc90cb4
JJ
12422 }
12423
978c4450 12424 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
12425 ++counts[lengths[hn]];
12426
978c4450 12427 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
12428 {
12429 unsigned long j;
12430 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12431 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
12432 for (j = 1; j <= maxlength; ++j)
12433 {
12434 nzero_counts += counts[j] * j;
12435 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12436 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
12437 (nzero_counts * 100.0) / nsyms);
12438 }
12439 }
12440
12441 free (counts);
12442 free (lengths);
fdc90cb4 12443 }
978c4450
AM
12444 free (filedata->gnubuckets);
12445 filedata->gnubuckets = NULL;
12446 filedata->ngnubuckets = 0;
12447 free (filedata->gnuchains);
12448 filedata->gnuchains = NULL;
12449 filedata->ngnuchains = 0;
12450 free (filedata->mipsxlat);
12451 filedata->mipsxlat = NULL;
32ec8896 12452 return TRUE;
fd486f32
AM
12453
12454 err_out:
978c4450
AM
12455 free (filedata->gnubuckets);
12456 filedata->gnubuckets = NULL;
12457 filedata->ngnubuckets = 0;
12458 free (filedata->gnuchains);
12459 filedata->gnuchains = NULL;
12460 filedata->ngnuchains = 0;
12461 free (filedata->mipsxlat);
12462 filedata->mipsxlat = NULL;
12463 free (filedata->buckets);
12464 filedata->buckets = NULL;
12465 filedata->nbuckets = 0;
12466 free (filedata->chains);
12467 filedata->chains = NULL;
fd486f32 12468 return FALSE;
252b5132
RH
12469}
12470
32ec8896 12471static bfd_boolean
dda8d76d 12472process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12473{
b4c96d0d 12474 unsigned int i;
252b5132 12475
978c4450 12476 if (filedata->dynamic_syminfo == NULL
252b5132
RH
12477 || !do_dynamic)
12478 /* No syminfo, this is ok. */
32ec8896 12479 return TRUE;
252b5132
RH
12480
12481 /* There better should be a dynamic symbol section. */
978c4450 12482 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
32ec8896 12483 return FALSE;
252b5132 12484
978c4450 12485 if (filedata->dynamic_addr)
d3a49aa8
AM
12486 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12487 "contains %d entry:\n",
12488 "\nDynamic info segment at offset 0x%lx "
12489 "contains %d entries:\n",
978c4450
AM
12490 filedata->dynamic_syminfo_nent),
12491 filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent);
252b5132
RH
12492
12493 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 12494 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 12495 {
978c4450 12496 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 12497
31104126 12498 printf ("%4d: ", i);
978c4450 12499 if (i >= filedata->num_dynamic_syms)
4082ef84 12500 printf (_("<corrupt index>"));
978c4450
AM
12501 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
12502 print_symbol (30, GET_DYNAMIC_NAME (filedata,
12503 filedata->dynamic_symbols[i].st_name));
d79b3d50 12504 else
978c4450 12505 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 12506 putchar (' ');
252b5132 12507
978c4450 12508 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
12509 {
12510 case SYMINFO_BT_SELF:
12511 fputs ("SELF ", stdout);
12512 break;
12513 case SYMINFO_BT_PARENT:
12514 fputs ("PARENT ", stdout);
12515 break;
12516 default:
978c4450
AM
12517 if (filedata->dynamic_syminfo[i].si_boundto > 0
12518 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
12519 && VALID_DYNAMIC_NAME (filedata,
12520 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12521 {
978c4450
AM
12522 print_symbol (10, GET_DYNAMIC_NAME (filedata,
12523 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12524 putchar (' ' );
12525 }
252b5132 12526 else
978c4450 12527 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
12528 break;
12529 }
12530
12531 if (flags & SYMINFO_FLG_DIRECT)
12532 printf (" DIRECT");
12533 if (flags & SYMINFO_FLG_PASSTHRU)
12534 printf (" PASSTHRU");
12535 if (flags & SYMINFO_FLG_COPY)
12536 printf (" COPY");
12537 if (flags & SYMINFO_FLG_LAZYLOAD)
12538 printf (" LAZYLOAD");
12539
12540 puts ("");
12541 }
12542
32ec8896 12543 return TRUE;
252b5132
RH
12544}
12545
75802ccb
CE
12546/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
12547 is contained by the region START .. END. The types of ADDR, START
12548 and END should all be the same. Note both ADDR + NELEM and END
12549 point to just beyond the end of the regions that are being tested. */
12550#define IN_RANGE(START,END,ADDR,NELEM) \
12551 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 12552
cf13d699
NC
12553/* Check to see if the given reloc needs to be handled in a target specific
12554 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12555 FALSE.
12556
12557 If called with reloc == NULL, then this is a signal that reloc processing
12558 for the current section has finished, and any saved state should be
12559 discarded. */
09c11c86 12560
cf13d699 12561static bfd_boolean
dda8d76d
NC
12562target_specific_reloc_handling (Filedata * filedata,
12563 Elf_Internal_Rela * reloc,
12564 unsigned char * start,
12565 unsigned char * end,
12566 Elf_Internal_Sym * symtab,
12567 unsigned long num_syms)
252b5132 12568{
f84ce13b
NC
12569 unsigned int reloc_type = 0;
12570 unsigned long sym_index = 0;
12571
12572 if (reloc)
12573 {
dda8d76d 12574 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12575 sym_index = get_reloc_symindex (reloc->r_info);
12576 }
252b5132 12577
dda8d76d 12578 switch (filedata->file_header.e_machine)
252b5132 12579 {
13761a11
NC
12580 case EM_MSP430:
12581 case EM_MSP430_OLD:
12582 {
12583 static Elf_Internal_Sym * saved_sym = NULL;
12584
f84ce13b
NC
12585 if (reloc == NULL)
12586 {
12587 saved_sym = NULL;
12588 return TRUE;
12589 }
12590
13761a11
NC
12591 switch (reloc_type)
12592 {
12593 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12594 if (uses_msp430x_relocs (filedata))
13761a11 12595 break;
1a0670f3 12596 /* Fall through. */
13761a11 12597 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12598 /* PR 21139. */
12599 if (sym_index >= num_syms)
12600 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12601 sym_index);
12602 else
12603 saved_sym = symtab + sym_index;
13761a11
NC
12604 return TRUE;
12605
12606 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12607 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12608 goto handle_sym_diff;
0b4362b0 12609
13761a11
NC
12610 case 5: /* R_MSP430_16_BYTE */
12611 case 9: /* R_MSP430_8 */
dda8d76d 12612 if (uses_msp430x_relocs (filedata))
13761a11
NC
12613 break;
12614 goto handle_sym_diff;
12615
12616 case 2: /* R_MSP430_ABS16 */
12617 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12618 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12619 break;
12620 goto handle_sym_diff;
0b4362b0 12621
13761a11
NC
12622 handle_sym_diff:
12623 if (saved_sym != NULL)
12624 {
03f7786e 12625 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12626 bfd_vma value;
12627
f84ce13b
NC
12628 if (sym_index >= num_syms)
12629 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12630 sym_index);
03f7786e 12631 else
f84ce13b
NC
12632 {
12633 value = reloc->r_addend + (symtab[sym_index].st_value
12634 - saved_sym->st_value);
12635
b32e566b 12636 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12637 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12638 else
12639 /* PR 21137 */
12640 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12641 (long) reloc->r_offset);
f84ce13b 12642 }
13761a11
NC
12643
12644 saved_sym = NULL;
12645 return TRUE;
12646 }
12647 break;
12648
12649 default:
12650 if (saved_sym != NULL)
071436c6 12651 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12652 break;
12653 }
12654 break;
12655 }
12656
cf13d699
NC
12657 case EM_MN10300:
12658 case EM_CYGNUS_MN10300:
12659 {
12660 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12661
f84ce13b
NC
12662 if (reloc == NULL)
12663 {
12664 saved_sym = NULL;
12665 return TRUE;
12666 }
12667
cf13d699
NC
12668 switch (reloc_type)
12669 {
12670 case 34: /* R_MN10300_ALIGN */
12671 return TRUE;
12672 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12673 if (sym_index >= num_syms)
12674 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12675 sym_index);
12676 else
12677 saved_sym = symtab + sym_index;
cf13d699 12678 return TRUE;
f84ce13b 12679
cf13d699
NC
12680 case 1: /* R_MN10300_32 */
12681 case 2: /* R_MN10300_16 */
12682 if (saved_sym != NULL)
12683 {
03f7786e 12684 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12685 bfd_vma value;
252b5132 12686
f84ce13b
NC
12687 if (sym_index >= num_syms)
12688 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12689 sym_index);
03f7786e 12690 else
f84ce13b
NC
12691 {
12692 value = reloc->r_addend + (symtab[sym_index].st_value
12693 - saved_sym->st_value);
12694
b32e566b 12695 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12696 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12697 else
12698 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12699 (long) reloc->r_offset);
f84ce13b 12700 }
252b5132 12701
cf13d699
NC
12702 saved_sym = NULL;
12703 return TRUE;
12704 }
12705 break;
12706 default:
12707 if (saved_sym != NULL)
071436c6 12708 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12709 break;
12710 }
12711 break;
12712 }
6ff71e76
NC
12713
12714 case EM_RL78:
12715 {
12716 static bfd_vma saved_sym1 = 0;
12717 static bfd_vma saved_sym2 = 0;
12718 static bfd_vma value;
12719
f84ce13b
NC
12720 if (reloc == NULL)
12721 {
12722 saved_sym1 = saved_sym2 = 0;
12723 return TRUE;
12724 }
12725
6ff71e76
NC
12726 switch (reloc_type)
12727 {
12728 case 0x80: /* R_RL78_SYM. */
12729 saved_sym1 = saved_sym2;
f84ce13b
NC
12730 if (sym_index >= num_syms)
12731 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12732 sym_index);
12733 else
12734 {
12735 saved_sym2 = symtab[sym_index].st_value;
12736 saved_sym2 += reloc->r_addend;
12737 }
6ff71e76
NC
12738 return TRUE;
12739
12740 case 0x83: /* R_RL78_OPsub. */
12741 value = saved_sym1 - saved_sym2;
12742 saved_sym2 = saved_sym1 = 0;
12743 return TRUE;
12744 break;
12745
12746 case 0x41: /* R_RL78_ABS32. */
b32e566b 12747 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12748 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12749 else
12750 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12751 (long) reloc->r_offset);
6ff71e76
NC
12752 value = 0;
12753 return TRUE;
12754
12755 case 0x43: /* R_RL78_ABS16. */
b32e566b 12756 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12757 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12758 else
12759 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12760 (long) reloc->r_offset);
6ff71e76
NC
12761 value = 0;
12762 return TRUE;
12763
12764 default:
12765 break;
12766 }
12767 break;
12768 }
252b5132
RH
12769 }
12770
cf13d699 12771 return FALSE;
252b5132
RH
12772}
12773
aca88567
NC
12774/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12775 DWARF debug sections. This is a target specific test. Note - we do not
12776 go through the whole including-target-headers-multiple-times route, (as
12777 we have already done with <elf/h8.h>) because this would become very
12778 messy and even then this function would have to contain target specific
12779 information (the names of the relocs instead of their numeric values).
12780 FIXME: This is not the correct way to solve this problem. The proper way
12781 is to have target specific reloc sizing and typing functions created by
12782 the reloc-macros.h header, in the same way that it already creates the
12783 reloc naming functions. */
12784
12785static bfd_boolean
dda8d76d 12786is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12787{
d347c9df 12788 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12789 switch (filedata->file_header.e_machine)
aca88567 12790 {
41e92641 12791 case EM_386:
22abe556 12792 case EM_IAMCU:
41e92641 12793 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12794 case EM_68K:
12795 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12796 case EM_860:
12797 return reloc_type == 1; /* R_860_32. */
12798 case EM_960:
12799 return reloc_type == 2; /* R_960_32. */
a06ea964 12800 case EM_AARCH64:
9282b95a
JW
12801 return (reloc_type == 258
12802 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
12803 case EM_BPF:
12804 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
12805 case EM_ADAPTEVA_EPIPHANY:
12806 return reloc_type == 3;
aca88567 12807 case EM_ALPHA:
137b6b5f 12808 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12809 case EM_ARC:
12810 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12811 case EM_ARC_COMPACT:
12812 case EM_ARC_COMPACT2:
12813 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12814 case EM_ARM:
12815 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12816 case EM_AVR_OLD:
aca88567
NC
12817 case EM_AVR:
12818 return reloc_type == 1;
12819 case EM_BLACKFIN:
12820 return reloc_type == 0x12; /* R_byte4_data. */
12821 case EM_CRIS:
12822 return reloc_type == 3; /* R_CRIS_32. */
12823 case EM_CR16:
12824 return reloc_type == 3; /* R_CR16_NUM32. */
12825 case EM_CRX:
12826 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
12827 case EM_CSKY:
12828 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
12829 case EM_CYGNUS_FRV:
12830 return reloc_type == 1;
41e92641
NC
12831 case EM_CYGNUS_D10V:
12832 case EM_D10V:
12833 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12834 case EM_CYGNUS_D30V:
12835 case EM_D30V:
12836 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12837 case EM_DLX:
12838 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12839 case EM_CYGNUS_FR30:
12840 case EM_FR30:
12841 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12842 case EM_FT32:
12843 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12844 case EM_H8S:
12845 case EM_H8_300:
12846 case EM_H8_300H:
12847 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12848 case EM_IA_64:
262cdac7
AM
12849 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12850 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12851 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12852 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12853 case EM_IP2K_OLD:
12854 case EM_IP2K:
12855 return reloc_type == 2; /* R_IP2K_32. */
12856 case EM_IQ2000:
12857 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12858 case EM_LATTICEMICO32:
12859 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12860 case EM_M32C_OLD:
aca88567
NC
12861 case EM_M32C:
12862 return reloc_type == 3; /* R_M32C_32. */
12863 case EM_M32R:
12864 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12865 case EM_68HC11:
12866 case EM_68HC12:
12867 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 12868 case EM_S12Z:
2849d19f
JD
12869 return reloc_type == 7 || /* R_S12Z_EXT32 */
12870 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
12871 case EM_MCORE:
12872 return reloc_type == 1; /* R_MCORE_ADDR32. */
12873 case EM_CYGNUS_MEP:
12874 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12875 case EM_METAG:
12876 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12877 case EM_MICROBLAZE:
12878 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12879 case EM_MIPS:
12880 return reloc_type == 2; /* R_MIPS_32. */
12881 case EM_MMIX:
12882 return reloc_type == 4; /* R_MMIX_32. */
12883 case EM_CYGNUS_MN10200:
12884 case EM_MN10200:
12885 return reloc_type == 1; /* R_MN10200_32. */
12886 case EM_CYGNUS_MN10300:
12887 case EM_MN10300:
12888 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12889 case EM_MOXIE:
12890 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12891 case EM_MSP430_OLD:
12892 case EM_MSP430:
13761a11 12893 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12894 case EM_MT:
12895 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12896 case EM_NDS32:
12897 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12898 case EM_ALTERA_NIOS2:
36591ba1 12899 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12900 case EM_NIOS32:
12901 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12902 case EM_OR1K:
12903 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12904 case EM_PARISC:
9abca702 12905 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 12906 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12907 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12908 case EM_PJ:
12909 case EM_PJ_OLD:
12910 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12911 case EM_PPC64:
12912 return reloc_type == 1; /* R_PPC64_ADDR32. */
12913 case EM_PPC:
12914 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12915 case EM_TI_PRU:
12916 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12917 case EM_RISCV:
12918 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12919 case EM_RL78:
12920 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12921 case EM_RX:
12922 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12923 case EM_S370:
12924 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12925 case EM_S390_OLD:
12926 case EM_S390:
12927 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12928 case EM_SCORE:
12929 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12930 case EM_SH:
12931 return reloc_type == 1; /* R_SH_DIR32. */
12932 case EM_SPARC32PLUS:
12933 case EM_SPARCV9:
12934 case EM_SPARC:
12935 return reloc_type == 3 /* R_SPARC_32. */
12936 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12937 case EM_SPU:
12938 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12939 case EM_TI_C6000:
12940 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12941 case EM_TILEGX:
12942 return reloc_type == 2; /* R_TILEGX_32. */
12943 case EM_TILEPRO:
12944 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12945 case EM_CYGNUS_V850:
12946 case EM_V850:
12947 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12948 case EM_V800:
12949 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12950 case EM_VAX:
12951 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12952 case EM_VISIUM:
12953 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12954 case EM_WEBASSEMBLY:
12955 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12956 case EM_X86_64:
8a9036a4 12957 case EM_L1OM:
7a9068fe 12958 case EM_K1OM:
aca88567 12959 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12960 case EM_XC16X:
12961 case EM_C166:
12962 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12963 case EM_XGATE:
12964 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12965 case EM_XSTORMY16:
12966 return reloc_type == 1; /* R_XSTROMY16_32. */
12967 case EM_XTENSA_OLD:
12968 case EM_XTENSA:
12969 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
12970 case EM_Z80:
12971 return reloc_type == 6; /* R_Z80_32. */
aca88567 12972 default:
bee0ee85
NC
12973 {
12974 static unsigned int prev_warn = 0;
12975
12976 /* Avoid repeating the same warning multiple times. */
dda8d76d 12977 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12978 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12979 filedata->file_header.e_machine);
12980 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12981 return FALSE;
12982 }
aca88567
NC
12983 }
12984}
12985
12986/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12987 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12988
12989static bfd_boolean
dda8d76d 12990is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12991{
dda8d76d 12992 switch (filedata->file_header.e_machine)
d347c9df 12993 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12994 {
41e92641 12995 case EM_386:
22abe556 12996 case EM_IAMCU:
3e0873ac 12997 return reloc_type == 2; /* R_386_PC32. */
aca88567 12998 case EM_68K:
3e0873ac 12999 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13000 case EM_AARCH64:
13001 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13002 case EM_ADAPTEVA_EPIPHANY:
13003 return reloc_type == 6;
aca88567
NC
13004 case EM_ALPHA:
13005 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13006 case EM_ARC_COMPACT:
13007 case EM_ARC_COMPACT2:
13008 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13009 case EM_ARM:
3e0873ac 13010 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13011 case EM_AVR_OLD:
13012 case EM_AVR:
13013 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13014 case EM_MICROBLAZE:
13015 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13016 case EM_OR1K:
13017 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13018 case EM_PARISC:
85acf597 13019 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13020 case EM_PPC:
13021 return reloc_type == 26; /* R_PPC_REL32. */
13022 case EM_PPC64:
3e0873ac 13023 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13024 case EM_RISCV:
13025 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13026 case EM_S390_OLD:
13027 case EM_S390:
3e0873ac 13028 return reloc_type == 5; /* R_390_PC32. */
aca88567 13029 case EM_SH:
3e0873ac 13030 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13031 case EM_SPARC32PLUS:
13032 case EM_SPARCV9:
13033 case EM_SPARC:
3e0873ac 13034 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13035 case EM_SPU:
13036 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13037 case EM_TILEGX:
13038 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13039 case EM_TILEPRO:
13040 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13041 case EM_VISIUM:
13042 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13043 case EM_X86_64:
8a9036a4 13044 case EM_L1OM:
7a9068fe 13045 case EM_K1OM:
3e0873ac 13046 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13047 case EM_VAX:
13048 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13049 case EM_XTENSA_OLD:
13050 case EM_XTENSA:
13051 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13052 default:
13053 /* Do not abort or issue an error message here. Not all targets use
13054 pc-relative 32-bit relocs in their DWARF debug information and we
13055 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13056 more helpful warning message will be generated by apply_relocations
13057 anyway, so just return. */
aca88567
NC
13058 return FALSE;
13059 }
13060}
13061
13062/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13063 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13064
13065static bfd_boolean
dda8d76d 13066is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13067{
dda8d76d 13068 switch (filedata->file_header.e_machine)
aca88567 13069 {
a06ea964
NC
13070 case EM_AARCH64:
13071 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13072 case EM_ALPHA:
13073 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13074 case EM_IA_64:
262cdac7
AM
13075 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13076 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13077 case EM_PARISC:
13078 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13079 case EM_PPC64:
13080 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13081 case EM_RISCV:
13082 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13083 case EM_SPARC32PLUS:
13084 case EM_SPARCV9:
13085 case EM_SPARC:
714da62f
NC
13086 return reloc_type == 32 /* R_SPARC_64. */
13087 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13088 case EM_X86_64:
8a9036a4 13089 case EM_L1OM:
7a9068fe 13090 case EM_K1OM:
aca88567 13091 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13092 case EM_S390_OLD:
13093 case EM_S390:
aa137e4d
NC
13094 return reloc_type == 22; /* R_S390_64. */
13095 case EM_TILEGX:
13096 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13097 case EM_MIPS:
aa137e4d 13098 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
13099 default:
13100 return FALSE;
13101 }
13102}
13103
85acf597
RH
13104/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13105 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13106
13107static bfd_boolean
dda8d76d 13108is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13109{
dda8d76d 13110 switch (filedata->file_header.e_machine)
85acf597 13111 {
a06ea964
NC
13112 case EM_AARCH64:
13113 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13114 case EM_ALPHA:
aa137e4d 13115 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13116 case EM_IA_64:
262cdac7
AM
13117 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13118 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13119 case EM_PARISC:
aa137e4d 13120 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13121 case EM_PPC64:
aa137e4d 13122 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13123 case EM_SPARC32PLUS:
13124 case EM_SPARCV9:
13125 case EM_SPARC:
aa137e4d 13126 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13127 case EM_X86_64:
8a9036a4 13128 case EM_L1OM:
7a9068fe 13129 case EM_K1OM:
aa137e4d 13130 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13131 case EM_S390_OLD:
13132 case EM_S390:
aa137e4d
NC
13133 return reloc_type == 23; /* R_S390_PC64. */
13134 case EM_TILEGX:
13135 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
13136 default:
13137 return FALSE;
13138 }
13139}
13140
4dc3c23d
AM
13141/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13142 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13143
13144static bfd_boolean
dda8d76d 13145is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13146{
dda8d76d 13147 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13148 {
13149 case EM_CYGNUS_MN10200:
13150 case EM_MN10200:
13151 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13152 case EM_FT32:
13153 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13154 case EM_Z80:
13155 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
13156 default:
13157 return FALSE;
13158 }
13159}
13160
aca88567
NC
13161/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13162 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13163
13164static bfd_boolean
dda8d76d 13165is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13166{
d347c9df 13167 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13168 switch (filedata->file_header.e_machine)
4b78141a 13169 {
886a2506
NC
13170 case EM_ARC:
13171 case EM_ARC_COMPACT:
13172 case EM_ARC_COMPACT2:
13173 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13174 case EM_ADAPTEVA_EPIPHANY:
13175 return reloc_type == 5;
aca88567
NC
13176 case EM_AVR_OLD:
13177 case EM_AVR:
13178 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13179 case EM_CYGNUS_D10V:
13180 case EM_D10V:
13181 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13182 case EM_FT32:
13183 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13184 case EM_H8S:
13185 case EM_H8_300:
13186 case EM_H8_300H:
aca88567
NC
13187 return reloc_type == R_H8_DIR16;
13188 case EM_IP2K_OLD:
13189 case EM_IP2K:
13190 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13191 case EM_M32C_OLD:
f4236fe4
DD
13192 case EM_M32C:
13193 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13194 case EM_CYGNUS_MN10200:
13195 case EM_MN10200:
13196 return reloc_type == 2; /* R_MN10200_16. */
13197 case EM_CYGNUS_MN10300:
13198 case EM_MN10300:
13199 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13200 case EM_MSP430:
dda8d76d 13201 if (uses_msp430x_relocs (filedata))
13761a11 13202 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13203 /* Fall through. */
78c8d46c 13204 case EM_MSP430_OLD:
aca88567 13205 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13206 case EM_NDS32:
13207 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13208 case EM_ALTERA_NIOS2:
36591ba1 13209 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13210 case EM_NIOS32:
13211 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13212 case EM_OR1K:
13213 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13214 case EM_RISCV:
13215 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13216 case EM_TI_PRU:
13217 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13218 case EM_TI_C6000:
13219 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13220 case EM_VISIUM:
13221 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13222 case EM_XC16X:
13223 case EM_C166:
13224 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13225 case EM_XGATE:
13226 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13227 case EM_Z80:
13228 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13229 default:
aca88567 13230 return FALSE;
4b78141a
NC
13231 }
13232}
13233
39e07931
AS
13234/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13235 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13236
13237static bfd_boolean
13238is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13239{
13240 switch (filedata->file_header.e_machine)
13241 {
13242 case EM_RISCV:
13243 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13244 case EM_Z80:
13245 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13246 default:
13247 return FALSE;
13248 }
13249}
13250
13251/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13252 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13253
13254static bfd_boolean
13255is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13256{
13257 switch (filedata->file_header.e_machine)
13258 {
13259 case EM_RISCV:
13260 return reloc_type == 53; /* R_RISCV_SET6. */
13261 default:
13262 return FALSE;
13263 }
13264}
13265
03336641
JW
13266/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13267 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13268
13269static bfd_boolean
13270is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13271{
13272 /* Please keep this table alpha-sorted for ease of visual lookup. */
13273 switch (filedata->file_header.e_machine)
13274 {
13275 case EM_RISCV:
13276 return reloc_type == 35; /* R_RISCV_ADD32. */
13277 default:
13278 return FALSE;
13279 }
13280}
13281
13282/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13283 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13284
13285static bfd_boolean
13286is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13287{
13288 /* Please keep this table alpha-sorted for ease of visual lookup. */
13289 switch (filedata->file_header.e_machine)
13290 {
13291 case EM_RISCV:
13292 return reloc_type == 39; /* R_RISCV_SUB32. */
13293 default:
13294 return FALSE;
13295 }
13296}
13297
13298/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13299 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13300
13301static bfd_boolean
13302is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13303{
13304 /* Please keep this table alpha-sorted for ease of visual lookup. */
13305 switch (filedata->file_header.e_machine)
13306 {
13307 case EM_RISCV:
13308 return reloc_type == 36; /* R_RISCV_ADD64. */
13309 default:
13310 return FALSE;
13311 }
13312}
13313
13314/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13315 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13316
13317static bfd_boolean
13318is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13319{
13320 /* Please keep this table alpha-sorted for ease of visual lookup. */
13321 switch (filedata->file_header.e_machine)
13322 {
13323 case EM_RISCV:
13324 return reloc_type == 40; /* R_RISCV_SUB64. */
13325 default:
13326 return FALSE;
13327 }
13328}
13329
13330/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13331 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13332
13333static bfd_boolean
13334is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13335{
13336 /* Please keep this table alpha-sorted for ease of visual lookup. */
13337 switch (filedata->file_header.e_machine)
13338 {
13339 case EM_RISCV:
13340 return reloc_type == 34; /* R_RISCV_ADD16. */
13341 default:
13342 return FALSE;
13343 }
13344}
13345
13346/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13347 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13348
13349static bfd_boolean
13350is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13351{
13352 /* Please keep this table alpha-sorted for ease of visual lookup. */
13353 switch (filedata->file_header.e_machine)
13354 {
13355 case EM_RISCV:
13356 return reloc_type == 38; /* R_RISCV_SUB16. */
13357 default:
13358 return FALSE;
13359 }
13360}
13361
13362/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13363 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13364
13365static bfd_boolean
13366is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13367{
13368 /* Please keep this table alpha-sorted for ease of visual lookup. */
13369 switch (filedata->file_header.e_machine)
13370 {
13371 case EM_RISCV:
13372 return reloc_type == 33; /* R_RISCV_ADD8. */
13373 default:
13374 return FALSE;
13375 }
13376}
13377
13378/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13379 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13380
13381static bfd_boolean
13382is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13383{
13384 /* Please keep this table alpha-sorted for ease of visual lookup. */
13385 switch (filedata->file_header.e_machine)
13386 {
13387 case EM_RISCV:
13388 return reloc_type == 37; /* R_RISCV_SUB8. */
13389 default:
13390 return FALSE;
13391 }
13392}
13393
39e07931
AS
13394/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13395 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13396
13397static bfd_boolean
13398is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13399{
13400 switch (filedata->file_header.e_machine)
13401 {
13402 case EM_RISCV:
13403 return reloc_type == 52; /* R_RISCV_SUB6. */
13404 default:
13405 return FALSE;
13406 }
13407}
13408
2a7b2e88
JK
13409/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13410 relocation entries (possibly formerly used for SHT_GROUP sections). */
13411
13412static bfd_boolean
dda8d76d 13413is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13414{
dda8d76d 13415 switch (filedata->file_header.e_machine)
2a7b2e88 13416 {
cb8f3167 13417 case EM_386: /* R_386_NONE. */
d347c9df 13418 case EM_68K: /* R_68K_NONE. */
cfb8c092 13419 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13420 case EM_ALPHA: /* R_ALPHA_NONE. */
13421 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13422 case EM_ARC: /* R_ARC_NONE. */
886a2506 13423 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13424 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13425 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13426 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13427 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13428 case EM_FT32: /* R_FT32_NONE. */
13429 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13430 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13431 case EM_L1OM: /* R_X86_64_NONE. */
13432 case EM_M32R: /* R_M32R_NONE. */
13433 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13434 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13435 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13436 case EM_NIOS32: /* R_NIOS_NONE. */
13437 case EM_OR1K: /* R_OR1K_NONE. */
13438 case EM_PARISC: /* R_PARISC_NONE. */
13439 case EM_PPC64: /* R_PPC64_NONE. */
13440 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13441 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13442 case EM_S390: /* R_390_NONE. */
13443 case EM_S390_OLD:
13444 case EM_SH: /* R_SH_NONE. */
13445 case EM_SPARC32PLUS:
13446 case EM_SPARC: /* R_SPARC_NONE. */
13447 case EM_SPARCV9:
aa137e4d
NC
13448 case EM_TILEGX: /* R_TILEGX_NONE. */
13449 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13450 case EM_TI_C6000:/* R_C6000_NONE. */
13451 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13452 case EM_XC16X:
6655dba2 13453 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 13454 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13455 return reloc_type == 0;
d347c9df 13456
a06ea964
NC
13457 case EM_AARCH64:
13458 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13459 case EM_AVR_OLD:
13460 case EM_AVR:
13461 return (reloc_type == 0 /* R_AVR_NONE. */
13462 || reloc_type == 30 /* R_AVR_DIFF8. */
13463 || reloc_type == 31 /* R_AVR_DIFF16. */
13464 || reloc_type == 32 /* R_AVR_DIFF32. */);
13465 case EM_METAG:
13466 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13467 case EM_NDS32:
13468 return (reloc_type == 0 /* R_XTENSA_NONE. */
13469 || reloc_type == 204 /* R_NDS32_DIFF8. */
13470 || reloc_type == 205 /* R_NDS32_DIFF16. */
13471 || reloc_type == 206 /* R_NDS32_DIFF32. */
13472 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13473 case EM_TI_PRU:
13474 return (reloc_type == 0 /* R_PRU_NONE. */
13475 || reloc_type == 65 /* R_PRU_DIFF8. */
13476 || reloc_type == 66 /* R_PRU_DIFF16. */
13477 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13478 case EM_XTENSA_OLD:
13479 case EM_XTENSA:
4dc3c23d
AM
13480 return (reloc_type == 0 /* R_XTENSA_NONE. */
13481 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13482 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
13483 || reloc_type == 19 /* R_XTENSA_DIFF32. */
13484 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
13485 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
13486 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
13487 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
13488 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
13489 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88
JK
13490 }
13491 return FALSE;
13492}
13493
d1c4b12b
NC
13494/* Returns TRUE if there is a relocation against
13495 section NAME at OFFSET bytes. */
13496
13497bfd_boolean
13498reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13499{
13500 Elf_Internal_Rela * relocs;
13501 Elf_Internal_Rela * rp;
13502
13503 if (dsec == NULL || dsec->reloc_info == NULL)
13504 return FALSE;
13505
13506 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13507
13508 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13509 if (rp->r_offset == offset)
13510 return TRUE;
13511
13512 return FALSE;
13513}
13514
cf13d699 13515/* Apply relocations to a section.
32ec8896
NC
13516 Returns TRUE upon success, FALSE otherwise.
13517 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13518 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13519 will be set to the number of relocs loaded.
13520
cf13d699 13521 Note: So far support has been added only for those relocations
32ec8896
NC
13522 which can be found in debug sections. FIXME: Add support for
13523 more relocations ? */
1b315056 13524
32ec8896 13525static bfd_boolean
dda8d76d 13526apply_relocations (Filedata * filedata,
d1c4b12b
NC
13527 const Elf_Internal_Shdr * section,
13528 unsigned char * start,
13529 bfd_size_type size,
1449284b 13530 void ** relocs_return,
d1c4b12b 13531 unsigned long * num_relocs_return)
1b315056 13532{
cf13d699 13533 Elf_Internal_Shdr * relsec;
0d2a7a93 13534 unsigned char * end = start + size;
cb8f3167 13535
d1c4b12b
NC
13536 if (relocs_return != NULL)
13537 {
13538 * (Elf_Internal_Rela **) relocs_return = NULL;
13539 * num_relocs_return = 0;
13540 }
13541
dda8d76d 13542 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13543 /* No relocs to apply. */
13544 return TRUE;
1b315056 13545
cf13d699 13546 /* Find the reloc section associated with the section. */
dda8d76d
NC
13547 for (relsec = filedata->section_headers;
13548 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13549 ++relsec)
252b5132 13550 {
41e92641
NC
13551 bfd_boolean is_rela;
13552 unsigned long num_relocs;
2cf0635d
NC
13553 Elf_Internal_Rela * relocs;
13554 Elf_Internal_Rela * rp;
13555 Elf_Internal_Shdr * symsec;
13556 Elf_Internal_Sym * symtab;
ba5cdace 13557 unsigned long num_syms;
2cf0635d 13558 Elf_Internal_Sym * sym;
252b5132 13559
41e92641 13560 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13561 || relsec->sh_info >= filedata->file_header.e_shnum
13562 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13563 || relsec->sh_size == 0
dda8d76d 13564 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13565 continue;
428409d5 13566
a788aedd
AM
13567 symsec = filedata->section_headers + relsec->sh_link;
13568 if (symsec->sh_type != SHT_SYMTAB
13569 && symsec->sh_type != SHT_DYNSYM)
13570 return FALSE;
13571
41e92641
NC
13572 is_rela = relsec->sh_type == SHT_RELA;
13573
13574 if (is_rela)
13575 {
dda8d76d 13576 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13577 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13578 return FALSE;
41e92641
NC
13579 }
13580 else
13581 {
dda8d76d 13582 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13583 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13584 return FALSE;
41e92641
NC
13585 }
13586
13587 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13588 if (filedata->file_header.e_machine == EM_SH)
41e92641 13589 is_rela = FALSE;
428409d5 13590
dda8d76d 13591 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13592
41e92641 13593 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13594 {
41e92641
NC
13595 bfd_vma addend;
13596 unsigned int reloc_type;
13597 unsigned int reloc_size;
03336641
JW
13598 bfd_boolean reloc_inplace = FALSE;
13599 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13600 unsigned char * rloc;
ba5cdace 13601 unsigned long sym_index;
4b78141a 13602
dda8d76d 13603 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13604
dda8d76d 13605 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13606 continue;
dda8d76d 13607 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13608 continue;
dda8d76d
NC
13609 else if (is_32bit_abs_reloc (filedata, reloc_type)
13610 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13611 reloc_size = 4;
dda8d76d
NC
13612 else if (is_64bit_abs_reloc (filedata, reloc_type)
13613 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13614 reloc_size = 8;
dda8d76d 13615 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13616 reloc_size = 3;
dda8d76d 13617 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13618 reloc_size = 2;
39e07931
AS
13619 else if (is_8bit_abs_reloc (filedata, reloc_type)
13620 || is_6bit_abs_reloc (filedata, reloc_type))
13621 reloc_size = 1;
03336641
JW
13622 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13623 reloc_type))
13624 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13625 {
13626 reloc_size = 4;
13627 reloc_inplace = TRUE;
13628 }
13629 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13630 reloc_type))
13631 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13632 {
13633 reloc_size = 8;
13634 reloc_inplace = TRUE;
13635 }
13636 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13637 reloc_type))
13638 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13639 {
13640 reloc_size = 2;
13641 reloc_inplace = TRUE;
13642 }
13643 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13644 reloc_type))
13645 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13646 {
13647 reloc_size = 1;
13648 reloc_inplace = TRUE;
13649 }
39e07931
AS
13650 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13651 reloc_type)))
13652 {
13653 reloc_size = 1;
13654 reloc_inplace = TRUE;
13655 }
aca88567 13656 else
4b78141a 13657 {
bee0ee85 13658 static unsigned int prev_reloc = 0;
dda8d76d 13659
bee0ee85
NC
13660 if (reloc_type != prev_reloc)
13661 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13662 reloc_type, printable_section_name (filedata, section));
bee0ee85 13663 prev_reloc = reloc_type;
4b78141a
NC
13664 continue;
13665 }
103f02d3 13666
91d6fa6a 13667 rloc = start + rp->r_offset;
75802ccb 13668 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
13669 {
13670 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13671 (unsigned long) rp->r_offset,
dda8d76d 13672 printable_section_name (filedata, section));
700dd8b7
L
13673 continue;
13674 }
103f02d3 13675
ba5cdace
NC
13676 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13677 if (sym_index >= num_syms)
13678 {
13679 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13680 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
13681 continue;
13682 }
13683 sym = symtab + sym_index;
41e92641
NC
13684
13685 /* If the reloc has a symbol associated with it,
55f25fc3
L
13686 make sure that it is of an appropriate type.
13687
13688 Relocations against symbols without type can happen.
13689 Gcc -feliminate-dwarf2-dups may generate symbols
13690 without type for debug info.
13691
13692 Icc generates relocations against function symbols
13693 instead of local labels.
13694
13695 Relocations against object symbols can happen, eg when
13696 referencing a global array. For an example of this see
13697 the _clz.o binary in libgcc.a. */
aca88567 13698 if (sym != symtab
b8871f35 13699 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13700 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13701 {
d3a49aa8 13702 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13703 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13704 printable_section_name (filedata, relsec),
d3a49aa8 13705 (long int)(rp - relocs));
aca88567 13706 continue;
5b18a4bc 13707 }
252b5132 13708
4dc3c23d
AM
13709 addend = 0;
13710 if (is_rela)
13711 addend += rp->r_addend;
c47320c3
AM
13712 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13713 partial_inplace. */
4dc3c23d 13714 if (!is_rela
dda8d76d 13715 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13716 && reloc_type == 1)
dda8d76d
NC
13717 || ((filedata->file_header.e_machine == EM_PJ
13718 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13719 && reloc_type == 1)
dda8d76d
NC
13720 || ((filedata->file_header.e_machine == EM_D30V
13721 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13722 && reloc_type == 12)
13723 || reloc_inplace)
39e07931
AS
13724 {
13725 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
13726 addend += byte_get (rloc, reloc_size) & 0x3f;
13727 else
13728 addend += byte_get (rloc, reloc_size);
13729 }
cb8f3167 13730
dda8d76d
NC
13731 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13732 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13733 {
13734 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13735 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13736 addend -= 8;
91d6fa6a 13737 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13738 reloc_size);
13739 }
39e07931
AS
13740 else if (is_6bit_abs_reloc (filedata, reloc_type)
13741 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
13742 {
13743 if (reloc_subtract)
13744 addend -= sym->st_value;
13745 else
13746 addend += sym->st_value;
13747 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
13748 byte_put (rloc, addend, reloc_size);
13749 }
03336641
JW
13750 else if (reloc_subtract)
13751 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13752 else
91d6fa6a 13753 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13754 }
252b5132 13755
5b18a4bc 13756 free (symtab);
f84ce13b
NC
13757 /* Let the target specific reloc processing code know that
13758 we have finished with these relocs. */
dda8d76d 13759 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13760
13761 if (relocs_return)
13762 {
13763 * (Elf_Internal_Rela **) relocs_return = relocs;
13764 * num_relocs_return = num_relocs;
13765 }
13766 else
13767 free (relocs);
13768
5b18a4bc
NC
13769 break;
13770 }
32ec8896 13771
dfc616fa 13772 return TRUE;
5b18a4bc 13773}
103f02d3 13774
cf13d699 13775#ifdef SUPPORT_DISASSEMBLY
32ec8896 13776static bfd_boolean
dda8d76d 13777disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13778{
dda8d76d 13779 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13780
74e1a04b 13781 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13782
32ec8896 13783 return TRUE;
cf13d699
NC
13784}
13785#endif
13786
13787/* Reads in the contents of SECTION from FILE, returning a pointer
13788 to a malloc'ed buffer or NULL if something went wrong. */
13789
13790static char *
dda8d76d 13791get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13792{
dda8d76d 13793 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13794
13795 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13796 {
c6b78c96 13797 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13798 printable_section_name (filedata, section));
cf13d699
NC
13799 return NULL;
13800 }
13801
dda8d76d 13802 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13803 _("section contents"));
cf13d699
NC
13804}
13805
0e602686
NC
13806/* Uncompresses a section that was compressed using zlib, in place. */
13807
13808static bfd_boolean
dda8d76d
NC
13809uncompress_section_contents (unsigned char ** buffer,
13810 dwarf_size_type uncompressed_size,
13811 dwarf_size_type * size)
0e602686
NC
13812{
13813 dwarf_size_type compressed_size = *size;
13814 unsigned char * compressed_buffer = *buffer;
13815 unsigned char * uncompressed_buffer;
13816 z_stream strm;
13817 int rc;
13818
13819 /* It is possible the section consists of several compressed
13820 buffers concatenated together, so we uncompress in a loop. */
13821 /* PR 18313: The state field in the z_stream structure is supposed
13822 to be invisible to the user (ie us), but some compilers will
13823 still complain about it being used without initialisation. So
13824 we first zero the entire z_stream structure and then set the fields
13825 that we need. */
13826 memset (& strm, 0, sizeof strm);
13827 strm.avail_in = compressed_size;
13828 strm.next_in = (Bytef *) compressed_buffer;
13829 strm.avail_out = uncompressed_size;
13830 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13831
13832 rc = inflateInit (& strm);
13833 while (strm.avail_in > 0)
13834 {
13835 if (rc != Z_OK)
13836 goto fail;
13837 strm.next_out = ((Bytef *) uncompressed_buffer
13838 + (uncompressed_size - strm.avail_out));
13839 rc = inflate (&strm, Z_FINISH);
13840 if (rc != Z_STREAM_END)
13841 goto fail;
13842 rc = inflateReset (& strm);
13843 }
13844 rc = inflateEnd (& strm);
13845 if (rc != Z_OK
13846 || strm.avail_out != 0)
13847 goto fail;
13848
13849 *buffer = uncompressed_buffer;
13850 *size = uncompressed_size;
13851 return TRUE;
13852
13853 fail:
13854 free (uncompressed_buffer);
13855 /* Indicate decompression failure. */
13856 *buffer = NULL;
13857 return FALSE;
13858}
dd24e3da 13859
32ec8896 13860static bfd_boolean
dda8d76d 13861dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13862{
0e602686
NC
13863 Elf_Internal_Shdr * relsec;
13864 bfd_size_type num_bytes;
fd8008d8
L
13865 unsigned char * data;
13866 unsigned char * end;
13867 unsigned char * real_start;
13868 unsigned char * start;
0e602686 13869 bfd_boolean some_strings_shown;
cf13d699 13870
dda8d76d 13871 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13872 if (start == NULL)
c6b78c96
NC
13873 /* PR 21820: Do not fail if the section was empty. */
13874 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13875
0e602686 13876 num_bytes = section->sh_size;
cf13d699 13877
dda8d76d 13878 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13879
0e602686
NC
13880 if (decompress_dumps)
13881 {
13882 dwarf_size_type new_size = num_bytes;
13883 dwarf_size_type uncompressed_size = 0;
13884
13885 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13886 {
13887 Elf_Internal_Chdr chdr;
13888 unsigned int compression_header_size
ebdf1ebf
NC
13889 = get_compression_header (& chdr, (unsigned char *) start,
13890 num_bytes);
5844b465
NC
13891 if (compression_header_size == 0)
13892 /* An error message will have already been generated
13893 by get_compression_header. */
13894 goto error_out;
0e602686 13895
813dabb9 13896 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13897 {
813dabb9 13898 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13899 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 13900 goto error_out;
813dabb9 13901 }
813dabb9
L
13902 uncompressed_size = chdr.ch_size;
13903 start += compression_header_size;
13904 new_size -= compression_header_size;
0e602686
NC
13905 }
13906 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13907 {
13908 /* Read the zlib header. In this case, it should be "ZLIB"
13909 followed by the uncompressed section size, 8 bytes in
13910 big-endian order. */
13911 uncompressed_size = start[4]; uncompressed_size <<= 8;
13912 uncompressed_size += start[5]; uncompressed_size <<= 8;
13913 uncompressed_size += start[6]; uncompressed_size <<= 8;
13914 uncompressed_size += start[7]; uncompressed_size <<= 8;
13915 uncompressed_size += start[8]; uncompressed_size <<= 8;
13916 uncompressed_size += start[9]; uncompressed_size <<= 8;
13917 uncompressed_size += start[10]; uncompressed_size <<= 8;
13918 uncompressed_size += start[11];
13919 start += 12;
13920 new_size -= 12;
13921 }
13922
1835f746
NC
13923 if (uncompressed_size)
13924 {
13925 if (uncompress_section_contents (& start,
13926 uncompressed_size, & new_size))
13927 num_bytes = new_size;
13928 else
13929 {
13930 error (_("Unable to decompress section %s\n"),
dda8d76d 13931 printable_section_name (filedata, section));
f761cb13 13932 goto error_out;
1835f746
NC
13933 }
13934 }
bc303e5d
NC
13935 else
13936 start = real_start;
0e602686 13937 }
fd8008d8 13938
cf13d699
NC
13939 /* If the section being dumped has relocations against it the user might
13940 be expecting these relocations to have been applied. Check for this
13941 case and issue a warning message in order to avoid confusion.
13942 FIXME: Maybe we ought to have an option that dumps a section with
13943 relocs applied ? */
dda8d76d
NC
13944 for (relsec = filedata->section_headers;
13945 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13946 ++relsec)
13947 {
13948 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13949 || relsec->sh_info >= filedata->file_header.e_shnum
13950 || filedata->section_headers + relsec->sh_info != section
cf13d699 13951 || relsec->sh_size == 0
dda8d76d 13952 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13953 continue;
13954
13955 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13956 break;
13957 }
13958
cf13d699
NC
13959 data = start;
13960 end = start + num_bytes;
13961 some_strings_shown = FALSE;
13962
ba3265d0
NC
13963#ifdef HAVE_MBSTATE_T
13964 mbstate_t state;
13965 /* Initialise the multibyte conversion state. */
13966 memset (& state, 0, sizeof (state));
13967#endif
13968
13969 bfd_boolean continuing = FALSE;
13970
cf13d699
NC
13971 while (data < end)
13972 {
13973 while (!ISPRINT (* data))
13974 if (++ data >= end)
13975 break;
13976
13977 if (data < end)
13978 {
071436c6
NC
13979 size_t maxlen = end - data;
13980
ba3265d0
NC
13981 if (continuing)
13982 {
13983 printf (" ");
13984 continuing = FALSE;
13985 }
13986 else
13987 {
cf13d699 13988#ifndef __MSVCRT__
ba3265d0
NC
13989 /* PR 11128: Use two separate invocations in order to work
13990 around bugs in the Solaris 8 implementation of printf. */
13991 printf (" [%6tx] ", data - start);
cf13d699 13992#else
ba3265d0 13993 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 13994#endif
ba3265d0
NC
13995 }
13996
4082ef84
NC
13997 if (maxlen > 0)
13998 {
ba3265d0
NC
13999 char c;
14000
14001 while (maxlen)
14002 {
14003 c = *data++;
14004
14005 if (c == 0)
14006 break;
14007
14008 /* PR 25543: Treat new-lines as string-ending characters. */
14009 if (c == '\n')
14010 {
14011 printf ("\\n\n");
14012 if (*data != 0)
14013 continuing = TRUE;
14014 break;
14015 }
14016
14017 /* Do not print control characters directly as they can affect terminal
14018 settings. Such characters usually appear in the names generated
14019 by the assembler for local labels. */
14020 if (ISCNTRL (c))
14021 {
14022 printf ("^%c", c + 0x40);
14023 }
14024 else if (ISPRINT (c))
14025 {
14026 putchar (c);
14027 }
14028 else
14029 {
14030 size_t n;
14031#ifdef HAVE_MBSTATE_T
14032 wchar_t w;
14033#endif
14034 /* Let printf do the hard work of displaying multibyte characters. */
14035 printf ("%.1s", data - 1);
14036#ifdef HAVE_MBSTATE_T
14037 /* Try to find out how many bytes made up the character that was
14038 just printed. Advance the symbol pointer past the bytes that
14039 were displayed. */
14040 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14041#else
14042 n = 1;
14043#endif
14044 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14045 data += (n - 1);
14046 }
14047 }
14048
14049 if (c != '\n')
14050 putchar ('\n');
4082ef84
NC
14051 }
14052 else
14053 {
14054 printf (_("<corrupt>\n"));
14055 data = end;
14056 }
cf13d699
NC
14057 some_strings_shown = TRUE;
14058 }
14059 }
14060
14061 if (! some_strings_shown)
14062 printf (_(" No strings found in this section."));
14063
0e602686 14064 free (real_start);
cf13d699
NC
14065
14066 putchar ('\n');
32ec8896 14067 return TRUE;
f761cb13
AM
14068
14069error_out:
14070 free (real_start);
14071 return FALSE;
cf13d699
NC
14072}
14073
32ec8896 14074static bfd_boolean
dda8d76d
NC
14075dump_section_as_bytes (Elf_Internal_Shdr * section,
14076 Filedata * filedata,
14077 bfd_boolean relocate)
cf13d699
NC
14078{
14079 Elf_Internal_Shdr * relsec;
0e602686
NC
14080 bfd_size_type bytes;
14081 bfd_size_type section_size;
14082 bfd_vma addr;
14083 unsigned char * data;
14084 unsigned char * real_start;
14085 unsigned char * start;
14086
dda8d76d 14087 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14088 if (start == NULL)
c6b78c96
NC
14089 /* PR 21820: Do not fail if the section was empty. */
14090 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 14091
0e602686 14092 section_size = section->sh_size;
cf13d699 14093
dda8d76d 14094 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14095
0e602686
NC
14096 if (decompress_dumps)
14097 {
14098 dwarf_size_type new_size = section_size;
14099 dwarf_size_type uncompressed_size = 0;
14100
14101 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14102 {
14103 Elf_Internal_Chdr chdr;
14104 unsigned int compression_header_size
ebdf1ebf 14105 = get_compression_header (& chdr, start, section_size);
0e602686 14106
5844b465
NC
14107 if (compression_header_size == 0)
14108 /* An error message will have already been generated
14109 by get_compression_header. */
14110 goto error_out;
14111
813dabb9 14112 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14113 {
813dabb9 14114 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14115 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14116 goto error_out;
0e602686 14117 }
813dabb9
L
14118 uncompressed_size = chdr.ch_size;
14119 start += compression_header_size;
14120 new_size -= compression_header_size;
0e602686
NC
14121 }
14122 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14123 {
14124 /* Read the zlib header. In this case, it should be "ZLIB"
14125 followed by the uncompressed section size, 8 bytes in
14126 big-endian order. */
14127 uncompressed_size = start[4]; uncompressed_size <<= 8;
14128 uncompressed_size += start[5]; uncompressed_size <<= 8;
14129 uncompressed_size += start[6]; uncompressed_size <<= 8;
14130 uncompressed_size += start[7]; uncompressed_size <<= 8;
14131 uncompressed_size += start[8]; uncompressed_size <<= 8;
14132 uncompressed_size += start[9]; uncompressed_size <<= 8;
14133 uncompressed_size += start[10]; uncompressed_size <<= 8;
14134 uncompressed_size += start[11];
14135 start += 12;
14136 new_size -= 12;
14137 }
14138
f055032e
NC
14139 if (uncompressed_size)
14140 {
14141 if (uncompress_section_contents (& start, uncompressed_size,
14142 & new_size))
bc303e5d
NC
14143 {
14144 section_size = new_size;
14145 }
f055032e
NC
14146 else
14147 {
14148 error (_("Unable to decompress section %s\n"),
dda8d76d 14149 printable_section_name (filedata, section));
bc303e5d 14150 /* FIXME: Print the section anyway ? */
f761cb13 14151 goto error_out;
f055032e
NC
14152 }
14153 }
bc303e5d
NC
14154 else
14155 start = real_start;
0e602686 14156 }
14ae95f2 14157
cf13d699
NC
14158 if (relocate)
14159 {
dda8d76d 14160 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14161 goto error_out;
cf13d699
NC
14162 }
14163 else
14164 {
14165 /* If the section being dumped has relocations against it the user might
14166 be expecting these relocations to have been applied. Check for this
14167 case and issue a warning message in order to avoid confusion.
14168 FIXME: Maybe we ought to have an option that dumps a section with
14169 relocs applied ? */
dda8d76d
NC
14170 for (relsec = filedata->section_headers;
14171 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14172 ++relsec)
14173 {
14174 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14175 || relsec->sh_info >= filedata->file_header.e_shnum
14176 || filedata->section_headers + relsec->sh_info != section
cf13d699 14177 || relsec->sh_size == 0
dda8d76d 14178 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14179 continue;
14180
14181 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14182 break;
14183 }
14184 }
14185
14186 addr = section->sh_addr;
0e602686 14187 bytes = section_size;
cf13d699
NC
14188 data = start;
14189
14190 while (bytes)
14191 {
14192 int j;
14193 int k;
14194 int lbytes;
14195
14196 lbytes = (bytes > 16 ? 16 : bytes);
14197
14198 printf (" 0x%8.8lx ", (unsigned long) addr);
14199
14200 for (j = 0; j < 16; j++)
14201 {
14202 if (j < lbytes)
14203 printf ("%2.2x", data[j]);
14204 else
14205 printf (" ");
14206
14207 if ((j & 3) == 3)
14208 printf (" ");
14209 }
14210
14211 for (j = 0; j < lbytes; j++)
14212 {
14213 k = data[j];
14214 if (k >= ' ' && k < 0x7f)
14215 printf ("%c", k);
14216 else
14217 printf (".");
14218 }
14219
14220 putchar ('\n');
14221
14222 data += lbytes;
14223 addr += lbytes;
14224 bytes -= lbytes;
14225 }
14226
0e602686 14227 free (real_start);
cf13d699
NC
14228
14229 putchar ('\n');
32ec8896 14230 return TRUE;
f761cb13
AM
14231
14232 error_out:
14233 free (real_start);
14234 return FALSE;
cf13d699
NC
14235}
14236
094e34f2 14237#ifdef ENABLE_LIBCTF
7d9813f1
NA
14238static ctf_sect_t *
14239shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14240{
90bd5423 14241 buf->cts_name = SECTION_NAME (shdr);
7d9813f1
NA
14242 buf->cts_size = shdr->sh_size;
14243 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14244
14245 return buf;
14246}
14247
14248/* Formatting callback function passed to ctf_dump. Returns either the pointer
14249 it is passed, or a pointer to newly-allocated storage, in which case
14250 dump_ctf() will free it when it no longer needs it. */
14251
2f6ecaed
NA
14252static char *
14253dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14254 char *s, void *arg)
7d9813f1 14255{
3e50a591 14256 const char *blanks = arg;
7d9813f1
NA
14257 char *new_s;
14258
3e50a591 14259 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14260 return s;
14261 return new_s;
14262}
14263
2f6ecaed
NA
14264/* Dump one CTF archive member. */
14265
14266static int
14267dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
14268{
14269 ctf_file_t *parent = (ctf_file_t *) arg;
14270 const char *things[] = {"Header", "Labels", "Data objects",
14271 "Function objects", "Variables", "Types", "Strings",
14272 ""};
14273 const char **thing;
8b37e7b6
NA
14274 ctf_next_t *it = NULL;
14275 char *errtext;
14276 int is_warning;
2f6ecaed 14277 size_t i;
8b37e7b6 14278 int err = 0;
2f6ecaed
NA
14279
14280 /* Only print out the name of non-default-named archive members.
14281 The name .ctf appears everywhere, even for things that aren't
14282 really archives, so printing it out is liable to be confusing.
14283
14284 The parent, if there is one, is the default-owned archive member:
14285 avoid importing it into itself. (This does no harm, but looks
14286 confusing.) */
14287
14288 if (strcmp (name, ".ctf") != 0)
14289 {
14290 printf (_("\nCTF archive member: %s:\n"), name);
14291 ctf_import (ctf, parent);
14292 }
14293
14294 for (i = 0, thing = things; *thing[0]; thing++, i++)
14295 {
14296 ctf_dump_state_t *s = NULL;
14297 char *item;
14298
14299 printf ("\n %s:\n", *thing);
14300 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14301 (void *) " ")) != NULL)
14302 {
14303 printf ("%s\n", item);
14304 free (item);
14305 }
14306
14307 if (ctf_errno (ctf))
14308 {
14309 error (_("Iteration failed: %s, %s\n"), *thing,
14310 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
14311 err = 1;
14312 goto out;
2f6ecaed
NA
14313 }
14314 }
8b37e7b6
NA
14315
14316 out:
14317 /* Dump accumulated errors and warnings. */
14318 while ((errtext = ctf_errwarning_next (ctf, &it, &is_warning)) != NULL)
14319 {
14320 error (_("%s: `%s'\n"), is_warning ? _("warning"): _("error"),
14321 errtext);
14322 free (errtext);
14323 }
14324 if (ctf_errno (ctf) != ECTF_NEXT_END)
14325 {
14326 error (_("CTF error: cannot get CTF errors: `%s'\n"),
14327 ctf_errmsg (ctf_errno (ctf)));
14328 }
14329 return err;
2f6ecaed
NA
14330}
14331
7d9813f1
NA
14332static bfd_boolean
14333dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14334{
14335 Elf_Internal_Shdr * parent_sec = NULL;
14336 Elf_Internal_Shdr * symtab_sec = NULL;
14337 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14338 void * data = NULL;
14339 void * symdata = NULL;
14340 void * strdata = NULL;
14341 void * parentdata = NULL;
14342 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14343 ctf_sect_t * symsectp = NULL;
14344 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
14345 ctf_archive_t * ctfa = NULL;
14346 ctf_archive_t * parenta = NULL, *lookparent;
14347 ctf_file_t * parent = NULL;
7d9813f1 14348
7d9813f1
NA
14349 int err;
14350 bfd_boolean ret = FALSE;
7d9813f1
NA
14351
14352 shdr_to_ctf_sect (&ctfsect, section, filedata);
14353 data = get_section_contents (section, filedata);
14354 ctfsect.cts_data = data;
14355
616febde
NA
14356 if (!dump_ctf_symtab_name)
14357 dump_ctf_symtab_name = strdup (".symtab");
14358
14359 if (!dump_ctf_strtab_name)
14360 dump_ctf_strtab_name = strdup (".strtab");
14361
14362 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14363 {
14364 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14365 {
14366 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14367 goto fail;
14368 }
14369 if ((symdata = (void *) get_data (NULL, filedata,
14370 symtab_sec->sh_offset, 1,
14371 symtab_sec->sh_size,
14372 _("symbols"))) == NULL)
14373 goto fail;
14374 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14375 symsect.cts_data = symdata;
14376 }
df16e041 14377 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
14378 {
14379 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14380 {
14381 error (_("No string table section named %s\n"),
14382 dump_ctf_strtab_name);
14383 goto fail;
14384 }
14385 if ((strdata = (void *) get_data (NULL, filedata,
14386 strtab_sec->sh_offset, 1,
14387 strtab_sec->sh_size,
14388 _("strings"))) == NULL)
14389 goto fail;
14390 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14391 strsect.cts_data = strdata;
14392 }
14393 if (dump_ctf_parent_name)
14394 {
14395 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14396 {
14397 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14398 goto fail;
14399 }
14400 if ((parentdata = (void *) get_data (NULL, filedata,
14401 parent_sec->sh_offset, 1,
14402 parent_sec->sh_size,
14403 _("CTF parent"))) == NULL)
14404 goto fail;
14405 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14406 parentsect.cts_data = parentdata;
14407 }
14408
2f6ecaed
NA
14409 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
14410 libctf papers over the difference, so we can pretend it is always an
14411 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 14412
2f6ecaed 14413 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1
NA
14414 {
14415 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14416 goto fail;
14417 }
14418
14419 if (parentdata)
14420 {
2f6ecaed
NA
14421 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
14422 &err)) == NULL)
7d9813f1
NA
14423 {
14424 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14425 goto fail;
14426 }
2f6ecaed
NA
14427 lookparent = parenta;
14428 }
14429 else
14430 lookparent = ctfa;
7d9813f1 14431
2f6ecaed
NA
14432 /* Assume that the applicable parent archive member is the default one.
14433 (This is what all known implementations are expected to do, if they
14434 put CTFs and their parents in archives together.) */
14435 if ((parent = ctf_arc_open_by_name (lookparent, NULL, &err)) == NULL)
14436 {
14437 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14438 goto fail;
7d9813f1
NA
14439 }
14440
14441 ret = TRUE;
14442
14443 printf (_("\nDump of CTF section '%s':\n"),
14444 printable_section_name (filedata, section));
14445
2f6ecaed
NA
14446 if (ctf_archive_iter (ctfa, dump_ctf_archive_member, parent) != 0)
14447 ret = FALSE;
7d9813f1
NA
14448
14449 fail:
7d9813f1 14450 ctf_file_close (parent);
2f6ecaed
NA
14451 ctf_close (ctfa);
14452 ctf_close (parenta);
7d9813f1
NA
14453 free (parentdata);
14454 free (data);
14455 free (symdata);
14456 free (strdata);
14457 return ret;
14458}
094e34f2 14459#endif
7d9813f1 14460
32ec8896 14461static bfd_boolean
dda8d76d
NC
14462load_specific_debug_section (enum dwarf_section_display_enum debug,
14463 const Elf_Internal_Shdr * sec,
14464 void * data)
1007acb3 14465{
2cf0635d 14466 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 14467 char buf [64];
dda8d76d 14468 Filedata * filedata = (Filedata *) data;
9abca702 14469
19e6b90e 14470 if (section->start != NULL)
dda8d76d
NC
14471 {
14472 /* If it is already loaded, do nothing. */
14473 if (streq (section->filename, filedata->file_name))
14474 return TRUE;
14475 free (section->start);
14476 }
1007acb3 14477
19e6b90e
L
14478 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
14479 section->address = sec->sh_addr;
06614111 14480 section->user_data = NULL;
dda8d76d
NC
14481 section->filename = filedata->file_name;
14482 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
14483 sec->sh_offset, 1,
14484 sec->sh_size, buf);
59245841
NC
14485 if (section->start == NULL)
14486 section->size = 0;
14487 else
14488 {
77115a4a
L
14489 unsigned char *start = section->start;
14490 dwarf_size_type size = sec->sh_size;
dab394de 14491 dwarf_size_type uncompressed_size = 0;
77115a4a
L
14492
14493 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
14494 {
14495 Elf_Internal_Chdr chdr;
d8024a91
NC
14496 unsigned int compression_header_size;
14497
f53be977
L
14498 if (size < (is_32bit_elf
14499 ? sizeof (Elf32_External_Chdr)
14500 : sizeof (Elf64_External_Chdr)))
d8024a91 14501 {
55be8fd0 14502 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 14503 section->name);
32ec8896 14504 return FALSE;
d8024a91
NC
14505 }
14506
ebdf1ebf 14507 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
14508 if (compression_header_size == 0)
14509 /* An error message will have already been generated
14510 by get_compression_header. */
14511 return FALSE;
d8024a91 14512
813dabb9
L
14513 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
14514 {
14515 warn (_("section '%s' has unsupported compress type: %d\n"),
14516 section->name, chdr.ch_type);
32ec8896 14517 return FALSE;
813dabb9 14518 }
dab394de 14519 uncompressed_size = chdr.ch_size;
77115a4a
L
14520 start += compression_header_size;
14521 size -= compression_header_size;
14522 }
dab394de
L
14523 else if (size > 12 && streq ((char *) start, "ZLIB"))
14524 {
14525 /* Read the zlib header. In this case, it should be "ZLIB"
14526 followed by the uncompressed section size, 8 bytes in
14527 big-endian order. */
14528 uncompressed_size = start[4]; uncompressed_size <<= 8;
14529 uncompressed_size += start[5]; uncompressed_size <<= 8;
14530 uncompressed_size += start[6]; uncompressed_size <<= 8;
14531 uncompressed_size += start[7]; uncompressed_size <<= 8;
14532 uncompressed_size += start[8]; uncompressed_size <<= 8;
14533 uncompressed_size += start[9]; uncompressed_size <<= 8;
14534 uncompressed_size += start[10]; uncompressed_size <<= 8;
14535 uncompressed_size += start[11];
14536 start += 12;
14537 size -= 12;
14538 }
14539
1835f746 14540 if (uncompressed_size)
77115a4a 14541 {
1835f746
NC
14542 if (uncompress_section_contents (&start, uncompressed_size,
14543 &size))
14544 {
14545 /* Free the compressed buffer, update the section buffer
14546 and the section size if uncompress is successful. */
14547 free (section->start);
14548 section->start = start;
14549 }
14550 else
14551 {
14552 error (_("Unable to decompress section %s\n"),
dda8d76d 14553 printable_section_name (filedata, sec));
32ec8896 14554 return FALSE;
1835f746 14555 }
77115a4a 14556 }
bc303e5d 14557
77115a4a 14558 section->size = size;
59245841 14559 }
4a114e3e 14560
1b315056 14561 if (section->start == NULL)
32ec8896 14562 return FALSE;
1b315056 14563
19e6b90e 14564 if (debug_displays [debug].relocate)
32ec8896 14565 {
dda8d76d 14566 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
14567 & section->reloc_info, & section->num_relocs))
14568 return FALSE;
14569 }
d1c4b12b
NC
14570 else
14571 {
14572 section->reloc_info = NULL;
14573 section->num_relocs = 0;
14574 }
1007acb3 14575
32ec8896 14576 return TRUE;
1007acb3
L
14577}
14578
301a9420
AM
14579#if HAVE_LIBDEBUGINFOD
14580/* Return a hex string representation of the build-id. */
14581unsigned char *
14582get_build_id (void * data)
14583{
14584 Filedata * filedata = (Filedata *)data;
14585 Elf_Internal_Shdr * shdr;
14586 unsigned long i;
14587
55be8fd0
NC
14588 /* Iterate through notes to find note.gnu.build-id.
14589 FIXME: Only the first note in any note section is examined. */
301a9420
AM
14590 for (i = 0, shdr = filedata->section_headers;
14591 i < filedata->file_header.e_shnum && shdr != NULL;
14592 i++, shdr++)
14593 {
14594 if (shdr->sh_type != SHT_NOTE)
14595 continue;
14596
14597 char * next;
14598 char * end;
14599 size_t data_remaining;
14600 size_t min_notesz;
14601 Elf_External_Note * enote;
14602 Elf_Internal_Note inote;
14603
14604 bfd_vma offset = shdr->sh_offset;
14605 bfd_vma align = shdr->sh_addralign;
14606 bfd_vma length = shdr->sh_size;
14607
14608 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
14609 if (enote == NULL)
14610 continue;
14611
14612 if (align < 4)
14613 align = 4;
14614 else if (align != 4 && align != 8)
f761cb13
AM
14615 {
14616 free (enote);
14617 continue;
14618 }
301a9420
AM
14619
14620 end = (char *) enote + length;
14621 data_remaining = end - (char *) enote;
14622
14623 if (!is_ia64_vms (filedata))
14624 {
14625 min_notesz = offsetof (Elf_External_Note, name);
14626 if (data_remaining < min_notesz)
14627 {
55be8fd0
NC
14628 warn (_("\
14629malformed note encountered in section %s whilst scanning for build-id note\n"),
14630 printable_section_name (filedata, shdr));
f761cb13 14631 free (enote);
55be8fd0 14632 continue;
301a9420
AM
14633 }
14634 data_remaining -= min_notesz;
14635
14636 inote.type = BYTE_GET (enote->type);
14637 inote.namesz = BYTE_GET (enote->namesz);
14638 inote.namedata = enote->name;
14639 inote.descsz = BYTE_GET (enote->descsz);
14640 inote.descdata = ((char *) enote
14641 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
14642 inote.descpos = offset + (inote.descdata - (char *) enote);
14643 next = ((char *) enote
14644 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
14645 }
14646 else
14647 {
14648 Elf64_External_VMS_Note *vms_enote;
14649
14650 /* PR binutils/15191
14651 Make sure that there is enough data to read. */
14652 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14653 if (data_remaining < min_notesz)
14654 {
55be8fd0
NC
14655 warn (_("\
14656malformed note encountered in section %s whilst scanning for build-id note\n"),
14657 printable_section_name (filedata, shdr));
f761cb13 14658 free (enote);
55be8fd0 14659 continue;
301a9420
AM
14660 }
14661 data_remaining -= min_notesz;
14662
14663 vms_enote = (Elf64_External_VMS_Note *) enote;
14664 inote.type = BYTE_GET (vms_enote->type);
14665 inote.namesz = BYTE_GET (vms_enote->namesz);
14666 inote.namedata = vms_enote->name;
14667 inote.descsz = BYTE_GET (vms_enote->descsz);
14668 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14669 inote.descpos = offset + (inote.descdata - (char *) enote);
14670 next = inote.descdata + align_power (inote.descsz, 3);
14671 }
14672
14673 /* Skip malformed notes. */
14674 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
14675 || (size_t) (inote.descdata - inote.namedata) > data_remaining
14676 || (size_t) (next - inote.descdata) < inote.descsz
14677 || ((size_t) (next - inote.descdata)
14678 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
14679 {
55be8fd0
NC
14680 warn (_("\
14681malformed note encountered in section %s whilst scanning for build-id note\n"),
14682 printable_section_name (filedata, shdr));
f761cb13 14683 free (enote);
301a9420
AM
14684 continue;
14685 }
14686
14687 /* Check if this is the build-id note. If so then convert the build-id
14688 bytes to a hex string. */
14689 if (inote.namesz > 0
14690 && const_strneq (inote.namedata, "GNU")
14691 && inote.type == NT_GNU_BUILD_ID)
14692 {
14693 unsigned long j;
14694 char * build_id;
14695
14696 build_id = malloc (inote.descsz * 2 + 1);
14697 if (build_id == NULL)
f761cb13
AM
14698 {
14699 free (enote);
14700 return NULL;
14701 }
301a9420
AM
14702
14703 for (j = 0; j < inote.descsz; ++j)
14704 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
14705 build_id[inote.descsz * 2] = '\0';
f761cb13 14706 free (enote);
301a9420 14707
55be8fd0 14708 return (unsigned char *) build_id;
301a9420 14709 }
f761cb13 14710 free (enote);
301a9420
AM
14711 }
14712
14713 return NULL;
14714}
14715#endif /* HAVE_LIBDEBUGINFOD */
14716
657d0d47
CC
14717/* If this is not NULL, load_debug_section will only look for sections
14718 within the list of sections given here. */
32ec8896 14719static unsigned int * section_subset = NULL;
657d0d47 14720
32ec8896 14721bfd_boolean
dda8d76d 14722load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 14723{
2cf0635d
NC
14724 struct dwarf_section * section = &debug_displays [debug].section;
14725 Elf_Internal_Shdr * sec;
dda8d76d
NC
14726 Filedata * filedata = (Filedata *) data;
14727
f425ec66
NC
14728 /* Without section headers we cannot find any sections. */
14729 if (filedata->section_headers == NULL)
14730 return FALSE;
14731
9c1ce108
AM
14732 if (filedata->string_table == NULL
14733 && filedata->file_header.e_shstrndx != SHN_UNDEF
14734 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
14735 {
14736 Elf_Internal_Shdr * strs;
14737
14738 /* Read in the string table, so that we have section names to scan. */
14739 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
14740
4dff97b2 14741 if (strs != NULL && strs->sh_size != 0)
dda8d76d 14742 {
9c1ce108
AM
14743 filedata->string_table
14744 = (char *) get_data (NULL, filedata, strs->sh_offset,
14745 1, strs->sh_size, _("string table"));
dda8d76d 14746
9c1ce108
AM
14747 filedata->string_table_length
14748 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
14749 }
14750 }
d966045b
DJ
14751
14752 /* Locate the debug section. */
dda8d76d 14753 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
14754 if (sec != NULL)
14755 section->name = section->uncompressed_name;
14756 else
14757 {
dda8d76d 14758 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
14759 if (sec != NULL)
14760 section->name = section->compressed_name;
14761 }
14762 if (sec == NULL)
32ec8896 14763 return FALSE;
d966045b 14764
657d0d47
CC
14765 /* If we're loading from a subset of sections, and we've loaded
14766 a section matching this name before, it's likely that it's a
14767 different one. */
14768 if (section_subset != NULL)
14769 free_debug_section (debug);
14770
dda8d76d 14771 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
14772}
14773
19e6b90e
L
14774void
14775free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 14776{
2cf0635d 14777 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 14778
19e6b90e
L
14779 if (section->start == NULL)
14780 return;
1007acb3 14781
19e6b90e
L
14782 free ((char *) section->start);
14783 section->start = NULL;
14784 section->address = 0;
14785 section->size = 0;
a788aedd 14786
9db70fc3
AM
14787 free (section->reloc_info);
14788 section->reloc_info = NULL;
14789 section->num_relocs = 0;
1007acb3
L
14790}
14791
32ec8896 14792static bfd_boolean
dda8d76d 14793display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 14794{
2cf0635d 14795 char * name = SECTION_NAME (section);
dda8d76d 14796 const char * print_name = printable_section_name (filedata, section);
19e6b90e 14797 bfd_size_type length;
32ec8896 14798 bfd_boolean result = TRUE;
3f5e193b 14799 int i;
1007acb3 14800
19e6b90e
L
14801 length = section->sh_size;
14802 if (length == 0)
1007acb3 14803 {
74e1a04b 14804 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 14805 return TRUE;
1007acb3 14806 }
5dff79d8
NC
14807 if (section->sh_type == SHT_NOBITS)
14808 {
14809 /* There is no point in dumping the contents of a debugging section
14810 which has the NOBITS type - the bits in the file will be random.
14811 This can happen when a file containing a .eh_frame section is
14812 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
14813 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
14814 print_name);
32ec8896 14815 return FALSE;
5dff79d8 14816 }
1007acb3 14817
0112cd26 14818 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 14819 name = ".debug_info";
1007acb3 14820
19e6b90e
L
14821 /* See if we know how to display the contents of this section. */
14822 for (i = 0; i < max; i++)
d85bf2ba
NC
14823 {
14824 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
14825 struct dwarf_section_display * display = debug_displays + i;
14826 struct dwarf_section * sec = & display->section;
d966045b 14827
d85bf2ba
NC
14828 if (streq (sec->uncompressed_name, name)
14829 || (id == line && const_strneq (name, ".debug_line."))
14830 || streq (sec->compressed_name, name))
14831 {
14832 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 14833
d85bf2ba
NC
14834 if (secondary)
14835 free_debug_section (id);
dda8d76d 14836
d85bf2ba
NC
14837 if (i == line && const_strneq (name, ".debug_line."))
14838 sec->name = name;
14839 else if (streq (sec->uncompressed_name, name))
14840 sec->name = sec->uncompressed_name;
14841 else
14842 sec->name = sec->compressed_name;
657d0d47 14843
d85bf2ba
NC
14844 if (load_specific_debug_section (id, section, filedata))
14845 {
14846 /* If this debug section is part of a CU/TU set in a .dwp file,
14847 restrict load_debug_section to the sections in that set. */
14848 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 14849
d85bf2ba 14850 result &= display->display (sec, filedata);
657d0d47 14851
d85bf2ba 14852 section_subset = NULL;
1007acb3 14853
d85bf2ba
NC
14854 if (secondary || (id != info && id != abbrev))
14855 free_debug_section (id);
14856 }
14857 break;
14858 }
14859 }
1007acb3 14860
19e6b90e 14861 if (i == max)
1007acb3 14862 {
74e1a04b 14863 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 14864 result = FALSE;
1007acb3
L
14865 }
14866
19e6b90e 14867 return result;
5b18a4bc 14868}
103f02d3 14869
aef1f6d0
DJ
14870/* Set DUMP_SECTS for all sections where dumps were requested
14871 based on section name. */
14872
14873static void
dda8d76d 14874initialise_dumps_byname (Filedata * filedata)
aef1f6d0 14875{
2cf0635d 14876 struct dump_list_entry * cur;
aef1f6d0
DJ
14877
14878 for (cur = dump_sects_byname; cur; cur = cur->next)
14879 {
14880 unsigned int i;
32ec8896 14881 bfd_boolean any = FALSE;
aef1f6d0 14882
dda8d76d
NC
14883 for (i = 0; i < filedata->file_header.e_shnum; i++)
14884 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 14885 {
6431e409 14886 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 14887 any = TRUE;
aef1f6d0
DJ
14888 }
14889
14890 if (!any)
14891 warn (_("Section '%s' was not dumped because it does not exist!\n"),
14892 cur->name);
14893 }
14894}
14895
32ec8896 14896static bfd_boolean
dda8d76d 14897process_section_contents (Filedata * filedata)
5b18a4bc 14898{
2cf0635d 14899 Elf_Internal_Shdr * section;
19e6b90e 14900 unsigned int i;
32ec8896 14901 bfd_boolean res = TRUE;
103f02d3 14902
19e6b90e 14903 if (! do_dump)
32ec8896 14904 return TRUE;
103f02d3 14905
dda8d76d 14906 initialise_dumps_byname (filedata);
aef1f6d0 14907
dda8d76d 14908 for (i = 0, section = filedata->section_headers;
6431e409 14909 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
14910 i++, section++)
14911 {
6431e409 14912 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 14913
19e6b90e 14914#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
14915 if (dump & DISASS_DUMP)
14916 {
14917 if (! disassemble_section (section, filedata))
14918 res = FALSE;
14919 }
19e6b90e 14920#endif
dda8d76d 14921 if (dump & HEX_DUMP)
32ec8896 14922 {
dda8d76d 14923 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
14924 res = FALSE;
14925 }
103f02d3 14926
dda8d76d 14927 if (dump & RELOC_DUMP)
32ec8896 14928 {
dda8d76d 14929 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
14930 res = FALSE;
14931 }
09c11c86 14932
dda8d76d 14933 if (dump & STRING_DUMP)
32ec8896 14934 {
dda8d76d 14935 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
14936 res = FALSE;
14937 }
cf13d699 14938
dda8d76d 14939 if (dump & DEBUG_DUMP)
32ec8896 14940 {
dda8d76d 14941 if (! display_debug_section (i, section, filedata))
32ec8896
NC
14942 res = FALSE;
14943 }
7d9813f1 14944
094e34f2 14945#ifdef ENABLE_LIBCTF
7d9813f1
NA
14946 if (dump & CTF_DUMP)
14947 {
14948 if (! dump_section_as_ctf (section, filedata))
14949 res = FALSE;
14950 }
094e34f2 14951#endif
5b18a4bc 14952 }
103f02d3 14953
19e6b90e
L
14954 /* Check to see if the user requested a
14955 dump of a section that does not exist. */
6431e409 14956 while (i < filedata->dump.num_dump_sects)
0ee3043f 14957 {
6431e409 14958 if (filedata->dump.dump_sects[i])
32ec8896
NC
14959 {
14960 warn (_("Section %d was not dumped because it does not exist!\n"), i);
14961 res = FALSE;
14962 }
0ee3043f
NC
14963 i++;
14964 }
32ec8896
NC
14965
14966 return res;
5b18a4bc 14967}
103f02d3 14968
5b18a4bc 14969static void
19e6b90e 14970process_mips_fpe_exception (int mask)
5b18a4bc 14971{
19e6b90e
L
14972 if (mask)
14973 {
32ec8896
NC
14974 bfd_boolean first = TRUE;
14975
19e6b90e 14976 if (mask & OEX_FPU_INEX)
32ec8896 14977 fputs ("INEX", stdout), first = FALSE;
19e6b90e 14978 if (mask & OEX_FPU_UFLO)
32ec8896 14979 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14980 if (mask & OEX_FPU_OFLO)
32ec8896 14981 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14982 if (mask & OEX_FPU_DIV0)
32ec8896 14983 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
14984 if (mask & OEX_FPU_INVAL)
14985 printf ("%sINVAL", first ? "" : "|");
14986 }
5b18a4bc 14987 else
19e6b90e 14988 fputs ("0", stdout);
5b18a4bc 14989}
103f02d3 14990
f6f0e17b
NC
14991/* Display's the value of TAG at location P. If TAG is
14992 greater than 0 it is assumed to be an unknown tag, and
14993 a message is printed to this effect. Otherwise it is
14994 assumed that a message has already been printed.
14995
14996 If the bottom bit of TAG is set it assumed to have a
14997 string value, otherwise it is assumed to have an integer
14998 value.
14999
15000 Returns an updated P pointing to the first unread byte
15001 beyond the end of TAG's value.
15002
15003 Reads at or beyond END will not be made. */
15004
15005static unsigned char *
60abdbed 15006display_tag_value (signed int tag,
f6f0e17b
NC
15007 unsigned char * p,
15008 const unsigned char * const end)
15009{
15010 unsigned long val;
15011
15012 if (tag > 0)
15013 printf (" Tag_unknown_%d: ", tag);
15014
15015 if (p >= end)
15016 {
4082ef84 15017 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15018 }
15019 else if (tag & 1)
15020 {
071436c6
NC
15021 /* PR 17531 file: 027-19978-0.004. */
15022 size_t maxlen = (end - p) - 1;
15023
15024 putchar ('"');
4082ef84
NC
15025 if (maxlen > 0)
15026 {
15027 print_symbol ((int) maxlen, (const char *) p);
15028 p += strnlen ((char *) p, maxlen) + 1;
15029 }
15030 else
15031 {
15032 printf (_("<corrupt string tag>"));
15033 p = (unsigned char *) end;
15034 }
071436c6 15035 printf ("\"\n");
f6f0e17b
NC
15036 }
15037 else
15038 {
cd30bcef 15039 READ_ULEB (val, p, end);
f6f0e17b
NC
15040 printf ("%ld (0x%lx)\n", val, val);
15041 }
15042
4082ef84 15043 assert (p <= end);
f6f0e17b
NC
15044 return p;
15045}
15046
53a346d8
CZ
15047/* ARC ABI attributes section. */
15048
15049static unsigned char *
15050display_arc_attribute (unsigned char * p,
15051 const unsigned char * const end)
15052{
15053 unsigned int tag;
53a346d8
CZ
15054 unsigned int val;
15055
cd30bcef 15056 READ_ULEB (tag, p, end);
53a346d8
CZ
15057
15058 switch (tag)
15059 {
15060 case Tag_ARC_PCS_config:
cd30bcef 15061 READ_ULEB (val, p, end);
53a346d8
CZ
15062 printf (" Tag_ARC_PCS_config: ");
15063 switch (val)
15064 {
15065 case 0:
15066 printf (_("Absent/Non standard\n"));
15067 break;
15068 case 1:
15069 printf (_("Bare metal/mwdt\n"));
15070 break;
15071 case 2:
15072 printf (_("Bare metal/newlib\n"));
15073 break;
15074 case 3:
15075 printf (_("Linux/uclibc\n"));
15076 break;
15077 case 4:
15078 printf (_("Linux/glibc\n"));
15079 break;
15080 default:
15081 printf (_("Unknown\n"));
15082 break;
15083 }
15084 break;
15085
15086 case Tag_ARC_CPU_base:
cd30bcef 15087 READ_ULEB (val, p, end);
53a346d8
CZ
15088 printf (" Tag_ARC_CPU_base: ");
15089 switch (val)
15090 {
15091 default:
15092 case TAG_CPU_NONE:
15093 printf (_("Absent\n"));
15094 break;
15095 case TAG_CPU_ARC6xx:
15096 printf ("ARC6xx\n");
15097 break;
15098 case TAG_CPU_ARC7xx:
15099 printf ("ARC7xx\n");
15100 break;
15101 case TAG_CPU_ARCEM:
15102 printf ("ARCEM\n");
15103 break;
15104 case TAG_CPU_ARCHS:
15105 printf ("ARCHS\n");
15106 break;
15107 }
15108 break;
15109
15110 case Tag_ARC_CPU_variation:
cd30bcef 15111 READ_ULEB (val, p, end);
53a346d8
CZ
15112 printf (" Tag_ARC_CPU_variation: ");
15113 switch (val)
15114 {
15115 default:
15116 if (val > 0 && val < 16)
53a346d8 15117 printf ("Core%d\n", val);
d8cbc93b
JL
15118 else
15119 printf ("Unknown\n");
15120 break;
15121
53a346d8
CZ
15122 case 0:
15123 printf (_("Absent\n"));
15124 break;
15125 }
15126 break;
15127
15128 case Tag_ARC_CPU_name:
15129 printf (" Tag_ARC_CPU_name: ");
15130 p = display_tag_value (-1, p, end);
15131 break;
15132
15133 case Tag_ARC_ABI_rf16:
cd30bcef 15134 READ_ULEB (val, p, end);
53a346d8
CZ
15135 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15136 break;
15137
15138 case Tag_ARC_ABI_osver:
cd30bcef 15139 READ_ULEB (val, p, end);
53a346d8
CZ
15140 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15141 break;
15142
15143 case Tag_ARC_ABI_pic:
15144 case Tag_ARC_ABI_sda:
cd30bcef 15145 READ_ULEB (val, p, end);
53a346d8
CZ
15146 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15147 : " Tag_ARC_ABI_pic: ");
15148 switch (val)
15149 {
15150 case 0:
15151 printf (_("Absent\n"));
15152 break;
15153 case 1:
15154 printf ("MWDT\n");
15155 break;
15156 case 2:
15157 printf ("GNU\n");
15158 break;
15159 default:
15160 printf (_("Unknown\n"));
15161 break;
15162 }
15163 break;
15164
15165 case Tag_ARC_ABI_tls:
cd30bcef 15166 READ_ULEB (val, p, end);
53a346d8
CZ
15167 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15168 break;
15169
15170 case Tag_ARC_ABI_enumsize:
cd30bcef 15171 READ_ULEB (val, p, end);
53a346d8
CZ
15172 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15173 _("smallest"));
15174 break;
15175
15176 case Tag_ARC_ABI_exceptions:
cd30bcef 15177 READ_ULEB (val, p, end);
53a346d8
CZ
15178 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15179 : _("default"));
15180 break;
15181
15182 case Tag_ARC_ABI_double_size:
cd30bcef 15183 READ_ULEB (val, p, end);
53a346d8
CZ
15184 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15185 break;
15186
15187 case Tag_ARC_ISA_config:
15188 printf (" Tag_ARC_ISA_config: ");
15189 p = display_tag_value (-1, p, end);
15190 break;
15191
15192 case Tag_ARC_ISA_apex:
15193 printf (" Tag_ARC_ISA_apex: ");
15194 p = display_tag_value (-1, p, end);
15195 break;
15196
15197 case Tag_ARC_ISA_mpy_option:
cd30bcef 15198 READ_ULEB (val, p, end);
53a346d8
CZ
15199 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15200 break;
15201
db1e1b45 15202 case Tag_ARC_ATR_version:
cd30bcef 15203 READ_ULEB (val, p, end);
db1e1b45 15204 printf (" Tag_ARC_ATR_version: %d\n", val);
15205 break;
15206
53a346d8
CZ
15207 default:
15208 return display_tag_value (tag & 1, p, end);
15209 }
15210
15211 return p;
15212}
15213
11c1ff18
PB
15214/* ARM EABI attributes section. */
15215typedef struct
15216{
70e99720 15217 unsigned int tag;
2cf0635d 15218 const char * name;
11c1ff18 15219 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15220 unsigned int type;
2cf0635d 15221 const char ** table;
11c1ff18
PB
15222} arm_attr_public_tag;
15223
2cf0635d 15224static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 15225 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15226 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15227 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
2cf0635d
NC
15228static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15229static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15230 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 15231static const char * arm_attr_tag_FP_arch[] =
bca38921 15232 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15233 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 15234static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 15235static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15236 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15237 "NEON for ARMv8.1"};
2cf0635d 15238static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
15239 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15240 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 15241static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15242 {"V6", "SB", "TLS", "Unused"};
2cf0635d 15243static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15244 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 15245static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15246 {"Absolute", "PC-relative", "None"};
2cf0635d 15247static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15248 {"None", "direct", "GOT-indirect"};
2cf0635d 15249static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15250 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
15251static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15252static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15253 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
15254static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15255static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15256static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15257 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 15258static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 15259 {"Unused", "small", "int", "forced to int"};
2cf0635d 15260static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15261 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 15262static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 15263 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 15264static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15265 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 15266static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15267 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15268 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 15269static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15270 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15271 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 15272static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 15273static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 15274 {"Not Allowed", "Allowed"};
2cf0635d 15275static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15276 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
15277static const char * arm_attr_tag_DSP_extension[] =
15278 {"Follow architecture", "Allowed"};
dd24e3da 15279static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
15280 {"Not Allowed", "Allowed"};
15281static const char * arm_attr_tag_DIV_use[] =
dd24e3da 15282 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15283 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
15284static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15285static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 15286 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15287 "TrustZone and Virtualization Extensions"};
dd24e3da 15288static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15289 {"Not Allowed", "Allowed"};
11c1ff18 15290
a7ad558c
AV
15291static const char * arm_attr_tag_MVE_arch[] =
15292 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15293
11c1ff18
PB
15294#define LOOKUP(id, name) \
15295 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15296static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15297{
15298 {4, "CPU_raw_name", 1, NULL},
15299 {5, "CPU_name", 1, NULL},
15300 LOOKUP(6, CPU_arch),
15301 {7, "CPU_arch_profile", 0, NULL},
15302 LOOKUP(8, ARM_ISA_use),
15303 LOOKUP(9, THUMB_ISA_use),
75375b3e 15304 LOOKUP(10, FP_arch),
11c1ff18 15305 LOOKUP(11, WMMX_arch),
f5f53991
AS
15306 LOOKUP(12, Advanced_SIMD_arch),
15307 LOOKUP(13, PCS_config),
11c1ff18
PB
15308 LOOKUP(14, ABI_PCS_R9_use),
15309 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15310 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15311 LOOKUP(17, ABI_PCS_GOT_use),
15312 LOOKUP(18, ABI_PCS_wchar_t),
15313 LOOKUP(19, ABI_FP_rounding),
15314 LOOKUP(20, ABI_FP_denormal),
15315 LOOKUP(21, ABI_FP_exceptions),
15316 LOOKUP(22, ABI_FP_user_exceptions),
15317 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15318 {24, "ABI_align_needed", 0, NULL},
15319 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15320 LOOKUP(26, ABI_enum_size),
15321 LOOKUP(27, ABI_HardFP_use),
15322 LOOKUP(28, ABI_VFP_args),
15323 LOOKUP(29, ABI_WMMX_args),
15324 LOOKUP(30, ABI_optimization_goals),
15325 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15326 {32, "compatibility", 0, NULL},
f5f53991 15327 LOOKUP(34, CPU_unaligned_access),
75375b3e 15328 LOOKUP(36, FP_HP_extension),
8e79c3df 15329 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15330 LOOKUP(42, MPextension_use),
15331 LOOKUP(44, DIV_use),
15afaa63 15332 LOOKUP(46, DSP_extension),
a7ad558c 15333 LOOKUP(48, MVE_arch),
f5f53991
AS
15334 {64, "nodefaults", 0, NULL},
15335 {65, "also_compatible_with", 0, NULL},
15336 LOOKUP(66, T2EE_use),
15337 {67, "conformance", 1, NULL},
15338 LOOKUP(68, Virtualization_use),
cd21e546 15339 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15340};
15341#undef LOOKUP
15342
11c1ff18 15343static unsigned char *
f6f0e17b
NC
15344display_arm_attribute (unsigned char * p,
15345 const unsigned char * const end)
11c1ff18 15346{
70e99720 15347 unsigned int tag;
70e99720 15348 unsigned int val;
2cf0635d 15349 arm_attr_public_tag * attr;
11c1ff18 15350 unsigned i;
70e99720 15351 unsigned int type;
11c1ff18 15352
cd30bcef 15353 READ_ULEB (tag, p, end);
11c1ff18 15354 attr = NULL;
2cf0635d 15355 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15356 {
15357 if (arm_attr_public_tags[i].tag == tag)
15358 {
15359 attr = &arm_attr_public_tags[i];
15360 break;
15361 }
15362 }
15363
15364 if (attr)
15365 {
15366 printf (" Tag_%s: ", attr->name);
15367 switch (attr->type)
15368 {
15369 case 0:
15370 switch (tag)
15371 {
15372 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15373 READ_ULEB (val, p, end);
11c1ff18
PB
15374 switch (val)
15375 {
2b692964
NC
15376 case 0: printf (_("None\n")); break;
15377 case 'A': printf (_("Application\n")); break;
15378 case 'R': printf (_("Realtime\n")); break;
15379 case 'M': printf (_("Microcontroller\n")); break;
15380 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15381 default: printf ("??? (%d)\n", val); break;
15382 }
15383 break;
15384
75375b3e 15385 case 24: /* Tag_align_needed. */
cd30bcef 15386 READ_ULEB (val, p, end);
75375b3e
MGD
15387 switch (val)
15388 {
2b692964
NC
15389 case 0: printf (_("None\n")); break;
15390 case 1: printf (_("8-byte\n")); break;
15391 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15392 case 3: printf ("??? 3\n"); break;
15393 default:
15394 if (val <= 12)
dd24e3da 15395 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15396 1 << val);
15397 else
15398 printf ("??? (%d)\n", val);
15399 break;
15400 }
15401 break;
15402
15403 case 25: /* Tag_align_preserved. */
cd30bcef 15404 READ_ULEB (val, p, end);
75375b3e
MGD
15405 switch (val)
15406 {
2b692964
NC
15407 case 0: printf (_("None\n")); break;
15408 case 1: printf (_("8-byte, except leaf SP\n")); break;
15409 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
15410 case 3: printf ("??? 3\n"); break;
15411 default:
15412 if (val <= 12)
dd24e3da 15413 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15414 1 << val);
15415 else
15416 printf ("??? (%d)\n", val);
15417 break;
15418 }
15419 break;
15420
11c1ff18 15421 case 32: /* Tag_compatibility. */
071436c6 15422 {
cd30bcef 15423 READ_ULEB (val, p, end);
071436c6 15424 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15425 if (p < end - 1)
15426 {
15427 size_t maxlen = (end - p) - 1;
15428
15429 print_symbol ((int) maxlen, (const char *) p);
15430 p += strnlen ((char *) p, maxlen) + 1;
15431 }
15432 else
15433 {
15434 printf (_("<corrupt>"));
15435 p = (unsigned char *) end;
15436 }
071436c6 15437 putchar ('\n');
071436c6 15438 }
11c1ff18
PB
15439 break;
15440
f5f53991 15441 case 64: /* Tag_nodefaults. */
541a3cbd
NC
15442 /* PR 17531: file: 001-505008-0.01. */
15443 if (p < end)
15444 p++;
2b692964 15445 printf (_("True\n"));
f5f53991
AS
15446 break;
15447
15448 case 65: /* Tag_also_compatible_with. */
cd30bcef 15449 READ_ULEB (val, p, end);
f5f53991
AS
15450 if (val == 6 /* Tag_CPU_arch. */)
15451 {
cd30bcef 15452 READ_ULEB (val, p, end);
071436c6 15453 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
15454 printf ("??? (%d)\n", val);
15455 else
15456 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
15457 }
15458 else
15459 printf ("???\n");
071436c6
NC
15460 while (p < end && *(p++) != '\0' /* NUL terminator. */)
15461 ;
f5f53991
AS
15462 break;
15463
11c1ff18 15464 default:
bee0ee85
NC
15465 printf (_("<unknown: %d>\n"), tag);
15466 break;
11c1ff18
PB
15467 }
15468 return p;
15469
15470 case 1:
f6f0e17b 15471 return display_tag_value (-1, p, end);
11c1ff18 15472 case 2:
f6f0e17b 15473 return display_tag_value (0, p, end);
11c1ff18
PB
15474
15475 default:
15476 assert (attr->type & 0x80);
cd30bcef 15477 READ_ULEB (val, p, end);
11c1ff18
PB
15478 type = attr->type & 0x7f;
15479 if (val >= type)
15480 printf ("??? (%d)\n", val);
15481 else
15482 printf ("%s\n", attr->table[val]);
15483 return p;
15484 }
15485 }
11c1ff18 15486
f6f0e17b 15487 return display_tag_value (tag, p, end);
11c1ff18
PB
15488}
15489
104d59d1 15490static unsigned char *
60bca95a 15491display_gnu_attribute (unsigned char * p,
60abdbed 15492 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 15493 const unsigned char * const end)
104d59d1 15494{
cd30bcef 15495 unsigned int tag;
60abdbed 15496 unsigned int val;
104d59d1 15497
cd30bcef 15498 READ_ULEB (tag, p, end);
104d59d1
JM
15499
15500 /* Tag_compatibility is the only generic GNU attribute defined at
15501 present. */
15502 if (tag == 32)
15503 {
cd30bcef 15504 READ_ULEB (val, p, end);
071436c6
NC
15505
15506 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
15507 if (p == end)
15508 {
071436c6 15509 printf (_("<corrupt>\n"));
f6f0e17b
NC
15510 warn (_("corrupt vendor attribute\n"));
15511 }
15512 else
15513 {
4082ef84
NC
15514 if (p < end - 1)
15515 {
15516 size_t maxlen = (end - p) - 1;
071436c6 15517
4082ef84
NC
15518 print_symbol ((int) maxlen, (const char *) p);
15519 p += strnlen ((char *) p, maxlen) + 1;
15520 }
15521 else
15522 {
15523 printf (_("<corrupt>"));
15524 p = (unsigned char *) end;
15525 }
071436c6 15526 putchar ('\n');
f6f0e17b 15527 }
104d59d1
JM
15528 return p;
15529 }
15530
15531 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 15532 return display_proc_gnu_attribute (p, tag, end);
104d59d1 15533
f6f0e17b 15534 return display_tag_value (tag, p, end);
104d59d1
JM
15535}
15536
85f7484a
PB
15537static unsigned char *
15538display_m68k_gnu_attribute (unsigned char * p,
15539 unsigned int tag,
15540 const unsigned char * const end)
15541{
15542 unsigned int val;
15543
15544 if (tag == Tag_GNU_M68K_ABI_FP)
15545 {
15546 printf (" Tag_GNU_M68K_ABI_FP: ");
15547 if (p == end)
15548 {
15549 printf (_("<corrupt>\n"));
15550 return p;
15551 }
15552 READ_ULEB (val, p, end);
15553
15554 if (val > 3)
15555 printf ("(%#x), ", val);
15556
15557 switch (val & 3)
15558 {
15559 case 0:
15560 printf (_("unspecified hard/soft float\n"));
15561 break;
15562 case 1:
15563 printf (_("hard float\n"));
15564 break;
15565 case 2:
15566 printf (_("soft float\n"));
15567 break;
15568 }
15569 return p;
15570 }
15571
15572 return display_tag_value (tag & 1, p, end);
15573}
15574
34c8bcba 15575static unsigned char *
f6f0e17b 15576display_power_gnu_attribute (unsigned char * p,
60abdbed 15577 unsigned int tag,
f6f0e17b 15578 const unsigned char * const end)
34c8bcba 15579{
005d79fd 15580 unsigned int val;
34c8bcba
JM
15581
15582 if (tag == Tag_GNU_Power_ABI_FP)
15583 {
34c8bcba 15584 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 15585 if (p == end)
005d79fd
AM
15586 {
15587 printf (_("<corrupt>\n"));
15588 return p;
15589 }
cd30bcef 15590 READ_ULEB (val, p, end);
60bca95a 15591
005d79fd
AM
15592 if (val > 15)
15593 printf ("(%#x), ", val);
15594
15595 switch (val & 3)
34c8bcba
JM
15596 {
15597 case 0:
005d79fd 15598 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
15599 break;
15600 case 1:
005d79fd 15601 printf (_("hard float, "));
34c8bcba
JM
15602 break;
15603 case 2:
005d79fd 15604 printf (_("soft float, "));
34c8bcba 15605 break;
3c7b9897 15606 case 3:
005d79fd 15607 printf (_("single-precision hard float, "));
3c7b9897 15608 break;
005d79fd
AM
15609 }
15610
15611 switch (val & 0xC)
15612 {
15613 case 0:
15614 printf (_("unspecified long double\n"));
15615 break;
15616 case 4:
15617 printf (_("128-bit IBM long double\n"));
15618 break;
15619 case 8:
15620 printf (_("64-bit long double\n"));
15621 break;
15622 case 12:
15623 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
15624 break;
15625 }
15626 return p;
005d79fd 15627 }
34c8bcba 15628
c6e65352
DJ
15629 if (tag == Tag_GNU_Power_ABI_Vector)
15630 {
c6e65352 15631 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 15632 if (p == end)
005d79fd
AM
15633 {
15634 printf (_("<corrupt>\n"));
15635 return p;
15636 }
cd30bcef 15637 READ_ULEB (val, p, end);
005d79fd
AM
15638
15639 if (val > 3)
15640 printf ("(%#x), ", val);
15641
15642 switch (val & 3)
c6e65352
DJ
15643 {
15644 case 0:
005d79fd 15645 printf (_("unspecified\n"));
c6e65352
DJ
15646 break;
15647 case 1:
005d79fd 15648 printf (_("generic\n"));
c6e65352
DJ
15649 break;
15650 case 2:
15651 printf ("AltiVec\n");
15652 break;
15653 case 3:
15654 printf ("SPE\n");
15655 break;
c6e65352
DJ
15656 }
15657 return p;
005d79fd 15658 }
c6e65352 15659
f82e0623
NF
15660 if (tag == Tag_GNU_Power_ABI_Struct_Return)
15661 {
005d79fd 15662 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 15663 if (p == end)
f6f0e17b 15664 {
005d79fd 15665 printf (_("<corrupt>\n"));
f6f0e17b
NC
15666 return p;
15667 }
cd30bcef 15668 READ_ULEB (val, p, end);
0b4362b0 15669
005d79fd
AM
15670 if (val > 2)
15671 printf ("(%#x), ", val);
15672
15673 switch (val & 3)
15674 {
15675 case 0:
15676 printf (_("unspecified\n"));
15677 break;
15678 case 1:
15679 printf ("r3/r4\n");
15680 break;
15681 case 2:
15682 printf (_("memory\n"));
15683 break;
15684 case 3:
15685 printf ("???\n");
15686 break;
15687 }
f82e0623
NF
15688 return p;
15689 }
15690
f6f0e17b 15691 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
15692}
15693
643f7afb
AK
15694static unsigned char *
15695display_s390_gnu_attribute (unsigned char * p,
60abdbed 15696 unsigned int tag,
643f7afb
AK
15697 const unsigned char * const end)
15698{
cd30bcef 15699 unsigned int val;
643f7afb
AK
15700
15701 if (tag == Tag_GNU_S390_ABI_Vector)
15702 {
643f7afb 15703 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 15704 READ_ULEB (val, p, end);
643f7afb
AK
15705
15706 switch (val)
15707 {
15708 case 0:
15709 printf (_("any\n"));
15710 break;
15711 case 1:
15712 printf (_("software\n"));
15713 break;
15714 case 2:
15715 printf (_("hardware\n"));
15716 break;
15717 default:
15718 printf ("??? (%d)\n", val);
15719 break;
15720 }
15721 return p;
15722 }
15723
15724 return display_tag_value (tag & 1, p, end);
15725}
15726
9e8c70f9 15727static void
60abdbed 15728display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
15729{
15730 if (mask)
15731 {
32ec8896 15732 bfd_boolean first = TRUE;
071436c6 15733
9e8c70f9 15734 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 15735 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 15736 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 15737 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 15738 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 15739 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 15740 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 15741 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 15742 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 15743 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 15744 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 15745 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 15746 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 15747 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 15748 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 15749 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 15750 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 15751 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 15752 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 15753 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 15754 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 15755 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 15756 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 15757 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 15758 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 15759 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 15760 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 15761 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 15762 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 15763 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 15764 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 15765 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
15766 }
15767 else
071436c6
NC
15768 fputc ('0', stdout);
15769 fputc ('\n', stdout);
9e8c70f9
DM
15770}
15771
3d68f91c 15772static void
60abdbed 15773display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
15774{
15775 if (mask)
15776 {
32ec8896 15777 bfd_boolean first = TRUE;
071436c6 15778
3d68f91c 15779 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 15780 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 15781 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 15782 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 15783 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 15784 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 15785 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 15786 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 15787 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 15788 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 15789 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 15790 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 15791 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 15792 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 15793 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 15794 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 15795 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 15796 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 15797 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 15798 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 15799 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 15800 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
15801 }
15802 else
071436c6
NC
15803 fputc ('0', stdout);
15804 fputc ('\n', stdout);
3d68f91c
JM
15805}
15806
9e8c70f9 15807static unsigned char *
f6f0e17b 15808display_sparc_gnu_attribute (unsigned char * p,
60abdbed 15809 unsigned int tag,
f6f0e17b 15810 const unsigned char * const end)
9e8c70f9 15811{
cd30bcef 15812 unsigned int val;
3d68f91c 15813
9e8c70f9
DM
15814 if (tag == Tag_GNU_Sparc_HWCAPS)
15815 {
cd30bcef 15816 READ_ULEB (val, p, end);
9e8c70f9 15817 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
15818 display_sparc_hwcaps (val);
15819 return p;
3d68f91c
JM
15820 }
15821 if (tag == Tag_GNU_Sparc_HWCAPS2)
15822 {
cd30bcef 15823 READ_ULEB (val, p, end);
3d68f91c
JM
15824 printf (" Tag_GNU_Sparc_HWCAPS2: ");
15825 display_sparc_hwcaps2 (val);
15826 return p;
15827 }
9e8c70f9 15828
f6f0e17b 15829 return display_tag_value (tag, p, end);
9e8c70f9
DM
15830}
15831
351cdf24 15832static void
32ec8896 15833print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
15834{
15835 switch (val)
15836 {
15837 case Val_GNU_MIPS_ABI_FP_ANY:
15838 printf (_("Hard or soft float\n"));
15839 break;
15840 case Val_GNU_MIPS_ABI_FP_DOUBLE:
15841 printf (_("Hard float (double precision)\n"));
15842 break;
15843 case Val_GNU_MIPS_ABI_FP_SINGLE:
15844 printf (_("Hard float (single precision)\n"));
15845 break;
15846 case Val_GNU_MIPS_ABI_FP_SOFT:
15847 printf (_("Soft float\n"));
15848 break;
15849 case Val_GNU_MIPS_ABI_FP_OLD_64:
15850 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
15851 break;
15852 case Val_GNU_MIPS_ABI_FP_XX:
15853 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
15854 break;
15855 case Val_GNU_MIPS_ABI_FP_64:
15856 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
15857 break;
15858 case Val_GNU_MIPS_ABI_FP_64A:
15859 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
15860 break;
3350cc01
CM
15861 case Val_GNU_MIPS_ABI_FP_NAN2008:
15862 printf (_("NaN 2008 compatibility\n"));
15863 break;
351cdf24
MF
15864 default:
15865 printf ("??? (%d)\n", val);
15866 break;
15867 }
15868}
15869
2cf19d5c 15870static unsigned char *
f6f0e17b 15871display_mips_gnu_attribute (unsigned char * p,
60abdbed 15872 unsigned int tag,
f6f0e17b 15873 const unsigned char * const end)
2cf19d5c 15874{
2cf19d5c
JM
15875 if (tag == Tag_GNU_MIPS_ABI_FP)
15876 {
32ec8896 15877 unsigned int val;
f6f0e17b 15878
2cf19d5c 15879 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 15880 READ_ULEB (val, p, end);
351cdf24 15881 print_mips_fp_abi_value (val);
2cf19d5c
JM
15882 return p;
15883 }
15884
a9f58168
CF
15885 if (tag == Tag_GNU_MIPS_ABI_MSA)
15886 {
32ec8896 15887 unsigned int val;
a9f58168 15888
a9f58168 15889 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 15890 READ_ULEB (val, p, end);
a9f58168
CF
15891
15892 switch (val)
15893 {
15894 case Val_GNU_MIPS_ABI_MSA_ANY:
15895 printf (_("Any MSA or not\n"));
15896 break;
15897 case Val_GNU_MIPS_ABI_MSA_128:
15898 printf (_("128-bit MSA\n"));
15899 break;
15900 default:
15901 printf ("??? (%d)\n", val);
15902 break;
15903 }
15904 return p;
15905 }
15906
f6f0e17b 15907 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
15908}
15909
59e6276b 15910static unsigned char *
f6f0e17b
NC
15911display_tic6x_attribute (unsigned char * p,
15912 const unsigned char * const end)
59e6276b 15913{
60abdbed 15914 unsigned int tag;
cd30bcef 15915 unsigned int val;
59e6276b 15916
cd30bcef 15917 READ_ULEB (tag, p, end);
59e6276b
JM
15918
15919 switch (tag)
15920 {
75fa6dc1 15921 case Tag_ISA:
75fa6dc1 15922 printf (" Tag_ISA: ");
cd30bcef 15923 READ_ULEB (val, p, end);
59e6276b
JM
15924
15925 switch (val)
15926 {
75fa6dc1 15927 case C6XABI_Tag_ISA_none:
59e6276b
JM
15928 printf (_("None\n"));
15929 break;
75fa6dc1 15930 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
15931 printf ("C62x\n");
15932 break;
75fa6dc1 15933 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
15934 printf ("C67x\n");
15935 break;
75fa6dc1 15936 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
15937 printf ("C67x+\n");
15938 break;
75fa6dc1 15939 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
15940 printf ("C64x\n");
15941 break;
75fa6dc1 15942 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
15943 printf ("C64x+\n");
15944 break;
75fa6dc1 15945 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
15946 printf ("C674x\n");
15947 break;
15948 default:
15949 printf ("??? (%d)\n", val);
15950 break;
15951 }
15952 return p;
15953
87779176 15954 case Tag_ABI_wchar_t:
87779176 15955 printf (" Tag_ABI_wchar_t: ");
cd30bcef 15956 READ_ULEB (val, p, end);
87779176
JM
15957 switch (val)
15958 {
15959 case 0:
15960 printf (_("Not used\n"));
15961 break;
15962 case 1:
15963 printf (_("2 bytes\n"));
15964 break;
15965 case 2:
15966 printf (_("4 bytes\n"));
15967 break;
15968 default:
15969 printf ("??? (%d)\n", val);
15970 break;
15971 }
15972 return p;
15973
15974 case Tag_ABI_stack_align_needed:
87779176 15975 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 15976 READ_ULEB (val, p, end);
87779176
JM
15977 switch (val)
15978 {
15979 case 0:
15980 printf (_("8-byte\n"));
15981 break;
15982 case 1:
15983 printf (_("16-byte\n"));
15984 break;
15985 default:
15986 printf ("??? (%d)\n", val);
15987 break;
15988 }
15989 return p;
15990
15991 case Tag_ABI_stack_align_preserved:
cd30bcef 15992 READ_ULEB (val, p, end);
87779176
JM
15993 printf (" Tag_ABI_stack_align_preserved: ");
15994 switch (val)
15995 {
15996 case 0:
15997 printf (_("8-byte\n"));
15998 break;
15999 case 1:
16000 printf (_("16-byte\n"));
16001 break;
16002 default:
16003 printf ("??? (%d)\n", val);
16004 break;
16005 }
16006 return p;
16007
b5593623 16008 case Tag_ABI_DSBT:
cd30bcef 16009 READ_ULEB (val, p, end);
b5593623
JM
16010 printf (" Tag_ABI_DSBT: ");
16011 switch (val)
16012 {
16013 case 0:
16014 printf (_("DSBT addressing not used\n"));
16015 break;
16016 case 1:
16017 printf (_("DSBT addressing used\n"));
16018 break;
16019 default:
16020 printf ("??? (%d)\n", val);
16021 break;
16022 }
16023 return p;
16024
87779176 16025 case Tag_ABI_PID:
cd30bcef 16026 READ_ULEB (val, p, end);
87779176
JM
16027 printf (" Tag_ABI_PID: ");
16028 switch (val)
16029 {
16030 case 0:
16031 printf (_("Data addressing position-dependent\n"));
16032 break;
16033 case 1:
16034 printf (_("Data addressing position-independent, GOT near DP\n"));
16035 break;
16036 case 2:
16037 printf (_("Data addressing position-independent, GOT far from DP\n"));
16038 break;
16039 default:
16040 printf ("??? (%d)\n", val);
16041 break;
16042 }
16043 return p;
16044
16045 case Tag_ABI_PIC:
cd30bcef 16046 READ_ULEB (val, p, end);
87779176
JM
16047 printf (" Tag_ABI_PIC: ");
16048 switch (val)
16049 {
16050 case 0:
16051 printf (_("Code addressing position-dependent\n"));
16052 break;
16053 case 1:
16054 printf (_("Code addressing position-independent\n"));
16055 break;
16056 default:
16057 printf ("??? (%d)\n", val);
16058 break;
16059 }
16060 return p;
16061
16062 case Tag_ABI_array_object_alignment:
cd30bcef 16063 READ_ULEB (val, p, end);
87779176
JM
16064 printf (" Tag_ABI_array_object_alignment: ");
16065 switch (val)
16066 {
16067 case 0:
16068 printf (_("8-byte\n"));
16069 break;
16070 case 1:
16071 printf (_("4-byte\n"));
16072 break;
16073 case 2:
16074 printf (_("16-byte\n"));
16075 break;
16076 default:
16077 printf ("??? (%d)\n", val);
16078 break;
16079 }
16080 return p;
16081
16082 case Tag_ABI_array_object_align_expected:
cd30bcef 16083 READ_ULEB (val, p, end);
87779176
JM
16084 printf (" Tag_ABI_array_object_align_expected: ");
16085 switch (val)
16086 {
16087 case 0:
16088 printf (_("8-byte\n"));
16089 break;
16090 case 1:
16091 printf (_("4-byte\n"));
16092 break;
16093 case 2:
16094 printf (_("16-byte\n"));
16095 break;
16096 default:
16097 printf ("??? (%d)\n", val);
16098 break;
16099 }
16100 return p;
16101
3cbd1c06 16102 case Tag_ABI_compatibility:
071436c6 16103 {
cd30bcef 16104 READ_ULEB (val, p, end);
071436c6 16105 printf (" Tag_ABI_compatibility: ");
071436c6 16106 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16107 if (p < end - 1)
16108 {
16109 size_t maxlen = (end - p) - 1;
16110
16111 print_symbol ((int) maxlen, (const char *) p);
16112 p += strnlen ((char *) p, maxlen) + 1;
16113 }
16114 else
16115 {
16116 printf (_("<corrupt>"));
16117 p = (unsigned char *) end;
16118 }
071436c6 16119 putchar ('\n');
071436c6
NC
16120 return p;
16121 }
87779176
JM
16122
16123 case Tag_ABI_conformance:
071436c6 16124 {
4082ef84
NC
16125 printf (" Tag_ABI_conformance: \"");
16126 if (p < end - 1)
16127 {
16128 size_t maxlen = (end - p) - 1;
071436c6 16129
4082ef84
NC
16130 print_symbol ((int) maxlen, (const char *) p);
16131 p += strnlen ((char *) p, maxlen) + 1;
16132 }
16133 else
16134 {
16135 printf (_("<corrupt>"));
16136 p = (unsigned char *) end;
16137 }
071436c6 16138 printf ("\"\n");
071436c6
NC
16139 return p;
16140 }
59e6276b
JM
16141 }
16142
f6f0e17b
NC
16143 return display_tag_value (tag, p, end);
16144}
59e6276b 16145
f6f0e17b 16146static void
60abdbed 16147display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16148{
16149 unsigned long addr = 0;
16150 size_t bytes = end - p;
16151
feceaa59 16152 assert (end >= p);
f6f0e17b 16153 while (bytes)
87779176 16154 {
f6f0e17b
NC
16155 int j;
16156 int k;
16157 int lbytes = (bytes > 16 ? 16 : bytes);
16158
16159 printf (" 0x%8.8lx ", addr);
16160
16161 for (j = 0; j < 16; j++)
16162 {
16163 if (j < lbytes)
16164 printf ("%2.2x", p[j]);
16165 else
16166 printf (" ");
16167
16168 if ((j & 3) == 3)
16169 printf (" ");
16170 }
16171
16172 for (j = 0; j < lbytes; j++)
16173 {
16174 k = p[j];
16175 if (k >= ' ' && k < 0x7f)
16176 printf ("%c", k);
16177 else
16178 printf (".");
16179 }
16180
16181 putchar ('\n');
16182
16183 p += lbytes;
16184 bytes -= lbytes;
16185 addr += lbytes;
87779176 16186 }
59e6276b 16187
f6f0e17b 16188 putchar ('\n');
59e6276b
JM
16189}
16190
13761a11
NC
16191static unsigned char *
16192display_msp430x_attribute (unsigned char * p,
16193 const unsigned char * const end)
16194{
60abdbed
NC
16195 unsigned int val;
16196 unsigned int tag;
13761a11 16197
cd30bcef 16198 READ_ULEB (tag, p, end);
0b4362b0 16199
13761a11
NC
16200 switch (tag)
16201 {
16202 case OFBA_MSPABI_Tag_ISA:
13761a11 16203 printf (" Tag_ISA: ");
cd30bcef 16204 READ_ULEB (val, p, end);
13761a11
NC
16205 switch (val)
16206 {
16207 case 0: printf (_("None\n")); break;
16208 case 1: printf (_("MSP430\n")); break;
16209 case 2: printf (_("MSP430X\n")); break;
16210 default: printf ("??? (%d)\n", val); break;
16211 }
16212 break;
16213
16214 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16215 printf (" Tag_Code_Model: ");
cd30bcef 16216 READ_ULEB (val, p, end);
13761a11
NC
16217 switch (val)
16218 {
16219 case 0: printf (_("None\n")); break;
16220 case 1: printf (_("Small\n")); break;
16221 case 2: printf (_("Large\n")); break;
16222 default: printf ("??? (%d)\n", val); break;
16223 }
16224 break;
16225
16226 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16227 printf (" Tag_Data_Model: ");
cd30bcef 16228 READ_ULEB (val, p, end);
13761a11
NC
16229 switch (val)
16230 {
16231 case 0: printf (_("None\n")); break;
16232 case 1: printf (_("Small\n")); break;
16233 case 2: printf (_("Large\n")); break;
16234 case 3: printf (_("Restricted Large\n")); break;
16235 default: printf ("??? (%d)\n", val); break;
16236 }
16237 break;
16238
16239 default:
16240 printf (_(" <unknown tag %d>: "), tag);
16241
16242 if (tag & 1)
16243 {
071436c6 16244 putchar ('"');
4082ef84
NC
16245 if (p < end - 1)
16246 {
16247 size_t maxlen = (end - p) - 1;
16248
16249 print_symbol ((int) maxlen, (const char *) p);
16250 p += strnlen ((char *) p, maxlen) + 1;
16251 }
16252 else
16253 {
16254 printf (_("<corrupt>"));
16255 p = (unsigned char *) end;
16256 }
071436c6 16257 printf ("\"\n");
13761a11
NC
16258 }
16259 else
16260 {
cd30bcef 16261 READ_ULEB (val, p, end);
13761a11
NC
16262 printf ("%d (0x%x)\n", val, val);
16263 }
16264 break;
16265 }
16266
4082ef84 16267 assert (p <= end);
13761a11
NC
16268 return p;
16269}
16270
c0ea7c52
JL
16271static unsigned char *
16272display_msp430_gnu_attribute (unsigned char * p,
16273 unsigned int tag,
16274 const unsigned char * const end)
16275{
16276 if (tag == Tag_GNU_MSP430_Data_Region)
16277 {
cd30bcef 16278 unsigned int val;
c0ea7c52 16279
c0ea7c52 16280 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16281 READ_ULEB (val, p, end);
c0ea7c52
JL
16282
16283 switch (val)
16284 {
16285 case Val_GNU_MSP430_Data_Region_Any:
16286 printf (_("Any Region\n"));
16287 break;
16288 case Val_GNU_MSP430_Data_Region_Lower:
16289 printf (_("Lower Region Only\n"));
16290 break;
16291 default:
cd30bcef 16292 printf ("??? (%u)\n", val);
c0ea7c52
JL
16293 }
16294 return p;
16295 }
16296 return display_tag_value (tag & 1, p, end);
16297}
16298
2dc8dd17
JW
16299struct riscv_attr_tag_t {
16300 const char *name;
cd30bcef 16301 unsigned int tag;
2dc8dd17
JW
16302};
16303
16304static struct riscv_attr_tag_t riscv_attr_tag[] =
16305{
16306#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16307 T(arch),
16308 T(priv_spec),
16309 T(priv_spec_minor),
16310 T(priv_spec_revision),
16311 T(unaligned_access),
16312 T(stack_align),
16313#undef T
16314};
16315
16316static unsigned char *
16317display_riscv_attribute (unsigned char *p,
16318 const unsigned char * const end)
16319{
cd30bcef
AM
16320 unsigned int val;
16321 unsigned int tag;
2dc8dd17
JW
16322 struct riscv_attr_tag_t *attr = NULL;
16323 unsigned i;
16324
cd30bcef 16325 READ_ULEB (tag, p, end);
2dc8dd17
JW
16326
16327 /* Find the name of attribute. */
16328 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16329 {
16330 if (riscv_attr_tag[i].tag == tag)
16331 {
16332 attr = &riscv_attr_tag[i];
16333 break;
16334 }
16335 }
16336
16337 if (attr)
16338 printf (" %s: ", attr->name);
16339 else
16340 return display_tag_value (tag, p, end);
16341
16342 switch (tag)
16343 {
16344 case Tag_RISCV_priv_spec:
16345 case Tag_RISCV_priv_spec_minor:
16346 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16347 READ_ULEB (val, p, end);
16348 printf (_("%u\n"), val);
2dc8dd17
JW
16349 break;
16350 case Tag_RISCV_unaligned_access:
cd30bcef 16351 READ_ULEB (val, p, end);
2dc8dd17
JW
16352 switch (val)
16353 {
16354 case 0:
16355 printf (_("No unaligned access\n"));
16356 break;
16357 case 1:
16358 printf (_("Unaligned access\n"));
16359 break;
16360 }
16361 break;
16362 case Tag_RISCV_stack_align:
cd30bcef
AM
16363 READ_ULEB (val, p, end);
16364 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16365 break;
16366 case Tag_RISCV_arch:
16367 p = display_tag_value (-1, p, end);
16368 break;
16369 default:
16370 return display_tag_value (tag, p, end);
16371 }
16372
16373 return p;
16374}
16375
32ec8896 16376static bfd_boolean
dda8d76d 16377process_attributes (Filedata * filedata,
60bca95a 16378 const char * public_name,
104d59d1 16379 unsigned int proc_type,
f6f0e17b 16380 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 16381 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 16382{
2cf0635d 16383 Elf_Internal_Shdr * sect;
11c1ff18 16384 unsigned i;
32ec8896 16385 bfd_boolean res = TRUE;
11c1ff18
PB
16386
16387 /* Find the section header so that we get the size. */
dda8d76d
NC
16388 for (i = 0, sect = filedata->section_headers;
16389 i < filedata->file_header.e_shnum;
11c1ff18
PB
16390 i++, sect++)
16391 {
071436c6
NC
16392 unsigned char * contents;
16393 unsigned char * p;
16394
104d59d1 16395 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
16396 continue;
16397
dda8d76d 16398 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 16399 sect->sh_size, _("attributes"));
60bca95a 16400 if (contents == NULL)
32ec8896
NC
16401 {
16402 res = FALSE;
16403 continue;
16404 }
60bca95a 16405
11c1ff18 16406 p = contents;
60abdbed
NC
16407 /* The first character is the version of the attributes.
16408 Currently only version 1, (aka 'A') is recognised here. */
16409 if (*p != 'A')
32ec8896
NC
16410 {
16411 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
16412 res = FALSE;
16413 }
60abdbed 16414 else
11c1ff18 16415 {
071436c6
NC
16416 bfd_vma section_len;
16417
16418 section_len = sect->sh_size - 1;
11c1ff18 16419 p++;
60bca95a 16420
071436c6 16421 while (section_len > 0)
11c1ff18 16422 {
071436c6 16423 bfd_vma attr_len;
e9847026 16424 unsigned int namelen;
11c1ff18 16425 bfd_boolean public_section;
104d59d1 16426 bfd_boolean gnu_section;
11c1ff18 16427
071436c6 16428 if (section_len <= 4)
e0a31db1
NC
16429 {
16430 error (_("Tag section ends prematurely\n"));
32ec8896 16431 res = FALSE;
e0a31db1
NC
16432 break;
16433 }
071436c6 16434 attr_len = byte_get (p, 4);
11c1ff18 16435 p += 4;
60bca95a 16436
071436c6 16437 if (attr_len > section_len)
11c1ff18 16438 {
071436c6
NC
16439 error (_("Bad attribute length (%u > %u)\n"),
16440 (unsigned) attr_len, (unsigned) section_len);
16441 attr_len = section_len;
32ec8896 16442 res = FALSE;
11c1ff18 16443 }
74e1a04b 16444 /* PR 17531: file: 001-101425-0.004 */
071436c6 16445 else if (attr_len < 5)
74e1a04b 16446 {
071436c6 16447 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 16448 res = FALSE;
74e1a04b
NC
16449 break;
16450 }
e9847026 16451
071436c6
NC
16452 section_len -= attr_len;
16453 attr_len -= 4;
16454
16455 namelen = strnlen ((char *) p, attr_len) + 1;
16456 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
16457 {
16458 error (_("Corrupt attribute section name\n"));
32ec8896 16459 res = FALSE;
e9847026
NC
16460 break;
16461 }
16462
071436c6
NC
16463 printf (_("Attribute Section: "));
16464 print_symbol (INT_MAX, (const char *) p);
16465 putchar ('\n');
60bca95a
NC
16466
16467 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
16468 public_section = TRUE;
16469 else
16470 public_section = FALSE;
60bca95a
NC
16471
16472 if (streq ((char *) p, "gnu"))
104d59d1
JM
16473 gnu_section = TRUE;
16474 else
16475 gnu_section = FALSE;
60bca95a 16476
11c1ff18 16477 p += namelen;
071436c6 16478 attr_len -= namelen;
e0a31db1 16479
071436c6 16480 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 16481 {
e0a31db1 16482 int tag;
cd30bcef 16483 unsigned int val;
11c1ff18 16484 bfd_vma size;
071436c6 16485 unsigned char * end;
60bca95a 16486
e0a31db1 16487 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 16488 if (attr_len < 6)
e0a31db1
NC
16489 {
16490 error (_("Unused bytes at end of section\n"));
32ec8896 16491 res = FALSE;
e0a31db1
NC
16492 section_len = 0;
16493 break;
16494 }
16495
16496 tag = *(p++);
11c1ff18 16497 size = byte_get (p, 4);
071436c6 16498 if (size > attr_len)
11c1ff18 16499 {
e9847026 16500 error (_("Bad subsection length (%u > %u)\n"),
071436c6 16501 (unsigned) size, (unsigned) attr_len);
32ec8896 16502 res = FALSE;
071436c6 16503 size = attr_len;
11c1ff18 16504 }
e0a31db1
NC
16505 /* PR binutils/17531: Safe handling of corrupt files. */
16506 if (size < 6)
16507 {
16508 error (_("Bad subsection length (%u < 6)\n"),
16509 (unsigned) size);
32ec8896 16510 res = FALSE;
e0a31db1
NC
16511 section_len = 0;
16512 break;
16513 }
60bca95a 16514
071436c6 16515 attr_len -= size;
11c1ff18 16516 end = p + size - 1;
071436c6 16517 assert (end <= contents + sect->sh_size);
11c1ff18 16518 p += 4;
60bca95a 16519
11c1ff18
PB
16520 switch (tag)
16521 {
16522 case 1:
2b692964 16523 printf (_("File Attributes\n"));
11c1ff18
PB
16524 break;
16525 case 2:
2b692964 16526 printf (_("Section Attributes:"));
11c1ff18
PB
16527 goto do_numlist;
16528 case 3:
2b692964 16529 printf (_("Symbol Attributes:"));
1a0670f3 16530 /* Fall through. */
11c1ff18
PB
16531 do_numlist:
16532 for (;;)
16533 {
cd30bcef 16534 READ_ULEB (val, p, end);
11c1ff18
PB
16535 if (val == 0)
16536 break;
16537 printf (" %d", val);
16538 }
16539 printf ("\n");
16540 break;
16541 default:
2b692964 16542 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
16543 public_section = FALSE;
16544 break;
16545 }
60bca95a 16546
071436c6 16547 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
16548 {
16549 while (p < end)
f6f0e17b 16550 p = display_pub_attribute (p, end);
60abdbed 16551 assert (p == end);
104d59d1 16552 }
071436c6 16553 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
16554 {
16555 while (p < end)
16556 p = display_gnu_attribute (p,
f6f0e17b
NC
16557 display_proc_gnu_attribute,
16558 end);
60abdbed 16559 assert (p == end);
11c1ff18 16560 }
071436c6 16561 else if (p < end)
11c1ff18 16562 {
071436c6 16563 printf (_(" Unknown attribute:\n"));
f6f0e17b 16564 display_raw_attribute (p, end);
11c1ff18
PB
16565 p = end;
16566 }
071436c6
NC
16567 else
16568 attr_len = 0;
11c1ff18
PB
16569 }
16570 }
16571 }
d70c5fc7 16572
60bca95a 16573 free (contents);
11c1ff18 16574 }
32ec8896
NC
16575
16576 return res;
11c1ff18
PB
16577}
16578
ccb4c951
RS
16579/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
16580 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
16581 and return the VMA of the next entry, or -1 if there was a problem.
16582 Does not read from DATA_END or beyond. */
ccb4c951
RS
16583
16584static bfd_vma
82b1b41b
NC
16585print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
16586 unsigned char * data_end)
ccb4c951
RS
16587{
16588 printf (" ");
16589 print_vma (addr, LONG_HEX);
16590 printf (" ");
16591 if (addr < pltgot + 0xfff0)
16592 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
16593 else
16594 printf ("%10s", "");
16595 printf (" ");
16596 if (data == NULL)
2b692964 16597 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
16598 else
16599 {
16600 bfd_vma entry;
82b1b41b 16601 unsigned char * from = data + addr - pltgot;
ccb4c951 16602
82b1b41b
NC
16603 if (from + (is_32bit_elf ? 4 : 8) > data_end)
16604 {
16605 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
16606 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
16607 return (bfd_vma) -1;
16608 }
16609 else
16610 {
16611 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16612 print_vma (entry, LONG_HEX);
16613 }
ccb4c951
RS
16614 }
16615 return addr + (is_32bit_elf ? 4 : 8);
16616}
16617
861fb55a
DJ
16618/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
16619 PLTGOT. Print the Address and Initial fields of an entry at VMA
16620 ADDR and return the VMA of the next entry. */
16621
16622static bfd_vma
2cf0635d 16623print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
16624{
16625 printf (" ");
16626 print_vma (addr, LONG_HEX);
16627 printf (" ");
16628 if (data == NULL)
2b692964 16629 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
16630 else
16631 {
16632 bfd_vma entry;
16633
16634 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16635 print_vma (entry, LONG_HEX);
16636 }
16637 return addr + (is_32bit_elf ? 4 : 8);
16638}
16639
351cdf24
MF
16640static void
16641print_mips_ases (unsigned int mask)
16642{
16643 if (mask & AFL_ASE_DSP)
16644 fputs ("\n\tDSP ASE", stdout);
16645 if (mask & AFL_ASE_DSPR2)
16646 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
16647 if (mask & AFL_ASE_DSPR3)
16648 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
16649 if (mask & AFL_ASE_EVA)
16650 fputs ("\n\tEnhanced VA Scheme", stdout);
16651 if (mask & AFL_ASE_MCU)
16652 fputs ("\n\tMCU (MicroController) ASE", stdout);
16653 if (mask & AFL_ASE_MDMX)
16654 fputs ("\n\tMDMX ASE", stdout);
16655 if (mask & AFL_ASE_MIPS3D)
16656 fputs ("\n\tMIPS-3D ASE", stdout);
16657 if (mask & AFL_ASE_MT)
16658 fputs ("\n\tMT ASE", stdout);
16659 if (mask & AFL_ASE_SMARTMIPS)
16660 fputs ("\n\tSmartMIPS ASE", stdout);
16661 if (mask & AFL_ASE_VIRT)
16662 fputs ("\n\tVZ ASE", stdout);
16663 if (mask & AFL_ASE_MSA)
16664 fputs ("\n\tMSA ASE", stdout);
16665 if (mask & AFL_ASE_MIPS16)
16666 fputs ("\n\tMIPS16 ASE", stdout);
16667 if (mask & AFL_ASE_MICROMIPS)
16668 fputs ("\n\tMICROMIPS ASE", stdout);
16669 if (mask & AFL_ASE_XPA)
16670 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
16671 if (mask & AFL_ASE_MIPS16E2)
16672 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
16673 if (mask & AFL_ASE_CRC)
16674 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
16675 if (mask & AFL_ASE_GINV)
16676 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
16677 if (mask & AFL_ASE_LOONGSON_MMI)
16678 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
16679 if (mask & AFL_ASE_LOONGSON_CAM)
16680 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
16681 if (mask & AFL_ASE_LOONGSON_EXT)
16682 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
16683 if (mask & AFL_ASE_LOONGSON_EXT2)
16684 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
16685 if (mask == 0)
16686 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
16687 else if ((mask & ~AFL_ASE_MASK) != 0)
16688 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
16689}
16690
16691static void
16692print_mips_isa_ext (unsigned int isa_ext)
16693{
16694 switch (isa_ext)
16695 {
16696 case 0:
16697 fputs (_("None"), stdout);
16698 break;
16699 case AFL_EXT_XLR:
16700 fputs ("RMI XLR", stdout);
16701 break;
2c629856
N
16702 case AFL_EXT_OCTEON3:
16703 fputs ("Cavium Networks Octeon3", stdout);
16704 break;
351cdf24
MF
16705 case AFL_EXT_OCTEON2:
16706 fputs ("Cavium Networks Octeon2", stdout);
16707 break;
16708 case AFL_EXT_OCTEONP:
16709 fputs ("Cavium Networks OcteonP", stdout);
16710 break;
351cdf24
MF
16711 case AFL_EXT_OCTEON:
16712 fputs ("Cavium Networks Octeon", stdout);
16713 break;
16714 case AFL_EXT_5900:
16715 fputs ("Toshiba R5900", stdout);
16716 break;
16717 case AFL_EXT_4650:
16718 fputs ("MIPS R4650", stdout);
16719 break;
16720 case AFL_EXT_4010:
16721 fputs ("LSI R4010", stdout);
16722 break;
16723 case AFL_EXT_4100:
16724 fputs ("NEC VR4100", stdout);
16725 break;
16726 case AFL_EXT_3900:
16727 fputs ("Toshiba R3900", stdout);
16728 break;
16729 case AFL_EXT_10000:
16730 fputs ("MIPS R10000", stdout);
16731 break;
16732 case AFL_EXT_SB1:
16733 fputs ("Broadcom SB-1", stdout);
16734 break;
16735 case AFL_EXT_4111:
16736 fputs ("NEC VR4111/VR4181", stdout);
16737 break;
16738 case AFL_EXT_4120:
16739 fputs ("NEC VR4120", stdout);
16740 break;
16741 case AFL_EXT_5400:
16742 fputs ("NEC VR5400", stdout);
16743 break;
16744 case AFL_EXT_5500:
16745 fputs ("NEC VR5500", stdout);
16746 break;
16747 case AFL_EXT_LOONGSON_2E:
16748 fputs ("ST Microelectronics Loongson 2E", stdout);
16749 break;
16750 case AFL_EXT_LOONGSON_2F:
16751 fputs ("ST Microelectronics Loongson 2F", stdout);
16752 break;
38bf472a
MR
16753 case AFL_EXT_INTERAPTIV_MR2:
16754 fputs ("Imagination interAptiv MR2", stdout);
16755 break;
351cdf24 16756 default:
00ac7aa0 16757 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
16758 }
16759}
16760
32ec8896 16761static signed int
351cdf24
MF
16762get_mips_reg_size (int reg_size)
16763{
16764 return (reg_size == AFL_REG_NONE) ? 0
16765 : (reg_size == AFL_REG_32) ? 32
16766 : (reg_size == AFL_REG_64) ? 64
16767 : (reg_size == AFL_REG_128) ? 128
16768 : -1;
16769}
16770
32ec8896 16771static bfd_boolean
dda8d76d 16772process_mips_specific (Filedata * filedata)
5b18a4bc 16773{
2cf0635d 16774 Elf_Internal_Dyn * entry;
351cdf24 16775 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
16776 size_t liblist_offset = 0;
16777 size_t liblistno = 0;
16778 size_t conflictsno = 0;
16779 size_t options_offset = 0;
16780 size_t conflicts_offset = 0;
861fb55a
DJ
16781 size_t pltrelsz = 0;
16782 size_t pltrel = 0;
ccb4c951 16783 bfd_vma pltgot = 0;
861fb55a
DJ
16784 bfd_vma mips_pltgot = 0;
16785 bfd_vma jmprel = 0;
ccb4c951
RS
16786 bfd_vma local_gotno = 0;
16787 bfd_vma gotsym = 0;
16788 bfd_vma symtabno = 0;
32ec8896 16789 bfd_boolean res = TRUE;
103f02d3 16790
dda8d76d 16791 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
16792 display_mips_gnu_attribute))
16793 res = FALSE;
2cf19d5c 16794
dda8d76d 16795 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
16796
16797 if (sect != NULL)
16798 {
16799 Elf_External_ABIFlags_v0 *abiflags_ext;
16800 Elf_Internal_ABIFlags_v0 abiflags_in;
16801
16802 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
16803 {
16804 error (_("Corrupt MIPS ABI Flags section.\n"));
16805 res = FALSE;
16806 }
351cdf24
MF
16807 else
16808 {
dda8d76d 16809 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
16810 sect->sh_size, _("MIPS ABI Flags section"));
16811 if (abiflags_ext)
16812 {
16813 abiflags_in.version = BYTE_GET (abiflags_ext->version);
16814 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
16815 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
16816 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
16817 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
16818 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
16819 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
16820 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
16821 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
16822 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
16823 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
16824
16825 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
16826 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
16827 if (abiflags_in.isa_rev > 1)
16828 printf ("r%d", abiflags_in.isa_rev);
16829 printf ("\nGPR size: %d",
16830 get_mips_reg_size (abiflags_in.gpr_size));
16831 printf ("\nCPR1 size: %d",
16832 get_mips_reg_size (abiflags_in.cpr1_size));
16833 printf ("\nCPR2 size: %d",
16834 get_mips_reg_size (abiflags_in.cpr2_size));
16835 fputs ("\nFP ABI: ", stdout);
16836 print_mips_fp_abi_value (abiflags_in.fp_abi);
16837 fputs ("ISA Extension: ", stdout);
16838 print_mips_isa_ext (abiflags_in.isa_ext);
16839 fputs ("\nASEs:", stdout);
16840 print_mips_ases (abiflags_in.ases);
16841 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
16842 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
16843 fputc ('\n', stdout);
16844 free (abiflags_ext);
16845 }
16846 }
16847 }
16848
19e6b90e 16849 /* We have a lot of special sections. Thanks SGI! */
978c4450 16850 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
16851 {
16852 /* No dynamic information available. See if there is static GOT. */
dda8d76d 16853 sect = find_section (filedata, ".got");
bbdd9a68
MR
16854 if (sect != NULL)
16855 {
16856 unsigned char *data_end;
16857 unsigned char *data;
16858 bfd_vma ent, end;
16859 int addr_size;
16860
16861 pltgot = sect->sh_addr;
16862
16863 ent = pltgot;
16864 addr_size = (is_32bit_elf ? 4 : 8);
16865 end = pltgot + sect->sh_size;
16866
dda8d76d 16867 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
16868 end - pltgot, 1,
16869 _("Global Offset Table data"));
16870 /* PR 12855: Null data is handled gracefully throughout. */
16871 data_end = data + (end - pltgot);
16872
16873 printf (_("\nStatic GOT:\n"));
16874 printf (_(" Canonical gp value: "));
16875 print_vma (ent + 0x7ff0, LONG_HEX);
16876 printf ("\n\n");
16877
16878 /* In a dynamic binary GOT[0] is reserved for the dynamic
16879 loader to store the lazy resolver pointer, however in
16880 a static binary it may well have been omitted and GOT
16881 reduced to a table of addresses.
16882 PR 21344: Check for the entry being fully available
16883 before fetching it. */
16884 if (data
16885 && data + ent - pltgot + addr_size <= data_end
16886 && byte_get (data + ent - pltgot, addr_size) == 0)
16887 {
16888 printf (_(" Reserved entries:\n"));
16889 printf (_(" %*s %10s %*s\n"),
16890 addr_size * 2, _("Address"), _("Access"),
16891 addr_size * 2, _("Value"));
16892 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16893 printf ("\n");
16894 if (ent == (bfd_vma) -1)
16895 goto sgot_print_fail;
16896
16897 /* Check for the MSB of GOT[1] being set, identifying a
16898 GNU object. This entry will be used by some runtime
16899 loaders, to store the module pointer. Otherwise this
16900 is an ordinary local entry.
16901 PR 21344: Check for the entry being fully available
16902 before fetching it. */
16903 if (data
16904 && data + ent - pltgot + addr_size <= data_end
16905 && (byte_get (data + ent - pltgot, addr_size)
16906 >> (addr_size * 8 - 1)) != 0)
16907 {
16908 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16909 printf ("\n");
16910 if (ent == (bfd_vma) -1)
16911 goto sgot_print_fail;
16912 }
16913 printf ("\n");
16914 }
16915
f17e9d8a 16916 if (data != NULL && ent < end)
bbdd9a68
MR
16917 {
16918 printf (_(" Local entries:\n"));
16919 printf (" %*s %10s %*s\n",
16920 addr_size * 2, _("Address"), _("Access"),
16921 addr_size * 2, _("Value"));
16922 while (ent < end)
16923 {
16924 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16925 printf ("\n");
16926 if (ent == (bfd_vma) -1)
16927 goto sgot_print_fail;
16928 }
16929 printf ("\n");
16930 }
16931
16932 sgot_print_fail:
9db70fc3 16933 free (data);
bbdd9a68
MR
16934 }
16935 return res;
16936 }
252b5132 16937
978c4450 16938 for (entry = filedata->dynamic_section;
071436c6 16939 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
16940 (entry < filedata->dynamic_section + filedata->dynamic_nent
16941 && entry->d_tag != DT_NULL);
071436c6 16942 ++entry)
252b5132
RH
16943 switch (entry->d_tag)
16944 {
16945 case DT_MIPS_LIBLIST:
d93f0186 16946 liblist_offset
dda8d76d 16947 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16948 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
16949 break;
16950 case DT_MIPS_LIBLISTNO:
16951 liblistno = entry->d_un.d_val;
16952 break;
16953 case DT_MIPS_OPTIONS:
dda8d76d 16954 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
16955 break;
16956 case DT_MIPS_CONFLICT:
d93f0186 16957 conflicts_offset
dda8d76d 16958 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16959 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
16960 break;
16961 case DT_MIPS_CONFLICTNO:
16962 conflictsno = entry->d_un.d_val;
16963 break;
ccb4c951 16964 case DT_PLTGOT:
861fb55a
DJ
16965 pltgot = entry->d_un.d_ptr;
16966 break;
ccb4c951
RS
16967 case DT_MIPS_LOCAL_GOTNO:
16968 local_gotno = entry->d_un.d_val;
16969 break;
16970 case DT_MIPS_GOTSYM:
16971 gotsym = entry->d_un.d_val;
16972 break;
16973 case DT_MIPS_SYMTABNO:
16974 symtabno = entry->d_un.d_val;
16975 break;
861fb55a
DJ
16976 case DT_MIPS_PLTGOT:
16977 mips_pltgot = entry->d_un.d_ptr;
16978 break;
16979 case DT_PLTREL:
16980 pltrel = entry->d_un.d_val;
16981 break;
16982 case DT_PLTRELSZ:
16983 pltrelsz = entry->d_un.d_val;
16984 break;
16985 case DT_JMPREL:
16986 jmprel = entry->d_un.d_ptr;
16987 break;
252b5132
RH
16988 default:
16989 break;
16990 }
16991
16992 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
16993 {
2cf0635d 16994 Elf32_External_Lib * elib;
252b5132
RH
16995 size_t cnt;
16996
dda8d76d 16997 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
16998 sizeof (Elf32_External_Lib),
16999 liblistno,
17000 _("liblist section data"));
a6e9f9df 17001 if (elib)
252b5132 17002 {
d3a49aa8
AM
17003 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17004 "\nSection '.liblist' contains %lu entries:\n",
17005 (unsigned long) liblistno),
a6e9f9df 17006 (unsigned long) liblistno);
2b692964 17007 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17008 stdout);
17009
17010 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17011 {
a6e9f9df 17012 Elf32_Lib liblist;
91d6fa6a 17013 time_t atime;
d5b07ef4 17014 char timebuf[128];
2cf0635d 17015 struct tm * tmp;
a6e9f9df
AM
17016
17017 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17018 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17019 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17020 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17021 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17022
91d6fa6a 17023 tmp = gmtime (&atime);
e9e44622
JJ
17024 snprintf (timebuf, sizeof (timebuf),
17025 "%04u-%02u-%02uT%02u:%02u:%02u",
17026 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17027 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17028
31104126 17029 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17030 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17031 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17032 else
2b692964 17033 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17034 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17035 liblist.l_version);
a6e9f9df
AM
17036
17037 if (liblist.l_flags == 0)
2b692964 17038 puts (_(" NONE"));
a6e9f9df
AM
17039 else
17040 {
17041 static const struct
252b5132 17042 {
2cf0635d 17043 const char * name;
a6e9f9df 17044 int bit;
252b5132 17045 }
a6e9f9df
AM
17046 l_flags_vals[] =
17047 {
17048 { " EXACT_MATCH", LL_EXACT_MATCH },
17049 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17050 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17051 { " EXPORTS", LL_EXPORTS },
17052 { " DELAY_LOAD", LL_DELAY_LOAD },
17053 { " DELTA", LL_DELTA }
17054 };
17055 int flags = liblist.l_flags;
17056 size_t fcnt;
17057
60bca95a 17058 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17059 if ((flags & l_flags_vals[fcnt].bit) != 0)
17060 {
17061 fputs (l_flags_vals[fcnt].name, stdout);
17062 flags ^= l_flags_vals[fcnt].bit;
17063 }
17064 if (flags != 0)
17065 printf (" %#x", (unsigned int) flags);
252b5132 17066
a6e9f9df
AM
17067 puts ("");
17068 }
252b5132 17069 }
252b5132 17070
a6e9f9df
AM
17071 free (elib);
17072 }
32ec8896
NC
17073 else
17074 res = FALSE;
252b5132
RH
17075 }
17076
17077 if (options_offset != 0)
17078 {
2cf0635d 17079 Elf_External_Options * eopt;
252b5132
RH
17080 size_t offset;
17081 int cnt;
dda8d76d 17082 sect = filedata->section_headers;
252b5132
RH
17083
17084 /* Find the section header so that we get the size. */
dda8d76d 17085 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17086 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17087 if (sect == NULL)
17088 {
17089 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 17090 return FALSE;
071436c6 17091 }
7fc0c668
NC
17092 /* PR 24243 */
17093 if (sect->sh_size < sizeof (* eopt))
17094 {
17095 error (_("The MIPS options section is too small.\n"));
17096 return FALSE;
17097 }
252b5132 17098
dda8d76d 17099 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17100 sect->sh_size, _("options"));
a6e9f9df 17101 if (eopt)
252b5132 17102 {
fd17d1e6 17103 Elf_Internal_Options option;
76da6bbe 17104
a6e9f9df 17105 offset = cnt = 0;
82b1b41b 17106 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17107 {
2cf0635d 17108 Elf_External_Options * eoption;
fd17d1e6 17109 unsigned int optsize;
252b5132 17110
a6e9f9df 17111 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17112
fd17d1e6 17113 optsize = BYTE_GET (eoption->size);
76da6bbe 17114
82b1b41b 17115 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17116 if (optsize < sizeof (* eopt)
17117 || optsize > sect->sh_size - offset)
82b1b41b 17118 {
645f43a8 17119 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17120 optsize);
645f43a8 17121 free (eopt);
32ec8896 17122 return FALSE;
82b1b41b 17123 }
fd17d1e6 17124 offset += optsize;
a6e9f9df
AM
17125 ++cnt;
17126 }
252b5132 17127
d3a49aa8
AM
17128 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17129 "\nSection '%s' contains %d entries:\n",
17130 cnt),
dda8d76d 17131 printable_section_name (filedata, sect), cnt);
76da6bbe 17132
82b1b41b 17133 offset = 0;
a6e9f9df 17134 while (cnt-- > 0)
252b5132 17135 {
a6e9f9df 17136 size_t len;
fd17d1e6
AM
17137 Elf_External_Options * eoption;
17138
17139 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17140
17141 option.kind = BYTE_GET (eoption->kind);
17142 option.size = BYTE_GET (eoption->size);
17143 option.section = BYTE_GET (eoption->section);
17144 option.info = BYTE_GET (eoption->info);
a6e9f9df 17145
fd17d1e6 17146 switch (option.kind)
252b5132 17147 {
a6e9f9df
AM
17148 case ODK_NULL:
17149 /* This shouldn't happen. */
d0c4e780 17150 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 17151 option.section, option.info);
a6e9f9df 17152 break;
2e6be59c 17153
a6e9f9df
AM
17154 case ODK_REGINFO:
17155 printf (" REGINFO ");
dda8d76d 17156 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17157 {
2cf0635d 17158 Elf32_External_RegInfo * ereg;
b34976b6 17159 Elf32_RegInfo reginfo;
a6e9f9df 17160
2e6be59c 17161 /* 32bit form. */
fd17d1e6
AM
17162 if (option.size < (sizeof (Elf_External_Options)
17163 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
17164 {
17165 printf (_("<corrupt>\n"));
17166 error (_("Truncated MIPS REGINFO option\n"));
17167 cnt = 0;
17168 break;
17169 }
17170
fd17d1e6 17171 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 17172
a6e9f9df
AM
17173 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17174 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17175 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17176 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17177 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17178 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17179
d0c4e780
AM
17180 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
17181 reginfo.ri_gprmask, reginfo.ri_gp_value);
17182 printf (" "
17183 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17184 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17185 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17186 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17187 }
17188 else
17189 {
17190 /* 64 bit form. */
2cf0635d 17191 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17192 Elf64_Internal_RegInfo reginfo;
17193
fd17d1e6
AM
17194 if (option.size < (sizeof (Elf_External_Options)
17195 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
17196 {
17197 printf (_("<corrupt>\n"));
17198 error (_("Truncated MIPS REGINFO option\n"));
17199 cnt = 0;
17200 break;
17201 }
17202
fd17d1e6 17203 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
17204 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17205 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17206 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17207 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17208 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 17209 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 17210
d0c4e780
AM
17211 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
17212 reginfo.ri_gprmask, reginfo.ri_gp_value);
17213 printf (" "
17214 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17215 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17216 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17217 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17218 }
fd17d1e6 17219 offset += option.size;
a6e9f9df 17220 continue;
2e6be59c 17221
a6e9f9df
AM
17222 case ODK_EXCEPTIONS:
17223 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 17224 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 17225 fputs (") fpe_max(", stdout);
fd17d1e6 17226 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
17227 fputs (")", stdout);
17228
fd17d1e6 17229 if (option.info & OEX_PAGE0)
a6e9f9df 17230 fputs (" PAGE0", stdout);
fd17d1e6 17231 if (option.info & OEX_SMM)
a6e9f9df 17232 fputs (" SMM", stdout);
fd17d1e6 17233 if (option.info & OEX_FPDBUG)
a6e9f9df 17234 fputs (" FPDBUG", stdout);
fd17d1e6 17235 if (option.info & OEX_DISMISS)
a6e9f9df
AM
17236 fputs (" DISMISS", stdout);
17237 break;
2e6be59c 17238
a6e9f9df
AM
17239 case ODK_PAD:
17240 fputs (" PAD ", stdout);
fd17d1e6 17241 if (option.info & OPAD_PREFIX)
a6e9f9df 17242 fputs (" PREFIX", stdout);
fd17d1e6 17243 if (option.info & OPAD_POSTFIX)
a6e9f9df 17244 fputs (" POSTFIX", stdout);
fd17d1e6 17245 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
17246 fputs (" SYMBOL", stdout);
17247 break;
2e6be59c 17248
a6e9f9df
AM
17249 case ODK_HWPATCH:
17250 fputs (" HWPATCH ", stdout);
fd17d1e6 17251 if (option.info & OHW_R4KEOP)
a6e9f9df 17252 fputs (" R4KEOP", stdout);
fd17d1e6 17253 if (option.info & OHW_R8KPFETCH)
a6e9f9df 17254 fputs (" R8KPFETCH", stdout);
fd17d1e6 17255 if (option.info & OHW_R5KEOP)
a6e9f9df 17256 fputs (" R5KEOP", stdout);
fd17d1e6 17257 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
17258 fputs (" R5KCVTL", stdout);
17259 break;
2e6be59c 17260
a6e9f9df
AM
17261 case ODK_FILL:
17262 fputs (" FILL ", stdout);
17263 /* XXX Print content of info word? */
17264 break;
2e6be59c 17265
a6e9f9df
AM
17266 case ODK_TAGS:
17267 fputs (" TAGS ", stdout);
17268 /* XXX Print content of info word? */
17269 break;
2e6be59c 17270
a6e9f9df
AM
17271 case ODK_HWAND:
17272 fputs (" HWAND ", stdout);
fd17d1e6 17273 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17274 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17275 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17276 fputs (" R4KEOP_CLEAN", stdout);
17277 break;
2e6be59c 17278
a6e9f9df
AM
17279 case ODK_HWOR:
17280 fputs (" HWOR ", stdout);
fd17d1e6 17281 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17282 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17283 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17284 fputs (" R4KEOP_CLEAN", stdout);
17285 break;
2e6be59c 17286
a6e9f9df 17287 case ODK_GP_GROUP:
d0c4e780 17288 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
17289 option.info & OGP_GROUP,
17290 (option.info & OGP_SELF) >> 16);
a6e9f9df 17291 break;
2e6be59c 17292
a6e9f9df 17293 case ODK_IDENT:
d0c4e780 17294 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
17295 option.info & OGP_GROUP,
17296 (option.info & OGP_SELF) >> 16);
a6e9f9df 17297 break;
2e6be59c 17298
a6e9f9df
AM
17299 default:
17300 /* This shouldn't happen. */
d0c4e780 17301 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 17302 option.kind, option.section, option.info);
a6e9f9df 17303 break;
252b5132 17304 }
a6e9f9df 17305
2cf0635d 17306 len = sizeof (* eopt);
fd17d1e6 17307 while (len < option.size)
82b1b41b 17308 {
fd17d1e6 17309 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 17310
82b1b41b
NC
17311 if (ISPRINT (datum))
17312 printf ("%c", datum);
17313 else
17314 printf ("\\%03o", datum);
17315 len ++;
17316 }
a6e9f9df 17317 fputs ("\n", stdout);
82b1b41b 17318
fd17d1e6 17319 offset += option.size;
252b5132 17320 }
a6e9f9df 17321 free (eopt);
252b5132 17322 }
32ec8896
NC
17323 else
17324 res = FALSE;
252b5132
RH
17325 }
17326
17327 if (conflicts_offset != 0 && conflictsno != 0)
17328 {
2cf0635d 17329 Elf32_Conflict * iconf;
252b5132
RH
17330 size_t cnt;
17331
978c4450 17332 if (filedata->dynamic_symbols == NULL)
252b5132 17333 {
591a748a 17334 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 17335 return FALSE;
252b5132
RH
17336 }
17337
7296a62a
NC
17338 /* PR 21345 - print a slightly more helpful error message
17339 if we are sure that the cmalloc will fail. */
645f43a8 17340 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
17341 {
17342 error (_("Overlarge number of conflicts detected: %lx\n"),
17343 (long) conflictsno);
17344 return FALSE;
17345 }
17346
3f5e193b 17347 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
17348 if (iconf == NULL)
17349 {
8b73c356 17350 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 17351 return FALSE;
252b5132
RH
17352 }
17353
9ea033b2 17354 if (is_32bit_elf)
252b5132 17355 {
2cf0635d 17356 Elf32_External_Conflict * econf32;
a6e9f9df 17357
3f5e193b 17358 econf32 = (Elf32_External_Conflict *)
95099889
AM
17359 get_data (NULL, filedata, conflicts_offset,
17360 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 17361 if (!econf32)
5a814d6d
AM
17362 {
17363 free (iconf);
17364 return FALSE;
17365 }
252b5132
RH
17366
17367 for (cnt = 0; cnt < conflictsno; ++cnt)
17368 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
17369
17370 free (econf32);
252b5132
RH
17371 }
17372 else
17373 {
2cf0635d 17374 Elf64_External_Conflict * econf64;
a6e9f9df 17375
3f5e193b 17376 econf64 = (Elf64_External_Conflict *)
95099889
AM
17377 get_data (NULL, filedata, conflicts_offset,
17378 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 17379 if (!econf64)
5a814d6d
AM
17380 {
17381 free (iconf);
17382 return FALSE;
17383 }
252b5132
RH
17384
17385 for (cnt = 0; cnt < conflictsno; ++cnt)
17386 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
17387
17388 free (econf64);
252b5132
RH
17389 }
17390
d3a49aa8
AM
17391 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
17392 "\nSection '.conflict' contains %lu entries:\n",
17393 (unsigned long) conflictsno),
c7e7ca54 17394 (unsigned long) conflictsno);
252b5132
RH
17395 puts (_(" Num: Index Value Name"));
17396
17397 for (cnt = 0; cnt < conflictsno; ++cnt)
17398 {
b34976b6 17399 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 17400
978c4450 17401 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 17402 printf (_("<corrupt symbol index>"));
d79b3d50 17403 else
e0a31db1
NC
17404 {
17405 Elf_Internal_Sym * psym;
17406
978c4450 17407 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
17408 print_vma (psym->st_value, FULL_HEX);
17409 putchar (' ');
978c4450
AM
17410 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17411 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17412 else
17413 printf (_("<corrupt: %14ld>"), psym->st_name);
17414 }
31104126 17415 putchar ('\n');
252b5132
RH
17416 }
17417
252b5132
RH
17418 free (iconf);
17419 }
17420
ccb4c951
RS
17421 if (pltgot != 0 && local_gotno != 0)
17422 {
91d6fa6a 17423 bfd_vma ent, local_end, global_end;
bbeee7ea 17424 size_t i, offset;
2cf0635d 17425 unsigned char * data;
82b1b41b 17426 unsigned char * data_end;
bbeee7ea 17427 int addr_size;
ccb4c951 17428
91d6fa6a 17429 ent = pltgot;
ccb4c951
RS
17430 addr_size = (is_32bit_elf ? 4 : 8);
17431 local_end = pltgot + local_gotno * addr_size;
ccb4c951 17432
74e1a04b
NC
17433 /* PR binutils/17533 file: 012-111227-0.004 */
17434 if (symtabno < gotsym)
17435 {
17436 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 17437 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 17438 return FALSE;
74e1a04b 17439 }
82b1b41b 17440
74e1a04b 17441 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
17442 /* PR 17531: file: 54c91a34. */
17443 if (global_end < local_end)
17444 {
17445 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 17446 return FALSE;
82b1b41b 17447 }
948f632f 17448
dda8d76d
NC
17449 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
17450 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
17451 global_end - pltgot, 1,
17452 _("Global Offset Table data"));
919383ac 17453 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 17454 data_end = data + (global_end - pltgot);
59245841 17455
ccb4c951
RS
17456 printf (_("\nPrimary GOT:\n"));
17457 printf (_(" Canonical gp value: "));
17458 print_vma (pltgot + 0x7ff0, LONG_HEX);
17459 printf ("\n\n");
17460
17461 printf (_(" Reserved entries:\n"));
17462 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
17463 addr_size * 2, _("Address"), _("Access"),
17464 addr_size * 2, _("Initial"));
82b1b41b 17465 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 17466 printf (_(" Lazy resolver\n"));
82b1b41b
NC
17467 if (ent == (bfd_vma) -1)
17468 goto got_print_fail;
75ec1fdb 17469
c4ab9505
MR
17470 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
17471 This entry will be used by some runtime loaders, to store the
17472 module pointer. Otherwise this is an ordinary local entry.
17473 PR 21344: Check for the entry being fully available before
17474 fetching it. */
17475 if (data
17476 && data + ent - pltgot + addr_size <= data_end
17477 && (byte_get (data + ent - pltgot, addr_size)
17478 >> (addr_size * 8 - 1)) != 0)
17479 {
17480 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17481 printf (_(" Module pointer (GNU extension)\n"));
17482 if (ent == (bfd_vma) -1)
17483 goto got_print_fail;
ccb4c951
RS
17484 }
17485 printf ("\n");
17486
f17e9d8a 17487 if (data != NULL && ent < local_end)
ccb4c951
RS
17488 {
17489 printf (_(" Local entries:\n"));
cc5914eb 17490 printf (" %*s %10s %*s\n",
2b692964
NC
17491 addr_size * 2, _("Address"), _("Access"),
17492 addr_size * 2, _("Initial"));
91d6fa6a 17493 while (ent < local_end)
ccb4c951 17494 {
82b1b41b 17495 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17496 printf ("\n");
82b1b41b
NC
17497 if (ent == (bfd_vma) -1)
17498 goto got_print_fail;
ccb4c951
RS
17499 }
17500 printf ("\n");
17501 }
17502
f17e9d8a 17503 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
17504 {
17505 int sym_width;
17506
17507 printf (_(" Global entries:\n"));
cc5914eb 17508 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
17509 addr_size * 2, _("Address"),
17510 _("Access"),
2b692964 17511 addr_size * 2, _("Initial"),
9cf03b7e
NC
17512 addr_size * 2, _("Sym.Val."),
17513 _("Type"),
17514 /* Note for translators: "Ndx" = abbreviated form of "Index". */
17515 _("Ndx"), _("Name"));
0b4362b0 17516
ccb4c951 17517 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 17518
ccb4c951
RS
17519 for (i = gotsym; i < symtabno; i++)
17520 {
82b1b41b 17521 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17522 printf (" ");
e0a31db1 17523
978c4450 17524 if (filedata->dynamic_symbols == NULL)
e0a31db1 17525 printf (_("<no dynamic symbols>"));
978c4450 17526 else if (i < filedata->num_dynamic_syms)
e0a31db1 17527 {
978c4450 17528 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
17529
17530 print_vma (psym->st_value, LONG_HEX);
17531 printf (" %-7s %3s ",
dda8d76d
NC
17532 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17533 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 17534
978c4450
AM
17535 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17536 print_symbol (sym_width,
17537 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17538 else
17539 printf (_("<corrupt: %14ld>"), psym->st_name);
17540 }
ccb4c951 17541 else
7fc5ac57
JBG
17542 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
17543 (unsigned long) i);
e0a31db1 17544
ccb4c951 17545 printf ("\n");
82b1b41b
NC
17546 if (ent == (bfd_vma) -1)
17547 break;
ccb4c951
RS
17548 }
17549 printf ("\n");
17550 }
17551
82b1b41b 17552 got_print_fail:
9db70fc3 17553 free (data);
ccb4c951
RS
17554 }
17555
861fb55a
DJ
17556 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
17557 {
91d6fa6a 17558 bfd_vma ent, end;
861fb55a
DJ
17559 size_t offset, rel_offset;
17560 unsigned long count, i;
2cf0635d 17561 unsigned char * data;
861fb55a 17562 int addr_size, sym_width;
2cf0635d 17563 Elf_Internal_Rela * rels;
861fb55a 17564
dda8d76d 17565 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
17566 if (pltrel == DT_RELA)
17567 {
dda8d76d 17568 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17569 return FALSE;
861fb55a
DJ
17570 }
17571 else
17572 {
dda8d76d 17573 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17574 return FALSE;
861fb55a
DJ
17575 }
17576
91d6fa6a 17577 ent = mips_pltgot;
861fb55a
DJ
17578 addr_size = (is_32bit_elf ? 4 : 8);
17579 end = mips_pltgot + (2 + count) * addr_size;
17580
dda8d76d
NC
17581 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
17582 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 17583 1, _("Procedure Linkage Table data"));
59245841 17584 if (data == NULL)
32ec8896 17585 return FALSE;
59245841 17586
9cf03b7e 17587 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
17588 printf (_(" Reserved entries:\n"));
17589 printf (_(" %*s %*s Purpose\n"),
2b692964 17590 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 17591 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17592 printf (_(" PLT lazy resolver\n"));
91d6fa6a 17593 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17594 printf (_(" Module pointer\n"));
861fb55a
DJ
17595 printf ("\n");
17596
17597 printf (_(" Entries:\n"));
cc5914eb 17598 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
17599 addr_size * 2, _("Address"),
17600 addr_size * 2, _("Initial"),
17601 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
17602 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
17603 for (i = 0; i < count; i++)
17604 {
df97ab2a 17605 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 17606
91d6fa6a 17607 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 17608 printf (" ");
e0a31db1 17609
978c4450 17610 if (idx >= filedata->num_dynamic_syms)
df97ab2a 17611 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 17612 else
e0a31db1 17613 {
978c4450 17614 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
17615
17616 print_vma (psym->st_value, LONG_HEX);
17617 printf (" %-7s %3s ",
dda8d76d
NC
17618 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17619 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
17620 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17621 print_symbol (sym_width,
17622 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17623 else
17624 printf (_("<corrupt: %14ld>"), psym->st_name);
17625 }
861fb55a
DJ
17626 printf ("\n");
17627 }
17628 printf ("\n");
17629
9db70fc3 17630 free (data);
861fb55a
DJ
17631 free (rels);
17632 }
17633
32ec8896 17634 return res;
252b5132
RH
17635}
17636
32ec8896 17637static bfd_boolean
dda8d76d 17638process_nds32_specific (Filedata * filedata)
35c08157
KLC
17639{
17640 Elf_Internal_Shdr *sect = NULL;
17641
dda8d76d 17642 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 17643 if (sect != NULL && sect->sh_size >= 4)
35c08157 17644 {
9c7b8e9b
AM
17645 unsigned char *buf;
17646 unsigned int flag;
35c08157
KLC
17647
17648 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
17649 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
17650 _("NDS32 elf flags section"));
35c08157 17651
9c7b8e9b 17652 if (buf == NULL)
32ec8896
NC
17653 return FALSE;
17654
9c7b8e9b
AM
17655 flag = byte_get (buf, 4);
17656 free (buf);
17657 switch (flag & 0x3)
35c08157
KLC
17658 {
17659 case 0:
17660 printf ("(VEC_SIZE):\tNo entry.\n");
17661 break;
17662 case 1:
17663 printf ("(VEC_SIZE):\t4 bytes\n");
17664 break;
17665 case 2:
17666 printf ("(VEC_SIZE):\t16 bytes\n");
17667 break;
17668 case 3:
17669 printf ("(VEC_SIZE):\treserved\n");
17670 break;
17671 }
17672 }
17673
17674 return TRUE;
17675}
17676
32ec8896 17677static bfd_boolean
dda8d76d 17678process_gnu_liblist (Filedata * filedata)
047b2264 17679{
2cf0635d
NC
17680 Elf_Internal_Shdr * section;
17681 Elf_Internal_Shdr * string_sec;
17682 Elf32_External_Lib * elib;
17683 char * strtab;
c256ffe7 17684 size_t strtab_size;
047b2264 17685 size_t cnt;
d3a49aa8 17686 unsigned long num_liblist;
047b2264 17687 unsigned i;
32ec8896 17688 bfd_boolean res = TRUE;
047b2264
JJ
17689
17690 if (! do_arch)
32ec8896 17691 return TRUE;
047b2264 17692
dda8d76d
NC
17693 for (i = 0, section = filedata->section_headers;
17694 i < filedata->file_header.e_shnum;
b34976b6 17695 i++, section++)
047b2264
JJ
17696 {
17697 switch (section->sh_type)
17698 {
17699 case SHT_GNU_LIBLIST:
dda8d76d 17700 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
17701 break;
17702
3f5e193b 17703 elib = (Elf32_External_Lib *)
dda8d76d 17704 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 17705 _("liblist section data"));
047b2264
JJ
17706
17707 if (elib == NULL)
32ec8896
NC
17708 {
17709 res = FALSE;
17710 break;
17711 }
047b2264 17712
dda8d76d
NC
17713 string_sec = filedata->section_headers + section->sh_link;
17714 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
17715 string_sec->sh_size,
17716 _("liblist string table"));
047b2264
JJ
17717 if (strtab == NULL
17718 || section->sh_entsize != sizeof (Elf32_External_Lib))
17719 {
17720 free (elib);
2842702f 17721 free (strtab);
32ec8896 17722 res = FALSE;
047b2264
JJ
17723 break;
17724 }
59245841 17725 strtab_size = string_sec->sh_size;
047b2264 17726
d3a49aa8
AM
17727 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
17728 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
17729 "\nLibrary list section '%s' contains %lu entries:\n",
17730 num_liblist),
dda8d76d 17731 printable_section_name (filedata, section),
d3a49aa8 17732 num_liblist);
047b2264 17733
2b692964 17734 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
17735
17736 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
17737 ++cnt)
17738 {
17739 Elf32_Lib liblist;
91d6fa6a 17740 time_t atime;
d5b07ef4 17741 char timebuf[128];
2cf0635d 17742 struct tm * tmp;
047b2264
JJ
17743
17744 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17745 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
17746 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17747 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17748 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17749
91d6fa6a 17750 tmp = gmtime (&atime);
e9e44622
JJ
17751 snprintf (timebuf, sizeof (timebuf),
17752 "%04u-%02u-%02uT%02u:%02u:%02u",
17753 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17754 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
17755
17756 printf ("%3lu: ", (unsigned long) cnt);
17757 if (do_wide)
c256ffe7 17758 printf ("%-20s", liblist.l_name < strtab_size
2b692964 17759 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 17760 else
c256ffe7 17761 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 17762 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
17763 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
17764 liblist.l_version, liblist.l_flags);
17765 }
17766
17767 free (elib);
2842702f 17768 free (strtab);
047b2264
JJ
17769 }
17770 }
17771
32ec8896 17772 return res;
047b2264
JJ
17773}
17774
9437c45b 17775static const char *
dda8d76d 17776get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
17777{
17778 static char buff[64];
103f02d3 17779
dda8d76d 17780 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
17781 switch (e_type)
17782 {
57346661 17783 case NT_AUXV:
1ec5cd37 17784 return _("NT_AUXV (auxiliary vector)");
57346661 17785 case NT_PRSTATUS:
1ec5cd37 17786 return _("NT_PRSTATUS (prstatus structure)");
57346661 17787 case NT_FPREGSET:
1ec5cd37 17788 return _("NT_FPREGSET (floating point registers)");
57346661 17789 case NT_PRPSINFO:
1ec5cd37 17790 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 17791 case NT_TASKSTRUCT:
1ec5cd37 17792 return _("NT_TASKSTRUCT (task structure)");
57346661 17793 case NT_PRXFPREG:
1ec5cd37 17794 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
17795 case NT_PPC_VMX:
17796 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
17797 case NT_PPC_VSX:
17798 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
17799 case NT_PPC_TAR:
17800 return _("NT_PPC_TAR (ppc TAR register)");
17801 case NT_PPC_PPR:
17802 return _("NT_PPC_PPR (ppc PPR register)");
17803 case NT_PPC_DSCR:
17804 return _("NT_PPC_DSCR (ppc DSCR register)");
17805 case NT_PPC_EBB:
17806 return _("NT_PPC_EBB (ppc EBB registers)");
17807 case NT_PPC_PMU:
17808 return _("NT_PPC_PMU (ppc PMU registers)");
17809 case NT_PPC_TM_CGPR:
17810 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
17811 case NT_PPC_TM_CFPR:
17812 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
17813 case NT_PPC_TM_CVMX:
17814 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
17815 case NT_PPC_TM_CVSX:
3fd21718 17816 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
17817 case NT_PPC_TM_SPR:
17818 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
17819 case NT_PPC_TM_CTAR:
17820 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
17821 case NT_PPC_TM_CPPR:
17822 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
17823 case NT_PPC_TM_CDSCR:
17824 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
17825 case NT_386_TLS:
17826 return _("NT_386_TLS (x86 TLS information)");
17827 case NT_386_IOPERM:
17828 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
17829 case NT_X86_XSTATE:
17830 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
17831 case NT_S390_HIGH_GPRS:
17832 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
17833 case NT_S390_TIMER:
17834 return _("NT_S390_TIMER (s390 timer register)");
17835 case NT_S390_TODCMP:
17836 return _("NT_S390_TODCMP (s390 TOD comparator register)");
17837 case NT_S390_TODPREG:
17838 return _("NT_S390_TODPREG (s390 TOD programmable register)");
17839 case NT_S390_CTRS:
17840 return _("NT_S390_CTRS (s390 control registers)");
17841 case NT_S390_PREFIX:
17842 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
17843 case NT_S390_LAST_BREAK:
17844 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
17845 case NT_S390_SYSTEM_CALL:
17846 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
17847 case NT_S390_TDB:
17848 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
17849 case NT_S390_VXRS_LOW:
17850 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
17851 case NT_S390_VXRS_HIGH:
17852 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
17853 case NT_S390_GS_CB:
17854 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
17855 case NT_S390_GS_BC:
17856 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
17857 case NT_ARM_VFP:
17858 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
17859 case NT_ARM_TLS:
17860 return _("NT_ARM_TLS (AArch TLS registers)");
17861 case NT_ARM_HW_BREAK:
17862 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
17863 case NT_ARM_HW_WATCH:
17864 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
17865 case NT_ARC_V2:
17866 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
57346661 17867 case NT_PSTATUS:
1ec5cd37 17868 return _("NT_PSTATUS (pstatus structure)");
57346661 17869 case NT_FPREGS:
1ec5cd37 17870 return _("NT_FPREGS (floating point registers)");
57346661 17871 case NT_PSINFO:
1ec5cd37 17872 return _("NT_PSINFO (psinfo structure)");
57346661 17873 case NT_LWPSTATUS:
1ec5cd37 17874 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 17875 case NT_LWPSINFO:
1ec5cd37 17876 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 17877 case NT_WIN32PSTATUS:
1ec5cd37 17878 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
17879 case NT_SIGINFO:
17880 return _("NT_SIGINFO (siginfo_t data)");
17881 case NT_FILE:
17882 return _("NT_FILE (mapped files)");
1ec5cd37
NC
17883 default:
17884 break;
17885 }
17886 else
17887 switch (e_type)
17888 {
17889 case NT_VERSION:
17890 return _("NT_VERSION (version)");
17891 case NT_ARCH:
17892 return _("NT_ARCH (architecture)");
9ef920e9 17893 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 17894 return _("OPEN");
9ef920e9 17895 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 17896 return _("func");
1ec5cd37
NC
17897 default:
17898 break;
17899 }
17900
e9e44622 17901 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 17902 return buff;
779fe533
NC
17903}
17904
32ec8896 17905static bfd_boolean
9ece1fa9
TT
17906print_core_note (Elf_Internal_Note *pnote)
17907{
17908 unsigned int addr_size = is_32bit_elf ? 4 : 8;
17909 bfd_vma count, page_size;
17910 unsigned char *descdata, *filenames, *descend;
17911
17912 if (pnote->type != NT_FILE)
04ac15ab
AS
17913 {
17914 if (do_wide)
17915 printf ("\n");
17916 return TRUE;
17917 }
9ece1fa9
TT
17918
17919#ifndef BFD64
17920 if (!is_32bit_elf)
17921 {
17922 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
17923 /* Still "successful". */
32ec8896 17924 return TRUE;
9ece1fa9
TT
17925 }
17926#endif
17927
17928 if (pnote->descsz < 2 * addr_size)
17929 {
32ec8896
NC
17930 error (_(" Malformed note - too short for header\n"));
17931 return FALSE;
9ece1fa9
TT
17932 }
17933
17934 descdata = (unsigned char *) pnote->descdata;
17935 descend = descdata + pnote->descsz;
17936
17937 if (descdata[pnote->descsz - 1] != '\0')
17938 {
32ec8896
NC
17939 error (_(" Malformed note - does not end with \\0\n"));
17940 return FALSE;
9ece1fa9
TT
17941 }
17942
17943 count = byte_get (descdata, addr_size);
17944 descdata += addr_size;
17945
17946 page_size = byte_get (descdata, addr_size);
17947 descdata += addr_size;
17948
5396a86e
AM
17949 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
17950 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 17951 {
32ec8896
NC
17952 error (_(" Malformed note - too short for supplied file count\n"));
17953 return FALSE;
9ece1fa9
TT
17954 }
17955
17956 printf (_(" Page size: "));
17957 print_vma (page_size, DEC);
17958 printf ("\n");
17959
17960 printf (_(" %*s%*s%*s\n"),
17961 (int) (2 + 2 * addr_size), _("Start"),
17962 (int) (4 + 2 * addr_size), _("End"),
17963 (int) (4 + 2 * addr_size), _("Page Offset"));
17964 filenames = descdata + count * 3 * addr_size;
595712bb 17965 while (count-- > 0)
9ece1fa9
TT
17966 {
17967 bfd_vma start, end, file_ofs;
17968
17969 if (filenames == descend)
17970 {
32ec8896
NC
17971 error (_(" Malformed note - filenames end too early\n"));
17972 return FALSE;
9ece1fa9
TT
17973 }
17974
17975 start = byte_get (descdata, addr_size);
17976 descdata += addr_size;
17977 end = byte_get (descdata, addr_size);
17978 descdata += addr_size;
17979 file_ofs = byte_get (descdata, addr_size);
17980 descdata += addr_size;
17981
17982 printf (" ");
17983 print_vma (start, FULL_HEX);
17984 printf (" ");
17985 print_vma (end, FULL_HEX);
17986 printf (" ");
17987 print_vma (file_ofs, FULL_HEX);
17988 printf ("\n %s\n", filenames);
17989
17990 filenames += 1 + strlen ((char *) filenames);
17991 }
17992
32ec8896 17993 return TRUE;
9ece1fa9
TT
17994}
17995
1118d252
RM
17996static const char *
17997get_gnu_elf_note_type (unsigned e_type)
17998{
1449284b 17999 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18000 switch (e_type)
18001 {
18002 case NT_GNU_ABI_TAG:
18003 return _("NT_GNU_ABI_TAG (ABI version tag)");
18004 case NT_GNU_HWCAP:
18005 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18006 case NT_GNU_BUILD_ID:
18007 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18008 case NT_GNU_GOLD_VERSION:
18009 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18010 case NT_GNU_PROPERTY_TYPE_0:
18011 return _("NT_GNU_PROPERTY_TYPE_0");
18012 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18013 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18014 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18015 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18016 default:
1449284b
NC
18017 {
18018 static char buff[64];
1118d252 18019
1449284b
NC
18020 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18021 return buff;
18022 }
18023 }
1118d252
RM
18024}
18025
a9eafb08
L
18026static void
18027decode_x86_compat_isa (unsigned int bitmask)
18028{
18029 while (bitmask)
18030 {
18031 unsigned int bit = bitmask & (- bitmask);
18032
18033 bitmask &= ~ bit;
18034 switch (bit)
18035 {
18036 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18037 printf ("i486");
18038 break;
18039 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18040 printf ("586");
18041 break;
18042 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18043 printf ("686");
18044 break;
18045 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18046 printf ("SSE");
18047 break;
18048 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18049 printf ("SSE2");
18050 break;
18051 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18052 printf ("SSE3");
18053 break;
18054 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18055 printf ("SSSE3");
18056 break;
18057 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18058 printf ("SSE4_1");
18059 break;
18060 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18061 printf ("SSE4_2");
18062 break;
18063 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18064 printf ("AVX");
18065 break;
18066 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18067 printf ("AVX2");
18068 break;
18069 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18070 printf ("AVX512F");
18071 break;
18072 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18073 printf ("AVX512CD");
18074 break;
18075 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18076 printf ("AVX512ER");
18077 break;
18078 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18079 printf ("AVX512PF");
18080 break;
18081 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18082 printf ("AVX512VL");
18083 break;
18084 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18085 printf ("AVX512DQ");
18086 break;
18087 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18088 printf ("AVX512BW");
18089 break;
65b3d26e
L
18090 default:
18091 printf (_("<unknown: %x>"), bit);
18092 break;
a9eafb08
L
18093 }
18094 if (bitmask)
18095 printf (", ");
18096 }
18097}
18098
9ef920e9 18099static void
1fc87489 18100decode_x86_isa (unsigned int bitmask)
9ef920e9 18101{
0a59decb 18102 if (!bitmask)
90c745dc
L
18103 {
18104 printf (_("<None>"));
18105 return;
18106 }
90c745dc 18107
9ef920e9
NC
18108 while (bitmask)
18109 {
1fc87489 18110 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18111
18112 bitmask &= ~ bit;
18113 switch (bit)
18114 {
a9eafb08
L
18115 case GNU_PROPERTY_X86_ISA_1_CMOV:
18116 printf ("CMOV");
18117 break;
18118 case GNU_PROPERTY_X86_ISA_1_SSE:
18119 printf ("SSE");
18120 break;
18121 case GNU_PROPERTY_X86_ISA_1_SSE2:
18122 printf ("SSE2");
18123 break;
18124 case GNU_PROPERTY_X86_ISA_1_SSE3:
18125 printf ("SSE3");
18126 break;
18127 case GNU_PROPERTY_X86_ISA_1_SSSE3:
18128 printf ("SSSE3");
18129 break;
18130 case GNU_PROPERTY_X86_ISA_1_SSE4_1:
18131 printf ("SSE4_1");
18132 break;
18133 case GNU_PROPERTY_X86_ISA_1_SSE4_2:
18134 printf ("SSE4_2");
18135 break;
18136 case GNU_PROPERTY_X86_ISA_1_AVX:
18137 printf ("AVX");
18138 break;
18139 case GNU_PROPERTY_X86_ISA_1_AVX2:
18140 printf ("AVX2");
18141 break;
18142 case GNU_PROPERTY_X86_ISA_1_FMA:
18143 printf ("FMA");
18144 break;
18145 case GNU_PROPERTY_X86_ISA_1_AVX512F:
18146 printf ("AVX512F");
18147 break;
18148 case GNU_PROPERTY_X86_ISA_1_AVX512CD:
18149 printf ("AVX512CD");
18150 break;
18151 case GNU_PROPERTY_X86_ISA_1_AVX512ER:
18152 printf ("AVX512ER");
18153 break;
18154 case GNU_PROPERTY_X86_ISA_1_AVX512PF:
18155 printf ("AVX512PF");
18156 break;
18157 case GNU_PROPERTY_X86_ISA_1_AVX512VL:
18158 printf ("AVX512VL");
18159 break;
18160 case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
18161 printf ("AVX512DQ");
18162 break;
18163 case GNU_PROPERTY_X86_ISA_1_AVX512BW:
18164 printf ("AVX512BW");
18165 break;
18166 case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
18167 printf ("AVX512_4FMAPS");
18168 break;
18169 case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
18170 printf ("AVX512_4VNNIW");
18171 break;
18172 case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
18173 printf ("AVX512_BITALG");
18174 break;
18175 case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
18176 printf ("AVX512_IFMA");
18177 break;
18178 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
18179 printf ("AVX512_VBMI");
18180 break;
18181 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
18182 printf ("AVX512_VBMI2");
18183 break;
18184 case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
18185 printf ("AVX512_VNNI");
18186 break;
462cac58
L
18187 case GNU_PROPERTY_X86_ISA_1_AVX512_BF16:
18188 printf ("AVX512_BF16");
18189 break;
65b3d26e
L
18190 default:
18191 printf (_("<unknown: %x>"), bit);
18192 break;
9ef920e9
NC
18193 }
18194 if (bitmask)
18195 printf (", ");
18196 }
18197}
18198
ee2fdd6f 18199static void
a9eafb08 18200decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 18201{
0a59decb 18202 if (!bitmask)
90c745dc
L
18203 {
18204 printf (_("<None>"));
18205 return;
18206 }
90c745dc 18207
ee2fdd6f
L
18208 while (bitmask)
18209 {
18210 unsigned int bit = bitmask & (- bitmask);
18211
18212 bitmask &= ~ bit;
18213 switch (bit)
18214 {
18215 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 18216 printf ("IBT");
ee2fdd6f 18217 break;
48580982 18218 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 18219 printf ("SHSTK");
48580982 18220 break;
ee2fdd6f
L
18221 default:
18222 printf (_("<unknown: %x>"), bit);
18223 break;
18224 }
18225 if (bitmask)
18226 printf (", ");
18227 }
18228}
18229
a9eafb08
L
18230static void
18231decode_x86_feature_2 (unsigned int bitmask)
18232{
0a59decb 18233 if (!bitmask)
90c745dc
L
18234 {
18235 printf (_("<None>"));
18236 return;
18237 }
90c745dc 18238
a9eafb08
L
18239 while (bitmask)
18240 {
18241 unsigned int bit = bitmask & (- bitmask);
18242
18243 bitmask &= ~ bit;
18244 switch (bit)
18245 {
18246 case GNU_PROPERTY_X86_FEATURE_2_X86:
18247 printf ("x86");
18248 break;
18249 case GNU_PROPERTY_X86_FEATURE_2_X87:
18250 printf ("x87");
18251 break;
18252 case GNU_PROPERTY_X86_FEATURE_2_MMX:
18253 printf ("MMX");
18254 break;
18255 case GNU_PROPERTY_X86_FEATURE_2_XMM:
18256 printf ("XMM");
18257 break;
18258 case GNU_PROPERTY_X86_FEATURE_2_YMM:
18259 printf ("YMM");
18260 break;
18261 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
18262 printf ("ZMM");
18263 break;
a308b89d
L
18264 case GNU_PROPERTY_X86_FEATURE_2_TMM:
18265 printf ("TMM");
18266 break;
a9eafb08
L
18267 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
18268 printf ("FXSR");
18269 break;
18270 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
18271 printf ("XSAVE");
18272 break;
18273 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
18274 printf ("XSAVEOPT");
18275 break;
18276 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
18277 printf ("XSAVEC");
18278 break;
65b3d26e
L
18279 default:
18280 printf (_("<unknown: %x>"), bit);
18281 break;
a9eafb08
L
18282 }
18283 if (bitmask)
18284 printf (", ");
18285 }
18286}
18287
cd702818
SD
18288static void
18289decode_aarch64_feature_1_and (unsigned int bitmask)
18290{
18291 while (bitmask)
18292 {
18293 unsigned int bit = bitmask & (- bitmask);
18294
18295 bitmask &= ~ bit;
18296 switch (bit)
18297 {
18298 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
18299 printf ("BTI");
18300 break;
18301
18302 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
18303 printf ("PAC");
18304 break;
18305
18306 default:
18307 printf (_("<unknown: %x>"), bit);
18308 break;
18309 }
18310 if (bitmask)
18311 printf (", ");
18312 }
18313}
18314
9ef920e9 18315static void
dda8d76d 18316print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
18317{
18318 unsigned char * ptr = (unsigned char *) pnote->descdata;
18319 unsigned char * ptr_end = ptr + pnote->descsz;
18320 unsigned int size = is_32bit_elf ? 4 : 8;
18321
18322 printf (_(" Properties: "));
18323
1fc87489 18324 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
18325 {
18326 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
18327 return;
18328 }
18329
6ab2c4ed 18330 while (ptr < ptr_end)
9ef920e9 18331 {
1fc87489 18332 unsigned int j;
6ab2c4ed
MC
18333 unsigned int type;
18334 unsigned int datasz;
18335
18336 if ((size_t) (ptr_end - ptr) < 8)
18337 {
18338 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
18339 break;
18340 }
18341
18342 type = byte_get (ptr, 4);
18343 datasz = byte_get (ptr + 4, 4);
9ef920e9 18344
1fc87489 18345 ptr += 8;
9ef920e9 18346
6ab2c4ed 18347 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 18348 {
1fc87489
L
18349 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
18350 type, datasz);
9ef920e9 18351 break;
1fc87489 18352 }
9ef920e9 18353
1fc87489
L
18354 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
18355 {
dda8d76d
NC
18356 if (filedata->file_header.e_machine == EM_X86_64
18357 || filedata->file_header.e_machine == EM_IAMCU
18358 || filedata->file_header.e_machine == EM_386)
1fc87489 18359 {
aa7bca9b
L
18360 unsigned int bitmask;
18361
18362 if (datasz == 4)
0a59decb 18363 bitmask = byte_get (ptr, 4);
aa7bca9b
L
18364 else
18365 bitmask = 0;
18366
1fc87489
L
18367 switch (type)
18368 {
18369 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 18370 if (datasz != 4)
aa7bca9b
L
18371 printf (_("x86 ISA used: <corrupt length: %#x> "),
18372 datasz);
1fc87489 18373 else
aa7bca9b
L
18374 {
18375 printf ("x86 ISA used: ");
18376 decode_x86_isa (bitmask);
18377 }
1fc87489 18378 goto next;
9ef920e9 18379
1fc87489 18380 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 18381 if (datasz != 4)
aa7bca9b
L
18382 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18383 datasz);
1fc87489 18384 else
aa7bca9b
L
18385 {
18386 printf ("x86 ISA needed: ");
18387 decode_x86_isa (bitmask);
18388 }
1fc87489 18389 goto next;
9ef920e9 18390
ee2fdd6f 18391 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 18392 if (datasz != 4)
aa7bca9b
L
18393 printf (_("x86 feature: <corrupt length: %#x> "),
18394 datasz);
ee2fdd6f 18395 else
aa7bca9b
L
18396 {
18397 printf ("x86 feature: ");
a9eafb08
L
18398 decode_x86_feature_1 (bitmask);
18399 }
18400 goto next;
18401
18402 case GNU_PROPERTY_X86_FEATURE_2_USED:
18403 if (datasz != 4)
18404 printf (_("x86 feature used: <corrupt length: %#x> "),
18405 datasz);
18406 else
18407 {
18408 printf ("x86 feature used: ");
18409 decode_x86_feature_2 (bitmask);
18410 }
18411 goto next;
18412
18413 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
18414 if (datasz != 4)
18415 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
18416 else
18417 {
18418 printf ("x86 feature needed: ");
18419 decode_x86_feature_2 (bitmask);
18420 }
18421 goto next;
18422
18423 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
18424 if (datasz != 4)
18425 printf (_("x86 ISA used: <corrupt length: %#x> "),
18426 datasz);
18427 else
18428 {
18429 printf ("x86 ISA used: ");
18430 decode_x86_compat_isa (bitmask);
18431 }
18432 goto next;
18433
18434 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
18435 if (datasz != 4)
18436 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18437 datasz);
18438 else
18439 {
18440 printf ("x86 ISA needed: ");
18441 decode_x86_compat_isa (bitmask);
aa7bca9b 18442 }
ee2fdd6f
L
18443 goto next;
18444
1fc87489
L
18445 default:
18446 break;
18447 }
18448 }
cd702818
SD
18449 else if (filedata->file_header.e_machine == EM_AARCH64)
18450 {
18451 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
18452 {
18453 printf ("AArch64 feature: ");
18454 if (datasz != 4)
18455 printf (_("<corrupt length: %#x> "), datasz);
18456 else
18457 decode_aarch64_feature_1_and (byte_get (ptr, 4));
18458 goto next;
18459 }
18460 }
1fc87489
L
18461 }
18462 else
18463 {
18464 switch (type)
9ef920e9 18465 {
1fc87489
L
18466 case GNU_PROPERTY_STACK_SIZE:
18467 printf (_("stack size: "));
18468 if (datasz != size)
18469 printf (_("<corrupt length: %#x> "), datasz);
18470 else
18471 printf ("%#lx", (unsigned long) byte_get (ptr, size));
18472 goto next;
18473
18474 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
18475 printf ("no copy on protected ");
18476 if (datasz)
18477 printf (_("<corrupt length: %#x> "), datasz);
18478 goto next;
18479
18480 default:
9ef920e9
NC
18481 break;
18482 }
9ef920e9
NC
18483 }
18484
1fc87489
L
18485 if (type < GNU_PROPERTY_LOPROC)
18486 printf (_("<unknown type %#x data: "), type);
18487 else if (type < GNU_PROPERTY_LOUSER)
18488 printf (_("<procesor-specific type %#x data: "), type);
18489 else
18490 printf (_("<application-specific type %#x data: "), type);
18491 for (j = 0; j < datasz; ++j)
18492 printf ("%02x ", ptr[j] & 0xff);
18493 printf (">");
18494
dc1e8a47 18495 next:
9ef920e9 18496 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
18497 if (ptr == ptr_end)
18498 break;
1fc87489 18499
6ab2c4ed
MC
18500 if (do_wide)
18501 printf (", ");
18502 else
18503 printf ("\n\t");
9ef920e9
NC
18504 }
18505
18506 printf ("\n");
18507}
18508
32ec8896 18509static bfd_boolean
dda8d76d 18510print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 18511{
1449284b 18512 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
18513 switch (pnote->type)
18514 {
18515 case NT_GNU_BUILD_ID:
18516 {
18517 unsigned long i;
18518
18519 printf (_(" Build ID: "));
18520 for (i = 0; i < pnote->descsz; ++i)
18521 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 18522 printf ("\n");
664f90a3
TT
18523 }
18524 break;
18525
18526 case NT_GNU_ABI_TAG:
18527 {
18528 unsigned long os, major, minor, subminor;
18529 const char *osname;
18530
3102e897
NC
18531 /* PR 17531: file: 030-599401-0.004. */
18532 if (pnote->descsz < 16)
18533 {
18534 printf (_(" <corrupt GNU_ABI_TAG>\n"));
18535 break;
18536 }
18537
664f90a3
TT
18538 os = byte_get ((unsigned char *) pnote->descdata, 4);
18539 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18540 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
18541 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
18542
18543 switch (os)
18544 {
18545 case GNU_ABI_TAG_LINUX:
18546 osname = "Linux";
18547 break;
18548 case GNU_ABI_TAG_HURD:
18549 osname = "Hurd";
18550 break;
18551 case GNU_ABI_TAG_SOLARIS:
18552 osname = "Solaris";
18553 break;
18554 case GNU_ABI_TAG_FREEBSD:
18555 osname = "FreeBSD";
18556 break;
18557 case GNU_ABI_TAG_NETBSD:
18558 osname = "NetBSD";
18559 break;
14ae95f2
RM
18560 case GNU_ABI_TAG_SYLLABLE:
18561 osname = "Syllable";
18562 break;
18563 case GNU_ABI_TAG_NACL:
18564 osname = "NaCl";
18565 break;
664f90a3
TT
18566 default:
18567 osname = "Unknown";
18568 break;
18569 }
18570
18571 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
18572 major, minor, subminor);
18573 }
18574 break;
926c5385
CC
18575
18576 case NT_GNU_GOLD_VERSION:
18577 {
18578 unsigned long i;
18579
18580 printf (_(" Version: "));
18581 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
18582 printf ("%c", pnote->descdata[i]);
18583 printf ("\n");
18584 }
18585 break;
1449284b
NC
18586
18587 case NT_GNU_HWCAP:
18588 {
18589 unsigned long num_entries, mask;
18590
18591 /* Hardware capabilities information. Word 0 is the number of entries.
18592 Word 1 is a bitmask of enabled entries. The rest of the descriptor
18593 is a series of entries, where each entry is a single byte followed
18594 by a nul terminated string. The byte gives the bit number to test
18595 if enabled in the bitmask. */
18596 printf (_(" Hardware Capabilities: "));
18597 if (pnote->descsz < 8)
18598 {
32ec8896
NC
18599 error (_("<corrupt GNU_HWCAP>\n"));
18600 return FALSE;
1449284b
NC
18601 }
18602 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
18603 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18604 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
18605 /* FIXME: Add code to display the entries... */
18606 }
18607 break;
18608
9ef920e9 18609 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 18610 print_gnu_property_note (filedata, pnote);
9ef920e9 18611 break;
9abca702 18612
1449284b
NC
18613 default:
18614 /* Handle unrecognised types. An error message should have already been
18615 created by get_gnu_elf_note_type(), so all that we need to do is to
18616 display the data. */
18617 {
18618 unsigned long i;
18619
18620 printf (_(" Description data: "));
18621 for (i = 0; i < pnote->descsz; ++i)
18622 printf ("%02x ", pnote->descdata[i] & 0xff);
18623 printf ("\n");
18624 }
18625 break;
664f90a3
TT
18626 }
18627
32ec8896 18628 return TRUE;
664f90a3
TT
18629}
18630
685080f2
NC
18631static const char *
18632get_v850_elf_note_type (enum v850_notes n_type)
18633{
18634 static char buff[64];
18635
18636 switch (n_type)
18637 {
18638 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
18639 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
18640 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
18641 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
18642 case V850_NOTE_CACHE_INFO: return _("Use of cache");
18643 case V850_NOTE_MMU_INFO: return _("Use of MMU");
18644 default:
18645 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
18646 return buff;
18647 }
18648}
18649
32ec8896 18650static bfd_boolean
685080f2
NC
18651print_v850_note (Elf_Internal_Note * pnote)
18652{
18653 unsigned int val;
18654
18655 if (pnote->descsz != 4)
32ec8896
NC
18656 return FALSE;
18657
685080f2
NC
18658 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
18659
18660 if (val == 0)
18661 {
18662 printf (_("not set\n"));
32ec8896 18663 return TRUE;
685080f2
NC
18664 }
18665
18666 switch (pnote->type)
18667 {
18668 case V850_NOTE_ALIGNMENT:
18669 switch (val)
18670 {
32ec8896
NC
18671 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
18672 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
18673 }
18674 break;
14ae95f2 18675
685080f2
NC
18676 case V850_NOTE_DATA_SIZE:
18677 switch (val)
18678 {
32ec8896
NC
18679 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
18680 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
18681 }
18682 break;
14ae95f2 18683
685080f2
NC
18684 case V850_NOTE_FPU_INFO:
18685 switch (val)
18686 {
32ec8896
NC
18687 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
18688 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
18689 }
18690 break;
14ae95f2 18691
685080f2
NC
18692 case V850_NOTE_MMU_INFO:
18693 case V850_NOTE_CACHE_INFO:
18694 case V850_NOTE_SIMD_INFO:
18695 if (val == EF_RH850_SIMD)
18696 {
18697 printf (_("yes\n"));
32ec8896 18698 return TRUE;
685080f2
NC
18699 }
18700 break;
18701
18702 default:
18703 /* An 'unknown note type' message will already have been displayed. */
18704 break;
18705 }
18706
18707 printf (_("unknown value: %x\n"), val);
32ec8896 18708 return FALSE;
685080f2
NC
18709}
18710
32ec8896 18711static bfd_boolean
c6056a74
SF
18712process_netbsd_elf_note (Elf_Internal_Note * pnote)
18713{
18714 unsigned int version;
18715
18716 switch (pnote->type)
18717 {
18718 case NT_NETBSD_IDENT:
b966f55f
AM
18719 if (pnote->descsz < 1)
18720 break;
c6056a74
SF
18721 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18722 if ((version / 10000) % 100)
b966f55f 18723 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
18724 version, version / 100000000, (version / 1000000) % 100,
18725 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 18726 'A' + (version / 10000) % 26);
c6056a74
SF
18727 else
18728 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 18729 version, version / 100000000, (version / 1000000) % 100,
15f205b1 18730 (version / 100) % 100);
32ec8896 18731 return TRUE;
c6056a74
SF
18732
18733 case NT_NETBSD_MARCH:
9abca702 18734 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 18735 pnote->descdata);
32ec8896 18736 return TRUE;
c6056a74 18737
9abca702
CZ
18738#ifdef NT_NETBSD_PAX
18739 case NT_NETBSD_PAX:
b966f55f
AM
18740 if (pnote->descsz < 1)
18741 break;
9abca702
CZ
18742 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18743 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
18744 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
18745 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
18746 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
18747 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
18748 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
18749 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
18750 return TRUE;
18751#endif
c6056a74 18752 }
b966f55f
AM
18753
18754 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
18755 pnote->descsz, pnote->type);
18756 return FALSE;
c6056a74
SF
18757}
18758
f4ddf30f 18759static const char *
dda8d76d 18760get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 18761{
f4ddf30f
JB
18762 switch (e_type)
18763 {
18764 case NT_FREEBSD_THRMISC:
18765 return _("NT_THRMISC (thrmisc structure)");
18766 case NT_FREEBSD_PROCSTAT_PROC:
18767 return _("NT_PROCSTAT_PROC (proc data)");
18768 case NT_FREEBSD_PROCSTAT_FILES:
18769 return _("NT_PROCSTAT_FILES (files data)");
18770 case NT_FREEBSD_PROCSTAT_VMMAP:
18771 return _("NT_PROCSTAT_VMMAP (vmmap data)");
18772 case NT_FREEBSD_PROCSTAT_GROUPS:
18773 return _("NT_PROCSTAT_GROUPS (groups data)");
18774 case NT_FREEBSD_PROCSTAT_UMASK:
18775 return _("NT_PROCSTAT_UMASK (umask data)");
18776 case NT_FREEBSD_PROCSTAT_RLIMIT:
18777 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
18778 case NT_FREEBSD_PROCSTAT_OSREL:
18779 return _("NT_PROCSTAT_OSREL (osreldate data)");
18780 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
18781 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
18782 case NT_FREEBSD_PROCSTAT_AUXV:
18783 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
18784 case NT_FREEBSD_PTLWPINFO:
18785 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 18786 }
dda8d76d 18787 return get_note_type (filedata, e_type);
f4ddf30f
JB
18788}
18789
9437c45b 18790static const char *
dda8d76d 18791get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
18792{
18793 static char buff[64];
18794
540e6170
CZ
18795 switch (e_type)
18796 {
18797 case NT_NETBSDCORE_PROCINFO:
18798 /* NetBSD core "procinfo" structure. */
18799 return _("NetBSD procinfo structure");
9437c45b 18800
540e6170
CZ
18801#ifdef NT_NETBSDCORE_AUXV
18802 case NT_NETBSDCORE_AUXV:
18803 return _("NetBSD ELF auxiliary vector data");
18804#endif
9437c45b 18805
06d949ec
KR
18806#ifdef NT_NETBSDCORE_LWPSTATUS
18807 case NT_NETBSDCORE_LWPSTATUS:
18808 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
18809#endif
18810
540e6170 18811 default:
06d949ec 18812 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
18813 defined for NetBSD core files. If the note type is less
18814 than the start of the machine-dependent note types, we don't
18815 understand it. */
18816
18817 if (e_type < NT_NETBSDCORE_FIRSTMACH)
18818 {
18819 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18820 return buff;
18821 }
18822 break;
9437c45b
JT
18823 }
18824
dda8d76d 18825 switch (filedata->file_header.e_machine)
9437c45b
JT
18826 {
18827 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
18828 and PT_GETFPREGS == mach+2. */
18829
18830 case EM_OLD_ALPHA:
18831 case EM_ALPHA:
18832 case EM_SPARC:
18833 case EM_SPARC32PLUS:
18834 case EM_SPARCV9:
18835 switch (e_type)
18836 {
2b692964 18837 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 18838 return _("PT_GETREGS (reg structure)");
2b692964 18839 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 18840 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18841 default:
18842 break;
18843 }
18844 break;
18845
c0d38b0e
CZ
18846 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
18847 There's also old PT___GETREGS40 == mach + 1 for old reg
18848 structure which lacks GBR. */
18849 case EM_SH:
18850 switch (e_type)
18851 {
18852 case NT_NETBSDCORE_FIRSTMACH + 1:
18853 return _("PT___GETREGS40 (old reg structure)");
18854 case NT_NETBSDCORE_FIRSTMACH + 3:
18855 return _("PT_GETREGS (reg structure)");
18856 case NT_NETBSDCORE_FIRSTMACH + 5:
18857 return _("PT_GETFPREGS (fpreg structure)");
18858 default:
18859 break;
18860 }
18861 break;
18862
9437c45b
JT
18863 /* On all other arch's, PT_GETREGS == mach+1 and
18864 PT_GETFPREGS == mach+3. */
18865 default:
18866 switch (e_type)
18867 {
2b692964 18868 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 18869 return _("PT_GETREGS (reg structure)");
2b692964 18870 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 18871 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18872 default:
18873 break;
18874 }
18875 }
18876
9cf03b7e 18877 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 18878 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
18879 return buff;
18880}
18881
70616151
TT
18882static const char *
18883get_stapsdt_note_type (unsigned e_type)
18884{
18885 static char buff[64];
18886
18887 switch (e_type)
18888 {
18889 case NT_STAPSDT:
18890 return _("NT_STAPSDT (SystemTap probe descriptors)");
18891
18892 default:
18893 break;
18894 }
18895
18896 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18897 return buff;
18898}
18899
32ec8896 18900static bfd_boolean
c6a9fc58
TT
18901print_stapsdt_note (Elf_Internal_Note *pnote)
18902{
3ca60c57
NC
18903 size_t len, maxlen;
18904 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
18905 char *data = pnote->descdata;
18906 char *data_end = pnote->descdata + pnote->descsz;
18907 bfd_vma pc, base_addr, semaphore;
18908 char *provider, *probe, *arg_fmt;
18909
3ca60c57
NC
18910 if (pnote->descsz < (addr_size * 3))
18911 goto stapdt_note_too_small;
18912
c6a9fc58
TT
18913 pc = byte_get ((unsigned char *) data, addr_size);
18914 data += addr_size;
3ca60c57 18915
c6a9fc58
TT
18916 base_addr = byte_get ((unsigned char *) data, addr_size);
18917 data += addr_size;
3ca60c57 18918
c6a9fc58
TT
18919 semaphore = byte_get ((unsigned char *) data, addr_size);
18920 data += addr_size;
18921
3ca60c57
NC
18922 if (data >= data_end)
18923 goto stapdt_note_too_small;
18924 maxlen = data_end - data;
18925 len = strnlen (data, maxlen);
18926 if (len < maxlen)
18927 {
18928 provider = data;
18929 data += len + 1;
18930 }
18931 else
18932 goto stapdt_note_too_small;
18933
18934 if (data >= data_end)
18935 goto stapdt_note_too_small;
18936 maxlen = data_end - data;
18937 len = strnlen (data, maxlen);
18938 if (len < maxlen)
18939 {
18940 probe = data;
18941 data += len + 1;
18942 }
18943 else
18944 goto stapdt_note_too_small;
9abca702 18945
3ca60c57
NC
18946 if (data >= data_end)
18947 goto stapdt_note_too_small;
18948 maxlen = data_end - data;
18949 len = strnlen (data, maxlen);
18950 if (len < maxlen)
18951 {
18952 arg_fmt = data;
18953 data += len + 1;
18954 }
18955 else
18956 goto stapdt_note_too_small;
c6a9fc58
TT
18957
18958 printf (_(" Provider: %s\n"), provider);
18959 printf (_(" Name: %s\n"), probe);
18960 printf (_(" Location: "));
18961 print_vma (pc, FULL_HEX);
18962 printf (_(", Base: "));
18963 print_vma (base_addr, FULL_HEX);
18964 printf (_(", Semaphore: "));
18965 print_vma (semaphore, FULL_HEX);
9cf03b7e 18966 printf ("\n");
c6a9fc58
TT
18967 printf (_(" Arguments: %s\n"), arg_fmt);
18968
18969 return data == data_end;
3ca60c57
NC
18970
18971 stapdt_note_too_small:
18972 printf (_(" <corrupt - note is too small>\n"));
18973 error (_("corrupt stapdt note - the data size is too small\n"));
18974 return FALSE;
c6a9fc58
TT
18975}
18976
00e98fc7
TG
18977static const char *
18978get_ia64_vms_note_type (unsigned e_type)
18979{
18980 static char buff[64];
18981
18982 switch (e_type)
18983 {
18984 case NT_VMS_MHD:
18985 return _("NT_VMS_MHD (module header)");
18986 case NT_VMS_LNM:
18987 return _("NT_VMS_LNM (language name)");
18988 case NT_VMS_SRC:
18989 return _("NT_VMS_SRC (source files)");
18990 case NT_VMS_TITLE:
9cf03b7e 18991 return "NT_VMS_TITLE";
00e98fc7
TG
18992 case NT_VMS_EIDC:
18993 return _("NT_VMS_EIDC (consistency check)");
18994 case NT_VMS_FPMODE:
18995 return _("NT_VMS_FPMODE (FP mode)");
18996 case NT_VMS_LINKTIME:
9cf03b7e 18997 return "NT_VMS_LINKTIME";
00e98fc7
TG
18998 case NT_VMS_IMGNAM:
18999 return _("NT_VMS_IMGNAM (image name)");
19000 case NT_VMS_IMGID:
19001 return _("NT_VMS_IMGID (image id)");
19002 case NT_VMS_LINKID:
19003 return _("NT_VMS_LINKID (link id)");
19004 case NT_VMS_IMGBID:
19005 return _("NT_VMS_IMGBID (build id)");
19006 case NT_VMS_GSTNAM:
19007 return _("NT_VMS_GSTNAM (sym table name)");
19008 case NT_VMS_ORIG_DYN:
9cf03b7e 19009 return "NT_VMS_ORIG_DYN";
00e98fc7 19010 case NT_VMS_PATCHTIME:
9cf03b7e 19011 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19012 default:
19013 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19014 return buff;
19015 }
19016}
19017
32ec8896 19018static bfd_boolean
00e98fc7
TG
19019print_ia64_vms_note (Elf_Internal_Note * pnote)
19020{
8d18bf79
NC
19021 int maxlen = pnote->descsz;
19022
19023 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19024 goto desc_size_fail;
19025
00e98fc7
TG
19026 switch (pnote->type)
19027 {
19028 case NT_VMS_MHD:
8d18bf79
NC
19029 if (maxlen <= 36)
19030 goto desc_size_fail;
19031
19032 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19033
19034 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19035 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19036 if (l + 34 < maxlen)
19037 {
19038 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19039 if (l + 35 < maxlen)
19040 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19041 else
19042 printf (_(" Module version : <missing>\n"));
19043 }
00e98fc7 19044 else
8d18bf79
NC
19045 {
19046 printf (_(" Module name : <missing>\n"));
19047 printf (_(" Module version : <missing>\n"));
19048 }
00e98fc7 19049 break;
8d18bf79 19050
00e98fc7 19051 case NT_VMS_LNM:
8d18bf79 19052 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19053 break;
8d18bf79 19054
00e98fc7
TG
19055#ifdef BFD64
19056 case NT_VMS_FPMODE:
9cf03b7e 19057 printf (_(" Floating Point mode: "));
8d18bf79
NC
19058 if (maxlen < 8)
19059 goto desc_size_fail;
19060 /* FIXME: Generate an error if descsz > 8 ? */
19061
4a5cb34f 19062 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19063 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19064 break;
8d18bf79 19065
00e98fc7
TG
19066 case NT_VMS_LINKTIME:
19067 printf (_(" Link time: "));
8d18bf79
NC
19068 if (maxlen < 8)
19069 goto desc_size_fail;
19070 /* FIXME: Generate an error if descsz > 8 ? */
19071
00e98fc7 19072 print_vms_time
8d18bf79 19073 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19074 printf ("\n");
19075 break;
8d18bf79 19076
00e98fc7
TG
19077 case NT_VMS_PATCHTIME:
19078 printf (_(" Patch time: "));
8d18bf79
NC
19079 if (maxlen < 8)
19080 goto desc_size_fail;
19081 /* FIXME: Generate an error if descsz > 8 ? */
19082
00e98fc7 19083 print_vms_time
8d18bf79 19084 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19085 printf ("\n");
19086 break;
8d18bf79 19087
00e98fc7 19088 case NT_VMS_ORIG_DYN:
8d18bf79
NC
19089 if (maxlen < 34)
19090 goto desc_size_fail;
19091
00e98fc7
TG
19092 printf (_(" Major id: %u, minor id: %u\n"),
19093 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
19094 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 19095 printf (_(" Last modified : "));
00e98fc7
TG
19096 print_vms_time
19097 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 19098 printf (_("\n Link flags : "));
4a5cb34f 19099 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 19100 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 19101 printf (_(" Header flags: 0x%08x\n"),
948f632f 19102 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 19103 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
19104 break;
19105#endif
8d18bf79 19106
00e98fc7 19107 case NT_VMS_IMGNAM:
8d18bf79 19108 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19109 break;
8d18bf79 19110
00e98fc7 19111 case NT_VMS_GSTNAM:
8d18bf79 19112 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19113 break;
8d18bf79 19114
00e98fc7 19115 case NT_VMS_IMGID:
8d18bf79 19116 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19117 break;
8d18bf79 19118
00e98fc7 19119 case NT_VMS_LINKID:
8d18bf79 19120 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19121 break;
8d18bf79 19122
00e98fc7 19123 default:
32ec8896 19124 return FALSE;
00e98fc7 19125 }
8d18bf79 19126
32ec8896 19127 return TRUE;
8d18bf79
NC
19128
19129 desc_size_fail:
19130 printf (_(" <corrupt - data size is too small>\n"));
19131 error (_("corrupt IA64 note: data size is too small\n"));
19132 return FALSE;
00e98fc7
TG
19133}
19134
fd486f32
AM
19135struct build_attr_cache {
19136 Filedata *filedata;
19137 char *strtab;
19138 unsigned long strtablen;
19139 Elf_Internal_Sym *symtab;
19140 unsigned long nsyms;
19141} ba_cache;
19142
6f156d7a
NC
19143/* Find the symbol associated with a build attribute that is attached
19144 to address OFFSET. If PNAME is non-NULL then store the name of
19145 the symbol (if found) in the provided pointer, Returns NULL if a
19146 symbol could not be found. */
c799a79d 19147
6f156d7a
NC
19148static Elf_Internal_Sym *
19149get_symbol_for_build_attribute (Filedata * filedata,
19150 unsigned long offset,
19151 bfd_boolean is_open_attr,
19152 const char ** pname)
9ef920e9 19153{
fd486f32
AM
19154 Elf_Internal_Sym *saved_sym = NULL;
19155 Elf_Internal_Sym *sym;
9ef920e9 19156
dda8d76d 19157 if (filedata->section_headers != NULL
fd486f32 19158 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 19159 {
c799a79d 19160 Elf_Internal_Shdr * symsec;
9ef920e9 19161
fd486f32
AM
19162 free (ba_cache.strtab);
19163 ba_cache.strtab = NULL;
19164 free (ba_cache.symtab);
19165 ba_cache.symtab = NULL;
19166
c799a79d 19167 /* Load the symbol and string sections. */
dda8d76d
NC
19168 for (symsec = filedata->section_headers;
19169 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 19170 symsec ++)
9ef920e9 19171 {
28d13567
AM
19172 if (symsec->sh_type == SHT_SYMTAB
19173 && get_symtab (filedata, symsec,
19174 &ba_cache.symtab, &ba_cache.nsyms,
19175 &ba_cache.strtab, &ba_cache.strtablen))
19176 break;
9ef920e9 19177 }
fd486f32 19178 ba_cache.filedata = filedata;
9ef920e9
NC
19179 }
19180
fd486f32 19181 if (ba_cache.symtab == NULL)
6f156d7a 19182 return NULL;
9ef920e9 19183
c799a79d 19184 /* Find a symbol whose value matches offset. */
fd486f32 19185 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
19186 if (sym->st_value == offset)
19187 {
fd486f32 19188 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
19189 /* Huh ? This should not happen. */
19190 continue;
9ef920e9 19191
fd486f32 19192 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 19193 continue;
9ef920e9 19194
8fd75781
NC
19195 /* The AArch64 and ARM architectures define mapping symbols
19196 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
19197 if (ba_cache.strtab[sym->st_name] == '$'
19198 && ba_cache.strtab[sym->st_name + 1] != 0
19199 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
19200 continue;
19201
c799a79d
NC
19202 if (is_open_attr)
19203 {
19204 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
19205 and FILE or OBJECT symbols over NOTYPE symbols. We skip
19206 FUNC symbols entirely. */
19207 switch (ELF_ST_TYPE (sym->st_info))
19208 {
c799a79d 19209 case STT_OBJECT:
6f156d7a 19210 case STT_FILE:
c799a79d 19211 saved_sym = sym;
6f156d7a
NC
19212 if (sym->st_size)
19213 {
19214 /* If the symbol has a size associated
19215 with it then we can stop searching. */
fd486f32 19216 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 19217 }
c799a79d 19218 continue;
9ef920e9 19219
c799a79d
NC
19220 case STT_FUNC:
19221 /* Ignore function symbols. */
19222 continue;
19223
19224 default:
19225 break;
19226 }
19227
19228 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 19229 {
c799a79d
NC
19230 case STB_GLOBAL:
19231 if (saved_sym == NULL
19232 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
19233 saved_sym = sym;
19234 break;
c871dade 19235
c799a79d
NC
19236 case STB_LOCAL:
19237 if (saved_sym == NULL)
19238 saved_sym = sym;
19239 break;
19240
19241 default:
9ef920e9
NC
19242 break;
19243 }
19244 }
c799a79d
NC
19245 else
19246 {
19247 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
19248 continue;
19249
19250 saved_sym = sym;
19251 break;
19252 }
19253 }
19254
6f156d7a 19255 if (saved_sym && pname)
fd486f32 19256 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
19257
19258 return saved_sym;
c799a79d
NC
19259}
19260
d20e98ab
NC
19261/* Returns true iff addr1 and addr2 are in the same section. */
19262
19263static bfd_boolean
19264same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
19265{
19266 Elf_Internal_Shdr * a1;
19267 Elf_Internal_Shdr * a2;
19268
19269 a1 = find_section_by_address (filedata, addr1);
19270 a2 = find_section_by_address (filedata, addr2);
9abca702 19271
d20e98ab
NC
19272 return a1 == a2 && a1 != NULL;
19273}
19274
c799a79d 19275static bfd_boolean
dda8d76d
NC
19276print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
19277 Filedata * filedata)
c799a79d 19278{
6f156d7a
NC
19279 static unsigned long global_offset = 0;
19280 static unsigned long global_end = 0;
19281 static unsigned long func_offset = 0;
19282 static unsigned long func_end = 0;
c871dade 19283
6f156d7a
NC
19284 Elf_Internal_Sym * sym;
19285 const char * name;
19286 unsigned long start;
19287 unsigned long end;
19288 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
19289
19290 switch (pnote->descsz)
c799a79d 19291 {
6f156d7a
NC
19292 case 0:
19293 /* A zero-length description means that the range of
19294 the previous note of the same type should be used. */
c799a79d 19295 if (is_open_attr)
c871dade 19296 {
6f156d7a
NC
19297 if (global_end > global_offset)
19298 printf (_(" Applies to region from %#lx to %#lx\n"),
19299 global_offset, global_end);
19300 else
19301 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
19302 }
19303 else
19304 {
6f156d7a
NC
19305 if (func_end > func_offset)
19306 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
19307 else
19308 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 19309 }
6f156d7a 19310 return TRUE;
9ef920e9 19311
6f156d7a
NC
19312 case 4:
19313 start = byte_get ((unsigned char *) pnote->descdata, 4);
19314 end = 0;
19315 break;
19316
19317 case 8:
19318 if (is_32bit_elf)
19319 {
19320 /* FIXME: We should check that version 3+ notes are being used here... */
19321 start = byte_get ((unsigned char *) pnote->descdata, 4);
19322 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19323 }
19324 else
19325 {
19326 start = byte_get ((unsigned char *) pnote->descdata, 8);
19327 end = 0;
19328 }
19329 break;
19330
19331 case 16:
19332 start = byte_get ((unsigned char *) pnote->descdata, 8);
19333 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
19334 break;
9abca702 19335
6f156d7a 19336 default:
c799a79d
NC
19337 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
19338 printf (_(" <invalid descsz>"));
19339 return FALSE;
19340 }
19341
6f156d7a
NC
19342 name = NULL;
19343 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
19344 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
19345 in order to avoid them being confused with the start address of the
19346 first function in the file... */
19347 if (sym == NULL && is_open_attr)
19348 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
19349 & name);
6f156d7a
NC
19350
19351 if (end == 0 && sym != NULL && sym->st_size > 0)
19352 end = start + sym->st_size;
c799a79d
NC
19353
19354 if (is_open_attr)
19355 {
d20e98ab
NC
19356 /* FIXME: Need to properly allow for section alignment.
19357 16 is just the alignment used on x86_64. */
19358 if (global_end > 0
19359 && start > BFD_ALIGN (global_end, 16)
19360 /* Build notes are not guaranteed to be organised in order of
19361 increasing address, but we should find the all of the notes
19362 for one section in the same place. */
19363 && same_section (filedata, start, global_end))
6f156d7a
NC
19364 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
19365 global_end + 1, start - 1);
19366
19367 printf (_(" Applies to region from %#lx"), start);
19368 global_offset = start;
19369
19370 if (end)
19371 {
19372 printf (_(" to %#lx"), end);
19373 global_end = end;
19374 }
c799a79d
NC
19375 }
19376 else
19377 {
6f156d7a
NC
19378 printf (_(" Applies to region from %#lx"), start);
19379 func_offset = start;
19380
19381 if (end)
19382 {
19383 printf (_(" to %#lx"), end);
19384 func_end = end;
19385 }
c799a79d
NC
19386 }
19387
6f156d7a
NC
19388 if (sym && name)
19389 printf (_(" (%s)"), name);
19390
19391 printf ("\n");
19392 return TRUE;
9ef920e9
NC
19393}
19394
19395static bfd_boolean
19396print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
19397{
1d15e434
NC
19398 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
19399 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
19400 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
19401 char name_type;
19402 char name_attribute;
1d15e434 19403 const char * expected_types;
9ef920e9
NC
19404 const char * name = pnote->namedata;
19405 const char * text;
88305e1b 19406 signed int left;
9ef920e9
NC
19407
19408 if (name == NULL || pnote->namesz < 2)
19409 {
19410 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 19411 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
19412 return FALSE;
19413 }
19414
6f156d7a
NC
19415 if (do_wide)
19416 left = 28;
19417 else
19418 left = 20;
88305e1b
NC
19419
19420 /* Version 2 of the spec adds a "GA" prefix to the name field. */
19421 if (name[0] == 'G' && name[1] == 'A')
19422 {
6f156d7a
NC
19423 if (pnote->namesz < 4)
19424 {
19425 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
19426 print_symbol (-20, _(" <corrupt name>"));
19427 return FALSE;
19428 }
19429
88305e1b
NC
19430 printf ("GA");
19431 name += 2;
19432 left -= 2;
19433 }
19434
9ef920e9
NC
19435 switch ((name_type = * name))
19436 {
19437 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19438 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19439 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19440 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19441 printf ("%c", * name);
88305e1b 19442 left --;
9ef920e9
NC
19443 break;
19444 default:
19445 error (_("unrecognised attribute type in name field: %d\n"), name_type);
19446 print_symbol (-20, _("<unknown name type>"));
19447 return FALSE;
19448 }
19449
9ef920e9
NC
19450 ++ name;
19451 text = NULL;
19452
19453 switch ((name_attribute = * name))
19454 {
19455 case GNU_BUILD_ATTRIBUTE_VERSION:
19456 text = _("<version>");
1d15e434 19457 expected_types = string_expected;
9ef920e9
NC
19458 ++ name;
19459 break;
19460 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19461 text = _("<stack prot>");
75d7d298 19462 expected_types = "!+*";
9ef920e9
NC
19463 ++ name;
19464 break;
19465 case GNU_BUILD_ATTRIBUTE_RELRO:
19466 text = _("<relro>");
1d15e434 19467 expected_types = bool_expected;
9ef920e9
NC
19468 ++ name;
19469 break;
19470 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
19471 text = _("<stack size>");
1d15e434 19472 expected_types = number_expected;
9ef920e9
NC
19473 ++ name;
19474 break;
19475 case GNU_BUILD_ATTRIBUTE_TOOL:
19476 text = _("<tool>");
1d15e434 19477 expected_types = string_expected;
9ef920e9
NC
19478 ++ name;
19479 break;
19480 case GNU_BUILD_ATTRIBUTE_ABI:
19481 text = _("<ABI>");
19482 expected_types = "$*";
19483 ++ name;
19484 break;
19485 case GNU_BUILD_ATTRIBUTE_PIC:
19486 text = _("<PIC>");
1d15e434 19487 expected_types = number_expected;
9ef920e9
NC
19488 ++ name;
19489 break;
a8be5506
NC
19490 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
19491 text = _("<short enum>");
1d15e434 19492 expected_types = bool_expected;
a8be5506
NC
19493 ++ name;
19494 break;
9ef920e9
NC
19495 default:
19496 if (ISPRINT (* name))
19497 {
19498 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
19499
19500 if (len > left && ! do_wide)
19501 len = left;
75d7d298 19502 printf ("%.*s:", len, name);
9ef920e9 19503 left -= len;
0dd6ae21 19504 name += len;
9ef920e9
NC
19505 }
19506 else
19507 {
3e6b6445 19508 static char tmpbuf [128];
88305e1b 19509
3e6b6445
NC
19510 error (_("unrecognised byte in name field: %d\n"), * name);
19511 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
19512 text = tmpbuf;
19513 name ++;
9ef920e9
NC
19514 }
19515 expected_types = "*$!+";
19516 break;
19517 }
19518
19519 if (text)
88305e1b 19520 left -= printf ("%s", text);
9ef920e9
NC
19521
19522 if (strchr (expected_types, name_type) == NULL)
75d7d298 19523 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
19524
19525 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
19526 {
19527 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
19528 (unsigned long) pnote->namesz,
19529 (long) (name - pnote->namedata));
19530 return FALSE;
19531 }
19532
19533 if (left < 1 && ! do_wide)
19534 return TRUE;
19535
19536 switch (name_type)
19537 {
19538 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19539 {
b06b2c92 19540 unsigned int bytes;
ddef72cd
NC
19541 unsigned long long val = 0;
19542 unsigned int shift = 0;
19543 char * decoded = NULL;
19544
b06b2c92
NC
19545 bytes = pnote->namesz - (name - pnote->namedata);
19546 if (bytes > 0)
19547 /* The -1 is because the name field is always 0 terminated, and we
19548 want to be able to ensure that the shift in the while loop below
19549 will not overflow. */
19550 -- bytes;
19551
ddef72cd
NC
19552 if (bytes > sizeof (val))
19553 {
3e6b6445
NC
19554 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
19555 bytes);
19556 bytes = sizeof (val);
ddef72cd 19557 }
3e6b6445
NC
19558 /* We do not bother to warn if bytes == 0 as this can
19559 happen with some early versions of the gcc plugin. */
9ef920e9
NC
19560
19561 while (bytes --)
19562 {
79a964dc
NC
19563 unsigned long byte = (* name ++) & 0xff;
19564
19565 val |= byte << shift;
9ef920e9
NC
19566 shift += 8;
19567 }
19568
75d7d298 19569 switch (name_attribute)
9ef920e9 19570 {
75d7d298 19571 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
19572 switch (val)
19573 {
75d7d298
NC
19574 case 0: decoded = "static"; break;
19575 case 1: decoded = "pic"; break;
19576 case 2: decoded = "PIC"; break;
19577 case 3: decoded = "pie"; break;
19578 case 4: decoded = "PIE"; break;
19579 default: break;
9ef920e9 19580 }
75d7d298
NC
19581 break;
19582 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19583 switch (val)
9ef920e9 19584 {
75d7d298
NC
19585 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
19586 case 0: decoded = "off"; break;
19587 case 1: decoded = "on"; break;
19588 case 2: decoded = "all"; break;
19589 case 3: decoded = "strong"; break;
19590 case 4: decoded = "explicit"; break;
19591 default: break;
9ef920e9 19592 }
75d7d298
NC
19593 break;
19594 default:
19595 break;
9ef920e9
NC
19596 }
19597
75d7d298 19598 if (decoded != NULL)
3e6b6445
NC
19599 {
19600 print_symbol (-left, decoded);
19601 left = 0;
19602 }
19603 else if (val == 0)
19604 {
19605 printf ("0x0");
19606 left -= 3;
19607 }
9ef920e9 19608 else
75d7d298
NC
19609 {
19610 if (do_wide)
ddef72cd 19611 left -= printf ("0x%llx", val);
75d7d298 19612 else
ddef72cd 19613 left -= printf ("0x%-.*llx", left, val);
75d7d298 19614 }
9ef920e9
NC
19615 }
19616 break;
19617 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19618 left -= print_symbol (- left, name);
19619 break;
19620 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19621 left -= print_symbol (- left, "true");
19622 break;
19623 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19624 left -= print_symbol (- left, "false");
19625 break;
19626 }
19627
19628 if (do_wide && left > 0)
19629 printf ("%-*s", left, " ");
9abca702 19630
9ef920e9
NC
19631 return TRUE;
19632}
19633
6d118b09
NC
19634/* Note that by the ELF standard, the name field is already null byte
19635 terminated, and namesz includes the terminating null byte.
19636 I.E. the value of namesz for the name "FSF" is 4.
19637
e3c8793a 19638 If the value of namesz is zero, there is no name present. */
9ef920e9 19639
32ec8896 19640static bfd_boolean
9ef920e9 19641process_note (Elf_Internal_Note * pnote,
dda8d76d 19642 Filedata * filedata)
779fe533 19643{
2cf0635d
NC
19644 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
19645 const char * nt;
9437c45b
JT
19646
19647 if (pnote->namesz == 0)
1ec5cd37
NC
19648 /* If there is no note name, then use the default set of
19649 note type strings. */
dda8d76d 19650 nt = get_note_type (filedata, pnote->type);
1ec5cd37 19651
1118d252
RM
19652 else if (const_strneq (pnote->namedata, "GNU"))
19653 /* GNU-specific object file notes. */
19654 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
19655
19656 else if (const_strneq (pnote->namedata, "FreeBSD"))
19657 /* FreeBSD-specific core file notes. */
dda8d76d 19658 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 19659
0112cd26 19660 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 19661 /* NetBSD-specific core file notes. */
dda8d76d 19662 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 19663
c6056a74
SF
19664 else if (const_strneq (pnote->namedata, "NetBSD"))
19665 /* NetBSD-specific core file notes. */
19666 return process_netbsd_elf_note (pnote);
19667
9abca702
CZ
19668 else if (const_strneq (pnote->namedata, "PaX"))
19669 /* NetBSD-specific core file notes. */
19670 return process_netbsd_elf_note (pnote);
19671
b15fa79e
AM
19672 else if (strneq (pnote->namedata, "SPU/", 4))
19673 {
19674 /* SPU-specific core file notes. */
19675 nt = pnote->namedata + 4;
19676 name = "SPU";
19677 }
19678
00e98fc7
TG
19679 else if (const_strneq (pnote->namedata, "IPF/VMS"))
19680 /* VMS/ia64-specific file notes. */
19681 nt = get_ia64_vms_note_type (pnote->type);
19682
70616151
TT
19683 else if (const_strneq (pnote->namedata, "stapsdt"))
19684 nt = get_stapsdt_note_type (pnote->type);
19685
9437c45b 19686 else
1ec5cd37
NC
19687 /* Don't recognize this note name; just use the default set of
19688 note type strings. */
dda8d76d 19689 nt = get_note_type (filedata, pnote->type);
9437c45b 19690
1449284b 19691 printf (" ");
9ef920e9 19692
483767a3
AM
19693 if (((const_strneq (pnote->namedata, "GA")
19694 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19695 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19696 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19697 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
19698 print_gnu_build_attribute_name (pnote);
19699 else
19700 print_symbol (-20, name);
19701
19702 if (do_wide)
19703 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
19704 else
19705 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
19706
19707 if (const_strneq (pnote->namedata, "IPF/VMS"))
19708 return print_ia64_vms_note (pnote);
664f90a3 19709 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 19710 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
19711 else if (const_strneq (pnote->namedata, "stapsdt"))
19712 return print_stapsdt_note (pnote);
9ece1fa9
TT
19713 else if (const_strneq (pnote->namedata, "CORE"))
19714 return print_core_note (pnote);
483767a3
AM
19715 else if (((const_strneq (pnote->namedata, "GA")
19716 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19717 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19718 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19719 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 19720 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 19721
9ef920e9 19722 if (pnote->descsz)
1449284b
NC
19723 {
19724 unsigned long i;
19725
19726 printf (_(" description data: "));
19727 for (i = 0; i < pnote->descsz; i++)
178d8719 19728 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
19729 if (!do_wide)
19730 printf ("\n");
1449284b
NC
19731 }
19732
9ef920e9
NC
19733 if (do_wide)
19734 printf ("\n");
19735
32ec8896 19736 return TRUE;
1449284b 19737}
6d118b09 19738
32ec8896 19739static bfd_boolean
dda8d76d
NC
19740process_notes_at (Filedata * filedata,
19741 Elf_Internal_Shdr * section,
19742 bfd_vma offset,
82ed9683
L
19743 bfd_vma length,
19744 bfd_vma align)
779fe533 19745{
2cf0635d
NC
19746 Elf_External_Note * pnotes;
19747 Elf_External_Note * external;
4dff97b2
NC
19748 char * end;
19749 bfd_boolean res = TRUE;
103f02d3 19750
779fe533 19751 if (length <= 0)
32ec8896 19752 return FALSE;
103f02d3 19753
1449284b
NC
19754 if (section)
19755 {
dda8d76d 19756 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 19757 if (pnotes)
32ec8896 19758 {
dda8d76d 19759 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
19760 {
19761 free (pnotes);
19762 return FALSE;
19763 }
32ec8896 19764 }
1449284b
NC
19765 }
19766 else
82ed9683 19767 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 19768 _("notes"));
4dff97b2 19769
dd24e3da 19770 if (pnotes == NULL)
32ec8896 19771 return FALSE;
779fe533 19772
103f02d3 19773 external = pnotes;
103f02d3 19774
1449284b 19775 if (section)
dda8d76d 19776 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
19777 else
19778 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
19779 (unsigned long) offset, (unsigned long) length);
19780
82ed9683
L
19781 /* NB: Some note sections may have alignment value of 0 or 1. gABI
19782 specifies that notes should be aligned to 4 bytes in 32-bit
19783 objects and to 8 bytes in 64-bit objects. As a Linux extension,
19784 we also support 4 byte alignment in 64-bit objects. If section
19785 alignment is less than 4, we treate alignment as 4 bytes. */
19786 if (align < 4)
19787 align = 4;
19788 else if (align != 4 && align != 8)
19789 {
19790 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
19791 (long) align);
a788aedd 19792 free (pnotes);
82ed9683
L
19793 return FALSE;
19794 }
19795
dbe15e4e 19796 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 19797
c8071705
NC
19798 end = (char *) pnotes + length;
19799 while ((char *) external < end)
779fe533 19800 {
b34976b6 19801 Elf_Internal_Note inote;
15b42fb0 19802 size_t min_notesz;
4dff97b2 19803 char * next;
2cf0635d 19804 char * temp = NULL;
c8071705 19805 size_t data_remaining = end - (char *) external;
6d118b09 19806
dda8d76d 19807 if (!is_ia64_vms (filedata))
15b42fb0 19808 {
9dd3a467
NC
19809 /* PR binutils/15191
19810 Make sure that there is enough data to read. */
15b42fb0
AM
19811 min_notesz = offsetof (Elf_External_Note, name);
19812 if (data_remaining < min_notesz)
9dd3a467 19813 {
d3a49aa8
AM
19814 warn (ngettext ("Corrupt note: only %ld byte remains, "
19815 "not enough for a full note\n",
19816 "Corrupt note: only %ld bytes remain, "
19817 "not enough for a full note\n",
19818 data_remaining),
19819 (long) data_remaining);
9dd3a467
NC
19820 break;
19821 }
5396a86e
AM
19822 data_remaining -= min_notesz;
19823
15b42fb0
AM
19824 inote.type = BYTE_GET (external->type);
19825 inote.namesz = BYTE_GET (external->namesz);
19826 inote.namedata = external->name;
19827 inote.descsz = BYTE_GET (external->descsz);
276da9b3 19828 inote.descdata = ((char *) external
4dff97b2 19829 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 19830 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 19831 next = ((char *) external
4dff97b2 19832 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 19833 }
00e98fc7 19834 else
15b42fb0
AM
19835 {
19836 Elf64_External_VMS_Note *vms_external;
00e98fc7 19837
9dd3a467
NC
19838 /* PR binutils/15191
19839 Make sure that there is enough data to read. */
15b42fb0
AM
19840 min_notesz = offsetof (Elf64_External_VMS_Note, name);
19841 if (data_remaining < min_notesz)
9dd3a467 19842 {
d3a49aa8
AM
19843 warn (ngettext ("Corrupt note: only %ld byte remains, "
19844 "not enough for a full note\n",
19845 "Corrupt note: only %ld bytes remain, "
19846 "not enough for a full note\n",
19847 data_remaining),
19848 (long) data_remaining);
9dd3a467
NC
19849 break;
19850 }
5396a86e 19851 data_remaining -= min_notesz;
3e55a963 19852
15b42fb0
AM
19853 vms_external = (Elf64_External_VMS_Note *) external;
19854 inote.type = BYTE_GET (vms_external->type);
19855 inote.namesz = BYTE_GET (vms_external->namesz);
19856 inote.namedata = vms_external->name;
19857 inote.descsz = BYTE_GET (vms_external->descsz);
19858 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
19859 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19860 next = inote.descdata + align_power (inote.descsz, 3);
19861 }
19862
5396a86e
AM
19863 /* PR 17531: file: 3443835e. */
19864 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
19865 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
19866 || (size_t) (inote.descdata - inote.namedata) > data_remaining
19867 || (size_t) (next - inote.descdata) < inote.descsz
19868 || ((size_t) (next - inote.descdata)
19869 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 19870 {
15b42fb0 19871 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 19872 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
19873 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
19874 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
19875 break;
19876 }
19877
15b42fb0 19878 external = (Elf_External_Note *) next;
dd24e3da 19879
6d118b09
NC
19880 /* Verify that name is null terminated. It appears that at least
19881 one version of Linux (RedHat 6.0) generates corefiles that don't
19882 comply with the ELF spec by failing to include the null byte in
19883 namesz. */
18344509 19884 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 19885 {
5396a86e 19886 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 19887 {
5396a86e
AM
19888 temp = (char *) malloc (inote.namesz + 1);
19889 if (temp == NULL)
19890 {
19891 error (_("Out of memory allocating space for inote name\n"));
19892 res = FALSE;
19893 break;
19894 }
76da6bbe 19895
5396a86e
AM
19896 memcpy (temp, inote.namedata, inote.namesz);
19897 inote.namedata = temp;
19898 }
19899 inote.namedata[inote.namesz] = 0;
6d118b09
NC
19900 }
19901
dda8d76d 19902 if (! process_note (& inote, filedata))
6b4bf3bc 19903 res = FALSE;
103f02d3 19904
9db70fc3
AM
19905 free (temp);
19906 temp = NULL;
779fe533
NC
19907 }
19908
19909 free (pnotes);
103f02d3 19910
779fe533
NC
19911 return res;
19912}
19913
32ec8896 19914static bfd_boolean
dda8d76d 19915process_corefile_note_segments (Filedata * filedata)
779fe533 19916{
2cf0635d 19917 Elf_Internal_Phdr * segment;
b34976b6 19918 unsigned int i;
32ec8896 19919 bfd_boolean res = TRUE;
103f02d3 19920
dda8d76d 19921 if (! get_program_headers (filedata))
6b4bf3bc 19922 return TRUE;
103f02d3 19923
dda8d76d
NC
19924 for (i = 0, segment = filedata->program_headers;
19925 i < filedata->file_header.e_phnum;
b34976b6 19926 i++, segment++)
779fe533
NC
19927 {
19928 if (segment->p_type == PT_NOTE)
dda8d76d 19929 if (! process_notes_at (filedata, NULL,
32ec8896 19930 (bfd_vma) segment->p_offset,
82ed9683
L
19931 (bfd_vma) segment->p_filesz,
19932 (bfd_vma) segment->p_align))
32ec8896 19933 res = FALSE;
779fe533 19934 }
103f02d3 19935
779fe533
NC
19936 return res;
19937}
19938
32ec8896 19939static bfd_boolean
dda8d76d 19940process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
19941{
19942 Elf_External_Note * pnotes;
19943 Elf_External_Note * external;
c8071705 19944 char * end;
32ec8896 19945 bfd_boolean res = TRUE;
685080f2
NC
19946
19947 if (length <= 0)
32ec8896 19948 return FALSE;
685080f2 19949
dda8d76d 19950 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
19951 _("v850 notes"));
19952 if (pnotes == NULL)
32ec8896 19953 return FALSE;
685080f2
NC
19954
19955 external = pnotes;
c8071705 19956 end = (char*) pnotes + length;
685080f2
NC
19957
19958 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
19959 (unsigned long) offset, (unsigned long) length);
19960
c8071705 19961 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
19962 {
19963 Elf_External_Note * next;
19964 Elf_Internal_Note inote;
19965
19966 inote.type = BYTE_GET (external->type);
19967 inote.namesz = BYTE_GET (external->namesz);
19968 inote.namedata = external->name;
19969 inote.descsz = BYTE_GET (external->descsz);
19970 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
19971 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19972
c8071705
NC
19973 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
19974 {
19975 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
19976 inote.descdata = inote.namedata;
19977 inote.namesz = 0;
19978 }
19979
685080f2
NC
19980 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
19981
c8071705 19982 if ( ((char *) next > end)
685080f2
NC
19983 || ((char *) next < (char *) pnotes))
19984 {
19985 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
19986 (unsigned long) ((char *) external - (char *) pnotes));
19987 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19988 inote.type, inote.namesz, inote.descsz);
19989 break;
19990 }
19991
19992 external = next;
19993
19994 /* Prevent out-of-bounds indexing. */
c8071705 19995 if ( inote.namedata + inote.namesz > end
685080f2
NC
19996 || inote.namedata + inote.namesz < inote.namedata)
19997 {
19998 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
19999 (unsigned long) ((char *) external - (char *) pnotes));
20000 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20001 inote.type, inote.namesz, inote.descsz);
20002 break;
20003 }
20004
20005 printf (" %s: ", get_v850_elf_note_type (inote.type));
20006
20007 if (! print_v850_note (& inote))
20008 {
32ec8896 20009 res = FALSE;
685080f2
NC
20010 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20011 inote.namesz, inote.descsz);
20012 }
20013 }
20014
20015 free (pnotes);
20016
20017 return res;
20018}
20019
32ec8896 20020static bfd_boolean
dda8d76d 20021process_note_sections (Filedata * filedata)
1ec5cd37 20022{
2cf0635d 20023 Elf_Internal_Shdr * section;
1ec5cd37 20024 unsigned long i;
32ec8896
NC
20025 unsigned int n = 0;
20026 bfd_boolean res = TRUE;
1ec5cd37 20027
dda8d76d
NC
20028 for (i = 0, section = filedata->section_headers;
20029 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20030 i++, section++)
685080f2
NC
20031 {
20032 if (section->sh_type == SHT_NOTE)
20033 {
dda8d76d 20034 if (! process_notes_at (filedata, section,
32ec8896 20035 (bfd_vma) section->sh_offset,
82ed9683
L
20036 (bfd_vma) section->sh_size,
20037 (bfd_vma) section->sh_addralign))
32ec8896 20038 res = FALSE;
685080f2
NC
20039 n++;
20040 }
20041
dda8d76d
NC
20042 if (( filedata->file_header.e_machine == EM_V800
20043 || filedata->file_header.e_machine == EM_V850
20044 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20045 && section->sh_type == SHT_RENESAS_INFO)
20046 {
dda8d76d 20047 if (! process_v850_notes (filedata,
32ec8896
NC
20048 (bfd_vma) section->sh_offset,
20049 (bfd_vma) section->sh_size))
20050 res = FALSE;
685080f2
NC
20051 n++;
20052 }
20053 }
df565f32
NC
20054
20055 if (n == 0)
20056 /* Try processing NOTE segments instead. */
dda8d76d 20057 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20058
20059 return res;
20060}
20061
32ec8896 20062static bfd_boolean
dda8d76d 20063process_notes (Filedata * filedata)
779fe533
NC
20064{
20065 /* If we have not been asked to display the notes then do nothing. */
20066 if (! do_notes)
32ec8896 20067 return TRUE;
103f02d3 20068
dda8d76d
NC
20069 if (filedata->file_header.e_type != ET_CORE)
20070 return process_note_sections (filedata);
103f02d3 20071
779fe533 20072 /* No program headers means no NOTE segment. */
dda8d76d
NC
20073 if (filedata->file_header.e_phnum > 0)
20074 return process_corefile_note_segments (filedata);
779fe533 20075
1ec5cd37 20076 printf (_("No note segments present in the core file.\n"));
32ec8896 20077 return TRUE;
779fe533
NC
20078}
20079
60abdbed
NC
20080static unsigned char *
20081display_public_gnu_attributes (unsigned char * start,
20082 const unsigned char * const end)
20083{
20084 printf (_(" Unknown GNU attribute: %s\n"), start);
20085
20086 start += strnlen ((char *) start, end - start);
20087 display_raw_attribute (start, end);
20088
20089 return (unsigned char *) end;
20090}
20091
20092static unsigned char *
20093display_generic_attribute (unsigned char * start,
20094 unsigned int tag,
20095 const unsigned char * const end)
20096{
20097 if (tag == 0)
20098 return (unsigned char *) end;
20099
20100 return display_tag_value (tag, start, end);
20101}
20102
32ec8896 20103static bfd_boolean
dda8d76d 20104process_arch_specific (Filedata * filedata)
252b5132 20105{
a952a375 20106 if (! do_arch)
32ec8896 20107 return TRUE;
a952a375 20108
dda8d76d 20109 switch (filedata->file_header.e_machine)
252b5132 20110 {
53a346d8
CZ
20111 case EM_ARC:
20112 case EM_ARC_COMPACT:
20113 case EM_ARC_COMPACT2:
dda8d76d 20114 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
20115 display_arc_attribute,
20116 display_generic_attribute);
11c1ff18 20117 case EM_ARM:
dda8d76d 20118 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
20119 display_arm_attribute,
20120 display_generic_attribute);
20121
252b5132 20122 case EM_MIPS:
4fe85591 20123 case EM_MIPS_RS3_LE:
dda8d76d 20124 return process_mips_specific (filedata);
60abdbed
NC
20125
20126 case EM_MSP430:
dda8d76d
NC
20127 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
20128 display_msp430x_attribute,
c0ea7c52 20129 display_msp430_gnu_attribute);
60abdbed 20130
2dc8dd17
JW
20131 case EM_RISCV:
20132 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
20133 display_riscv_attribute,
20134 display_generic_attribute);
20135
35c08157 20136 case EM_NDS32:
dda8d76d 20137 return process_nds32_specific (filedata);
60abdbed 20138
85f7484a
PB
20139 case EM_68K:
20140 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
20141 display_m68k_gnu_attribute);
20142
34c8bcba 20143 case EM_PPC:
b82317dd 20144 case EM_PPC64:
dda8d76d 20145 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20146 display_power_gnu_attribute);
20147
643f7afb
AK
20148 case EM_S390:
20149 case EM_S390_OLD:
dda8d76d 20150 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20151 display_s390_gnu_attribute);
20152
9e8c70f9
DM
20153 case EM_SPARC:
20154 case EM_SPARC32PLUS:
20155 case EM_SPARCV9:
dda8d76d 20156 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20157 display_sparc_gnu_attribute);
20158
59e6276b 20159 case EM_TI_C6000:
dda8d76d 20160 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
20161 display_tic6x_attribute,
20162 display_generic_attribute);
20163
252b5132 20164 default:
dda8d76d 20165 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
20166 display_public_gnu_attributes,
20167 display_generic_attribute);
252b5132 20168 }
252b5132
RH
20169}
20170
32ec8896 20171static bfd_boolean
dda8d76d 20172get_file_header (Filedata * filedata)
252b5132 20173{
9ea033b2 20174 /* Read in the identity array. */
dda8d76d 20175 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20176 return FALSE;
252b5132 20177
9ea033b2 20178 /* Determine how to read the rest of the header. */
dda8d76d 20179 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 20180 {
1a0670f3
AM
20181 default:
20182 case ELFDATANONE:
adab8cdc
AO
20183 case ELFDATA2LSB:
20184 byte_get = byte_get_little_endian;
20185 byte_put = byte_put_little_endian;
20186 break;
20187 case ELFDATA2MSB:
20188 byte_get = byte_get_big_endian;
20189 byte_put = byte_put_big_endian;
20190 break;
9ea033b2
NC
20191 }
20192
20193 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 20194 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
20195
20196 /* Read in the rest of the header. */
20197 if (is_32bit_elf)
20198 {
20199 Elf32_External_Ehdr ehdr32;
252b5132 20200
dda8d76d 20201 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20202 return FALSE;
103f02d3 20203
dda8d76d
NC
20204 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
20205 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
20206 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
20207 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
20208 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
20209 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
20210 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
20211 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
20212 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
20213 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
20214 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
20215 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
20216 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 20217 }
252b5132 20218 else
9ea033b2
NC
20219 {
20220 Elf64_External_Ehdr ehdr64;
a952a375
NC
20221
20222 /* If we have been compiled with sizeof (bfd_vma) == 4, then
20223 we will not be able to cope with the 64bit data found in
20224 64 ELF files. Detect this now and abort before we start
50c2245b 20225 overwriting things. */
a952a375
NC
20226 if (sizeof (bfd_vma) < 8)
20227 {
e3c8793a
NC
20228 error (_("This instance of readelf has been built without support for a\n\
2022964 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 20230 return FALSE;
a952a375 20231 }
103f02d3 20232
dda8d76d 20233 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20234 return FALSE;
103f02d3 20235
dda8d76d
NC
20236 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
20237 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
20238 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
20239 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
20240 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
20241 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
20242 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
20243 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
20244 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
20245 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
20246 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
20247 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
20248 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 20249 }
252b5132 20250
dda8d76d 20251 if (filedata->file_header.e_shoff)
7ece0d85
JJ
20252 {
20253 /* There may be some extensions in the first section header. Don't
20254 bomb if we can't read it. */
20255 if (is_32bit_elf)
dda8d76d 20256 get_32bit_section_headers (filedata, TRUE);
7ece0d85 20257 else
dda8d76d 20258 get_64bit_section_headers (filedata, TRUE);
7ece0d85 20259 }
560f3c1c 20260
32ec8896 20261 return TRUE;
252b5132
RH
20262}
20263
dda8d76d
NC
20264static void
20265close_file (Filedata * filedata)
20266{
20267 if (filedata)
20268 {
20269 if (filedata->handle)
20270 fclose (filedata->handle);
20271 free (filedata);
20272 }
20273}
20274
20275void
20276close_debug_file (void * data)
20277{
20278 close_file ((Filedata *) data);
20279}
20280
20281static Filedata *
20282open_file (const char * pathname)
20283{
20284 struct stat statbuf;
20285 Filedata * filedata = NULL;
20286
20287 if (stat (pathname, & statbuf) < 0
20288 || ! S_ISREG (statbuf.st_mode))
20289 goto fail;
20290
20291 filedata = calloc (1, sizeof * filedata);
20292 if (filedata == NULL)
20293 goto fail;
20294
20295 filedata->handle = fopen (pathname, "rb");
20296 if (filedata->handle == NULL)
20297 goto fail;
20298
20299 filedata->file_size = (bfd_size_type) statbuf.st_size;
20300 filedata->file_name = pathname;
20301
20302 if (! get_file_header (filedata))
20303 goto fail;
20304
20305 if (filedata->file_header.e_shoff)
20306 {
20307 bfd_boolean res;
20308
20309 /* Read the section headers again, this time for real. */
20310 if (is_32bit_elf)
20311 res = get_32bit_section_headers (filedata, FALSE);
20312 else
20313 res = get_64bit_section_headers (filedata, FALSE);
20314
20315 if (!res)
20316 goto fail;
20317 }
20318
20319 return filedata;
20320
20321 fail:
20322 if (filedata)
20323 {
20324 if (filedata->handle)
20325 fclose (filedata->handle);
20326 free (filedata);
20327 }
20328 return NULL;
20329}
20330
20331void *
20332open_debug_file (const char * pathname)
20333{
20334 return open_file (pathname);
20335}
20336
fb52b2f4
NC
20337/* Process one ELF object file according to the command line options.
20338 This file may actually be stored in an archive. The file is
32ec8896
NC
20339 positioned at the start of the ELF object. Returns TRUE if no
20340 problems were encountered, FALSE otherwise. */
fb52b2f4 20341
32ec8896 20342static bfd_boolean
dda8d76d 20343process_object (Filedata * filedata)
252b5132 20344{
24841daa 20345 bfd_boolean have_separate_files;
252b5132 20346 unsigned int i;
2482f306 20347 bfd_boolean res;
252b5132 20348
dda8d76d 20349 if (! get_file_header (filedata))
252b5132 20350 {
dda8d76d 20351 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 20352 return FALSE;
252b5132
RH
20353 }
20354
20355 /* Initialise per file variables. */
978c4450
AM
20356 for (i = ARRAY_SIZE (filedata->version_info); i--;)
20357 filedata->version_info[i] = 0;
252b5132 20358
978c4450
AM
20359 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
20360 filedata->dynamic_info[i] = 0;
20361 filedata->dynamic_info_DT_GNU_HASH = 0;
20362 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
20363
20364 /* Process the file. */
20365 if (show_name)
dda8d76d 20366 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 20367
18bd398b
NC
20368 /* Initialise the dump_sects array from the cmdline_dump_sects array.
20369 Note we do this even if cmdline_dump_sects is empty because we
20370 must make sure that the dump_sets array is zeroed out before each
20371 object file is processed. */
6431e409
AM
20372 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
20373 memset (filedata->dump.dump_sects, 0,
20374 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20375
dda8d76d 20376 if (cmdline.num_dump_sects > 0)
18bd398b 20377 {
6431e409 20378 if (filedata->dump.num_dump_sects == 0)
18bd398b 20379 /* A sneaky way of allocating the dump_sects array. */
6431e409 20380 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 20381
6431e409
AM
20382 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
20383 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
20384 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20385 }
d70c5fc7 20386
dda8d76d 20387 if (! process_file_header (filedata))
32ec8896 20388 return FALSE;
252b5132 20389
dda8d76d 20390 if (! process_section_headers (filedata))
2f62977e 20391 {
32ec8896
NC
20392 /* Without loaded section headers we cannot process lots of things. */
20393 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 20394
2f62977e 20395 if (! do_using_dynamic)
32ec8896 20396 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 20397 }
252b5132 20398
dda8d76d 20399 if (! process_section_groups (filedata))
32ec8896
NC
20400 /* Without loaded section groups we cannot process unwind. */
20401 do_unwind = FALSE;
d1f5c6e3 20402
2482f306
AM
20403 res = process_program_headers (filedata);
20404 if (res)
20405 res = process_dynamic_section (filedata);
252b5132 20406
dda8d76d 20407 if (! process_relocs (filedata))
32ec8896 20408 res = FALSE;
252b5132 20409
dda8d76d 20410 if (! process_unwind (filedata))
32ec8896 20411 res = FALSE;
4d6ed7c8 20412
dda8d76d 20413 if (! process_symbol_table (filedata))
32ec8896 20414 res = FALSE;
252b5132 20415
dda8d76d 20416 if (! process_syminfo (filedata))
32ec8896 20417 res = FALSE;
252b5132 20418
dda8d76d 20419 if (! process_version_sections (filedata))
32ec8896 20420 res = FALSE;
252b5132 20421
82ed9683 20422 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 20423 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 20424 else
24841daa 20425 have_separate_files = FALSE;
dda8d76d
NC
20426
20427 if (! process_section_contents (filedata))
32ec8896 20428 res = FALSE;
f5842774 20429
24841daa 20430 if (have_separate_files)
dda8d76d 20431 {
24841daa
NC
20432 separate_info * d;
20433
20434 for (d = first_separate_info; d != NULL; d = d->next)
20435 {
20436 if (! process_section_headers (d->handle))
20437 res = FALSE;
20438 else if (! process_section_contents (d->handle))
20439 res = FALSE;
20440 }
20441
20442 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
20443 }
20444
20445 if (! process_notes (filedata))
32ec8896 20446 res = FALSE;
103f02d3 20447
dda8d76d 20448 if (! process_gnu_liblist (filedata))
32ec8896 20449 res = FALSE;
047b2264 20450
dda8d76d 20451 if (! process_arch_specific (filedata))
32ec8896 20452 res = FALSE;
252b5132 20453
dda8d76d
NC
20454 free (filedata->program_headers);
20455 filedata->program_headers = NULL;
d93f0186 20456
dda8d76d
NC
20457 free (filedata->section_headers);
20458 filedata->section_headers = NULL;
252b5132 20459
dda8d76d
NC
20460 free (filedata->string_table);
20461 filedata->string_table = NULL;
20462 filedata->string_table_length = 0;
252b5132 20463
9db70fc3
AM
20464 free (filedata->dump.dump_sects);
20465 filedata->dump.dump_sects = NULL;
20466 filedata->dump.num_dump_sects = 0;
a788aedd 20467
9db70fc3
AM
20468 free (filedata->dynamic_strings);
20469 filedata->dynamic_strings = NULL;
20470 filedata->dynamic_strings_length = 0;
252b5132 20471
9db70fc3
AM
20472 free (filedata->dynamic_symbols);
20473 filedata->dynamic_symbols = NULL;
20474 filedata->num_dynamic_syms = 0;
252b5132 20475
9db70fc3
AM
20476 free (filedata->dynamic_syminfo);
20477 filedata->dynamic_syminfo = NULL;
ff78d6d6 20478
9db70fc3
AM
20479 free (filedata->dynamic_section);
20480 filedata->dynamic_section = NULL;
293c573e 20481
978c4450 20482 while (filedata->symtab_shndx_list != NULL)
8fb879cd 20483 {
978c4450
AM
20484 elf_section_list *next = filedata->symtab_shndx_list->next;
20485 free (filedata->symtab_shndx_list);
20486 filedata->symtab_shndx_list = next;
8fb879cd
AM
20487 }
20488
9db70fc3
AM
20489 free (filedata->section_headers_groups);
20490 filedata->section_headers_groups = NULL;
e4b17d5c 20491
978c4450 20492 if (filedata->section_groups)
e4b17d5c 20493 {
2cf0635d
NC
20494 struct group_list * g;
20495 struct group_list * next;
e4b17d5c 20496
978c4450 20497 for (i = 0; i < filedata->group_count; i++)
e4b17d5c 20498 {
978c4450 20499 for (g = filedata->section_groups [i].root; g != NULL; g = next)
e4b17d5c
L
20500 {
20501 next = g->next;
20502 free (g);
20503 }
20504 }
20505
978c4450
AM
20506 free (filedata->section_groups);
20507 filedata->section_groups = NULL;
e4b17d5c
L
20508 }
20509
19e6b90e 20510 free_debug_memory ();
18bd398b 20511
32ec8896 20512 return res;
252b5132
RH
20513}
20514
2cf0635d 20515/* Process an ELF archive.
32ec8896
NC
20516 On entry the file is positioned just after the ARMAG string.
20517 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 20518
32ec8896 20519static bfd_boolean
dda8d76d 20520process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
20521{
20522 struct archive_info arch;
20523 struct archive_info nested_arch;
20524 size_t got;
32ec8896 20525 bfd_boolean ret = TRUE;
2cf0635d 20526
32ec8896 20527 show_name = TRUE;
2cf0635d
NC
20528
20529 /* The ARCH structure is used to hold information about this archive. */
20530 arch.file_name = NULL;
20531 arch.file = NULL;
20532 arch.index_array = NULL;
20533 arch.sym_table = NULL;
20534 arch.longnames = NULL;
20535
20536 /* The NESTED_ARCH structure is used as a single-item cache of information
20537 about a nested archive (when members of a thin archive reside within
20538 another regular archive file). */
20539 nested_arch.file_name = NULL;
20540 nested_arch.file = NULL;
20541 nested_arch.index_array = NULL;
20542 nested_arch.sym_table = NULL;
20543 nested_arch.longnames = NULL;
20544
dda8d76d 20545 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
20546 filedata->file_size, is_thin_archive,
20547 do_archive_index) != 0)
2cf0635d 20548 {
32ec8896 20549 ret = FALSE;
2cf0635d 20550 goto out;
4145f1d5 20551 }
fb52b2f4 20552
4145f1d5
NC
20553 if (do_archive_index)
20554 {
2cf0635d 20555 if (arch.sym_table == NULL)
1cb7d8b1
AM
20556 error (_("%s: unable to dump the index as none was found\n"),
20557 filedata->file_name);
4145f1d5
NC
20558 else
20559 {
591f7597 20560 unsigned long i, l;
4145f1d5
NC
20561 unsigned long current_pos;
20562
1cb7d8b1
AM
20563 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
20564 "in the symbol table)\n"),
20565 filedata->file_name, (unsigned long) arch.index_num,
20566 arch.sym_size);
dda8d76d
NC
20567
20568 current_pos = ftell (filedata->handle);
4145f1d5 20569
2cf0635d 20570 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 20571 {
1cb7d8b1
AM
20572 if (i == 0
20573 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
20574 {
20575 char * member_name
20576 = get_archive_member_name_at (&arch, arch.index_array[i],
20577 &nested_arch);
2cf0635d 20578
1cb7d8b1
AM
20579 if (member_name != NULL)
20580 {
20581 char * qualified_name
20582 = make_qualified_name (&arch, &nested_arch,
20583 member_name);
2cf0635d 20584
1cb7d8b1
AM
20585 if (qualified_name != NULL)
20586 {
20587 printf (_("Contents of binary %s at offset "),
20588 qualified_name);
c2a7d3f5
NC
20589 (void) print_vma (arch.index_array[i], PREFIX_HEX);
20590 putchar ('\n');
1cb7d8b1
AM
20591 free (qualified_name);
20592 }
fd486f32 20593 free (member_name);
4145f1d5
NC
20594 }
20595 }
2cf0635d
NC
20596
20597 if (l >= arch.sym_size)
4145f1d5 20598 {
1cb7d8b1
AM
20599 error (_("%s: end of the symbol table reached "
20600 "before the end of the index\n"),
dda8d76d 20601 filedata->file_name);
32ec8896 20602 ret = FALSE;
cb8f3167 20603 break;
4145f1d5 20604 }
591f7597 20605 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
20606 printf ("\t%.*s\n",
20607 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 20608 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
20609 }
20610
67ce483b 20611 if (arch.uses_64bit_indices)
c2a7d3f5
NC
20612 l = (l + 7) & ~ 7;
20613 else
20614 l += l & 1;
20615
2cf0635d 20616 if (l < arch.sym_size)
32ec8896 20617 {
d3a49aa8
AM
20618 error (ngettext ("%s: %ld byte remains in the symbol table, "
20619 "but without corresponding entries in "
20620 "the index table\n",
20621 "%s: %ld bytes remain in the symbol table, "
20622 "but without corresponding entries in "
20623 "the index table\n",
20624 arch.sym_size - l),
dda8d76d 20625 filedata->file_name, arch.sym_size - l);
32ec8896
NC
20626 ret = FALSE;
20627 }
4145f1d5 20628
dda8d76d 20629 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 20630 {
1cb7d8b1
AM
20631 error (_("%s: failed to seek back to start of object files "
20632 "in the archive\n"),
dda8d76d 20633 filedata->file_name);
32ec8896 20634 ret = FALSE;
2cf0635d 20635 goto out;
4145f1d5 20636 }
fb52b2f4 20637 }
4145f1d5
NC
20638
20639 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
20640 && !do_segments && !do_header && !do_dump && !do_version
20641 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 20642 && !do_section_groups && !do_dyn_syms)
2cf0635d 20643 {
32ec8896 20644 ret = TRUE; /* Archive index only. */
2cf0635d
NC
20645 goto out;
20646 }
fb52b2f4
NC
20647 }
20648
fb52b2f4
NC
20649 while (1)
20650 {
2cf0635d
NC
20651 char * name;
20652 size_t namelen;
20653 char * qualified_name;
20654
20655 /* Read the next archive header. */
dda8d76d 20656 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
20657 {
20658 error (_("%s: failed to seek to next archive header\n"),
20659 arch.file_name);
20660 ret = FALSE;
20661 break;
20662 }
dda8d76d 20663 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 20664 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
20665 {
20666 if (got == 0)
2cf0635d 20667 break;
28e817cc
NC
20668 /* PR 24049 - we cannot use filedata->file_name as this will
20669 have already been freed. */
20670 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 20671
1cb7d8b1
AM
20672 ret = FALSE;
20673 break;
20674 }
2cf0635d 20675 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
20676 {
20677 error (_("%s: did not find a valid archive header\n"),
20678 arch.file_name);
20679 ret = FALSE;
20680 break;
20681 }
2cf0635d
NC
20682
20683 arch.next_arhdr_offset += sizeof arch.arhdr;
20684
978c4450
AM
20685 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
20686 if (filedata->archive_file_size & 01)
20687 ++filedata->archive_file_size;
2cf0635d
NC
20688
20689 name = get_archive_member_name (&arch, &nested_arch);
20690 if (name == NULL)
fb52b2f4 20691 {
28e817cc 20692 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 20693 ret = FALSE;
d989285c 20694 break;
fb52b2f4 20695 }
2cf0635d 20696 namelen = strlen (name);
fb52b2f4 20697
2cf0635d
NC
20698 qualified_name = make_qualified_name (&arch, &nested_arch, name);
20699 if (qualified_name == NULL)
fb52b2f4 20700 {
28e817cc 20701 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 20702 free (name);
32ec8896 20703 ret = FALSE;
d989285c 20704 break;
fb52b2f4
NC
20705 }
20706
2cf0635d 20707 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
20708 {
20709 /* This is a proxy for an external member of a thin archive. */
20710 Filedata * member_filedata;
20711 char * member_file_name = adjust_relative_path
dda8d76d 20712 (filedata->file_name, name, namelen);
32ec8896 20713
fd486f32 20714 free (name);
1cb7d8b1
AM
20715 if (member_file_name == NULL)
20716 {
fd486f32 20717 free (qualified_name);
1cb7d8b1
AM
20718 ret = FALSE;
20719 break;
20720 }
2cf0635d 20721
1cb7d8b1
AM
20722 member_filedata = open_file (member_file_name);
20723 if (member_filedata == NULL)
20724 {
20725 error (_("Input file '%s' is not readable.\n"), member_file_name);
20726 free (member_file_name);
fd486f32 20727 free (qualified_name);
1cb7d8b1
AM
20728 ret = FALSE;
20729 break;
20730 }
2cf0635d 20731
978c4450 20732 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 20733 member_filedata->file_name = qualified_name;
2cf0635d 20734
1cb7d8b1 20735 if (! process_object (member_filedata))
32ec8896 20736 ret = FALSE;
2cf0635d 20737
1cb7d8b1
AM
20738 close_file (member_filedata);
20739 free (member_file_name);
1cb7d8b1 20740 }
2cf0635d 20741 else if (is_thin_archive)
1cb7d8b1
AM
20742 {
20743 Filedata thin_filedata;
eb02c04d 20744
1cb7d8b1 20745 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 20746
a043396b
NC
20747 /* PR 15140: Allow for corrupt thin archives. */
20748 if (nested_arch.file == NULL)
20749 {
20750 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 20751 qualified_name, name);
fd486f32
AM
20752 free (qualified_name);
20753 free (name);
32ec8896 20754 ret = FALSE;
a043396b
NC
20755 break;
20756 }
fd486f32 20757 free (name);
a043396b 20758
1cb7d8b1 20759 /* This is a proxy for a member of a nested archive. */
978c4450
AM
20760 filedata->archive_file_offset
20761 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 20762
1cb7d8b1
AM
20763 /* The nested archive file will have been opened and setup by
20764 get_archive_member_name. */
978c4450
AM
20765 if (fseek (nested_arch.file, filedata->archive_file_offset,
20766 SEEK_SET) != 0)
1cb7d8b1
AM
20767 {
20768 error (_("%s: failed to seek to archive member.\n"),
20769 nested_arch.file_name);
fd486f32 20770 free (qualified_name);
1cb7d8b1
AM
20771 ret = FALSE;
20772 break;
20773 }
2cf0635d 20774
dda8d76d
NC
20775 thin_filedata.handle = nested_arch.file;
20776 thin_filedata.file_name = qualified_name;
9abca702 20777
1cb7d8b1 20778 if (! process_object (& thin_filedata))
32ec8896 20779 ret = FALSE;
1cb7d8b1 20780 }
2cf0635d 20781 else
1cb7d8b1 20782 {
fd486f32 20783 free (name);
978c4450 20784 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 20785 filedata->file_name = qualified_name;
1cb7d8b1 20786 if (! process_object (filedata))
32ec8896 20787 ret = FALSE;
978c4450 20788 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 20789 /* Stop looping with "negative" archive_file_size. */
978c4450 20790 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 20791 arch.next_arhdr_offset = -1ul;
1cb7d8b1 20792 }
fb52b2f4 20793
2cf0635d 20794 free (qualified_name);
fb52b2f4
NC
20795 }
20796
4145f1d5 20797 out:
2cf0635d
NC
20798 if (nested_arch.file != NULL)
20799 fclose (nested_arch.file);
20800 release_archive (&nested_arch);
20801 release_archive (&arch);
fb52b2f4 20802
d989285c 20803 return ret;
fb52b2f4
NC
20804}
20805
32ec8896 20806static bfd_boolean
2cf0635d 20807process_file (char * file_name)
fb52b2f4 20808{
dda8d76d 20809 Filedata * filedata = NULL;
fb52b2f4
NC
20810 struct stat statbuf;
20811 char armag[SARMAG];
32ec8896 20812 bfd_boolean ret = TRUE;
fb52b2f4
NC
20813
20814 if (stat (file_name, &statbuf) < 0)
20815 {
f24ddbdd
NC
20816 if (errno == ENOENT)
20817 error (_("'%s': No such file\n"), file_name);
20818 else
20819 error (_("Could not locate '%s'. System error message: %s\n"),
20820 file_name, strerror (errno));
32ec8896 20821 return FALSE;
f24ddbdd
NC
20822 }
20823
20824 if (! S_ISREG (statbuf.st_mode))
20825 {
20826 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 20827 return FALSE;
fb52b2f4
NC
20828 }
20829
dda8d76d
NC
20830 filedata = calloc (1, sizeof * filedata);
20831 if (filedata == NULL)
20832 {
20833 error (_("Out of memory allocating file data structure\n"));
20834 return FALSE;
20835 }
20836
20837 filedata->file_name = file_name;
20838 filedata->handle = fopen (file_name, "rb");
20839 if (filedata->handle == NULL)
fb52b2f4 20840 {
f24ddbdd 20841 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 20842 free (filedata);
32ec8896 20843 return FALSE;
fb52b2f4
NC
20844 }
20845
dda8d76d 20846 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 20847 {
4145f1d5 20848 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
20849 fclose (filedata->handle);
20850 free (filedata);
32ec8896 20851 return FALSE;
fb52b2f4
NC
20852 }
20853
dda8d76d 20854 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 20855
fb52b2f4 20856 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 20857 {
dda8d76d 20858 if (! process_archive (filedata, FALSE))
32ec8896
NC
20859 ret = FALSE;
20860 }
2cf0635d 20861 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 20862 {
dda8d76d 20863 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
20864 ret = FALSE;
20865 }
fb52b2f4
NC
20866 else
20867 {
1b513401 20868 if (do_archive_index && !check_all)
4145f1d5
NC
20869 error (_("File %s is not an archive so its index cannot be displayed.\n"),
20870 file_name);
20871
dda8d76d 20872 rewind (filedata->handle);
978c4450 20873 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 20874
dda8d76d 20875 if (! process_object (filedata))
32ec8896 20876 ret = FALSE;
fb52b2f4
NC
20877 }
20878
dda8d76d 20879 fclose (filedata->handle);
8fb879cd
AM
20880 free (filedata->section_headers);
20881 free (filedata->program_headers);
20882 free (filedata->string_table);
6431e409 20883 free (filedata->dump.dump_sects);
dda8d76d 20884 free (filedata);
32ec8896 20885
fd486f32 20886 free (ba_cache.strtab);
1bd6175a 20887 ba_cache.strtab = NULL;
fd486f32 20888 free (ba_cache.symtab);
1bd6175a 20889 ba_cache.symtab = NULL;
fd486f32
AM
20890 ba_cache.filedata = NULL;
20891
fb52b2f4
NC
20892 return ret;
20893}
20894
252b5132
RH
20895#ifdef SUPPORT_DISASSEMBLY
20896/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 20897 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 20898 symbols. */
252b5132
RH
20899
20900void
2cf0635d 20901print_address (unsigned int addr, FILE * outfile)
252b5132
RH
20902{
20903 fprintf (outfile,"0x%8.8x", addr);
20904}
20905
e3c8793a 20906/* Needed by the i386 disassembler. */
dda8d76d 20907
252b5132
RH
20908void
20909db_task_printsym (unsigned int addr)
20910{
20911 print_address (addr, stderr);
20912}
20913#endif
20914
20915int
2cf0635d 20916main (int argc, char ** argv)
252b5132 20917{
ff78d6d6
L
20918 int err;
20919
252b5132
RH
20920#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
20921 setlocale (LC_MESSAGES, "");
3882b010
L
20922#endif
20923#if defined (HAVE_SETLOCALE)
20924 setlocale (LC_CTYPE, "");
252b5132
RH
20925#endif
20926 bindtextdomain (PACKAGE, LOCALEDIR);
20927 textdomain (PACKAGE);
20928
869b9d07
MM
20929 expandargv (&argc, &argv);
20930
dda8d76d 20931 parse_args (& cmdline, argc, argv);
59f14fc0 20932
18bd398b 20933 if (optind < (argc - 1))
1b513401
NC
20934 /* When displaying information for more than one file,
20935 prefix the information with the file name. */
32ec8896 20936 show_name = TRUE;
5656ba2c
L
20937 else if (optind >= argc)
20938 {
1b513401
NC
20939 /* Ensure that the warning is always displayed. */
20940 do_checks = TRUE;
20941
5656ba2c
L
20942 warn (_("Nothing to do.\n"));
20943 usage (stderr);
20944 }
18bd398b 20945
32ec8896 20946 err = FALSE;
252b5132 20947 while (optind < argc)
32ec8896
NC
20948 if (! process_file (argv[optind++]))
20949 err = TRUE;
252b5132 20950
9db70fc3 20951 free (cmdline.dump_sects);
252b5132 20952
7d9813f1
NA
20953 free (dump_ctf_symtab_name);
20954 free (dump_ctf_strtab_name);
20955 free (dump_ctf_parent_name);
20956
32ec8896 20957 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 20958}