Automatic date update in version.in
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
219d1afa 2 Copyright (C) 1998-2018 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"
252b5132
RH
63
64#include "elf/common.h"
65#include "elf/external.h"
66#include "elf/internal.h"
252b5132 67
4b78141a
NC
68
69/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
70 we can obtain the H8 reloc numbers. We need these for the
71 get_reloc_size() function. We include h8.h again after defining
72 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
73
74#include "elf/h8.h"
75#undef _ELF_H8_H
76
77/* Undo the effects of #including reloc-macros.h. */
78
79#undef START_RELOC_NUMBERS
80#undef RELOC_NUMBER
81#undef FAKE_RELOC
82#undef EMPTY_RELOC
83#undef END_RELOC_NUMBERS
84#undef _RELOC_MACROS_H
85
252b5132
RH
86/* The following headers use the elf/reloc-macros.h file to
87 automatically generate relocation recognition functions
88 such as elf_mips_reloc_type() */
89
90#define RELOC_MACROS_GEN_FUNC
91
a06ea964 92#include "elf/aarch64.h"
252b5132 93#include "elf/alpha.h"
3b16e843 94#include "elf/arc.h"
252b5132 95#include "elf/arm.h"
3b16e843 96#include "elf/avr.h"
1d65ded4 97#include "elf/bfin.h"
60bca95a 98#include "elf/cr16.h"
3b16e843 99#include "elf/cris.h"
1c0d3aa6 100#include "elf/crx.h"
252b5132
RH
101#include "elf/d10v.h"
102#include "elf/d30v.h"
d172d4ba 103#include "elf/dlx.h"
cfb8c092 104#include "elf/epiphany.h"
252b5132 105#include "elf/fr30.h"
5c70f934 106#include "elf/frv.h"
3f8107ab 107#include "elf/ft32.h"
3b16e843
NC
108#include "elf/h8.h"
109#include "elf/hppa.h"
110#include "elf/i386.h"
35b1837e 111#include "elf/i370.h"
3b16e843 112#include "elf/ia64.h"
1e4cf259 113#include "elf/ip2k.h"
84e94c90 114#include "elf/lm32.h"
1c0d3aa6 115#include "elf/iq2000.h"
49f58d10 116#include "elf/m32c.h"
3b16e843
NC
117#include "elf/m32r.h"
118#include "elf/m68k.h"
75751cd9 119#include "elf/m68hc11.h"
252b5132 120#include "elf/mcore.h"
15ab5209 121#include "elf/mep.h"
a3c62988 122#include "elf/metag.h"
7ba29e2a 123#include "elf/microblaze.h"
3b16e843 124#include "elf/mips.h"
3c3bdf30 125#include "elf/mmix.h"
3b16e843
NC
126#include "elf/mn10200.h"
127#include "elf/mn10300.h"
5506d11a 128#include "elf/moxie.h"
4970f871 129#include "elf/mt.h"
2469cfa2 130#include "elf/msp430.h"
35c08157 131#include "elf/nds32.h"
13761a11 132#include "elf/nios2.h"
73589c9d 133#include "elf/or1k.h"
7d466069 134#include "elf/pj.h"
3b16e843 135#include "elf/ppc.h"
c833c019 136#include "elf/ppc64.h"
2b100bb5 137#include "elf/pru.h"
03336641 138#include "elf/riscv.h"
99c513f6 139#include "elf/rl78.h"
c7927a3c 140#include "elf/rx.h"
a85d7ed0 141#include "elf/s390.h"
1c0d3aa6 142#include "elf/score.h"
3b16e843
NC
143#include "elf/sh.h"
144#include "elf/sparc.h"
e9f53129 145#include "elf/spu.h"
40b36596 146#include "elf/tic6x.h"
aa137e4d
NC
147#include "elf/tilegx.h"
148#include "elf/tilepro.h"
3b16e843 149#include "elf/v850.h"
179d3252 150#include "elf/vax.h"
619ed720 151#include "elf/visium.h"
f96bd6c2 152#include "elf/wasm32.h"
3b16e843 153#include "elf/x86-64.h"
c29aca4a 154#include "elf/xc16x.h"
f6c1a2d5 155#include "elf/xgate.h"
93fbbb04 156#include "elf/xstormy16.h"
88da6820 157#include "elf/xtensa.h"
252b5132 158
252b5132 159#include "getopt.h"
566b0d53 160#include "libiberty.h"
09c11c86 161#include "safe-ctype.h"
2cf0635d 162#include "filenames.h"
252b5132 163
15b42fb0
AM
164#ifndef offsetof
165#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
166#endif
167
6a40cf0c
NC
168typedef struct elf_section_list
169{
dda8d76d
NC
170 Elf_Internal_Shdr * hdr;
171 struct elf_section_list * next;
6a40cf0c
NC
172} elf_section_list;
173
dda8d76d
NC
174/* Flag bits indicating particular types of dump. */
175#define HEX_DUMP (1 << 0) /* The -x command line switch. */
176#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
177#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
178#define STRING_DUMP (1 << 3) /* The -p command line switch. */
179#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
180
181typedef unsigned char dump_type;
182
183/* A linked list of the section names for which dumps were requested. */
184struct dump_list_entry
185{
186 char * name;
187 dump_type type;
188 struct dump_list_entry * next;
189};
190
191typedef struct filedata
192{
193 const char * file_name;
194 FILE * handle;
195 bfd_size_type file_size;
196 Elf_Internal_Ehdr file_header;
197 Elf_Internal_Shdr * section_headers;
198 Elf_Internal_Phdr * program_headers;
199 char * string_table;
200 unsigned long string_table_length;
201 /* A dynamic array of flags indicating for which sections a dump of
202 some kind has been requested. It is reset on a per-object file
203 basis and then initialised from the cmdline_dump_sects array,
204 the results of interpreting the -w switch, and the
205 dump_sects_byname list. */
206 dump_type * dump_sects;
207 unsigned int num_dump_sects;
208} Filedata;
209
2cf0635d 210char * program_name = "readelf";
dda8d76d 211
c9c1d674 212static unsigned long archive_file_offset;
85b1c36d
BE
213static unsigned long archive_file_size;
214static unsigned long dynamic_addr;
215static bfd_size_type dynamic_size;
8b73c356 216static size_t dynamic_nent;
2cf0635d 217static char * dynamic_strings;
85b1c36d 218static unsigned long dynamic_strings_length;
85b1c36d 219static unsigned long num_dynamic_syms;
2cf0635d
NC
220static Elf_Internal_Sym * dynamic_symbols;
221static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
222static unsigned long dynamic_syminfo_offset;
223static unsigned int dynamic_syminfo_nent;
f8eae8b2 224static char program_interpreter[PATH_MAX];
bb8a0291 225static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 226static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d 227static bfd_vma version_info[16];
2cf0635d 228static Elf_Internal_Dyn * dynamic_section;
6a40cf0c 229static elf_section_list * symtab_shndx_list;
32ec8896
NC
230static bfd_boolean show_name = FALSE;
231static bfd_boolean do_dynamic = FALSE;
232static bfd_boolean do_syms = FALSE;
233static bfd_boolean do_dyn_syms = FALSE;
234static bfd_boolean do_reloc = FALSE;
235static bfd_boolean do_sections = FALSE;
236static bfd_boolean do_section_groups = FALSE;
237static bfd_boolean do_section_details = FALSE;
238static bfd_boolean do_segments = FALSE;
239static bfd_boolean do_unwind = FALSE;
240static bfd_boolean do_using_dynamic = FALSE;
241static bfd_boolean do_header = FALSE;
242static bfd_boolean do_dump = FALSE;
243static bfd_boolean do_version = FALSE;
244static bfd_boolean do_histogram = FALSE;
245static bfd_boolean do_debugging = FALSE;
246static bfd_boolean do_arch = FALSE;
247static bfd_boolean do_notes = FALSE;
248static bfd_boolean do_archive_index = FALSE;
249static bfd_boolean is_32bit_elf = FALSE;
250static bfd_boolean decompress_dumps = FALSE;
252b5132 251
e4b17d5c
L
252struct group_list
253{
dda8d76d
NC
254 struct group_list * next;
255 unsigned int section_index;
e4b17d5c
L
256};
257
258struct group
259{
dda8d76d
NC
260 struct group_list * root;
261 unsigned int group_index;
e4b17d5c
L
262};
263
dda8d76d
NC
264static size_t group_count;
265static struct group * section_groups;
266static struct group ** section_headers_groups;
aef1f6d0 267
09c11c86
NC
268/* A dynamic array of flags indicating for which sections a dump
269 has been requested via command line switches. */
dda8d76d 270static Filedata cmdline;
252b5132 271
dda8d76d 272static struct dump_list_entry * dump_sects_byname;
252b5132 273
c256ffe7 274/* How to print a vma value. */
843dd992
NC
275typedef enum print_mode
276{
277 HEX,
278 DEC,
279 DEC_5,
280 UNSIGNED,
281 PREFIX_HEX,
282 FULL_HEX,
283 LONG_HEX
284}
285print_mode;
286
bb4d2ac2
L
287/* Versioned symbol info. */
288enum versioned_symbol_info
289{
290 symbol_undefined,
291 symbol_hidden,
292 symbol_public
293};
294
32ec8896 295static const char * get_symbol_version_string
dda8d76d 296 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 297 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 298
9c19a809
NC
299#define UNKNOWN -1
300
2b692964
NC
301#define SECTION_NAME(X) \
302 ((X) == NULL ? _("<none>") \
dda8d76d
NC
303 : filedata->string_table == NULL ? _("<no-strings>") \
304 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
305 : filedata->string_table + (X)->sh_name))
252b5132 306
ee42cf8c 307#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 308
ba5cdace
NC
309#define GET_ELF_SYMBOLS(file, section, sym_count) \
310 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
311 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 312
d79b3d50
NC
313#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
314/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
315 already been called and verified that the string exists. */
316#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 317
61865e30
NC
318#define REMOVE_ARCH_BITS(ADDR) \
319 do \
320 { \
dda8d76d 321 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
322 (ADDR) &= ~1; \
323 } \
324 while (0)
d79b3d50 325\f
66cfc0fd
AM
326/* Print a BFD_VMA to an internal buffer, for use in error messages.
327 BFD_FMA_FMT can't be used in translated strings. */
328
329static const char *
330bfd_vmatoa (char *fmtch, bfd_vma value)
331{
332 /* bfd_vmatoa is used more then once in a printf call for output.
333 Cycle through an array of buffers. */
334 static int buf_pos = 0;
335 static struct bfd_vmatoa_buf
336 {
337 char place[64];
338 } buf[4];
339 char *ret;
340 char fmt[32];
341
342 ret = buf[buf_pos++].place;
343 buf_pos %= ARRAY_SIZE (buf);
344
345 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
346 snprintf (ret, sizeof (buf[0].place), fmt, value);
347 return ret;
348}
349
dda8d76d
NC
350/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
351 OFFSET + the offset of the current archive member, if we are examining an
352 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
353 allocate a buffer using malloc and fill that. In either case return the
354 pointer to the start of the retrieved data or NULL if something went wrong.
355 If something does go wrong and REASON is not NULL then emit an error
356 message using REASON as part of the context. */
59245841 357
c256ffe7 358static void *
dda8d76d
NC
359get_data (void * var,
360 Filedata * filedata,
361 unsigned long offset,
362 bfd_size_type size,
363 bfd_size_type nmemb,
364 const char * reason)
a6e9f9df 365{
2cf0635d 366 void * mvar;
57028622 367 bfd_size_type amt = size * nmemb;
a6e9f9df 368
c256ffe7 369 if (size == 0 || nmemb == 0)
a6e9f9df
AM
370 return NULL;
371
57028622
NC
372 /* If the size_t type is smaller than the bfd_size_type, eg because
373 you are building a 32-bit tool on a 64-bit host, then make sure
374 that when the sizes are cast to (size_t) no information is lost. */
375 if (sizeof (size_t) < sizeof (bfd_size_type)
376 && ( (bfd_size_type) ((size_t) size) != size
377 || (bfd_size_type) ((size_t) nmemb) != nmemb))
378 {
379 if (reason)
66cfc0fd
AM
380 error (_("Size truncation prevents reading %s"
381 " elements of size %s for %s\n"),
382 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
383 return NULL;
384 }
385
386 /* Check for size overflow. */
387 if (amt < nmemb)
388 {
389 if (reason)
66cfc0fd
AM
390 error (_("Size overflow prevents reading %s"
391 " elements of size %s for %s\n"),
392 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
393 return NULL;
394 }
395
c9c1d674
EG
396 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
397 attempting to allocate memory when the read is bound to fail. */
dda8d76d
NC
398 if (amt > filedata->file_size
399 || offset + archive_file_offset + amt > filedata->file_size)
a6e9f9df 400 {
049b0c3a 401 if (reason)
66cfc0fd
AM
402 error (_("Reading %s bytes extends past end of file for %s\n"),
403 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
404 return NULL;
405 }
406
dda8d76d 407 if (fseek (filedata->handle, archive_file_offset + offset, SEEK_SET))
071436c6
NC
408 {
409 if (reason)
c9c1d674 410 error (_("Unable to seek to 0x%lx for %s\n"),
ed754a13 411 archive_file_offset + offset, reason);
071436c6
NC
412 return NULL;
413 }
414
a6e9f9df
AM
415 mvar = var;
416 if (mvar == NULL)
417 {
c256ffe7 418 /* Check for overflow. */
57028622 419 if (nmemb < (~(bfd_size_type) 0 - 1) / size)
c256ffe7 420 /* + 1 so that we can '\0' terminate invalid string table sections. */
57028622 421 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
422
423 if (mvar == NULL)
424 {
049b0c3a 425 if (reason)
66cfc0fd
AM
426 error (_("Out of memory allocating %s bytes for %s\n"),
427 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
428 return NULL;
429 }
c256ffe7 430
c9c1d674 431 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
432 }
433
dda8d76d 434 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 435 {
049b0c3a 436 if (reason)
66cfc0fd
AM
437 error (_("Unable to read in %s bytes of %s\n"),
438 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
439 if (mvar != var)
440 free (mvar);
441 return NULL;
442 }
443
444 return mvar;
445}
446
32ec8896
NC
447/* Print a VMA value in the MODE specified.
448 Returns the number of characters displayed. */
cb8f3167 449
32ec8896 450static unsigned int
14a91970 451print_vma (bfd_vma vma, print_mode mode)
66543521 452{
32ec8896 453 unsigned int nc = 0;
66543521 454
14a91970 455 switch (mode)
66543521 456 {
14a91970
AM
457 case FULL_HEX:
458 nc = printf ("0x");
1a0670f3 459 /* Fall through. */
14a91970 460 case LONG_HEX:
f7a99963 461#ifdef BFD64
14a91970 462 if (is_32bit_elf)
437c2fb7 463 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 464#endif
14a91970
AM
465 printf_vma (vma);
466 return nc + 16;
b19aac67 467
14a91970
AM
468 case DEC_5:
469 if (vma <= 99999)
470 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 471 /* Fall through. */
14a91970
AM
472 case PREFIX_HEX:
473 nc = printf ("0x");
1a0670f3 474 /* Fall through. */
14a91970
AM
475 case HEX:
476 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 477
14a91970
AM
478 case DEC:
479 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 480
14a91970
AM
481 case UNSIGNED:
482 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
483
484 default:
485 /* FIXME: Report unrecognised mode ? */
486 return 0;
f7a99963 487 }
f7a99963
NC
488}
489
7bfd842d 490/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 491 multibye characters (assuming the host environment supports them).
31104126 492
7bfd842d
NC
493 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
494
495 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
496 padding as necessary.
171191ba
NC
497
498 Returns the number of emitted characters. */
499
500static unsigned int
32ec8896 501print_symbol (signed int width, const char *symbol)
31104126 502{
171191ba 503 bfd_boolean extra_padding = FALSE;
32ec8896 504 signed int num_printed = 0;
3bfcb652 505#ifdef HAVE_MBSTATE_T
7bfd842d 506 mbstate_t state;
3bfcb652 507#endif
32ec8896 508 unsigned int width_remaining;
961c521f 509
7bfd842d 510 if (width < 0)
961c521f 511 {
88305e1b 512 /* Keep the width positive. This helps the code below. */
961c521f 513 width = - width;
171191ba 514 extra_padding = TRUE;
0b4362b0 515 }
74e1a04b 516 assert (width != 0);
961c521f 517
7bfd842d
NC
518 if (do_wide)
519 /* Set the remaining width to a very large value.
520 This simplifies the code below. */
521 width_remaining = INT_MAX;
522 else
523 width_remaining = width;
cb8f3167 524
3bfcb652 525#ifdef HAVE_MBSTATE_T
7bfd842d
NC
526 /* Initialise the multibyte conversion state. */
527 memset (& state, 0, sizeof (state));
3bfcb652 528#endif
961c521f 529
7bfd842d
NC
530 while (width_remaining)
531 {
532 size_t n;
7bfd842d 533 const char c = *symbol++;
961c521f 534
7bfd842d 535 if (c == 0)
961c521f
NC
536 break;
537
7bfd842d
NC
538 /* Do not print control characters directly as they can affect terminal
539 settings. Such characters usually appear in the names generated
540 by the assembler for local labels. */
541 if (ISCNTRL (c))
961c521f 542 {
7bfd842d 543 if (width_remaining < 2)
961c521f
NC
544 break;
545
7bfd842d
NC
546 printf ("^%c", c + 0x40);
547 width_remaining -= 2;
171191ba 548 num_printed += 2;
961c521f 549 }
7bfd842d
NC
550 else if (ISPRINT (c))
551 {
552 putchar (c);
553 width_remaining --;
554 num_printed ++;
555 }
961c521f
NC
556 else
557 {
3bfcb652
NC
558#ifdef HAVE_MBSTATE_T
559 wchar_t w;
560#endif
7bfd842d
NC
561 /* Let printf do the hard work of displaying multibyte characters. */
562 printf ("%.1s", symbol - 1);
563 width_remaining --;
564 num_printed ++;
565
3bfcb652 566#ifdef HAVE_MBSTATE_T
7bfd842d
NC
567 /* Try to find out how many bytes made up the character that was
568 just printed. Advance the symbol pointer past the bytes that
569 were displayed. */
570 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
571#else
572 n = 1;
573#endif
7bfd842d
NC
574 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
575 symbol += (n - 1);
961c521f 576 }
961c521f 577 }
171191ba 578
7bfd842d 579 if (extra_padding && num_printed < width)
171191ba
NC
580 {
581 /* Fill in the remaining spaces. */
7bfd842d
NC
582 printf ("%-*s", width - num_printed, " ");
583 num_printed = width;
171191ba
NC
584 }
585
586 return num_printed;
31104126
NC
587}
588
1449284b 589/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
590 the given section's name. Like print_symbol, except that it does not try
591 to print multibyte characters, it just interprets them as hex values. */
592
593static const char *
dda8d76d 594printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
595{
596#define MAX_PRINT_SEC_NAME_LEN 128
597 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
598 const char * name = SECTION_NAME (sec);
599 char * buf = sec_name_buf;
600 char c;
601 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
602
603 while ((c = * name ++) != 0)
604 {
605 if (ISCNTRL (c))
606 {
607 if (remaining < 2)
608 break;
948f632f 609
74e1a04b
NC
610 * buf ++ = '^';
611 * buf ++ = c + 0x40;
612 remaining -= 2;
613 }
614 else if (ISPRINT (c))
615 {
616 * buf ++ = c;
617 remaining -= 1;
618 }
619 else
620 {
621 static char hex[17] = "0123456789ABCDEF";
622
623 if (remaining < 4)
624 break;
625 * buf ++ = '<';
626 * buf ++ = hex[(c & 0xf0) >> 4];
627 * buf ++ = hex[c & 0x0f];
628 * buf ++ = '>';
629 remaining -= 4;
630 }
631
632 if (remaining == 0)
633 break;
634 }
635
636 * buf = 0;
637 return sec_name_buf;
638}
639
640static const char *
dda8d76d 641printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 642{
dda8d76d 643 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
644 return _("<corrupt>");
645
dda8d76d 646 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
647}
648
89fac5e3
RS
649/* Return a pointer to section NAME, or NULL if no such section exists. */
650
651static Elf_Internal_Shdr *
dda8d76d 652find_section (Filedata * filedata, const char * name)
89fac5e3
RS
653{
654 unsigned int i;
655
68807c3c
NC
656 if (filedata->section_headers == NULL)
657 return NULL;
dda8d76d
NC
658
659 for (i = 0; i < filedata->file_header.e_shnum; i++)
660 if (streq (SECTION_NAME (filedata->section_headers + i), name))
661 return filedata->section_headers + i;
89fac5e3
RS
662
663 return NULL;
664}
665
0b6ae522
DJ
666/* Return a pointer to a section containing ADDR, or NULL if no such
667 section exists. */
668
669static Elf_Internal_Shdr *
dda8d76d 670find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
671{
672 unsigned int i;
673
68807c3c
NC
674 if (filedata->section_headers == NULL)
675 return NULL;
676
dda8d76d 677 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 678 {
dda8d76d
NC
679 Elf_Internal_Shdr *sec = filedata->section_headers + i;
680
0b6ae522
DJ
681 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
682 return sec;
683 }
684
685 return NULL;
686}
687
071436c6 688static Elf_Internal_Shdr *
dda8d76d 689find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
690{
691 unsigned int i;
692
68807c3c
NC
693 if (filedata->section_headers == NULL)
694 return NULL;
695
dda8d76d 696 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 697 {
dda8d76d
NC
698 Elf_Internal_Shdr *sec = filedata->section_headers + i;
699
071436c6
NC
700 if (sec->sh_type == type)
701 return sec;
702 }
703
704 return NULL;
705}
706
657d0d47
CC
707/* Return a pointer to section NAME, or NULL if no such section exists,
708 restricted to the list of sections given in SET. */
709
710static Elf_Internal_Shdr *
dda8d76d 711find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
712{
713 unsigned int i;
714
68807c3c
NC
715 if (filedata->section_headers == NULL)
716 return NULL;
717
657d0d47
CC
718 if (set != NULL)
719 {
720 while ((i = *set++) > 0)
b814a36d
NC
721 {
722 /* See PR 21156 for a reproducer. */
dda8d76d 723 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
724 continue; /* FIXME: Should we issue an error message ? */
725
dda8d76d
NC
726 if (streq (SECTION_NAME (filedata->section_headers + i), name))
727 return filedata->section_headers + i;
b814a36d 728 }
657d0d47
CC
729 }
730
dda8d76d 731 return find_section (filedata, name);
657d0d47
CC
732}
733
32ec8896
NC
734/* Read an unsigned LEB128 encoded value from DATA.
735 Set *LENGTH_RETURN to the number of bytes read. */
0b6ae522 736
f6f0e17b 737static inline unsigned long
32ec8896
NC
738read_uleb128 (unsigned char * data,
739 unsigned int * length_return,
f6f0e17b 740 const unsigned char * const end)
0b6ae522 741{
f6f0e17b 742 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
743}
744
32ec8896 745/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
746 This OS has so many departures from the ELF standard that we test it at
747 many places. */
748
32ec8896 749static inline bfd_boolean
dda8d76d 750is_ia64_vms (Filedata * filedata)
28f997cf 751{
dda8d76d
NC
752 return filedata->file_header.e_machine == EM_IA_64
753 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
754}
755
bcedfee6 756/* Guess the relocation size commonly used by the specific machines. */
252b5132 757
32ec8896 758static bfd_boolean
2dc4cec1 759guess_is_rela (unsigned int e_machine)
252b5132 760{
9c19a809 761 switch (e_machine)
252b5132
RH
762 {
763 /* Targets that use REL relocations. */
252b5132 764 case EM_386:
22abe556 765 case EM_IAMCU:
e9f53129 766 case EM_ARM:
2b0337b0 767 case EM_D10V:
252b5132 768 case EM_CYGNUS_D10V:
e9f53129 769 case EM_DLX:
252b5132 770 case EM_MIPS:
4fe85591 771 case EM_MIPS_RS3_LE:
e9f53129 772 case EM_CYGNUS_M32R:
1c0d3aa6 773 case EM_SCORE:
f6c1a2d5 774 case EM_XGATE:
9c19a809 775 return FALSE;
103f02d3 776
252b5132
RH
777 /* Targets that use RELA relocations. */
778 case EM_68K:
a06ea964 779 case EM_AARCH64:
cfb8c092 780 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
781 case EM_ALPHA:
782 case EM_ALTERA_NIOS2:
886a2506
NC
783 case EM_ARC:
784 case EM_ARC_COMPACT:
785 case EM_ARC_COMPACT2:
e9f53129
AM
786 case EM_AVR:
787 case EM_AVR_OLD:
788 case EM_BLACKFIN:
60bca95a 789 case EM_CR16:
e9f53129
AM
790 case EM_CRIS:
791 case EM_CRX:
2b0337b0 792 case EM_D30V:
252b5132 793 case EM_CYGNUS_D30V:
2b0337b0 794 case EM_FR30:
3f8107ab 795 case EM_FT32:
252b5132 796 case EM_CYGNUS_FR30:
5c70f934 797 case EM_CYGNUS_FRV:
e9f53129
AM
798 case EM_H8S:
799 case EM_H8_300:
800 case EM_H8_300H:
800eeca4 801 case EM_IA_64:
1e4cf259
NC
802 case EM_IP2K:
803 case EM_IP2K_OLD:
3b36097d 804 case EM_IQ2000:
84e94c90 805 case EM_LATTICEMICO32:
ff7eeb89 806 case EM_M32C_OLD:
49f58d10 807 case EM_M32C:
e9f53129
AM
808 case EM_M32R:
809 case EM_MCORE:
15ab5209 810 case EM_CYGNUS_MEP:
a3c62988 811 case EM_METAG:
e9f53129
AM
812 case EM_MMIX:
813 case EM_MN10200:
814 case EM_CYGNUS_MN10200:
815 case EM_MN10300:
816 case EM_CYGNUS_MN10300:
5506d11a 817 case EM_MOXIE:
e9f53129
AM
818 case EM_MSP430:
819 case EM_MSP430_OLD:
d031aafb 820 case EM_MT:
35c08157 821 case EM_NDS32:
64fd6348 822 case EM_NIOS32:
73589c9d 823 case EM_OR1K:
e9f53129
AM
824 case EM_PPC64:
825 case EM_PPC:
2b100bb5 826 case EM_TI_PRU:
e23eba97 827 case EM_RISCV:
99c513f6 828 case EM_RL78:
c7927a3c 829 case EM_RX:
e9f53129
AM
830 case EM_S390:
831 case EM_S390_OLD:
832 case EM_SH:
833 case EM_SPARC:
834 case EM_SPARC32PLUS:
835 case EM_SPARCV9:
836 case EM_SPU:
40b36596 837 case EM_TI_C6000:
aa137e4d
NC
838 case EM_TILEGX:
839 case EM_TILEPRO:
708e2187 840 case EM_V800:
e9f53129
AM
841 case EM_V850:
842 case EM_CYGNUS_V850:
843 case EM_VAX:
619ed720 844 case EM_VISIUM:
e9f53129 845 case EM_X86_64:
8a9036a4 846 case EM_L1OM:
7a9068fe 847 case EM_K1OM:
e9f53129
AM
848 case EM_XSTORMY16:
849 case EM_XTENSA:
850 case EM_XTENSA_OLD:
7ba29e2a
NC
851 case EM_MICROBLAZE:
852 case EM_MICROBLAZE_OLD:
f96bd6c2 853 case EM_WEBASSEMBLY:
9c19a809 854 return TRUE;
103f02d3 855
e9f53129
AM
856 case EM_68HC05:
857 case EM_68HC08:
858 case EM_68HC11:
859 case EM_68HC16:
860 case EM_FX66:
861 case EM_ME16:
d1133906 862 case EM_MMA:
d1133906
NC
863 case EM_NCPU:
864 case EM_NDR1:
e9f53129 865 case EM_PCP:
d1133906 866 case EM_ST100:
e9f53129 867 case EM_ST19:
d1133906 868 case EM_ST7:
e9f53129
AM
869 case EM_ST9PLUS:
870 case EM_STARCORE:
d1133906 871 case EM_SVX:
e9f53129 872 case EM_TINYJ:
9c19a809
NC
873 default:
874 warn (_("Don't know about relocations on this machine architecture\n"));
875 return FALSE;
876 }
877}
252b5132 878
dda8d76d 879/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
880 Returns TRUE upon success, FALSE otherwise. If successful then a
881 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
882 and the number of relocs loaded is placed in *NRELASP. It is the caller's
883 responsibility to free the allocated buffer. */
884
885static bfd_boolean
dda8d76d
NC
886slurp_rela_relocs (Filedata * filedata,
887 unsigned long rel_offset,
888 unsigned long rel_size,
889 Elf_Internal_Rela ** relasp,
890 unsigned long * nrelasp)
9c19a809 891{
2cf0635d 892 Elf_Internal_Rela * relas;
8b73c356 893 size_t nrelas;
4d6ed7c8 894 unsigned int i;
252b5132 895
4d6ed7c8
NC
896 if (is_32bit_elf)
897 {
2cf0635d 898 Elf32_External_Rela * erelas;
103f02d3 899
dda8d76d 900 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 901 rel_size, _("32-bit relocation data"));
a6e9f9df 902 if (!erelas)
32ec8896 903 return FALSE;
252b5132 904
4d6ed7c8 905 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 906
3f5e193b
NC
907 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
908 sizeof (Elf_Internal_Rela));
103f02d3 909
4d6ed7c8
NC
910 if (relas == NULL)
911 {
c256ffe7 912 free (erelas);
591a748a 913 error (_("out of memory parsing relocs\n"));
32ec8896 914 return FALSE;
4d6ed7c8 915 }
103f02d3 916
4d6ed7c8
NC
917 for (i = 0; i < nrelas; i++)
918 {
919 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
920 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 921 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 922 }
103f02d3 923
4d6ed7c8
NC
924 free (erelas);
925 }
926 else
927 {
2cf0635d 928 Elf64_External_Rela * erelas;
103f02d3 929
dda8d76d 930 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 931 rel_size, _("64-bit relocation data"));
a6e9f9df 932 if (!erelas)
32ec8896 933 return FALSE;
4d6ed7c8
NC
934
935 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 936
3f5e193b
NC
937 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
938 sizeof (Elf_Internal_Rela));
103f02d3 939
4d6ed7c8
NC
940 if (relas == NULL)
941 {
c256ffe7 942 free (erelas);
591a748a 943 error (_("out of memory parsing relocs\n"));
32ec8896 944 return FALSE;
9c19a809 945 }
4d6ed7c8
NC
946
947 for (i = 0; i < nrelas; i++)
9c19a809 948 {
66543521
AM
949 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
950 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 951 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
952
953 /* The #ifdef BFD64 below is to prevent a compile time
954 warning. We know that if we do not have a 64 bit data
955 type that we will never execute this code anyway. */
956#ifdef BFD64
dda8d76d
NC
957 if (filedata->file_header.e_machine == EM_MIPS
958 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
959 {
960 /* In little-endian objects, r_info isn't really a
961 64-bit little-endian value: it has a 32-bit
962 little-endian symbol index followed by four
963 individual byte fields. Reorder INFO
964 accordingly. */
91d6fa6a
NC
965 bfd_vma inf = relas[i].r_info;
966 inf = (((inf & 0xffffffff) << 32)
967 | ((inf >> 56) & 0xff)
968 | ((inf >> 40) & 0xff00)
969 | ((inf >> 24) & 0xff0000)
970 | ((inf >> 8) & 0xff000000));
971 relas[i].r_info = inf;
861fb55a
DJ
972 }
973#endif /* BFD64 */
4d6ed7c8 974 }
103f02d3 975
4d6ed7c8
NC
976 free (erelas);
977 }
32ec8896 978
4d6ed7c8
NC
979 *relasp = relas;
980 *nrelasp = nrelas;
32ec8896 981 return TRUE;
4d6ed7c8 982}
103f02d3 983
dda8d76d 984/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
985 Returns TRUE upon success, FALSE otherwise. If successful then a
986 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
987 and the number of relocs loaded is placed in *NRELSP. It is the caller's
988 responsibility to free the allocated buffer. */
989
990static bfd_boolean
dda8d76d
NC
991slurp_rel_relocs (Filedata * filedata,
992 unsigned long rel_offset,
993 unsigned long rel_size,
994 Elf_Internal_Rela ** relsp,
995 unsigned long * nrelsp)
4d6ed7c8 996{
2cf0635d 997 Elf_Internal_Rela * rels;
8b73c356 998 size_t nrels;
4d6ed7c8 999 unsigned int i;
103f02d3 1000
4d6ed7c8
NC
1001 if (is_32bit_elf)
1002 {
2cf0635d 1003 Elf32_External_Rel * erels;
103f02d3 1004
dda8d76d 1005 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1006 rel_size, _("32-bit relocation data"));
a6e9f9df 1007 if (!erels)
32ec8896 1008 return FALSE;
103f02d3 1009
4d6ed7c8 1010 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1011
3f5e193b 1012 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1013
4d6ed7c8
NC
1014 if (rels == NULL)
1015 {
c256ffe7 1016 free (erels);
591a748a 1017 error (_("out of memory parsing relocs\n"));
32ec8896 1018 return FALSE;
4d6ed7c8
NC
1019 }
1020
1021 for (i = 0; i < nrels; i++)
1022 {
1023 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1024 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1025 rels[i].r_addend = 0;
9ea033b2 1026 }
4d6ed7c8
NC
1027
1028 free (erels);
9c19a809
NC
1029 }
1030 else
1031 {
2cf0635d 1032 Elf64_External_Rel * erels;
9ea033b2 1033
dda8d76d 1034 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1035 rel_size, _("64-bit relocation data"));
a6e9f9df 1036 if (!erels)
32ec8896 1037 return FALSE;
103f02d3 1038
4d6ed7c8 1039 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1040
3f5e193b 1041 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1042
4d6ed7c8 1043 if (rels == NULL)
9c19a809 1044 {
c256ffe7 1045 free (erels);
591a748a 1046 error (_("out of memory parsing relocs\n"));
32ec8896 1047 return FALSE;
4d6ed7c8 1048 }
103f02d3 1049
4d6ed7c8
NC
1050 for (i = 0; i < nrels; i++)
1051 {
66543521
AM
1052 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1053 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1054 rels[i].r_addend = 0;
861fb55a
DJ
1055
1056 /* The #ifdef BFD64 below is to prevent a compile time
1057 warning. We know that if we do not have a 64 bit data
1058 type that we will never execute this code anyway. */
1059#ifdef BFD64
dda8d76d
NC
1060 if (filedata->file_header.e_machine == EM_MIPS
1061 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1062 {
1063 /* In little-endian objects, r_info isn't really a
1064 64-bit little-endian value: it has a 32-bit
1065 little-endian symbol index followed by four
1066 individual byte fields. Reorder INFO
1067 accordingly. */
91d6fa6a
NC
1068 bfd_vma inf = rels[i].r_info;
1069 inf = (((inf & 0xffffffff) << 32)
1070 | ((inf >> 56) & 0xff)
1071 | ((inf >> 40) & 0xff00)
1072 | ((inf >> 24) & 0xff0000)
1073 | ((inf >> 8) & 0xff000000));
1074 rels[i].r_info = inf;
861fb55a
DJ
1075 }
1076#endif /* BFD64 */
4d6ed7c8 1077 }
103f02d3 1078
4d6ed7c8
NC
1079 free (erels);
1080 }
32ec8896 1081
4d6ed7c8
NC
1082 *relsp = rels;
1083 *nrelsp = nrels;
32ec8896 1084 return TRUE;
4d6ed7c8 1085}
103f02d3 1086
aca88567
NC
1087/* Returns the reloc type extracted from the reloc info field. */
1088
1089static unsigned int
dda8d76d 1090get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1091{
1092 if (is_32bit_elf)
1093 return ELF32_R_TYPE (reloc_info);
1094
dda8d76d 1095 switch (filedata->file_header.e_machine)
aca88567
NC
1096 {
1097 case EM_MIPS:
1098 /* Note: We assume that reloc_info has already been adjusted for us. */
1099 return ELF64_MIPS_R_TYPE (reloc_info);
1100
1101 case EM_SPARCV9:
1102 return ELF64_R_TYPE_ID (reloc_info);
1103
1104 default:
1105 return ELF64_R_TYPE (reloc_info);
1106 }
1107}
1108
1109/* Return the symbol index extracted from the reloc info field. */
1110
1111static bfd_vma
1112get_reloc_symindex (bfd_vma reloc_info)
1113{
1114 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1115}
1116
13761a11 1117static inline bfd_boolean
dda8d76d 1118uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1119{
1120 return
dda8d76d 1121 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1122 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1123 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1124 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1125 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1126}
1127
d3ba0551
AM
1128/* Display the contents of the relocation data found at the specified
1129 offset. */
ee42cf8c 1130
32ec8896 1131static bfd_boolean
dda8d76d
NC
1132dump_relocations (Filedata * filedata,
1133 unsigned long rel_offset,
1134 unsigned long rel_size,
1135 Elf_Internal_Sym * symtab,
1136 unsigned long nsyms,
1137 char * strtab,
1138 unsigned long strtablen,
1139 int is_rela,
1140 bfd_boolean is_dynsym)
4d6ed7c8 1141{
32ec8896 1142 unsigned long i;
2cf0635d 1143 Elf_Internal_Rela * rels;
32ec8896 1144 bfd_boolean res = TRUE;
103f02d3 1145
4d6ed7c8 1146 if (is_rela == UNKNOWN)
dda8d76d 1147 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1148
4d6ed7c8
NC
1149 if (is_rela)
1150 {
dda8d76d 1151 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1152 return FALSE;
4d6ed7c8
NC
1153 }
1154 else
1155 {
dda8d76d 1156 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1157 return FALSE;
252b5132
RH
1158 }
1159
410f7a12
L
1160 if (is_32bit_elf)
1161 {
1162 if (is_rela)
2c71103e
NC
1163 {
1164 if (do_wide)
1165 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1166 else
1167 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1168 }
410f7a12 1169 else
2c71103e
NC
1170 {
1171 if (do_wide)
1172 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1173 else
1174 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1175 }
410f7a12 1176 }
252b5132 1177 else
410f7a12
L
1178 {
1179 if (is_rela)
2c71103e
NC
1180 {
1181 if (do_wide)
8beeaeb7 1182 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1183 else
1184 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1185 }
410f7a12 1186 else
2c71103e
NC
1187 {
1188 if (do_wide)
8beeaeb7 1189 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1190 else
1191 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1192 }
410f7a12 1193 }
252b5132
RH
1194
1195 for (i = 0; i < rel_size; i++)
1196 {
2cf0635d 1197 const char * rtype;
b34976b6 1198 bfd_vma offset;
91d6fa6a 1199 bfd_vma inf;
b34976b6
AM
1200 bfd_vma symtab_index;
1201 bfd_vma type;
103f02d3 1202
b34976b6 1203 offset = rels[i].r_offset;
91d6fa6a 1204 inf = rels[i].r_info;
103f02d3 1205
dda8d76d 1206 type = get_reloc_type (filedata, inf);
91d6fa6a 1207 symtab_index = get_reloc_symindex (inf);
252b5132 1208
410f7a12
L
1209 if (is_32bit_elf)
1210 {
39dbeff8
AM
1211 printf ("%8.8lx %8.8lx ",
1212 (unsigned long) offset & 0xffffffff,
91d6fa6a 1213 (unsigned long) inf & 0xffffffff);
410f7a12
L
1214 }
1215 else
1216 {
39dbeff8
AM
1217#if BFD_HOST_64BIT_LONG
1218 printf (do_wide
1219 ? "%16.16lx %16.16lx "
1220 : "%12.12lx %12.12lx ",
91d6fa6a 1221 offset, inf);
39dbeff8 1222#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1223#ifndef __MSVCRT__
39dbeff8
AM
1224 printf (do_wide
1225 ? "%16.16llx %16.16llx "
1226 : "%12.12llx %12.12llx ",
91d6fa6a 1227 offset, inf);
6e3d6dc1
NC
1228#else
1229 printf (do_wide
1230 ? "%16.16I64x %16.16I64x "
1231 : "%12.12I64x %12.12I64x ",
91d6fa6a 1232 offset, inf);
6e3d6dc1 1233#endif
39dbeff8 1234#else
2c71103e
NC
1235 printf (do_wide
1236 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1237 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1238 _bfd_int64_high (offset),
1239 _bfd_int64_low (offset),
91d6fa6a
NC
1240 _bfd_int64_high (inf),
1241 _bfd_int64_low (inf));
9ea033b2 1242#endif
410f7a12 1243 }
103f02d3 1244
dda8d76d 1245 switch (filedata->file_header.e_machine)
252b5132
RH
1246 {
1247 default:
1248 rtype = NULL;
1249 break;
1250
a06ea964
NC
1251 case EM_AARCH64:
1252 rtype = elf_aarch64_reloc_type (type);
1253 break;
1254
2b0337b0 1255 case EM_M32R:
252b5132 1256 case EM_CYGNUS_M32R:
9ea033b2 1257 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1258 break;
1259
1260 case EM_386:
22abe556 1261 case EM_IAMCU:
9ea033b2 1262 rtype = elf_i386_reloc_type (type);
252b5132
RH
1263 break;
1264
ba2685cc
AM
1265 case EM_68HC11:
1266 case EM_68HC12:
1267 rtype = elf_m68hc11_reloc_type (type);
1268 break;
75751cd9 1269
252b5132 1270 case EM_68K:
9ea033b2 1271 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1272 break;
1273
adde6300 1274 case EM_AVR:
2b0337b0 1275 case EM_AVR_OLD:
adde6300
AM
1276 rtype = elf_avr_reloc_type (type);
1277 break;
1278
9ea033b2
NC
1279 case EM_OLD_SPARCV9:
1280 case EM_SPARC32PLUS:
1281 case EM_SPARCV9:
252b5132 1282 case EM_SPARC:
9ea033b2 1283 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1284 break;
1285
e9f53129
AM
1286 case EM_SPU:
1287 rtype = elf_spu_reloc_type (type);
1288 break;
1289
708e2187
NC
1290 case EM_V800:
1291 rtype = v800_reloc_type (type);
1292 break;
2b0337b0 1293 case EM_V850:
252b5132 1294 case EM_CYGNUS_V850:
9ea033b2 1295 rtype = v850_reloc_type (type);
252b5132
RH
1296 break;
1297
2b0337b0 1298 case EM_D10V:
252b5132 1299 case EM_CYGNUS_D10V:
9ea033b2 1300 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1301 break;
1302
2b0337b0 1303 case EM_D30V:
252b5132 1304 case EM_CYGNUS_D30V:
9ea033b2 1305 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1306 break;
1307
d172d4ba
NC
1308 case EM_DLX:
1309 rtype = elf_dlx_reloc_type (type);
1310 break;
1311
252b5132 1312 case EM_SH:
9ea033b2 1313 rtype = elf_sh_reloc_type (type);
252b5132
RH
1314 break;
1315
2b0337b0 1316 case EM_MN10300:
252b5132 1317 case EM_CYGNUS_MN10300:
9ea033b2 1318 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1319 break;
1320
2b0337b0 1321 case EM_MN10200:
252b5132 1322 case EM_CYGNUS_MN10200:
9ea033b2 1323 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1324 break;
1325
2b0337b0 1326 case EM_FR30:
252b5132 1327 case EM_CYGNUS_FR30:
9ea033b2 1328 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1329 break;
1330
ba2685cc
AM
1331 case EM_CYGNUS_FRV:
1332 rtype = elf_frv_reloc_type (type);
1333 break;
5c70f934 1334
3f8107ab
AM
1335 case EM_FT32:
1336 rtype = elf_ft32_reloc_type (type);
1337 break;
1338
252b5132 1339 case EM_MCORE:
9ea033b2 1340 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1341 break;
1342
3c3bdf30
NC
1343 case EM_MMIX:
1344 rtype = elf_mmix_reloc_type (type);
1345 break;
1346
5506d11a
AM
1347 case EM_MOXIE:
1348 rtype = elf_moxie_reloc_type (type);
1349 break;
1350
2469cfa2 1351 case EM_MSP430:
dda8d76d 1352 if (uses_msp430x_relocs (filedata))
13761a11
NC
1353 {
1354 rtype = elf_msp430x_reloc_type (type);
1355 break;
1356 }
1a0670f3 1357 /* Fall through. */
2469cfa2
NC
1358 case EM_MSP430_OLD:
1359 rtype = elf_msp430_reloc_type (type);
1360 break;
1361
35c08157
KLC
1362 case EM_NDS32:
1363 rtype = elf_nds32_reloc_type (type);
1364 break;
1365
252b5132 1366 case EM_PPC:
9ea033b2 1367 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1368 break;
1369
c833c019
AM
1370 case EM_PPC64:
1371 rtype = elf_ppc64_reloc_type (type);
1372 break;
1373
252b5132 1374 case EM_MIPS:
4fe85591 1375 case EM_MIPS_RS3_LE:
9ea033b2 1376 rtype = elf_mips_reloc_type (type);
252b5132
RH
1377 break;
1378
e23eba97
NC
1379 case EM_RISCV:
1380 rtype = elf_riscv_reloc_type (type);
1381 break;
1382
252b5132 1383 case EM_ALPHA:
9ea033b2 1384 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1385 break;
1386
1387 case EM_ARM:
9ea033b2 1388 rtype = elf_arm_reloc_type (type);
252b5132
RH
1389 break;
1390
584da044 1391 case EM_ARC:
886a2506
NC
1392 case EM_ARC_COMPACT:
1393 case EM_ARC_COMPACT2:
9ea033b2 1394 rtype = elf_arc_reloc_type (type);
252b5132
RH
1395 break;
1396
1397 case EM_PARISC:
69e617ca 1398 rtype = elf_hppa_reloc_type (type);
252b5132 1399 break;
7d466069 1400
b8720f9d
JL
1401 case EM_H8_300:
1402 case EM_H8_300H:
1403 case EM_H8S:
1404 rtype = elf_h8_reloc_type (type);
1405 break;
1406
73589c9d
CS
1407 case EM_OR1K:
1408 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1409 break;
1410
7d466069 1411 case EM_PJ:
2b0337b0 1412 case EM_PJ_OLD:
7d466069
ILT
1413 rtype = elf_pj_reloc_type (type);
1414 break;
800eeca4
JW
1415 case EM_IA_64:
1416 rtype = elf_ia64_reloc_type (type);
1417 break;
1b61cf92
HPN
1418
1419 case EM_CRIS:
1420 rtype = elf_cris_reloc_type (type);
1421 break;
535c37ff 1422
bcedfee6 1423 case EM_X86_64:
8a9036a4 1424 case EM_L1OM:
7a9068fe 1425 case EM_K1OM:
bcedfee6
NC
1426 rtype = elf_x86_64_reloc_type (type);
1427 break;
a85d7ed0 1428
35b1837e
AM
1429 case EM_S370:
1430 rtype = i370_reloc_type (type);
1431 break;
1432
53c7db4b
KH
1433 case EM_S390_OLD:
1434 case EM_S390:
1435 rtype = elf_s390_reloc_type (type);
1436 break;
93fbbb04 1437
1c0d3aa6
NC
1438 case EM_SCORE:
1439 rtype = elf_score_reloc_type (type);
1440 break;
1441
93fbbb04
GK
1442 case EM_XSTORMY16:
1443 rtype = elf_xstormy16_reloc_type (type);
1444 break;
179d3252 1445
1fe1f39c
NC
1446 case EM_CRX:
1447 rtype = elf_crx_reloc_type (type);
1448 break;
1449
179d3252
JT
1450 case EM_VAX:
1451 rtype = elf_vax_reloc_type (type);
1452 break;
1e4cf259 1453
619ed720
EB
1454 case EM_VISIUM:
1455 rtype = elf_visium_reloc_type (type);
1456 break;
1457
cfb8c092
NC
1458 case EM_ADAPTEVA_EPIPHANY:
1459 rtype = elf_epiphany_reloc_type (type);
1460 break;
1461
1e4cf259
NC
1462 case EM_IP2K:
1463 case EM_IP2K_OLD:
1464 rtype = elf_ip2k_reloc_type (type);
1465 break;
3b36097d
SC
1466
1467 case EM_IQ2000:
1468 rtype = elf_iq2000_reloc_type (type);
1469 break;
88da6820
NC
1470
1471 case EM_XTENSA_OLD:
1472 case EM_XTENSA:
1473 rtype = elf_xtensa_reloc_type (type);
1474 break;
a34e3ecb 1475
84e94c90
NC
1476 case EM_LATTICEMICO32:
1477 rtype = elf_lm32_reloc_type (type);
1478 break;
1479
ff7eeb89 1480 case EM_M32C_OLD:
49f58d10
JB
1481 case EM_M32C:
1482 rtype = elf_m32c_reloc_type (type);
1483 break;
1484
d031aafb
NS
1485 case EM_MT:
1486 rtype = elf_mt_reloc_type (type);
a34e3ecb 1487 break;
1d65ded4
CM
1488
1489 case EM_BLACKFIN:
1490 rtype = elf_bfin_reloc_type (type);
1491 break;
15ab5209
DB
1492
1493 case EM_CYGNUS_MEP:
1494 rtype = elf_mep_reloc_type (type);
1495 break;
60bca95a
NC
1496
1497 case EM_CR16:
1498 rtype = elf_cr16_reloc_type (type);
1499 break;
dd24e3da 1500
7ba29e2a
NC
1501 case EM_MICROBLAZE:
1502 case EM_MICROBLAZE_OLD:
1503 rtype = elf_microblaze_reloc_type (type);
1504 break;
c7927a3c 1505
99c513f6
DD
1506 case EM_RL78:
1507 rtype = elf_rl78_reloc_type (type);
1508 break;
1509
c7927a3c
NC
1510 case EM_RX:
1511 rtype = elf_rx_reloc_type (type);
1512 break;
c29aca4a 1513
a3c62988
NC
1514 case EM_METAG:
1515 rtype = elf_metag_reloc_type (type);
1516 break;
1517
c29aca4a
NC
1518 case EM_XC16X:
1519 case EM_C166:
1520 rtype = elf_xc16x_reloc_type (type);
1521 break;
40b36596
JM
1522
1523 case EM_TI_C6000:
1524 rtype = elf_tic6x_reloc_type (type);
1525 break;
aa137e4d
NC
1526
1527 case EM_TILEGX:
1528 rtype = elf_tilegx_reloc_type (type);
1529 break;
1530
1531 case EM_TILEPRO:
1532 rtype = elf_tilepro_reloc_type (type);
1533 break;
f6c1a2d5 1534
f96bd6c2
PC
1535 case EM_WEBASSEMBLY:
1536 rtype = elf_wasm32_reloc_type (type);
1537 break;
1538
f6c1a2d5
NC
1539 case EM_XGATE:
1540 rtype = elf_xgate_reloc_type (type);
1541 break;
36591ba1
SL
1542
1543 case EM_ALTERA_NIOS2:
1544 rtype = elf_nios2_reloc_type (type);
1545 break;
2b100bb5
DD
1546
1547 case EM_TI_PRU:
1548 rtype = elf_pru_reloc_type (type);
1549 break;
252b5132
RH
1550 }
1551
1552 if (rtype == NULL)
39dbeff8 1553 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1554 else
5c144731 1555 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1556
dda8d76d 1557 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1558 && rtype != NULL
7ace3541
RH
1559 && streq (rtype, "R_ALPHA_LITUSE")
1560 && is_rela)
1561 {
1562 switch (rels[i].r_addend)
1563 {
1564 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1565 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1566 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1567 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1568 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1569 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1570 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1571 default: rtype = NULL;
1572 }
32ec8896 1573
7ace3541
RH
1574 if (rtype)
1575 printf (" (%s)", rtype);
1576 else
1577 {
1578 putchar (' ');
1579 printf (_("<unknown addend: %lx>"),
1580 (unsigned long) rels[i].r_addend);
32ec8896 1581 res = FALSE;
7ace3541
RH
1582 }
1583 }
1584 else if (symtab_index)
252b5132 1585 {
af3fc3bc 1586 if (symtab == NULL || symtab_index >= nsyms)
32ec8896
NC
1587 {
1588 error (_(" bad symbol index: %08lx in reloc"), (unsigned long) symtab_index);
1589 res = FALSE;
1590 }
af3fc3bc 1591 else
19936277 1592 {
2cf0635d 1593 Elf_Internal_Sym * psym;
bb4d2ac2
L
1594 const char * version_string;
1595 enum versioned_symbol_info sym_info;
1596 unsigned short vna_other;
19936277 1597
af3fc3bc 1598 psym = symtab + symtab_index;
103f02d3 1599
bb4d2ac2 1600 version_string
dda8d76d 1601 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1602 strtab, strtablen,
1603 symtab_index,
1604 psym,
1605 &sym_info,
1606 &vna_other);
1607
af3fc3bc 1608 printf (" ");
171191ba 1609
d8045f23
NC
1610 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1611 {
1612 const char * name;
1613 unsigned int len;
1614 unsigned int width = is_32bit_elf ? 8 : 14;
1615
1616 /* Relocations against GNU_IFUNC symbols do not use the value
1617 of the symbol as the address to relocate against. Instead
1618 they invoke the function named by the symbol and use its
1619 result as the address for relocation.
1620
1621 To indicate this to the user, do not display the value of
1622 the symbol in the "Symbols's Value" field. Instead show
1623 its name followed by () as a hint that the symbol is
1624 invoked. */
1625
1626 if (strtab == NULL
1627 || psym->st_name == 0
1628 || psym->st_name >= strtablen)
1629 name = "??";
1630 else
1631 name = strtab + psym->st_name;
1632
1633 len = print_symbol (width, name);
bb4d2ac2
L
1634 if (version_string)
1635 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1636 version_string);
d8045f23
NC
1637 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1638 }
1639 else
1640 {
1641 print_vma (psym->st_value, LONG_HEX);
171191ba 1642
d8045f23
NC
1643 printf (is_32bit_elf ? " " : " ");
1644 }
103f02d3 1645
af3fc3bc 1646 if (psym->st_name == 0)
f1ef08cb 1647 {
2cf0635d 1648 const char * sec_name = "<null>";
f1ef08cb
AM
1649 char name_buf[40];
1650
1651 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1652 {
dda8d76d
NC
1653 if (psym->st_shndx < filedata->file_header.e_shnum)
1654 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1655 else if (psym->st_shndx == SHN_ABS)
1656 sec_name = "ABS";
1657 else if (psym->st_shndx == SHN_COMMON)
1658 sec_name = "COMMON";
dda8d76d 1659 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1660 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1661 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1662 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1663 sec_name = "SCOMMON";
dda8d76d 1664 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1665 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1666 sec_name = "SUNDEF";
dda8d76d
NC
1667 else if ((filedata->file_header.e_machine == EM_X86_64
1668 || filedata->file_header.e_machine == EM_L1OM
1669 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1670 && psym->st_shndx == SHN_X86_64_LCOMMON)
1671 sec_name = "LARGE_COMMON";
dda8d76d
NC
1672 else if (filedata->file_header.e_machine == EM_IA_64
1673 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1674 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1675 sec_name = "ANSI_COM";
dda8d76d 1676 else if (is_ia64_vms (filedata)
148b93f2
NC
1677 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1678 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1679 else
1680 {
1681 sprintf (name_buf, "<section 0x%x>",
1682 (unsigned int) psym->st_shndx);
1683 sec_name = name_buf;
1684 }
1685 }
1686 print_symbol (22, sec_name);
1687 }
af3fc3bc 1688 else if (strtab == NULL)
d79b3d50 1689 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1690 else if (psym->st_name >= strtablen)
32ec8896
NC
1691 {
1692 error (_("<corrupt string table index: %3ld>"), psym->st_name);
1693 res = FALSE;
1694 }
af3fc3bc 1695 else
bb4d2ac2
L
1696 {
1697 print_symbol (22, strtab + psym->st_name);
1698 if (version_string)
1699 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1700 version_string);
1701 }
103f02d3 1702
af3fc3bc 1703 if (is_rela)
171191ba 1704 {
7360e63f 1705 bfd_vma off = rels[i].r_addend;
171191ba 1706
7360e63f 1707 if ((bfd_signed_vma) off < 0)
598aaa76 1708 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1709 else
598aaa76 1710 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1711 }
19936277 1712 }
252b5132 1713 }
1b228002 1714 else if (is_rela)
f7a99963 1715 {
7360e63f 1716 bfd_vma off = rels[i].r_addend;
e04d7088
L
1717
1718 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1719 if ((bfd_signed_vma) off < 0)
e04d7088
L
1720 printf ("-%" BFD_VMA_FMT "x", - off);
1721 else
1722 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1723 }
252b5132 1724
dda8d76d 1725 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1726 && rtype != NULL
1727 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1728 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1729
252b5132 1730 putchar ('\n');
2c71103e 1731
aca88567 1732#ifdef BFD64
dda8d76d 1733 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1734 {
91d6fa6a
NC
1735 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1736 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1737 const char * rtype2 = elf_mips_reloc_type (type2);
1738 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1739
2c71103e
NC
1740 printf (" Type2: ");
1741
1742 if (rtype2 == NULL)
39dbeff8
AM
1743 printf (_("unrecognized: %-7lx"),
1744 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1745 else
1746 printf ("%-17.17s", rtype2);
1747
18bd398b 1748 printf ("\n Type3: ");
2c71103e
NC
1749
1750 if (rtype3 == NULL)
39dbeff8
AM
1751 printf (_("unrecognized: %-7lx"),
1752 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1753 else
1754 printf ("%-17.17s", rtype3);
1755
53c7db4b 1756 putchar ('\n');
2c71103e 1757 }
aca88567 1758#endif /* BFD64 */
252b5132
RH
1759 }
1760
c8286bd1 1761 free (rels);
32ec8896
NC
1762
1763 return res;
252b5132
RH
1764}
1765
1766static const char *
d3ba0551 1767get_mips_dynamic_type (unsigned long type)
252b5132
RH
1768{
1769 switch (type)
1770 {
1771 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1772 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1773 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1774 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1775 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1776 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1777 case DT_MIPS_MSYM: return "MIPS_MSYM";
1778 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1779 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1780 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1781 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1782 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1783 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1784 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1785 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1786 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1787 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1788 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1789 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1790 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1791 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1792 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1793 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1794 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1795 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1796 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1797 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1798 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1799 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1800 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1801 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1802 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1803 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1804 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1805 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1806 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1807 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1808 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1809 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1810 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1811 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1812 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1813 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1814 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1815 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1816 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1817 default:
1818 return NULL;
1819 }
1820}
1821
9a097730 1822static const char *
d3ba0551 1823get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1824{
1825 switch (type)
1826 {
1827 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1828 default:
1829 return NULL;
1830 }
103f02d3
UD
1831}
1832
7490d522
AM
1833static const char *
1834get_ppc_dynamic_type (unsigned long type)
1835{
1836 switch (type)
1837 {
a7f2871e 1838 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1839 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1840 default:
1841 return NULL;
1842 }
1843}
1844
f1cb7e17 1845static const char *
d3ba0551 1846get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1847{
1848 switch (type)
1849 {
a7f2871e
AM
1850 case DT_PPC64_GLINK: return "PPC64_GLINK";
1851 case DT_PPC64_OPD: return "PPC64_OPD";
1852 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1853 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1854 default:
1855 return NULL;
1856 }
1857}
1858
103f02d3 1859static const char *
d3ba0551 1860get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1861{
1862 switch (type)
1863 {
1864 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1865 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1866 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1867 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1868 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1869 case DT_HP_PREINIT: return "HP_PREINIT";
1870 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1871 case DT_HP_NEEDED: return "HP_NEEDED";
1872 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1873 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1874 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1875 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1876 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1877 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1878 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1879 case DT_HP_FILTERED: return "HP_FILTERED";
1880 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1881 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1882 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1883 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1884 case DT_PLT: return "PLT";
1885 case DT_PLT_SIZE: return "PLT_SIZE";
1886 case DT_DLT: return "DLT";
1887 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1888 default:
1889 return NULL;
1890 }
1891}
9a097730 1892
ecc51f48 1893static const char *
d3ba0551 1894get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1895{
1896 switch (type)
1897 {
148b93f2
NC
1898 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1899 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1900 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1901 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1902 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1903 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1904 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1905 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1906 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1907 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1908 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1909 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1910 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1911 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1912 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1913 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1914 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1915 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1916 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1917 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1918 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1919 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1920 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1921 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1922 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1923 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1924 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1925 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1926 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1927 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1928 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1929 default:
1930 return NULL;
1931 }
1932}
1933
fd85a6a1
NC
1934static const char *
1935get_solaris_section_type (unsigned long type)
1936{
1937 switch (type)
1938 {
1939 case 0x6fffffee: return "SUNW_ancillary";
1940 case 0x6fffffef: return "SUNW_capchain";
1941 case 0x6ffffff0: return "SUNW_capinfo";
1942 case 0x6ffffff1: return "SUNW_symsort";
1943 case 0x6ffffff2: return "SUNW_tlssort";
1944 case 0x6ffffff3: return "SUNW_LDYNSYM";
1945 case 0x6ffffff4: return "SUNW_dof";
1946 case 0x6ffffff5: return "SUNW_cap";
1947 case 0x6ffffff6: return "SUNW_SIGNATURE";
1948 case 0x6ffffff7: return "SUNW_ANNOTATE";
1949 case 0x6ffffff8: return "SUNW_DEBUGSTR";
1950 case 0x6ffffff9: return "SUNW_DEBUG";
1951 case 0x6ffffffa: return "SUNW_move";
1952 case 0x6ffffffb: return "SUNW_COMDAT";
1953 case 0x6ffffffc: return "SUNW_syminfo";
1954 case 0x6ffffffd: return "SUNW_verdef";
1955 case 0x6ffffffe: return "SUNW_verneed";
1956 case 0x6fffffff: return "SUNW_versym";
1957 case 0x70000000: return "SPARC_GOTDATA";
1958 default: return NULL;
1959 }
1960}
1961
fabcb361
RH
1962static const char *
1963get_alpha_dynamic_type (unsigned long type)
1964{
1965 switch (type)
1966 {
1967 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 1968 default: return NULL;
fabcb361
RH
1969 }
1970}
1971
1c0d3aa6
NC
1972static const char *
1973get_score_dynamic_type (unsigned long type)
1974{
1975 switch (type)
1976 {
1977 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1978 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1979 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1980 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1981 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1982 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 1983 default: return NULL;
1c0d3aa6
NC
1984 }
1985}
1986
40b36596
JM
1987static const char *
1988get_tic6x_dynamic_type (unsigned long type)
1989{
1990 switch (type)
1991 {
1992 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1993 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1994 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1995 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1996 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1997 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 1998 default: return NULL;
40b36596
JM
1999 }
2000}
1c0d3aa6 2001
36591ba1
SL
2002static const char *
2003get_nios2_dynamic_type (unsigned long type)
2004{
2005 switch (type)
2006 {
2007 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2008 default: return NULL;
36591ba1
SL
2009 }
2010}
2011
fd85a6a1
NC
2012static const char *
2013get_solaris_dynamic_type (unsigned long type)
2014{
2015 switch (type)
2016 {
2017 case 0x6000000d: return "SUNW_AUXILIARY";
2018 case 0x6000000e: return "SUNW_RTLDINF";
2019 case 0x6000000f: return "SUNW_FILTER";
2020 case 0x60000010: return "SUNW_CAP";
2021 case 0x60000011: return "SUNW_SYMTAB";
2022 case 0x60000012: return "SUNW_SYMSZ";
2023 case 0x60000013: return "SUNW_SORTENT";
2024 case 0x60000014: return "SUNW_SYMSORT";
2025 case 0x60000015: return "SUNW_SYMSORTSZ";
2026 case 0x60000016: return "SUNW_TLSSORT";
2027 case 0x60000017: return "SUNW_TLSSORTSZ";
2028 case 0x60000018: return "SUNW_CAPINFO";
2029 case 0x60000019: return "SUNW_STRPAD";
2030 case 0x6000001a: return "SUNW_CAPCHAIN";
2031 case 0x6000001b: return "SUNW_LDMACH";
2032 case 0x6000001d: return "SUNW_CAPCHAINENT";
2033 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2034 case 0x60000021: return "SUNW_PARENT";
2035 case 0x60000023: return "SUNW_ASLR";
2036 case 0x60000025: return "SUNW_RELAX";
2037 case 0x60000029: return "SUNW_NXHEAP";
2038 case 0x6000002b: return "SUNW_NXSTACK";
2039
2040 case 0x70000001: return "SPARC_REGISTER";
2041 case 0x7ffffffd: return "AUXILIARY";
2042 case 0x7ffffffe: return "USED";
2043 case 0x7fffffff: return "FILTER";
2044
15f205b1 2045 default: return NULL;
fd85a6a1
NC
2046 }
2047}
2048
252b5132 2049static const char *
dda8d76d 2050get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2051{
e9e44622 2052 static char buff[64];
252b5132
RH
2053
2054 switch (type)
2055 {
2056 case DT_NULL: return "NULL";
2057 case DT_NEEDED: return "NEEDED";
2058 case DT_PLTRELSZ: return "PLTRELSZ";
2059 case DT_PLTGOT: return "PLTGOT";
2060 case DT_HASH: return "HASH";
2061 case DT_STRTAB: return "STRTAB";
2062 case DT_SYMTAB: return "SYMTAB";
2063 case DT_RELA: return "RELA";
2064 case DT_RELASZ: return "RELASZ";
2065 case DT_RELAENT: return "RELAENT";
2066 case DT_STRSZ: return "STRSZ";
2067 case DT_SYMENT: return "SYMENT";
2068 case DT_INIT: return "INIT";
2069 case DT_FINI: return "FINI";
2070 case DT_SONAME: return "SONAME";
2071 case DT_RPATH: return "RPATH";
2072 case DT_SYMBOLIC: return "SYMBOLIC";
2073 case DT_REL: return "REL";
2074 case DT_RELSZ: return "RELSZ";
2075 case DT_RELENT: return "RELENT";
2076 case DT_PLTREL: return "PLTREL";
2077 case DT_DEBUG: return "DEBUG";
2078 case DT_TEXTREL: return "TEXTREL";
2079 case DT_JMPREL: return "JMPREL";
2080 case DT_BIND_NOW: return "BIND_NOW";
2081 case DT_INIT_ARRAY: return "INIT_ARRAY";
2082 case DT_FINI_ARRAY: return "FINI_ARRAY";
2083 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2084 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2085 case DT_RUNPATH: return "RUNPATH";
2086 case DT_FLAGS: return "FLAGS";
2d0e6f43 2087
d1133906
NC
2088 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2089 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2090 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2091
05107a46 2092 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2093 case DT_PLTPADSZ: return "PLTPADSZ";
2094 case DT_MOVEENT: return "MOVEENT";
2095 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2096 case DT_FEATURE: return "FEATURE";
252b5132
RH
2097 case DT_POSFLAG_1: return "POSFLAG_1";
2098 case DT_SYMINSZ: return "SYMINSZ";
2099 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2100
252b5132 2101 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2102 case DT_CONFIG: return "CONFIG";
2103 case DT_DEPAUDIT: return "DEPAUDIT";
2104 case DT_AUDIT: return "AUDIT";
2105 case DT_PLTPAD: return "PLTPAD";
2106 case DT_MOVETAB: return "MOVETAB";
252b5132 2107 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2108
252b5132 2109 case DT_VERSYM: return "VERSYM";
103f02d3 2110
67a4f2b7
AO
2111 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2112 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2113 case DT_RELACOUNT: return "RELACOUNT";
2114 case DT_RELCOUNT: return "RELCOUNT";
2115 case DT_FLAGS_1: return "FLAGS_1";
2116 case DT_VERDEF: return "VERDEF";
2117 case DT_VERDEFNUM: return "VERDEFNUM";
2118 case DT_VERNEED: return "VERNEED";
2119 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2120
019148e4 2121 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2122 case DT_USED: return "USED";
2123 case DT_FILTER: return "FILTER";
103f02d3 2124
047b2264
JJ
2125 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2126 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2127 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2128 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2129 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2130 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2131
252b5132
RH
2132 default:
2133 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2134 {
2cf0635d 2135 const char * result;
103f02d3 2136
dda8d76d 2137 switch (filedata->file_header.e_machine)
252b5132
RH
2138 {
2139 case EM_MIPS:
4fe85591 2140 case EM_MIPS_RS3_LE:
252b5132
RH
2141 result = get_mips_dynamic_type (type);
2142 break;
9a097730
RH
2143 case EM_SPARCV9:
2144 result = get_sparc64_dynamic_type (type);
2145 break;
7490d522
AM
2146 case EM_PPC:
2147 result = get_ppc_dynamic_type (type);
2148 break;
f1cb7e17
AM
2149 case EM_PPC64:
2150 result = get_ppc64_dynamic_type (type);
2151 break;
ecc51f48
NC
2152 case EM_IA_64:
2153 result = get_ia64_dynamic_type (type);
2154 break;
fabcb361
RH
2155 case EM_ALPHA:
2156 result = get_alpha_dynamic_type (type);
2157 break;
1c0d3aa6
NC
2158 case EM_SCORE:
2159 result = get_score_dynamic_type (type);
2160 break;
40b36596
JM
2161 case EM_TI_C6000:
2162 result = get_tic6x_dynamic_type (type);
2163 break;
36591ba1
SL
2164 case EM_ALTERA_NIOS2:
2165 result = get_nios2_dynamic_type (type);
2166 break;
252b5132 2167 default:
dda8d76d 2168 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2169 result = get_solaris_dynamic_type (type);
2170 else
2171 result = NULL;
252b5132
RH
2172 break;
2173 }
2174
2175 if (result != NULL)
2176 return result;
2177
e9e44622 2178 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2179 }
eec8f817 2180 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2181 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2182 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2183 {
2cf0635d 2184 const char * result;
103f02d3 2185
dda8d76d 2186 switch (filedata->file_header.e_machine)
103f02d3
UD
2187 {
2188 case EM_PARISC:
2189 result = get_parisc_dynamic_type (type);
2190 break;
148b93f2
NC
2191 case EM_IA_64:
2192 result = get_ia64_dynamic_type (type);
2193 break;
103f02d3 2194 default:
dda8d76d 2195 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2196 result = get_solaris_dynamic_type (type);
2197 else
2198 result = NULL;
103f02d3
UD
2199 break;
2200 }
2201
2202 if (result != NULL)
2203 return result;
2204
e9e44622
JJ
2205 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2206 type);
103f02d3 2207 }
252b5132 2208 else
e9e44622 2209 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2210
252b5132
RH
2211 return buff;
2212 }
2213}
2214
2215static char *
d3ba0551 2216get_file_type (unsigned e_type)
252b5132 2217{
b34976b6 2218 static char buff[32];
252b5132
RH
2219
2220 switch (e_type)
2221 {
32ec8896
NC
2222 case ET_NONE: return _("NONE (None)");
2223 case ET_REL: return _("REL (Relocatable file)");
2224 case ET_EXEC: return _("EXEC (Executable file)");
2225 case ET_DYN: return _("DYN (Shared object file)");
2226 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2227
2228 default:
2229 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2230 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2231 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2232 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2233 else
e9e44622 2234 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2235 return buff;
2236 }
2237}
2238
2239static char *
d3ba0551 2240get_machine_name (unsigned e_machine)
252b5132 2241{
b34976b6 2242 static char buff[64]; /* XXX */
252b5132
RH
2243
2244 switch (e_machine)
2245 {
55e22ca8
NC
2246 /* Please keep this switch table sorted by increasing EM_ value. */
2247 /* 0 */
c45021f2
NC
2248 case EM_NONE: return _("None");
2249 case EM_M32: return "WE32100";
2250 case EM_SPARC: return "Sparc";
2251 case EM_386: return "Intel 80386";
2252 case EM_68K: return "MC68000";
2253 case EM_88K: return "MC88000";
22abe556 2254 case EM_IAMCU: return "Intel MCU";
c45021f2
NC
2255 case EM_MIPS: return "MIPS R3000";
2256 case EM_S370: return "IBM System/370";
55e22ca8 2257 /* 10 */
7036c0e1 2258 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2259 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2260 case EM_PARISC: return "HPPA";
55e22ca8 2261 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2262 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2 2263 case EM_PPC: return "PowerPC";
55e22ca8 2264 /* 20 */
285d1771 2265 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2266 case EM_S390_OLD:
2267 case EM_S390: return "IBM S/390";
2268 case EM_SPU: return "SPU";
2269 /* 30 */
2270 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2271 case EM_FR20: return "Fujitsu FR20";
2272 case EM_RH32: return "TRW RH32";
b34976b6 2273 case EM_MCORE: return "MCORE";
55e22ca8 2274 /* 40 */
7036c0e1
AJ
2275 case EM_ARM: return "ARM";
2276 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2277 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2278 case EM_SPARCV9: return "Sparc v9";
2279 case EM_TRICORE: return "Siemens Tricore";
584da044 2280 case EM_ARC: return "ARC";
c2dcd04e
NC
2281 case EM_H8_300: return "Renesas H8/300";
2282 case EM_H8_300H: return "Renesas H8/300H";
2283 case EM_H8S: return "Renesas H8S";
2284 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2285 /* 50 */
30800947 2286 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2287 case EM_MIPS_X: return "Stanford MIPS-X";
2288 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2289 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2290 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2291 case EM_PCP: return "Siemens PCP";
2292 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2293 case EM_NDR1: return "Denso NDR1 microprocesspr";
2294 case EM_STARCORE: return "Motorola Star*Core processor";
2295 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2296 /* 60 */
7036c0e1
AJ
2297 case EM_ST100: return "STMicroelectronics ST100 processor";
2298 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2299 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2300 case EM_PDSP: return "Sony DSP processor";
2301 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2302 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2303 case EM_FX66: return "Siemens FX66 microcontroller";
2304 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2305 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2306 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2307 /* 70 */
7036c0e1
AJ
2308 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2309 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2310 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2311 case EM_SVX: return "Silicon Graphics SVx";
2312 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2313 case EM_VAX: return "Digital VAX";
1b61cf92 2314 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2315 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2316 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2317 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2318 /* 80 */
b34976b6 2319 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2320 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2321 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2322 case EM_AVR_OLD:
2323 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2324 case EM_CYGNUS_FR30:
2325 case EM_FR30: return "Fujitsu FR30";
2326 case EM_CYGNUS_D10V:
2327 case EM_D10V: return "d10v";
2328 case EM_CYGNUS_D30V:
2329 case EM_D30V: return "d30v";
2330 case EM_CYGNUS_V850:
2331 case EM_V850: return "Renesas V850";
2332 case EM_CYGNUS_M32R:
2333 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2334 case EM_CYGNUS_MN10300:
2335 case EM_MN10300: return "mn10300";
2336 /* 90 */
2337 case EM_CYGNUS_MN10200:
2338 case EM_MN10200: return "mn10200";
2339 case EM_PJ: return "picoJava";
73589c9d 2340 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2341 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2342 case EM_XTENSA_OLD:
2343 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2344 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2345 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2346 case EM_NS32K: return "National Semiconductor 32000 series";
2347 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2348 case EM_SNP1K: return "Trebia SNP 1000 processor";
2349 /* 100 */
2350 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2351 case EM_IP2K_OLD:
2352 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2353 case EM_MAX: return "MAX Processor";
2354 case EM_CR: return "National Semiconductor CompactRISC";
2355 case EM_F2MC16: return "Fujitsu F2MC16";
2356 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2357 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2358 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2359 case EM_SEP: return "Sharp embedded microprocessor";
2360 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2361 /* 110 */
11636f9e
JM
2362 case EM_UNICORE: return "Unicore";
2363 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2364 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2365 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2366 case EM_CRX: return "National Semiconductor CRX microprocessor";
2367 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2368 case EM_C166:
d70c5fc7 2369 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2370 case EM_M16C: return "Renesas M16C series microprocessors";
2371 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2372 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2373 /* 120 */
2374 case EM_M32C: return "Renesas M32c";
2375 /* 130 */
11636f9e
JM
2376 case EM_TSK3000: return "Altium TSK3000 core";
2377 case EM_RS08: return "Freescale RS08 embedded processor";
2378 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2379 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2380 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2381 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2382 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2383 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2384 /* 140 */
11636f9e
JM
2385 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2386 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2387 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2388 case EM_TI_PRU: return "TI PRU I/O processor";
2389 /* 160 */
11636f9e
JM
2390 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2391 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2392 case EM_R32C: return "Renesas R32C series microprocessors";
2393 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2394 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2395 case EM_8051: return "Intel 8051 and variants";
2396 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2397 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2398 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2399 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2400 /* 170 */
11636f9e
JM
2401 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2402 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2403 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2404 case EM_RX: return "Renesas RX";
a3c62988 2405 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2406 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2407 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2408 case EM_CR16:
2409 case EM_MICROBLAZE:
2410 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2411 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2412 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2413 /* 180 */
2414 case EM_L1OM: return "Intel L1OM";
2415 case EM_K1OM: return "Intel K1OM";
2416 case EM_INTEL182: return "Intel (reserved)";
2417 case EM_AARCH64: return "AArch64";
2418 case EM_ARM184: return "ARM (reserved)";
2419 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2420 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2421 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2422 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2423 /* 190 */
11636f9e 2424 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2425 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2426 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2427 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2428 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2429 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2430 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2431 case EM_RL78: return "Renesas RL78";
6d913794 2432 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2433 case EM_78K0R: return "Renesas 78K0R";
2434 /* 200 */
6d913794 2435 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2436 case EM_BA1: return "Beyond BA1 CPU architecture";
2437 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2438 case EM_XCORE: return "XMOS xCORE processor family";
2439 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2440 /* 210 */
6d913794
NC
2441 case EM_KM32: return "KM211 KM32 32-bit processor";
2442 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2443 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2444 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2445 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2446 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2447 case EM_COGE: return "Cognitive Smart Memory Processor";
2448 case EM_COOL: return "Bluechip Systems CoolEngine";
2449 case EM_NORC: return "Nanoradio Optimized RISC";
2450 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2451 /* 220 */
15f205b1 2452 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2453 case EM_VISIUM: return "CDS VISIUMcore processor";
2454 case EM_FT32: return "FTDI Chip FT32";
2455 case EM_MOXIE: return "Moxie";
2456 case EM_AMDGPU: return "AMD GPU";
2457 case EM_RISCV: return "RISC-V";
2458 case EM_LANAI: return "Lanai 32-bit processor";
2459 case EM_BPF: return "Linux BPF";
2460
2461 /* Large numbers... */
2462 case EM_MT: return "Morpho Techologies MT processor";
2463 case EM_ALPHA: return "Alpha";
2464 case EM_WEBASSEMBLY: return "Web Assembly";
2465 case EM_DLX: return "OpenDLX";
2466 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2467 case EM_IQ2000: return "Vitesse IQ2000";
2468 case EM_M32C_OLD:
2469 case EM_NIOS32: return "Altera Nios";
2470 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2471 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2472 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2473
252b5132 2474 default:
35d9dd2f 2475 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2476 return buff;
2477 }
2478}
2479
a9522a21
AB
2480static void
2481decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2482{
2483 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2484 other compilers don't a specific architecture type in the e_flags, and
2485 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2486 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2487 architectures.
2488
2489 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2490 but also sets a specific architecture type in the e_flags field.
2491
2492 However, when decoding the flags we don't worry if we see an
2493 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2494 ARCEM architecture type. */
2495
2496 switch (e_flags & EF_ARC_MACH_MSK)
2497 {
2498 /* We only expect these to occur for EM_ARC_COMPACT2. */
2499 case EF_ARC_CPU_ARCV2EM:
2500 strcat (buf, ", ARC EM");
2501 break;
2502 case EF_ARC_CPU_ARCV2HS:
2503 strcat (buf, ", ARC HS");
2504 break;
2505
2506 /* We only expect these to occur for EM_ARC_COMPACT. */
2507 case E_ARC_MACH_ARC600:
2508 strcat (buf, ", ARC600");
2509 break;
2510 case E_ARC_MACH_ARC601:
2511 strcat (buf, ", ARC601");
2512 break;
2513 case E_ARC_MACH_ARC700:
2514 strcat (buf, ", ARC700");
2515 break;
2516
2517 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2518 new ELF with new architecture being read by an old version of
2519 readelf, or (c) An ELF built with non-GNU compiler that does not
2520 set the architecture in the e_flags. */
2521 default:
2522 if (e_machine == EM_ARC_COMPACT)
2523 strcat (buf, ", Unknown ARCompact");
2524 else
2525 strcat (buf, ", Unknown ARC");
2526 break;
2527 }
2528
2529 switch (e_flags & EF_ARC_OSABI_MSK)
2530 {
2531 case E_ARC_OSABI_ORIG:
2532 strcat (buf, ", (ABI:legacy)");
2533 break;
2534 case E_ARC_OSABI_V2:
2535 strcat (buf, ", (ABI:v2)");
2536 break;
2537 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2538 case E_ARC_OSABI_V3:
2539 strcat (buf, ", v3 no-legacy-syscalls ABI");
2540 break;
53a346d8
CZ
2541 case E_ARC_OSABI_V4:
2542 strcat (buf, ", v4 ABI");
2543 break;
a9522a21
AB
2544 default:
2545 strcat (buf, ", unrecognised ARC OSABI flag");
2546 break;
2547 }
2548}
2549
f3485b74 2550static void
d3ba0551 2551decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2552{
2553 unsigned eabi;
32ec8896 2554 bfd_boolean unknown = FALSE;
f3485b74
NC
2555
2556 eabi = EF_ARM_EABI_VERSION (e_flags);
2557 e_flags &= ~ EF_ARM_EABIMASK;
2558
2559 /* Handle "generic" ARM flags. */
2560 if (e_flags & EF_ARM_RELEXEC)
2561 {
2562 strcat (buf, ", relocatable executable");
2563 e_flags &= ~ EF_ARM_RELEXEC;
2564 }
76da6bbe 2565
f3485b74
NC
2566 /* Now handle EABI specific flags. */
2567 switch (eabi)
2568 {
2569 default:
2c71103e 2570 strcat (buf, ", <unrecognized EABI>");
f3485b74 2571 if (e_flags)
32ec8896 2572 unknown = TRUE;
f3485b74
NC
2573 break;
2574
2575 case EF_ARM_EABI_VER1:
a5bcd848 2576 strcat (buf, ", Version1 EABI");
f3485b74
NC
2577 while (e_flags)
2578 {
2579 unsigned flag;
76da6bbe 2580
f3485b74
NC
2581 /* Process flags one bit at a time. */
2582 flag = e_flags & - e_flags;
2583 e_flags &= ~ flag;
76da6bbe 2584
f3485b74
NC
2585 switch (flag)
2586 {
a5bcd848 2587 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2588 strcat (buf, ", sorted symbol tables");
2589 break;
76da6bbe 2590
f3485b74 2591 default:
32ec8896 2592 unknown = TRUE;
f3485b74
NC
2593 break;
2594 }
2595 }
2596 break;
76da6bbe 2597
a5bcd848
PB
2598 case EF_ARM_EABI_VER2:
2599 strcat (buf, ", Version2 EABI");
2600 while (e_flags)
2601 {
2602 unsigned flag;
2603
2604 /* Process flags one bit at a time. */
2605 flag = e_flags & - e_flags;
2606 e_flags &= ~ flag;
2607
2608 switch (flag)
2609 {
2610 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2611 strcat (buf, ", sorted symbol tables");
2612 break;
2613
2614 case EF_ARM_DYNSYMSUSESEGIDX:
2615 strcat (buf, ", dynamic symbols use segment index");
2616 break;
2617
2618 case EF_ARM_MAPSYMSFIRST:
2619 strcat (buf, ", mapping symbols precede others");
2620 break;
2621
2622 default:
32ec8896 2623 unknown = TRUE;
a5bcd848
PB
2624 break;
2625 }
2626 }
2627 break;
2628
d507cf36
PB
2629 case EF_ARM_EABI_VER3:
2630 strcat (buf, ", Version3 EABI");
8cb51566
PB
2631 break;
2632
2633 case EF_ARM_EABI_VER4:
2634 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2635 while (e_flags)
2636 {
2637 unsigned flag;
2638
2639 /* Process flags one bit at a time. */
2640 flag = e_flags & - e_flags;
2641 e_flags &= ~ flag;
2642
2643 switch (flag)
2644 {
2645 case EF_ARM_BE8:
2646 strcat (buf, ", BE8");
2647 break;
2648
2649 case EF_ARM_LE8:
2650 strcat (buf, ", LE8");
2651 break;
2652
2653 default:
32ec8896 2654 unknown = TRUE;
3bfcb652
NC
2655 break;
2656 }
3bfcb652
NC
2657 }
2658 break;
3a4a14e9
PB
2659
2660 case EF_ARM_EABI_VER5:
2661 strcat (buf, ", Version5 EABI");
d507cf36
PB
2662 while (e_flags)
2663 {
2664 unsigned flag;
2665
2666 /* Process flags one bit at a time. */
2667 flag = e_flags & - e_flags;
2668 e_flags &= ~ flag;
2669
2670 switch (flag)
2671 {
2672 case EF_ARM_BE8:
2673 strcat (buf, ", BE8");
2674 break;
2675
2676 case EF_ARM_LE8:
2677 strcat (buf, ", LE8");
2678 break;
2679
3bfcb652
NC
2680 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2681 strcat (buf, ", soft-float ABI");
2682 break;
2683
2684 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2685 strcat (buf, ", hard-float ABI");
2686 break;
2687
d507cf36 2688 default:
32ec8896 2689 unknown = TRUE;
d507cf36
PB
2690 break;
2691 }
2692 }
2693 break;
2694
f3485b74 2695 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2696 strcat (buf, ", GNU EABI");
f3485b74
NC
2697 while (e_flags)
2698 {
2699 unsigned flag;
76da6bbe 2700
f3485b74
NC
2701 /* Process flags one bit at a time. */
2702 flag = e_flags & - e_flags;
2703 e_flags &= ~ flag;
76da6bbe 2704
f3485b74
NC
2705 switch (flag)
2706 {
a5bcd848 2707 case EF_ARM_INTERWORK:
f3485b74
NC
2708 strcat (buf, ", interworking enabled");
2709 break;
76da6bbe 2710
a5bcd848 2711 case EF_ARM_APCS_26:
f3485b74
NC
2712 strcat (buf, ", uses APCS/26");
2713 break;
76da6bbe 2714
a5bcd848 2715 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2716 strcat (buf, ", uses APCS/float");
2717 break;
76da6bbe 2718
a5bcd848 2719 case EF_ARM_PIC:
f3485b74
NC
2720 strcat (buf, ", position independent");
2721 break;
76da6bbe 2722
a5bcd848 2723 case EF_ARM_ALIGN8:
f3485b74
NC
2724 strcat (buf, ", 8 bit structure alignment");
2725 break;
76da6bbe 2726
a5bcd848 2727 case EF_ARM_NEW_ABI:
f3485b74
NC
2728 strcat (buf, ", uses new ABI");
2729 break;
76da6bbe 2730
a5bcd848 2731 case EF_ARM_OLD_ABI:
f3485b74
NC
2732 strcat (buf, ", uses old ABI");
2733 break;
76da6bbe 2734
a5bcd848 2735 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2736 strcat (buf, ", software FP");
2737 break;
76da6bbe 2738
90e01f86
ILT
2739 case EF_ARM_VFP_FLOAT:
2740 strcat (buf, ", VFP");
2741 break;
2742
fde78edd
NC
2743 case EF_ARM_MAVERICK_FLOAT:
2744 strcat (buf, ", Maverick FP");
2745 break;
2746
f3485b74 2747 default:
32ec8896 2748 unknown = TRUE;
f3485b74
NC
2749 break;
2750 }
2751 }
2752 }
f3485b74
NC
2753
2754 if (unknown)
2b692964 2755 strcat (buf,_(", <unknown>"));
f3485b74
NC
2756}
2757
343433df
AB
2758static void
2759decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2760{
2761 --size; /* Leave space for null terminator. */
2762
2763 switch (e_flags & EF_AVR_MACH)
2764 {
2765 case E_AVR_MACH_AVR1:
2766 strncat (buf, ", avr:1", size);
2767 break;
2768 case E_AVR_MACH_AVR2:
2769 strncat (buf, ", avr:2", size);
2770 break;
2771 case E_AVR_MACH_AVR25:
2772 strncat (buf, ", avr:25", size);
2773 break;
2774 case E_AVR_MACH_AVR3:
2775 strncat (buf, ", avr:3", size);
2776 break;
2777 case E_AVR_MACH_AVR31:
2778 strncat (buf, ", avr:31", size);
2779 break;
2780 case E_AVR_MACH_AVR35:
2781 strncat (buf, ", avr:35", size);
2782 break;
2783 case E_AVR_MACH_AVR4:
2784 strncat (buf, ", avr:4", size);
2785 break;
2786 case E_AVR_MACH_AVR5:
2787 strncat (buf, ", avr:5", size);
2788 break;
2789 case E_AVR_MACH_AVR51:
2790 strncat (buf, ", avr:51", size);
2791 break;
2792 case E_AVR_MACH_AVR6:
2793 strncat (buf, ", avr:6", size);
2794 break;
2795 case E_AVR_MACH_AVRTINY:
2796 strncat (buf, ", avr:100", size);
2797 break;
2798 case E_AVR_MACH_XMEGA1:
2799 strncat (buf, ", avr:101", size);
2800 break;
2801 case E_AVR_MACH_XMEGA2:
2802 strncat (buf, ", avr:102", size);
2803 break;
2804 case E_AVR_MACH_XMEGA3:
2805 strncat (buf, ", avr:103", size);
2806 break;
2807 case E_AVR_MACH_XMEGA4:
2808 strncat (buf, ", avr:104", size);
2809 break;
2810 case E_AVR_MACH_XMEGA5:
2811 strncat (buf, ", avr:105", size);
2812 break;
2813 case E_AVR_MACH_XMEGA6:
2814 strncat (buf, ", avr:106", size);
2815 break;
2816 case E_AVR_MACH_XMEGA7:
2817 strncat (buf, ", avr:107", size);
2818 break;
2819 default:
2820 strncat (buf, ", avr:<unknown>", size);
2821 break;
2822 }
2823
2824 size -= strlen (buf);
2825 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2826 strncat (buf, ", link-relax", size);
2827}
2828
35c08157
KLC
2829static void
2830decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2831{
2832 unsigned abi;
2833 unsigned arch;
2834 unsigned config;
2835 unsigned version;
32ec8896
NC
2836 bfd_boolean has_fpu = FALSE;
2837 unsigned int r = 0;
35c08157
KLC
2838
2839 static const char *ABI_STRINGS[] =
2840 {
2841 "ABI v0", /* use r5 as return register; only used in N1213HC */
2842 "ABI v1", /* use r0 as return register */
2843 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2844 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2845 "AABI",
2846 "ABI2 FP+"
35c08157
KLC
2847 };
2848 static const char *VER_STRINGS[] =
2849 {
2850 "Andes ELF V1.3 or older",
2851 "Andes ELF V1.3.1",
2852 "Andes ELF V1.4"
2853 };
2854 static const char *ARCH_STRINGS[] =
2855 {
2856 "",
2857 "Andes Star v1.0",
2858 "Andes Star v2.0",
2859 "Andes Star v3.0",
2860 "Andes Star v3.0m"
2861 };
2862
2863 abi = EF_NDS_ABI & e_flags;
2864 arch = EF_NDS_ARCH & e_flags;
2865 config = EF_NDS_INST & e_flags;
2866 version = EF_NDS32_ELF_VERSION & e_flags;
2867
2868 memset (buf, 0, size);
2869
2870 switch (abi)
2871 {
2872 case E_NDS_ABI_V0:
2873 case E_NDS_ABI_V1:
2874 case E_NDS_ABI_V2:
2875 case E_NDS_ABI_V2FP:
2876 case E_NDS_ABI_AABI:
40c7a7cb 2877 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2878 /* In case there are holes in the array. */
2879 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2880 break;
2881
2882 default:
2883 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2884 break;
2885 }
2886
2887 switch (version)
2888 {
2889 case E_NDS32_ELF_VER_1_2:
2890 case E_NDS32_ELF_VER_1_3:
2891 case E_NDS32_ELF_VER_1_4:
2892 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2893 break;
2894
2895 default:
2896 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2897 break;
2898 }
2899
2900 if (E_NDS_ABI_V0 == abi)
2901 {
2902 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2903 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2904 if (arch == E_NDS_ARCH_STAR_V1_0)
2905 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2906 return;
2907 }
2908
2909 switch (arch)
2910 {
2911 case E_NDS_ARCH_STAR_V1_0:
2912 case E_NDS_ARCH_STAR_V2_0:
2913 case E_NDS_ARCH_STAR_V3_0:
2914 case E_NDS_ARCH_STAR_V3_M:
2915 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2916 break;
2917
2918 default:
2919 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2920 /* ARCH version determines how the e_flags are interpreted.
2921 If it is unknown, we cannot proceed. */
2922 return;
2923 }
2924
2925 /* Newer ABI; Now handle architecture specific flags. */
2926 if (arch == E_NDS_ARCH_STAR_V1_0)
2927 {
2928 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2929 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2930
2931 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2932 r += snprintf (buf + r, size -r, ", MAC");
2933
2934 if (config & E_NDS32_HAS_DIV_INST)
2935 r += snprintf (buf + r, size -r, ", DIV");
2936
2937 if (config & E_NDS32_HAS_16BIT_INST)
2938 r += snprintf (buf + r, size -r, ", 16b");
2939 }
2940 else
2941 {
2942 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2943 {
2944 if (version <= E_NDS32_ELF_VER_1_3)
2945 r += snprintf (buf + r, size -r, ", [B8]");
2946 else
2947 r += snprintf (buf + r, size -r, ", EX9");
2948 }
2949
2950 if (config & E_NDS32_HAS_MAC_DX_INST)
2951 r += snprintf (buf + r, size -r, ", MAC_DX");
2952
2953 if (config & E_NDS32_HAS_DIV_DX_INST)
2954 r += snprintf (buf + r, size -r, ", DIV_DX");
2955
2956 if (config & E_NDS32_HAS_16BIT_INST)
2957 {
2958 if (version <= E_NDS32_ELF_VER_1_3)
2959 r += snprintf (buf + r, size -r, ", 16b");
2960 else
2961 r += snprintf (buf + r, size -r, ", IFC");
2962 }
2963 }
2964
2965 if (config & E_NDS32_HAS_EXT_INST)
2966 r += snprintf (buf + r, size -r, ", PERF1");
2967
2968 if (config & E_NDS32_HAS_EXT2_INST)
2969 r += snprintf (buf + r, size -r, ", PERF2");
2970
2971 if (config & E_NDS32_HAS_FPU_INST)
2972 {
32ec8896 2973 has_fpu = TRUE;
35c08157
KLC
2974 r += snprintf (buf + r, size -r, ", FPU_SP");
2975 }
2976
2977 if (config & E_NDS32_HAS_FPU_DP_INST)
2978 {
32ec8896 2979 has_fpu = TRUE;
35c08157
KLC
2980 r += snprintf (buf + r, size -r, ", FPU_DP");
2981 }
2982
2983 if (config & E_NDS32_HAS_FPU_MAC_INST)
2984 {
32ec8896 2985 has_fpu = TRUE;
35c08157
KLC
2986 r += snprintf (buf + r, size -r, ", FPU_MAC");
2987 }
2988
2989 if (has_fpu)
2990 {
2991 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2992 {
2993 case E_NDS32_FPU_REG_8SP_4DP:
2994 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2995 break;
2996 case E_NDS32_FPU_REG_16SP_8DP:
2997 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2998 break;
2999 case E_NDS32_FPU_REG_32SP_16DP:
3000 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3001 break;
3002 case E_NDS32_FPU_REG_32SP_32DP:
3003 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3004 break;
3005 }
3006 }
3007
3008 if (config & E_NDS32_HAS_AUDIO_INST)
3009 r += snprintf (buf + r, size -r, ", AUDIO");
3010
3011 if (config & E_NDS32_HAS_STRING_INST)
3012 r += snprintf (buf + r, size -r, ", STR");
3013
3014 if (config & E_NDS32_HAS_REDUCED_REGS)
3015 r += snprintf (buf + r, size -r, ", 16REG");
3016
3017 if (config & E_NDS32_HAS_VIDEO_INST)
3018 {
3019 if (version <= E_NDS32_ELF_VER_1_3)
3020 r += snprintf (buf + r, size -r, ", VIDEO");
3021 else
3022 r += snprintf (buf + r, size -r, ", SATURATION");
3023 }
3024
3025 if (config & E_NDS32_HAS_ENCRIPT_INST)
3026 r += snprintf (buf + r, size -r, ", ENCRP");
3027
3028 if (config & E_NDS32_HAS_L2C_INST)
3029 r += snprintf (buf + r, size -r, ", L2C");
3030}
3031
252b5132 3032static char *
dda8d76d 3033get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3034{
b34976b6 3035 static char buf[1024];
252b5132
RH
3036
3037 buf[0] = '\0';
76da6bbe 3038
252b5132
RH
3039 if (e_flags)
3040 {
3041 switch (e_machine)
3042 {
3043 default:
3044 break;
3045
886a2506 3046 case EM_ARC_COMPACT2:
886a2506 3047 case EM_ARC_COMPACT:
a9522a21
AB
3048 decode_ARC_machine_flags (e_flags, e_machine, buf);
3049 break;
886a2506 3050
f3485b74
NC
3051 case EM_ARM:
3052 decode_ARM_machine_flags (e_flags, buf);
3053 break;
76da6bbe 3054
343433df
AB
3055 case EM_AVR:
3056 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3057 break;
3058
781303ce
MF
3059 case EM_BLACKFIN:
3060 if (e_flags & EF_BFIN_PIC)
3061 strcat (buf, ", PIC");
3062
3063 if (e_flags & EF_BFIN_FDPIC)
3064 strcat (buf, ", FDPIC");
3065
3066 if (e_flags & EF_BFIN_CODE_IN_L1)
3067 strcat (buf, ", code in L1");
3068
3069 if (e_flags & EF_BFIN_DATA_IN_L1)
3070 strcat (buf, ", data in L1");
3071
3072 break;
3073
ec2dfb42
AO
3074 case EM_CYGNUS_FRV:
3075 switch (e_flags & EF_FRV_CPU_MASK)
3076 {
3077 case EF_FRV_CPU_GENERIC:
3078 break;
3079
3080 default:
3081 strcat (buf, ", fr???");
3082 break;
57346661 3083
ec2dfb42
AO
3084 case EF_FRV_CPU_FR300:
3085 strcat (buf, ", fr300");
3086 break;
3087
3088 case EF_FRV_CPU_FR400:
3089 strcat (buf, ", fr400");
3090 break;
3091 case EF_FRV_CPU_FR405:
3092 strcat (buf, ", fr405");
3093 break;
3094
3095 case EF_FRV_CPU_FR450:
3096 strcat (buf, ", fr450");
3097 break;
3098
3099 case EF_FRV_CPU_FR500:
3100 strcat (buf, ", fr500");
3101 break;
3102 case EF_FRV_CPU_FR550:
3103 strcat (buf, ", fr550");
3104 break;
3105
3106 case EF_FRV_CPU_SIMPLE:
3107 strcat (buf, ", simple");
3108 break;
3109 case EF_FRV_CPU_TOMCAT:
3110 strcat (buf, ", tomcat");
3111 break;
3112 }
1c877e87 3113 break;
ec2dfb42 3114
53c7db4b 3115 case EM_68K:
425c6cb0 3116 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3117 strcat (buf, ", m68000");
425c6cb0 3118 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3119 strcat (buf, ", cpu32");
3120 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3121 strcat (buf, ", fido_a");
425c6cb0 3122 else
266abb8f 3123 {
2cf0635d
NC
3124 char const * isa = _("unknown");
3125 char const * mac = _("unknown mac");
3126 char const * additional = NULL;
0112cd26 3127
c694fd50 3128 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3129 {
c694fd50 3130 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3131 isa = "A";
3132 additional = ", nodiv";
3133 break;
c694fd50 3134 case EF_M68K_CF_ISA_A:
266abb8f
NS
3135 isa = "A";
3136 break;
c694fd50 3137 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3138 isa = "A+";
3139 break;
c694fd50 3140 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3141 isa = "B";
3142 additional = ", nousp";
3143 break;
c694fd50 3144 case EF_M68K_CF_ISA_B:
266abb8f
NS
3145 isa = "B";
3146 break;
f608cd77
NS
3147 case EF_M68K_CF_ISA_C:
3148 isa = "C";
3149 break;
3150 case EF_M68K_CF_ISA_C_NODIV:
3151 isa = "C";
3152 additional = ", nodiv";
3153 break;
266abb8f
NS
3154 }
3155 strcat (buf, ", cf, isa ");
3156 strcat (buf, isa);
0b2e31dc
NS
3157 if (additional)
3158 strcat (buf, additional);
c694fd50 3159 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3160 strcat (buf, ", float");
c694fd50 3161 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3162 {
3163 case 0:
3164 mac = NULL;
3165 break;
c694fd50 3166 case EF_M68K_CF_MAC:
266abb8f
NS
3167 mac = "mac";
3168 break;
c694fd50 3169 case EF_M68K_CF_EMAC:
266abb8f
NS
3170 mac = "emac";
3171 break;
f608cd77
NS
3172 case EF_M68K_CF_EMAC_B:
3173 mac = "emac_b";
3174 break;
266abb8f
NS
3175 }
3176 if (mac)
3177 {
3178 strcat (buf, ", ");
3179 strcat (buf, mac);
3180 }
266abb8f 3181 }
53c7db4b 3182 break;
33c63f9d 3183
153a2776
NC
3184 case EM_CYGNUS_MEP:
3185 switch (e_flags & EF_MEP_CPU_MASK)
3186 {
3187 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3188 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3189 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3190 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3191 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3192 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3193 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3194 }
3195
3196 switch (e_flags & EF_MEP_COP_MASK)
3197 {
3198 case EF_MEP_COP_NONE: break;
3199 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3200 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3201 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3202 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3203 default: strcat (buf, _("<unknown MeP copro type>")); break;
3204 }
3205
3206 if (e_flags & EF_MEP_LIBRARY)
3207 strcat (buf, ", Built for Library");
3208
3209 if (e_flags & EF_MEP_INDEX_MASK)
3210 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3211 e_flags & EF_MEP_INDEX_MASK);
3212
3213 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3214 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3215 e_flags & ~ EF_MEP_ALL_FLAGS);
3216 break;
3217
252b5132
RH
3218 case EM_PPC:
3219 if (e_flags & EF_PPC_EMB)
3220 strcat (buf, ", emb");
3221
3222 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3223 strcat (buf, _(", relocatable"));
252b5132
RH
3224
3225 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3226 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3227 break;
3228
ee67d69a
AM
3229 case EM_PPC64:
3230 if (e_flags & EF_PPC64_ABI)
3231 {
3232 char abi[] = ", abiv0";
3233
3234 abi[6] += e_flags & EF_PPC64_ABI;
3235 strcat (buf, abi);
3236 }
3237 break;
3238
708e2187
NC
3239 case EM_V800:
3240 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3241 strcat (buf, ", RH850 ABI");
0b4362b0 3242
708e2187
NC
3243 if (e_flags & EF_V800_850E3)
3244 strcat (buf, ", V3 architecture");
3245
3246 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3247 strcat (buf, ", FPU not used");
3248
3249 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3250 strcat (buf, ", regmode: COMMON");
3251
3252 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3253 strcat (buf, ", r4 not used");
3254
3255 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3256 strcat (buf, ", r30 not used");
3257
3258 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3259 strcat (buf, ", r5 not used");
3260
3261 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3262 strcat (buf, ", r2 not used");
3263
3264 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3265 {
3266 switch (e_flags & - e_flags)
3267 {
3268 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3269 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3270 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3271 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3272 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3273 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3274 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3275 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3276 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3277 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3278 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3279 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3280 default: break;
3281 }
3282 }
3283 break;
3284
2b0337b0 3285 case EM_V850:
252b5132
RH
3286 case EM_CYGNUS_V850:
3287 switch (e_flags & EF_V850_ARCH)
3288 {
78c8d46c
NC
3289 case E_V850E3V5_ARCH:
3290 strcat (buf, ", v850e3v5");
3291 break;
1cd986c5
NC
3292 case E_V850E2V3_ARCH:
3293 strcat (buf, ", v850e2v3");
3294 break;
3295 case E_V850E2_ARCH:
3296 strcat (buf, ", v850e2");
3297 break;
3298 case E_V850E1_ARCH:
3299 strcat (buf, ", v850e1");
8ad30312 3300 break;
252b5132
RH
3301 case E_V850E_ARCH:
3302 strcat (buf, ", v850e");
3303 break;
252b5132
RH
3304 case E_V850_ARCH:
3305 strcat (buf, ", v850");
3306 break;
3307 default:
2b692964 3308 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3309 break;
3310 }
3311 break;
3312
2b0337b0 3313 case EM_M32R:
252b5132
RH
3314 case EM_CYGNUS_M32R:
3315 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3316 strcat (buf, ", m32r");
252b5132
RH
3317 break;
3318
3319 case EM_MIPS:
4fe85591 3320 case EM_MIPS_RS3_LE:
252b5132
RH
3321 if (e_flags & EF_MIPS_NOREORDER)
3322 strcat (buf, ", noreorder");
3323
3324 if (e_flags & EF_MIPS_PIC)
3325 strcat (buf, ", pic");
3326
3327 if (e_flags & EF_MIPS_CPIC)
3328 strcat (buf, ", cpic");
3329
d1bdd336
TS
3330 if (e_flags & EF_MIPS_UCODE)
3331 strcat (buf, ", ugen_reserved");
3332
252b5132
RH
3333 if (e_flags & EF_MIPS_ABI2)
3334 strcat (buf, ", abi2");
3335
43521d43
TS
3336 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3337 strcat (buf, ", odk first");
3338
a5d22d2a
TS
3339 if (e_flags & EF_MIPS_32BITMODE)
3340 strcat (buf, ", 32bitmode");
3341
ba92f887
MR
3342 if (e_flags & EF_MIPS_NAN2008)
3343 strcat (buf, ", nan2008");
3344
fef1b0b3
SE
3345 if (e_flags & EF_MIPS_FP64)
3346 strcat (buf, ", fp64");
3347
156c2f8b
NC
3348 switch ((e_flags & EF_MIPS_MACH))
3349 {
3350 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3351 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3352 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3353 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3354 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3355 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3356 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3357 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3358 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3359 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3360 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3361 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3362 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 3363 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 3364 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3365 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3366 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3367 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3368 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3369 case 0:
3370 /* We simply ignore the field in this case to avoid confusion:
3371 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3372 extension. */
3373 break;
2b692964 3374 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3375 }
43521d43
TS
3376
3377 switch ((e_flags & EF_MIPS_ABI))
3378 {
3379 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3380 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3381 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3382 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3383 case 0:
3384 /* We simply ignore the field in this case to avoid confusion:
3385 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3386 This means it is likely to be an o32 file, but not for
3387 sure. */
3388 break;
2b692964 3389 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3390 }
3391
3392 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3393 strcat (buf, ", mdmx");
3394
3395 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3396 strcat (buf, ", mips16");
3397
df58fc94
RS
3398 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3399 strcat (buf, ", micromips");
3400
43521d43
TS
3401 switch ((e_flags & EF_MIPS_ARCH))
3402 {
3403 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3404 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3405 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3406 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3407 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3408 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3409 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3410 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3411 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3412 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3413 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3414 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3415 }
252b5132 3416 break;
351b4b40 3417
35c08157
KLC
3418 case EM_NDS32:
3419 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3420 break;
3421
e23eba97
NC
3422 case EM_RISCV:
3423 if (e_flags & EF_RISCV_RVC)
3424 strcat (buf, ", RVC");
2922d21d
AW
3425
3426 switch (e_flags & EF_RISCV_FLOAT_ABI)
3427 {
3428 case EF_RISCV_FLOAT_ABI_SOFT:
3429 strcat (buf, ", soft-float ABI");
3430 break;
3431
3432 case EF_RISCV_FLOAT_ABI_SINGLE:
3433 strcat (buf, ", single-float ABI");
3434 break;
3435
3436 case EF_RISCV_FLOAT_ABI_DOUBLE:
3437 strcat (buf, ", double-float ABI");
3438 break;
3439
3440 case EF_RISCV_FLOAT_ABI_QUAD:
3441 strcat (buf, ", quad-float ABI");
3442 break;
3443 }
e23eba97
NC
3444 break;
3445
ccde1100
AO
3446 case EM_SH:
3447 switch ((e_flags & EF_SH_MACH_MASK))
3448 {
3449 case EF_SH1: strcat (buf, ", sh1"); break;
3450 case EF_SH2: strcat (buf, ", sh2"); break;
3451 case EF_SH3: strcat (buf, ", sh3"); break;
3452 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3453 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3454 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3455 case EF_SH3E: strcat (buf, ", sh3e"); break;
3456 case EF_SH4: strcat (buf, ", sh4"); break;
3457 case EF_SH5: strcat (buf, ", sh5"); break;
3458 case EF_SH2E: strcat (buf, ", sh2e"); break;
3459 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3460 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3461 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3462 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3463 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3464 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3465 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3466 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3467 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3468 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3469 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3470 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3471 }
3472
cec6a5b8
MR
3473 if (e_flags & EF_SH_PIC)
3474 strcat (buf, ", pic");
3475
3476 if (e_flags & EF_SH_FDPIC)
3477 strcat (buf, ", fdpic");
ccde1100 3478 break;
948f632f 3479
73589c9d
CS
3480 case EM_OR1K:
3481 if (e_flags & EF_OR1K_NODELAY)
3482 strcat (buf, ", no delay");
3483 break;
57346661 3484
351b4b40
RH
3485 case EM_SPARCV9:
3486 if (e_flags & EF_SPARC_32PLUS)
3487 strcat (buf, ", v8+");
3488
3489 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3490 strcat (buf, ", ultrasparcI");
3491
3492 if (e_flags & EF_SPARC_SUN_US3)
3493 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3494
3495 if (e_flags & EF_SPARC_HAL_R1)
3496 strcat (buf, ", halr1");
3497
3498 if (e_flags & EF_SPARC_LEDATA)
3499 strcat (buf, ", ledata");
3500
3501 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3502 strcat (buf, ", tso");
3503
3504 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3505 strcat (buf, ", pso");
3506
3507 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3508 strcat (buf, ", rmo");
3509 break;
7d466069 3510
103f02d3
UD
3511 case EM_PARISC:
3512 switch (e_flags & EF_PARISC_ARCH)
3513 {
3514 case EFA_PARISC_1_0:
3515 strcpy (buf, ", PA-RISC 1.0");
3516 break;
3517 case EFA_PARISC_1_1:
3518 strcpy (buf, ", PA-RISC 1.1");
3519 break;
3520 case EFA_PARISC_2_0:
3521 strcpy (buf, ", PA-RISC 2.0");
3522 break;
3523 default:
3524 break;
3525 }
3526 if (e_flags & EF_PARISC_TRAPNIL)
3527 strcat (buf, ", trapnil");
3528 if (e_flags & EF_PARISC_EXT)
3529 strcat (buf, ", ext");
3530 if (e_flags & EF_PARISC_LSB)
3531 strcat (buf, ", lsb");
3532 if (e_flags & EF_PARISC_WIDE)
3533 strcat (buf, ", wide");
3534 if (e_flags & EF_PARISC_NO_KABP)
3535 strcat (buf, ", no kabp");
3536 if (e_flags & EF_PARISC_LAZYSWAP)
3537 strcat (buf, ", lazyswap");
30800947 3538 break;
76da6bbe 3539
7d466069 3540 case EM_PJ:
2b0337b0 3541 case EM_PJ_OLD:
7d466069
ILT
3542 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3543 strcat (buf, ", new calling convention");
3544
3545 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3546 strcat (buf, ", gnu calling convention");
3547 break;
4d6ed7c8
NC
3548
3549 case EM_IA_64:
3550 if ((e_flags & EF_IA_64_ABI64))
3551 strcat (buf, ", 64-bit");
3552 else
3553 strcat (buf, ", 32-bit");
3554 if ((e_flags & EF_IA_64_REDUCEDFP))
3555 strcat (buf, ", reduced fp model");
3556 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3557 strcat (buf, ", no function descriptors, constant gp");
3558 else if ((e_flags & EF_IA_64_CONS_GP))
3559 strcat (buf, ", constant gp");
3560 if ((e_flags & EF_IA_64_ABSOLUTE))
3561 strcat (buf, ", absolute");
dda8d76d 3562 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3563 {
3564 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3565 strcat (buf, ", vms_linkages");
3566 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3567 {
3568 case EF_IA_64_VMS_COMCOD_SUCCESS:
3569 break;
3570 case EF_IA_64_VMS_COMCOD_WARNING:
3571 strcat (buf, ", warning");
3572 break;
3573 case EF_IA_64_VMS_COMCOD_ERROR:
3574 strcat (buf, ", error");
3575 break;
3576 case EF_IA_64_VMS_COMCOD_ABORT:
3577 strcat (buf, ", abort");
3578 break;
3579 default:
bee0ee85
NC
3580 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3581 e_flags & EF_IA_64_VMS_COMCOD);
3582 strcat (buf, ", <unknown>");
28f997cf
TG
3583 }
3584 }
4d6ed7c8 3585 break;
179d3252
JT
3586
3587 case EM_VAX:
3588 if ((e_flags & EF_VAX_NONPIC))
3589 strcat (buf, ", non-PIC");
3590 if ((e_flags & EF_VAX_DFLOAT))
3591 strcat (buf, ", D-Float");
3592 if ((e_flags & EF_VAX_GFLOAT))
3593 strcat (buf, ", G-Float");
3594 break;
c7927a3c 3595
619ed720
EB
3596 case EM_VISIUM:
3597 if (e_flags & EF_VISIUM_ARCH_MCM)
3598 strcat (buf, ", mcm");
3599 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3600 strcat (buf, ", mcm24");
3601 if (e_flags & EF_VISIUM_ARCH_GR6)
3602 strcat (buf, ", gr6");
3603 break;
3604
4046d87a 3605 case EM_RL78:
1740ba0c
NC
3606 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3607 {
3608 case E_FLAG_RL78_ANY_CPU: break;
3609 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3610 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3611 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3612 }
856ea05c
KP
3613 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3614 strcat (buf, ", 64-bit doubles");
4046d87a 3615 break;
0b4362b0 3616
c7927a3c
NC
3617 case EM_RX:
3618 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3619 strcat (buf, ", 64-bit doubles");
3620 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3621 strcat (buf, ", dsp");
d4cb0ea0 3622 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3623 strcat (buf, ", pid");
708e2187
NC
3624 if (e_flags & E_FLAG_RX_ABI)
3625 strcat (buf, ", RX ABI");
3525236c
NC
3626 if (e_flags & E_FLAG_RX_SINSNS_SET)
3627 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3628 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3629 if (e_flags & E_FLAG_RX_V2)
3630 strcat (buf, ", V2");
d4cb0ea0 3631 break;
55786da2
AK
3632
3633 case EM_S390:
3634 if (e_flags & EF_S390_HIGH_GPRS)
3635 strcat (buf, ", highgprs");
d4cb0ea0 3636 break;
40b36596
JM
3637
3638 case EM_TI_C6000:
3639 if ((e_flags & EF_C6000_REL))
3640 strcat (buf, ", relocatable module");
d4cb0ea0 3641 break;
13761a11
NC
3642
3643 case EM_MSP430:
3644 strcat (buf, _(": architecture variant: "));
3645 switch (e_flags & EF_MSP430_MACH)
3646 {
3647 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3648 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3649 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3650 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3651 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3652 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3653 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3654 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3655 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3656 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3657 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3658 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3659 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3660 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3661 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3662 default:
3663 strcat (buf, _(": unknown")); break;
3664 }
3665
3666 if (e_flags & ~ EF_MSP430_MACH)
3667 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3668 }
3669 }
3670
3671 return buf;
3672}
3673
252b5132 3674static const char *
dda8d76d 3675get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3676{
3677 static char buff[32];
3678
3679 switch (osabi)
3680 {
3681 case ELFOSABI_NONE: return "UNIX - System V";
3682 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3683 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3684 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3685 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3686 case ELFOSABI_AIX: return "UNIX - AIX";
3687 case ELFOSABI_IRIX: return "UNIX - IRIX";
3688 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3689 case ELFOSABI_TRU64: return "UNIX - TRU64";
3690 case ELFOSABI_MODESTO: return "Novell - Modesto";
3691 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3692 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3693 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3694 case ELFOSABI_AROS: return "AROS";
11636f9e 3695 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3696 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3697 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3698 default:
40b36596 3699 if (osabi >= 64)
dda8d76d 3700 switch (filedata->file_header.e_machine)
40b36596
JM
3701 {
3702 case EM_ARM:
3703 switch (osabi)
3704 {
3705 case ELFOSABI_ARM: return "ARM";
3706 default:
3707 break;
3708 }
3709 break;
3710
3711 case EM_MSP430:
3712 case EM_MSP430_OLD:
619ed720 3713 case EM_VISIUM:
40b36596
JM
3714 switch (osabi)
3715 {
3716 case ELFOSABI_STANDALONE: return _("Standalone App");
3717 default:
3718 break;
3719 }
3720 break;
3721
3722 case EM_TI_C6000:
3723 switch (osabi)
3724 {
3725 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3726 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3727 default:
3728 break;
3729 }
3730 break;
3731
3732 default:
3733 break;
3734 }
e9e44622 3735 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3736 return buff;
3737 }
3738}
3739
a06ea964
NC
3740static const char *
3741get_aarch64_segment_type (unsigned long type)
3742{
3743 switch (type)
3744 {
32ec8896
NC
3745 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3746 default: return NULL;
a06ea964 3747 }
a06ea964
NC
3748}
3749
b294bdf8
MM
3750static const char *
3751get_arm_segment_type (unsigned long type)
3752{
3753 switch (type)
3754 {
32ec8896
NC
3755 case PT_ARM_EXIDX: return "EXIDX";
3756 default: return NULL;
b294bdf8 3757 }
b294bdf8
MM
3758}
3759
b4cbbe8f
AK
3760static const char *
3761get_s390_segment_type (unsigned long type)
3762{
3763 switch (type)
3764 {
3765 case PT_S390_PGSTE: return "S390_PGSTE";
3766 default: return NULL;
3767 }
3768}
3769
d3ba0551
AM
3770static const char *
3771get_mips_segment_type (unsigned long type)
252b5132
RH
3772{
3773 switch (type)
3774 {
32ec8896
NC
3775 case PT_MIPS_REGINFO: return "REGINFO";
3776 case PT_MIPS_RTPROC: return "RTPROC";
3777 case PT_MIPS_OPTIONS: return "OPTIONS";
3778 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3779 default: return NULL;
252b5132 3780 }
252b5132
RH
3781}
3782
103f02d3 3783static const char *
d3ba0551 3784get_parisc_segment_type (unsigned long type)
103f02d3
UD
3785{
3786 switch (type)
3787 {
3788 case PT_HP_TLS: return "HP_TLS";
3789 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3790 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3791 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3792 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3793 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3794 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3795 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3796 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3797 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3798 case PT_HP_PARALLEL: return "HP_PARALLEL";
3799 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3800 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3801 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3802 case PT_HP_STACK: return "HP_STACK";
3803 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3804 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3805 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3806 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3807 default: return NULL;
103f02d3 3808 }
103f02d3
UD
3809}
3810
4d6ed7c8 3811static const char *
d3ba0551 3812get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3813{
3814 switch (type)
3815 {
3816 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3817 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3818 case PT_HP_TLS: return "HP_TLS";
3819 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3820 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3821 case PT_IA_64_HP_STACK: return "HP_STACK";
32ec8896 3822 default: return NULL;
4d6ed7c8 3823 }
4d6ed7c8
NC
3824}
3825
40b36596
JM
3826static const char *
3827get_tic6x_segment_type (unsigned long type)
3828{
3829 switch (type)
3830 {
32ec8896
NC
3831 case PT_C6000_PHATTR: return "C6000_PHATTR";
3832 default: return NULL;
40b36596 3833 }
40b36596
JM
3834}
3835
5522f910
NC
3836static const char *
3837get_solaris_segment_type (unsigned long type)
3838{
3839 switch (type)
3840 {
3841 case 0x6464e550: return "PT_SUNW_UNWIND";
3842 case 0x6474e550: return "PT_SUNW_EH_FRAME";
3843 case 0x6ffffff7: return "PT_LOSUNW";
3844 case 0x6ffffffa: return "PT_SUNWBSS";
3845 case 0x6ffffffb: return "PT_SUNWSTACK";
3846 case 0x6ffffffc: return "PT_SUNWDTRACE";
3847 case 0x6ffffffd: return "PT_SUNWCAP";
3848 case 0x6fffffff: return "PT_HISUNW";
32ec8896 3849 default: return NULL;
5522f910
NC
3850 }
3851}
3852
252b5132 3853static const char *
dda8d76d 3854get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 3855{
b34976b6 3856 static char buff[32];
252b5132
RH
3857
3858 switch (p_type)
3859 {
b34976b6
AM
3860 case PT_NULL: return "NULL";
3861 case PT_LOAD: return "LOAD";
252b5132 3862 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3863 case PT_INTERP: return "INTERP";
3864 case PT_NOTE: return "NOTE";
3865 case PT_SHLIB: return "SHLIB";
3866 case PT_PHDR: return "PHDR";
13ae64f3 3867 case PT_TLS: return "TLS";
32ec8896 3868 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 3869 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3870 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3871
252b5132 3872 default:
a91e1603
L
3873 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
3874 {
3875 sprintf (buff, "GNU_MBIND+%#lx",
3876 p_type - PT_GNU_MBIND_LO);
3877 }
3878 else if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 3879 {
2cf0635d 3880 const char * result;
103f02d3 3881
dda8d76d 3882 switch (filedata->file_header.e_machine)
252b5132 3883 {
a06ea964
NC
3884 case EM_AARCH64:
3885 result = get_aarch64_segment_type (p_type);
3886 break;
b294bdf8
MM
3887 case EM_ARM:
3888 result = get_arm_segment_type (p_type);
3889 break;
252b5132 3890 case EM_MIPS:
4fe85591 3891 case EM_MIPS_RS3_LE:
252b5132
RH
3892 result = get_mips_segment_type (p_type);
3893 break;
103f02d3
UD
3894 case EM_PARISC:
3895 result = get_parisc_segment_type (p_type);
3896 break;
4d6ed7c8
NC
3897 case EM_IA_64:
3898 result = get_ia64_segment_type (p_type);
3899 break;
40b36596
JM
3900 case EM_TI_C6000:
3901 result = get_tic6x_segment_type (p_type);
3902 break;
b4cbbe8f
AK
3903 case EM_S390:
3904 case EM_S390_OLD:
3905 result = get_s390_segment_type (p_type);
3906 break;
252b5132
RH
3907 default:
3908 result = NULL;
3909 break;
3910 }
103f02d3 3911
252b5132
RH
3912 if (result != NULL)
3913 return result;
103f02d3 3914
1a9ccd70 3915 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
3916 }
3917 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3918 {
2cf0635d 3919 const char * result;
103f02d3 3920
dda8d76d 3921 switch (filedata->file_header.e_machine)
103f02d3
UD
3922 {
3923 case EM_PARISC:
3924 result = get_parisc_segment_type (p_type);
3925 break;
00428cca
AM
3926 case EM_IA_64:
3927 result = get_ia64_segment_type (p_type);
3928 break;
103f02d3 3929 default:
dda8d76d 3930 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5522f910
NC
3931 result = get_solaris_segment_type (p_type);
3932 else
3933 result = NULL;
103f02d3
UD
3934 break;
3935 }
3936
3937 if (result != NULL)
3938 return result;
3939
1a9ccd70 3940 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 3941 }
252b5132 3942 else
e9e44622 3943 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3944
3945 return buff;
3946 }
3947}
3948
53a346d8
CZ
3949static const char *
3950get_arc_section_type_name (unsigned int sh_type)
3951{
3952 switch (sh_type)
3953 {
3954 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
3955 default:
3956 break;
3957 }
3958 return NULL;
3959}
3960
252b5132 3961static const char *
d3ba0551 3962get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3963{
3964 switch (sh_type)
3965 {
b34976b6
AM
3966 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3967 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3968 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3969 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3970 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3971 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3972 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3973 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3974 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3975 case SHT_MIPS_RELD: return "MIPS_RELD";
3976 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3977 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3978 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3979 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3980 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3981 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3982 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3983 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3984 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3985 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3986 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3987 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3988 case SHT_MIPS_LINE: return "MIPS_LINE";
3989 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3990 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3991 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3992 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3993 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3994 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3995 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3996 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3997 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3998 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3999 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4000 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4001 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4002 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4003 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4004 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4005 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
4006 default:
4007 break;
4008 }
4009 return NULL;
4010}
4011
103f02d3 4012static const char *
d3ba0551 4013get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4014{
4015 switch (sh_type)
4016 {
4017 case SHT_PARISC_EXT: return "PARISC_EXT";
4018 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4019 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4020 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4021 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4022 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4023 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4024 default: return NULL;
103f02d3 4025 }
103f02d3
UD
4026}
4027
4d6ed7c8 4028static const char *
dda8d76d 4029get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4030{
18bd398b 4031 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4032 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4033 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4034
4d6ed7c8
NC
4035 switch (sh_type)
4036 {
148b93f2
NC
4037 case SHT_IA_64_EXT: return "IA_64_EXT";
4038 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4039 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4040 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4041 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4042 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4043 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4044 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4045 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4046 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4047 default:
4048 break;
4049 }
4050 return NULL;
4051}
4052
d2b2c203
DJ
4053static const char *
4054get_x86_64_section_type_name (unsigned int sh_type)
4055{
4056 switch (sh_type)
4057 {
4058 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4059 default: return NULL;
d2b2c203 4060 }
d2b2c203
DJ
4061}
4062
a06ea964
NC
4063static const char *
4064get_aarch64_section_type_name (unsigned int sh_type)
4065{
4066 switch (sh_type)
4067 {
32ec8896
NC
4068 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4069 default: return NULL;
a06ea964 4070 }
a06ea964
NC
4071}
4072
40a18ebd
NC
4073static const char *
4074get_arm_section_type_name (unsigned int sh_type)
4075{
4076 switch (sh_type)
4077 {
7f6fed87
NC
4078 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4079 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4080 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4081 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4082 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4083 default: return NULL;
40a18ebd 4084 }
40a18ebd
NC
4085}
4086
40b36596
JM
4087static const char *
4088get_tic6x_section_type_name (unsigned int sh_type)
4089{
4090 switch (sh_type)
4091 {
32ec8896
NC
4092 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4093 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4094 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4095 case SHT_TI_ICODE: return "TI_ICODE";
4096 case SHT_TI_XREF: return "TI_XREF";
4097 case SHT_TI_HANDLER: return "TI_HANDLER";
4098 case SHT_TI_INITINFO: return "TI_INITINFO";
4099 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4100 default: return NULL;
40b36596 4101 }
40b36596
JM
4102}
4103
13761a11
NC
4104static const char *
4105get_msp430x_section_type_name (unsigned int sh_type)
4106{
4107 switch (sh_type)
4108 {
32ec8896
NC
4109 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4110 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4111 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4112 default: return NULL;
13761a11
NC
4113 }
4114}
4115
685080f2
NC
4116static const char *
4117get_v850_section_type_name (unsigned int sh_type)
4118{
4119 switch (sh_type)
4120 {
32ec8896
NC
4121 case SHT_V850_SCOMMON: return "V850 Small Common";
4122 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4123 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4124 case SHT_RENESAS_IOP: return "RENESAS IOP";
4125 case SHT_RENESAS_INFO: return "RENESAS INFO";
4126 default: return NULL;
685080f2
NC
4127 }
4128}
4129
252b5132 4130static const char *
dda8d76d 4131get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4132{
b34976b6 4133 static char buff[32];
9fb71ee4 4134 const char * result;
252b5132
RH
4135
4136 switch (sh_type)
4137 {
4138 case SHT_NULL: return "NULL";
4139 case SHT_PROGBITS: return "PROGBITS";
4140 case SHT_SYMTAB: return "SYMTAB";
4141 case SHT_STRTAB: return "STRTAB";
4142 case SHT_RELA: return "RELA";
4143 case SHT_HASH: return "HASH";
4144 case SHT_DYNAMIC: return "DYNAMIC";
4145 case SHT_NOTE: return "NOTE";
4146 case SHT_NOBITS: return "NOBITS";
4147 case SHT_REL: return "REL";
4148 case SHT_SHLIB: return "SHLIB";
4149 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4150 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4151 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4152 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4153 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
4154 case SHT_GROUP: return "GROUP";
4155 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
4156 case SHT_GNU_verdef: return "VERDEF";
4157 case SHT_GNU_verneed: return "VERNEED";
4158 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4159 case 0x6ffffff0: return "VERSYM";
4160 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4161 case 0x7ffffffd: return "AUXILIARY";
4162 case 0x7fffffff: return "FILTER";
047b2264 4163 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4164
4165 default:
4166 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4167 {
dda8d76d 4168 switch (filedata->file_header.e_machine)
252b5132 4169 {
53a346d8
CZ
4170 case EM_ARC:
4171 case EM_ARC_COMPACT:
4172 case EM_ARC_COMPACT2:
4173 result = get_arc_section_type_name (sh_type);
4174 break;
252b5132 4175 case EM_MIPS:
4fe85591 4176 case EM_MIPS_RS3_LE:
252b5132
RH
4177 result = get_mips_section_type_name (sh_type);
4178 break;
103f02d3
UD
4179 case EM_PARISC:
4180 result = get_parisc_section_type_name (sh_type);
4181 break;
4d6ed7c8 4182 case EM_IA_64:
dda8d76d 4183 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4184 break;
d2b2c203 4185 case EM_X86_64:
8a9036a4 4186 case EM_L1OM:
7a9068fe 4187 case EM_K1OM:
d2b2c203
DJ
4188 result = get_x86_64_section_type_name (sh_type);
4189 break;
a06ea964
NC
4190 case EM_AARCH64:
4191 result = get_aarch64_section_type_name (sh_type);
4192 break;
40a18ebd
NC
4193 case EM_ARM:
4194 result = get_arm_section_type_name (sh_type);
4195 break;
40b36596
JM
4196 case EM_TI_C6000:
4197 result = get_tic6x_section_type_name (sh_type);
4198 break;
13761a11
NC
4199 case EM_MSP430:
4200 result = get_msp430x_section_type_name (sh_type);
4201 break;
685080f2
NC
4202 case EM_V800:
4203 case EM_V850:
4204 case EM_CYGNUS_V850:
4205 result = get_v850_section_type_name (sh_type);
4206 break;
252b5132
RH
4207 default:
4208 result = NULL;
4209 break;
4210 }
4211
4212 if (result != NULL)
4213 return result;
4214
9fb71ee4 4215 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4216 }
4217 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4218 {
dda8d76d 4219 switch (filedata->file_header.e_machine)
148b93f2
NC
4220 {
4221 case EM_IA_64:
dda8d76d 4222 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4223 break;
4224 default:
dda8d76d 4225 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4226 result = get_solaris_section_type (sh_type);
4227 else
1b4b80bf
NC
4228 {
4229 switch (sh_type)
4230 {
4231 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4232 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4233 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4234 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4235 default:
4236 result = NULL;
4237 break;
4238 }
4239 }
148b93f2
NC
4240 break;
4241 }
4242
4243 if (result != NULL)
4244 return result;
4245
9fb71ee4 4246 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4247 }
252b5132 4248 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4249 {
dda8d76d 4250 switch (filedata->file_header.e_machine)
685080f2
NC
4251 {
4252 case EM_V800:
4253 case EM_V850:
4254 case EM_CYGNUS_V850:
9fb71ee4 4255 result = get_v850_section_type_name (sh_type);
a9fb83be 4256 break;
685080f2 4257 default:
9fb71ee4 4258 result = NULL;
685080f2
NC
4259 break;
4260 }
4261
9fb71ee4
NC
4262 if (result != NULL)
4263 return result;
4264
4265 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4266 }
252b5132 4267 else
a7dbfd1c
NC
4268 /* This message is probably going to be displayed in a 15
4269 character wide field, so put the hex value first. */
4270 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4271
252b5132
RH
4272 return buff;
4273 }
4274}
4275
2979dc34 4276#define OPTION_DEBUG_DUMP 512
2c610e4b 4277#define OPTION_DYN_SYMS 513
fd2f0033
TT
4278#define OPTION_DWARF_DEPTH 514
4279#define OPTION_DWARF_START 515
4723351a 4280#define OPTION_DWARF_CHECK 516
2979dc34 4281
85b1c36d 4282static struct option options[] =
252b5132 4283{
b34976b6 4284 {"all", no_argument, 0, 'a'},
252b5132
RH
4285 {"file-header", no_argument, 0, 'h'},
4286 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4287 {"headers", no_argument, 0, 'e'},
4288 {"histogram", no_argument, 0, 'I'},
4289 {"segments", no_argument, 0, 'l'},
4290 {"sections", no_argument, 0, 'S'},
252b5132 4291 {"section-headers", no_argument, 0, 'S'},
f5842774 4292 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4293 {"section-details", no_argument, 0, 't'},
595cf52e 4294 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4295 {"symbols", no_argument, 0, 's'},
4296 {"syms", no_argument, 0, 's'},
2c610e4b 4297 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4298 {"relocs", no_argument, 0, 'r'},
4299 {"notes", no_argument, 0, 'n'},
4300 {"dynamic", no_argument, 0, 'd'},
a952a375 4301 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4302 {"version-info", no_argument, 0, 'V'},
4303 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4304 {"unwind", no_argument, 0, 'u'},
4145f1d5 4305 {"archive-index", no_argument, 0, 'c'},
b34976b6 4306 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4307 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4308 {"string-dump", required_argument, 0, 'p'},
0e602686 4309 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4310#ifdef SUPPORT_DISASSEMBLY
4311 {"instruction-dump", required_argument, 0, 'i'},
4312#endif
cf13d699 4313 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4314
fd2f0033
TT
4315 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4316 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4317 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4318
b34976b6
AM
4319 {"version", no_argument, 0, 'v'},
4320 {"wide", no_argument, 0, 'W'},
4321 {"help", no_argument, 0, 'H'},
4322 {0, no_argument, 0, 0}
252b5132
RH
4323};
4324
4325static void
2cf0635d 4326usage (FILE * stream)
252b5132 4327{
92f01d61
JM
4328 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4329 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4330 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4331 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4332 -h --file-header Display the ELF file header\n\
4333 -l --program-headers Display the program headers\n\
4334 --segments An alias for --program-headers\n\
4335 -S --section-headers Display the sections' header\n\
4336 --sections An alias for --section-headers\n\
f5842774 4337 -g --section-groups Display the section groups\n\
5477e8a0 4338 -t --section-details Display the section details\n\
8b53311e
NC
4339 -e --headers Equivalent to: -h -l -S\n\
4340 -s --syms Display the symbol table\n\
3f08eb35 4341 --symbols An alias for --syms\n\
2c610e4b 4342 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4343 -n --notes Display the core notes (if present)\n\
4344 -r --relocs Display the relocations (if present)\n\
4345 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4346 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4347 -V --version-info Display the version sections (if present)\n\
1b31d05e 4348 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4349 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4350 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
4351 -x --hex-dump=<number|name>\n\
4352 Dump the contents of section <number|name> as bytes\n\
4353 -p --string-dump=<number|name>\n\
4354 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4355 -R --relocated-dump=<number|name>\n\
4356 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4357 -z --decompress Decompress section before dumping it\n\
dda8d76d 4358 -w[lLiaprmfFsoRtUuTgAckK] or\n\
1ed06042 4359 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4360 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47 4361 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4362 =addr,=cu_index,=links,=follow-links]\n\
4363 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4364 fprintf (stream, _("\
4365 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4366 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4367 or deeper\n"));
252b5132 4368#ifdef SUPPORT_DISASSEMBLY
92f01d61 4369 fprintf (stream, _("\
09c11c86
NC
4370 -i --instruction-dump=<number|name>\n\
4371 Disassemble the contents of section <number|name>\n"));
252b5132 4372#endif
92f01d61 4373 fprintf (stream, _("\
8b53311e
NC
4374 -I --histogram Display histogram of bucket list lengths\n\
4375 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4376 @<file> Read options from <file>\n\
8b53311e
NC
4377 -H --help Display this information\n\
4378 -v --version Display the version number of readelf\n"));
1118d252 4379
92f01d61
JM
4380 if (REPORT_BUGS_TO[0] && stream == stdout)
4381 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4382
92f01d61 4383 exit (stream == stdout ? 0 : 1);
252b5132
RH
4384}
4385
18bd398b
NC
4386/* Record the fact that the user wants the contents of section number
4387 SECTION to be displayed using the method(s) encoded as flags bits
4388 in TYPE. Note, TYPE can be zero if we are creating the array for
4389 the first time. */
4390
252b5132 4391static void
dda8d76d 4392request_dump_bynumber (Filedata * filedata, unsigned int section, dump_type type)
252b5132 4393{
dda8d76d 4394 if (section >= filedata->num_dump_sects)
252b5132 4395 {
2cf0635d 4396 dump_type * new_dump_sects;
252b5132 4397
3f5e193b 4398 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4399 sizeof (* new_dump_sects));
252b5132
RH
4400
4401 if (new_dump_sects == NULL)
591a748a 4402 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4403 else
4404 {
dda8d76d 4405 if (filedata->dump_sects)
21b65bac
NC
4406 {
4407 /* Copy current flag settings. */
dda8d76d
NC
4408 memcpy (new_dump_sects, filedata->dump_sects,
4409 filedata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4410
dda8d76d 4411 free (filedata->dump_sects);
21b65bac 4412 }
252b5132 4413
dda8d76d
NC
4414 filedata->dump_sects = new_dump_sects;
4415 filedata->num_dump_sects = section + 1;
252b5132
RH
4416 }
4417 }
4418
dda8d76d
NC
4419 if (filedata->dump_sects)
4420 filedata->dump_sects[section] |= type;
252b5132
RH
4421}
4422
aef1f6d0
DJ
4423/* Request a dump by section name. */
4424
4425static void
2cf0635d 4426request_dump_byname (const char * section, dump_type type)
aef1f6d0 4427{
2cf0635d 4428 struct dump_list_entry * new_request;
aef1f6d0 4429
3f5e193b
NC
4430 new_request = (struct dump_list_entry *)
4431 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4432 if (!new_request)
591a748a 4433 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4434
4435 new_request->name = strdup (section);
4436 if (!new_request->name)
591a748a 4437 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4438
4439 new_request->type = type;
4440
4441 new_request->next = dump_sects_byname;
4442 dump_sects_byname = new_request;
4443}
4444
cf13d699 4445static inline void
dda8d76d 4446request_dump (Filedata * filedata, dump_type type)
cf13d699
NC
4447{
4448 int section;
4449 char * cp;
4450
4451 do_dump++;
4452 section = strtoul (optarg, & cp, 0);
4453
4454 if (! *cp && section >= 0)
dda8d76d 4455 request_dump_bynumber (filedata, section, type);
cf13d699
NC
4456 else
4457 request_dump_byname (optarg, type);
4458}
4459
252b5132 4460static void
dda8d76d 4461parse_args (Filedata * filedata, int argc, char ** argv)
252b5132
RH
4462{
4463 int c;
4464
4465 if (argc < 2)
92f01d61 4466 usage (stderr);
252b5132
RH
4467
4468 while ((c = getopt_long
0e602686 4469 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4470 {
252b5132
RH
4471 switch (c)
4472 {
4473 case 0:
4474 /* Long options. */
4475 break;
4476 case 'H':
92f01d61 4477 usage (stdout);
252b5132
RH
4478 break;
4479
4480 case 'a':
32ec8896
NC
4481 do_syms = TRUE;
4482 do_reloc = TRUE;
4483 do_unwind = TRUE;
4484 do_dynamic = TRUE;
4485 do_header = TRUE;
4486 do_sections = TRUE;
4487 do_section_groups = TRUE;
4488 do_segments = TRUE;
4489 do_version = TRUE;
4490 do_histogram = TRUE;
4491 do_arch = TRUE;
4492 do_notes = TRUE;
252b5132 4493 break;
f5842774 4494 case 'g':
32ec8896 4495 do_section_groups = TRUE;
f5842774 4496 break;
5477e8a0 4497 case 't':
595cf52e 4498 case 'N':
32ec8896
NC
4499 do_sections = TRUE;
4500 do_section_details = TRUE;
595cf52e 4501 break;
252b5132 4502 case 'e':
32ec8896
NC
4503 do_header = TRUE;
4504 do_sections = TRUE;
4505 do_segments = TRUE;
252b5132 4506 break;
a952a375 4507 case 'A':
32ec8896 4508 do_arch = TRUE;
a952a375 4509 break;
252b5132 4510 case 'D':
32ec8896 4511 do_using_dynamic = TRUE;
252b5132
RH
4512 break;
4513 case 'r':
32ec8896 4514 do_reloc = TRUE;
252b5132 4515 break;
4d6ed7c8 4516 case 'u':
32ec8896 4517 do_unwind = TRUE;
4d6ed7c8 4518 break;
252b5132 4519 case 'h':
32ec8896 4520 do_header = TRUE;
252b5132
RH
4521 break;
4522 case 'l':
32ec8896 4523 do_segments = TRUE;
252b5132
RH
4524 break;
4525 case 's':
32ec8896 4526 do_syms = TRUE;
252b5132
RH
4527 break;
4528 case 'S':
32ec8896 4529 do_sections = TRUE;
252b5132
RH
4530 break;
4531 case 'd':
32ec8896 4532 do_dynamic = TRUE;
252b5132 4533 break;
a952a375 4534 case 'I':
32ec8896 4535 do_histogram = TRUE;
a952a375 4536 break;
779fe533 4537 case 'n':
32ec8896 4538 do_notes = TRUE;
779fe533 4539 break;
4145f1d5 4540 case 'c':
32ec8896 4541 do_archive_index = TRUE;
4145f1d5 4542 break;
252b5132 4543 case 'x':
dda8d76d 4544 request_dump (filedata, HEX_DUMP);
aef1f6d0 4545 break;
09c11c86 4546 case 'p':
dda8d76d 4547 request_dump (filedata, STRING_DUMP);
cf13d699
NC
4548 break;
4549 case 'R':
dda8d76d 4550 request_dump (filedata, RELOC_DUMP);
09c11c86 4551 break;
0e602686 4552 case 'z':
32ec8896 4553 decompress_dumps = TRUE;
0e602686 4554 break;
252b5132 4555 case 'w':
32ec8896 4556 do_dump = TRUE;
252b5132 4557 if (optarg == 0)
613ff48b 4558 {
32ec8896 4559 do_debugging = TRUE;
613ff48b
CC
4560 dwarf_select_sections_all ();
4561 }
252b5132
RH
4562 else
4563 {
32ec8896 4564 do_debugging = FALSE;
4cb93e3b 4565 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4566 }
4567 break;
2979dc34 4568 case OPTION_DEBUG_DUMP:
32ec8896 4569 do_dump = TRUE;
2979dc34 4570 if (optarg == 0)
32ec8896 4571 do_debugging = TRUE;
2979dc34
JJ
4572 else
4573 {
32ec8896 4574 do_debugging = FALSE;
4cb93e3b 4575 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4576 }
4577 break;
fd2f0033
TT
4578 case OPTION_DWARF_DEPTH:
4579 {
4580 char *cp;
4581
4582 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4583 }
4584 break;
4585 case OPTION_DWARF_START:
4586 {
4587 char *cp;
4588
4589 dwarf_start_die = strtoul (optarg, & cp, 0);
4590 }
4591 break;
4723351a 4592 case OPTION_DWARF_CHECK:
32ec8896 4593 dwarf_check = TRUE;
4723351a 4594 break;
2c610e4b 4595 case OPTION_DYN_SYMS:
32ec8896 4596 do_dyn_syms = TRUE;
2c610e4b 4597 break;
252b5132
RH
4598#ifdef SUPPORT_DISASSEMBLY
4599 case 'i':
dda8d76d 4600 request_dump (filedata, DISASS_DUMP);
cf13d699 4601 break;
252b5132
RH
4602#endif
4603 case 'v':
4604 print_version (program_name);
4605 break;
4606 case 'V':
32ec8896 4607 do_version = TRUE;
252b5132 4608 break;
d974e256 4609 case 'W':
32ec8896 4610 do_wide = TRUE;
d974e256 4611 break;
252b5132 4612 default:
252b5132
RH
4613 /* xgettext:c-format */
4614 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4615 /* Fall through. */
252b5132 4616 case '?':
92f01d61 4617 usage (stderr);
252b5132
RH
4618 }
4619 }
4620
4d6ed7c8 4621 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4622 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4623 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4624 && !do_section_groups && !do_archive_index
4625 && !do_dyn_syms)
92f01d61 4626 usage (stderr);
252b5132
RH
4627}
4628
4629static const char *
d3ba0551 4630get_elf_class (unsigned int elf_class)
252b5132 4631{
b34976b6 4632 static char buff[32];
103f02d3 4633
252b5132
RH
4634 switch (elf_class)
4635 {
4636 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4637 case ELFCLASS32: return "ELF32";
4638 case ELFCLASS64: return "ELF64";
ab5e7794 4639 default:
e9e44622 4640 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4641 return buff;
252b5132
RH
4642 }
4643}
4644
4645static const char *
d3ba0551 4646get_data_encoding (unsigned int encoding)
252b5132 4647{
b34976b6 4648 static char buff[32];
103f02d3 4649
252b5132
RH
4650 switch (encoding)
4651 {
4652 case ELFDATANONE: return _("none");
33c63f9d
CM
4653 case ELFDATA2LSB: return _("2's complement, little endian");
4654 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4655 default:
e9e44622 4656 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4657 return buff;
252b5132
RH
4658 }
4659}
4660
dda8d76d 4661/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4662
32ec8896 4663static bfd_boolean
dda8d76d 4664process_file_header (Filedata * filedata)
252b5132 4665{
dda8d76d
NC
4666 Elf_Internal_Ehdr * header = & filedata->file_header;
4667
4668 if ( header->e_ident[EI_MAG0] != ELFMAG0
4669 || header->e_ident[EI_MAG1] != ELFMAG1
4670 || header->e_ident[EI_MAG2] != ELFMAG2
4671 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4672 {
4673 error
4674 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4675 return FALSE;
252b5132
RH
4676 }
4677
dda8d76d 4678 init_dwarf_regnames (header->e_machine);
2dc4cec1 4679
252b5132
RH
4680 if (do_header)
4681 {
32ec8896 4682 unsigned i;
252b5132
RH
4683
4684 printf (_("ELF Header:\n"));
4685 printf (_(" Magic: "));
b34976b6 4686 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4687 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4688 printf ("\n");
4689 printf (_(" Class: %s\n"),
dda8d76d 4690 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4691 printf (_(" Data: %s\n"),
dda8d76d 4692 get_data_encoding (header->e_ident[EI_DATA]));
252b5132 4693 printf (_(" Version: %d %s\n"),
dda8d76d
NC
4694 header->e_ident[EI_VERSION],
4695 (header->e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4696 ? "(current)"
dda8d76d 4697 : (header->e_ident[EI_VERSION] != EV_NONE
2b692964 4698 ? _("<unknown: %lx>")
789be9f7 4699 : "")));
252b5132 4700 printf (_(" OS/ABI: %s\n"),
dda8d76d 4701 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 4702 printf (_(" ABI Version: %d\n"),
dda8d76d 4703 header->e_ident[EI_ABIVERSION]);
252b5132 4704 printf (_(" Type: %s\n"),
dda8d76d 4705 get_file_type (header->e_type));
252b5132 4706 printf (_(" Machine: %s\n"),
dda8d76d 4707 get_machine_name (header->e_machine));
252b5132 4708 printf (_(" Version: 0x%lx\n"),
dda8d76d 4709 (unsigned long) header->e_version);
76da6bbe 4710
f7a99963 4711 printf (_(" Entry point address: "));
dda8d76d 4712 print_vma ((bfd_vma) header->e_entry, PREFIX_HEX);
f7a99963 4713 printf (_("\n Start of program headers: "));
dda8d76d 4714 print_vma ((bfd_vma) header->e_phoff, DEC);
f7a99963 4715 printf (_(" (bytes into file)\n Start of section headers: "));
dda8d76d 4716 print_vma ((bfd_vma) header->e_shoff, DEC);
f7a99963 4717 printf (_(" (bytes into file)\n"));
76da6bbe 4718
252b5132 4719 printf (_(" Flags: 0x%lx%s\n"),
dda8d76d
NC
4720 (unsigned long) header->e_flags,
4721 get_machine_flags (filedata, header->e_flags, header->e_machine));
252b5132 4722 printf (_(" Size of this header: %ld (bytes)\n"),
dda8d76d 4723 (long) header->e_ehsize);
252b5132 4724 printf (_(" Size of program headers: %ld (bytes)\n"),
dda8d76d 4725 (long) header->e_phentsize);
2046a35d 4726 printf (_(" Number of program headers: %ld"),
dda8d76d
NC
4727 (long) header->e_phnum);
4728 if (filedata->section_headers != NULL
4729 && header->e_phnum == PN_XNUM
4730 && filedata->section_headers[0].sh_info != 0)
4731 printf (" (%ld)", (long) filedata->section_headers[0].sh_info);
2046a35d 4732 putc ('\n', stdout);
252b5132 4733 printf (_(" Size of section headers: %ld (bytes)\n"),
dda8d76d 4734 (long) header->e_shentsize);
560f3c1c 4735 printf (_(" Number of section headers: %ld"),
dda8d76d
NC
4736 (long) header->e_shnum);
4737 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
4738 printf (" (%ld)", (long) filedata->section_headers[0].sh_size);
560f3c1c
AM
4739 putc ('\n', stdout);
4740 printf (_(" Section header string table index: %ld"),
dda8d76d
NC
4741 (long) header->e_shstrndx);
4742 if (filedata->section_headers != NULL
4743 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
4744 printf (" (%u)", filedata->section_headers[0].sh_link);
4745 else if (header->e_shstrndx != SHN_UNDEF
4746 && header->e_shstrndx >= header->e_shnum)
2b692964 4747 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4748 putc ('\n', stdout);
4749 }
4750
dda8d76d 4751 if (filedata->section_headers != NULL)
560f3c1c 4752 {
dda8d76d
NC
4753 if (header->e_phnum == PN_XNUM
4754 && filedata->section_headers[0].sh_info != 0)
4755 header->e_phnum = filedata->section_headers[0].sh_info;
4756 if (header->e_shnum == SHN_UNDEF)
4757 header->e_shnum = filedata->section_headers[0].sh_size;
4758 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
4759 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 4760 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
4761 header->e_shstrndx = SHN_UNDEF;
4762 free (filedata->section_headers);
4763 filedata->section_headers = NULL;
252b5132 4764 }
103f02d3 4765
32ec8896 4766 return TRUE;
9ea033b2
NC
4767}
4768
dda8d76d
NC
4769/* Read in the program headers from FILEDATA and store them in PHEADERS.
4770 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
4771
e0a31db1 4772static bfd_boolean
dda8d76d 4773get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4774{
2cf0635d
NC
4775 Elf32_External_Phdr * phdrs;
4776 Elf32_External_Phdr * external;
4777 Elf_Internal_Phdr * internal;
b34976b6 4778 unsigned int i;
dda8d76d
NC
4779 unsigned int size = filedata->file_header.e_phentsize;
4780 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4781
4782 /* PR binutils/17531: Cope with unexpected section header sizes. */
4783 if (size == 0 || num == 0)
4784 return FALSE;
4785 if (size < sizeof * phdrs)
4786 {
4787 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4788 return FALSE;
4789 }
4790 if (size > sizeof * phdrs)
4791 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4792
dda8d76d 4793 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
4794 size, num, _("program headers"));
4795 if (phdrs == NULL)
4796 return FALSE;
9ea033b2 4797
91d6fa6a 4798 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4799 i < filedata->file_header.e_phnum;
b34976b6 4800 i++, internal++, external++)
252b5132 4801 {
9ea033b2
NC
4802 internal->p_type = BYTE_GET (external->p_type);
4803 internal->p_offset = BYTE_GET (external->p_offset);
4804 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4805 internal->p_paddr = BYTE_GET (external->p_paddr);
4806 internal->p_filesz = BYTE_GET (external->p_filesz);
4807 internal->p_memsz = BYTE_GET (external->p_memsz);
4808 internal->p_flags = BYTE_GET (external->p_flags);
4809 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4810 }
4811
9ea033b2 4812 free (phdrs);
e0a31db1 4813 return TRUE;
252b5132
RH
4814}
4815
dda8d76d
NC
4816/* Read in the program headers from FILEDATA and store them in PHEADERS.
4817 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
4818
e0a31db1 4819static bfd_boolean
dda8d76d 4820get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4821{
2cf0635d
NC
4822 Elf64_External_Phdr * phdrs;
4823 Elf64_External_Phdr * external;
4824 Elf_Internal_Phdr * internal;
b34976b6 4825 unsigned int i;
dda8d76d
NC
4826 unsigned int size = filedata->file_header.e_phentsize;
4827 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4828
4829 /* PR binutils/17531: Cope with unexpected section header sizes. */
4830 if (size == 0 || num == 0)
4831 return FALSE;
4832 if (size < sizeof * phdrs)
4833 {
4834 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4835 return FALSE;
4836 }
4837 if (size > sizeof * phdrs)
4838 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4839
dda8d76d 4840 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 4841 size, num, _("program headers"));
a6e9f9df 4842 if (!phdrs)
e0a31db1 4843 return FALSE;
9ea033b2 4844
91d6fa6a 4845 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4846 i < filedata->file_header.e_phnum;
b34976b6 4847 i++, internal++, external++)
9ea033b2
NC
4848 {
4849 internal->p_type = BYTE_GET (external->p_type);
4850 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4851 internal->p_offset = BYTE_GET (external->p_offset);
4852 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4853 internal->p_paddr = BYTE_GET (external->p_paddr);
4854 internal->p_filesz = BYTE_GET (external->p_filesz);
4855 internal->p_memsz = BYTE_GET (external->p_memsz);
4856 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4857 }
4858
4859 free (phdrs);
e0a31db1 4860 return TRUE;
9ea033b2 4861}
252b5132 4862
32ec8896 4863/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 4864
32ec8896 4865static bfd_boolean
dda8d76d 4866get_program_headers (Filedata * filedata)
d93f0186 4867{
2cf0635d 4868 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4869
4870 /* Check cache of prior read. */
dda8d76d 4871 if (filedata->program_headers != NULL)
32ec8896 4872 return TRUE;
d93f0186 4873
82156ab7
NC
4874 /* Be kind to memory checkers by looking for
4875 e_phnum values which we know must be invalid. */
dda8d76d 4876 if (filedata->file_header.e_phnum
82156ab7 4877 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 4878 >= filedata->file_size)
82156ab7
NC
4879 {
4880 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 4881 filedata->file_header.e_phnum);
82156ab7
NC
4882 return FALSE;
4883 }
d93f0186 4884
dda8d76d 4885 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 4886 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4887 if (phdrs == NULL)
4888 {
8b73c356 4889 error (_("Out of memory reading %u program headers\n"),
dda8d76d 4890 filedata->file_header.e_phnum);
32ec8896 4891 return FALSE;
d93f0186
NC
4892 }
4893
4894 if (is_32bit_elf
dda8d76d
NC
4895 ? get_32bit_program_headers (filedata, phdrs)
4896 : get_64bit_program_headers (filedata, phdrs))
d93f0186 4897 {
dda8d76d 4898 filedata->program_headers = phdrs;
32ec8896 4899 return TRUE;
d93f0186
NC
4900 }
4901
4902 free (phdrs);
32ec8896 4903 return FALSE;
d93f0186
NC
4904}
4905
32ec8896 4906/* Returns TRUE if the program headers were loaded. */
2f62977e 4907
32ec8896 4908static bfd_boolean
dda8d76d 4909process_program_headers (Filedata * filedata)
252b5132 4910{
2cf0635d 4911 Elf_Internal_Phdr * segment;
b34976b6 4912 unsigned int i;
1a9ccd70 4913 Elf_Internal_Phdr * previous_load = NULL;
252b5132 4914
dda8d76d 4915 if (filedata->file_header.e_phnum == 0)
252b5132 4916 {
82f2dbf7 4917 /* PR binutils/12467. */
dda8d76d 4918 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
4919 {
4920 warn (_("possibly corrupt ELF header - it has a non-zero program"
4921 " header offset, but no program headers\n"));
4922 return FALSE;
4923 }
82f2dbf7 4924 else if (do_segments)
252b5132 4925 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 4926 return TRUE;
252b5132
RH
4927 }
4928
4929 if (do_segments && !do_header)
4930 {
dda8d76d
NC
4931 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
4932 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
4933 printf (ngettext ("There is %d program header, starting at offset %s\n",
4934 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
4935 filedata->file_header.e_phnum),
4936 filedata->file_header.e_phnum,
4937 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
4938 }
4939
dda8d76d 4940 if (! get_program_headers (filedata))
6b4bf3bc 4941 return TRUE;
103f02d3 4942
252b5132
RH
4943 if (do_segments)
4944 {
dda8d76d 4945 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
4946 printf (_("\nProgram Headers:\n"));
4947 else
4948 printf (_("\nProgram Headers:\n"));
76da6bbe 4949
f7a99963
NC
4950 if (is_32bit_elf)
4951 printf
4952 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4953 else if (do_wide)
4954 printf
4955 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4956 else
4957 {
4958 printf
4959 (_(" Type Offset VirtAddr PhysAddr\n"));
4960 printf
4961 (_(" FileSiz MemSiz Flags Align\n"));
4962 }
252b5132
RH
4963 }
4964
252b5132 4965 dynamic_addr = 0;
1b228002 4966 dynamic_size = 0;
252b5132 4967
dda8d76d
NC
4968 for (i = 0, segment = filedata->program_headers;
4969 i < filedata->file_header.e_phnum;
b34976b6 4970 i++, segment++)
252b5132
RH
4971 {
4972 if (do_segments)
4973 {
dda8d76d 4974 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
4975
4976 if (is_32bit_elf)
4977 {
4978 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4979 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4980 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4981 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4982 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4983 printf ("%c%c%c ",
4984 (segment->p_flags & PF_R ? 'R' : ' '),
4985 (segment->p_flags & PF_W ? 'W' : ' '),
4986 (segment->p_flags & PF_X ? 'E' : ' '));
4987 printf ("%#lx", (unsigned long) segment->p_align);
4988 }
d974e256
JJ
4989 else if (do_wide)
4990 {
4991 if ((unsigned long) segment->p_offset == segment->p_offset)
4992 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4993 else
4994 {
4995 print_vma (segment->p_offset, FULL_HEX);
4996 putchar (' ');
4997 }
4998
4999 print_vma (segment->p_vaddr, FULL_HEX);
5000 putchar (' ');
5001 print_vma (segment->p_paddr, FULL_HEX);
5002 putchar (' ');
5003
5004 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5005 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5006 else
5007 {
5008 print_vma (segment->p_filesz, FULL_HEX);
5009 putchar (' ');
5010 }
5011
5012 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5013 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5014 else
5015 {
f48e6c45 5016 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5017 }
5018
5019 printf (" %c%c%c ",
5020 (segment->p_flags & PF_R ? 'R' : ' '),
5021 (segment->p_flags & PF_W ? 'W' : ' '),
5022 (segment->p_flags & PF_X ? 'E' : ' '));
5023
5024 if ((unsigned long) segment->p_align == segment->p_align)
5025 printf ("%#lx", (unsigned long) segment->p_align);
5026 else
5027 {
5028 print_vma (segment->p_align, PREFIX_HEX);
5029 }
5030 }
f7a99963
NC
5031 else
5032 {
5033 print_vma (segment->p_offset, FULL_HEX);
5034 putchar (' ');
5035 print_vma (segment->p_vaddr, FULL_HEX);
5036 putchar (' ');
5037 print_vma (segment->p_paddr, FULL_HEX);
5038 printf ("\n ");
5039 print_vma (segment->p_filesz, FULL_HEX);
5040 putchar (' ');
5041 print_vma (segment->p_memsz, FULL_HEX);
5042 printf (" %c%c%c ",
5043 (segment->p_flags & PF_R ? 'R' : ' '),
5044 (segment->p_flags & PF_W ? 'W' : ' '),
5045 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5046 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5047 }
252b5132 5048
1a9ccd70
NC
5049 putc ('\n', stdout);
5050 }
f54498b4 5051
252b5132
RH
5052 switch (segment->p_type)
5053 {
1a9ccd70 5054 case PT_LOAD:
502d895c
NC
5055#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5056 required by the ELF standard, several programs, including the Linux
5057 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5058 if (previous_load
5059 && previous_load->p_vaddr > segment->p_vaddr)
5060 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5061#endif
1a9ccd70
NC
5062 if (segment->p_memsz < segment->p_filesz)
5063 error (_("the segment's file size is larger than its memory size\n"));
5064 previous_load = segment;
5065 break;
5066
5067 case PT_PHDR:
5068 /* PR 20815 - Verify that the program header is loaded into memory. */
5069 if (i > 0 && previous_load != NULL)
5070 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5071 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5072 {
5073 unsigned int j;
5074
dda8d76d
NC
5075 for (j = 1; j < filedata->file_header.e_phnum; j++)
5076 if (filedata->program_headers[j].p_vaddr <= segment->p_vaddr
5077 && (filedata->program_headers[j].p_vaddr
5078 + filedata->program_headers[j].p_memsz)
1a9ccd70
NC
5079 >= (segment->p_vaddr + segment->p_filesz))
5080 break;
dda8d76d 5081 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5082 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5083 }
5084 break;
5085
252b5132
RH
5086 case PT_DYNAMIC:
5087 if (dynamic_addr)
5088 error (_("more than one dynamic segment\n"));
5089
20737c13
AM
5090 /* By default, assume that the .dynamic section is the first
5091 section in the DYNAMIC segment. */
5092 dynamic_addr = segment->p_offset;
5093 dynamic_size = segment->p_filesz;
5094
b2d38a17
NC
5095 /* Try to locate the .dynamic section. If there is
5096 a section header table, we can easily locate it. */
dda8d76d 5097 if (filedata->section_headers != NULL)
b2d38a17 5098 {
2cf0635d 5099 Elf_Internal_Shdr * sec;
b2d38a17 5100
dda8d76d 5101 sec = find_section (filedata, ".dynamic");
89fac5e3 5102 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5103 {
28f997cf
TG
5104 /* A corresponding .dynamic section is expected, but on
5105 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5106 if (!is_ia64_vms (filedata))
28f997cf 5107 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5108 break;
5109 }
5110
42bb2e33 5111 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
5112 {
5113 dynamic_size = 0;
5114 break;
5115 }
42bb2e33 5116
b2d38a17
NC
5117 dynamic_addr = sec->sh_offset;
5118 dynamic_size = sec->sh_size;
5119
5120 if (dynamic_addr < segment->p_offset
5121 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
5122 warn (_("the .dynamic section is not contained"
5123 " within the dynamic segment\n"));
b2d38a17 5124 else if (dynamic_addr > segment->p_offset)
20737c13
AM
5125 warn (_("the .dynamic section is not the first section"
5126 " in the dynamic segment.\n"));
b2d38a17 5127 }
39e224f6
MW
5128
5129 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5130 segment. Check this after matching against the section headers
5131 so we don't warn on debuginfo file (which have NOBITS .dynamic
5132 sections). */
dda8d76d 5133 if (dynamic_addr + dynamic_size >= filedata->file_size)
39e224f6
MW
5134 {
5135 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
5136 dynamic_addr = dynamic_size = 0;
5137 }
252b5132
RH
5138 break;
5139
5140 case PT_INTERP:
dda8d76d 5141 if (fseek (filedata->handle, archive_file_offset + (long) segment->p_offset,
fb52b2f4 5142 SEEK_SET))
252b5132
RH
5143 error (_("Unable to find program interpreter name\n"));
5144 else
5145 {
f8eae8b2 5146 char fmt [32];
9495b2e6 5147 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5148
5149 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5150 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5151
252b5132 5152 program_interpreter[0] = 0;
dda8d76d 5153 if (fscanf (filedata->handle, fmt, program_interpreter) <= 0)
7bd7b3ef 5154 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5155
5156 if (do_segments)
f54498b4 5157 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
5158 program_interpreter);
5159 }
5160 break;
5161 }
252b5132
RH
5162 }
5163
dda8d76d
NC
5164 if (do_segments
5165 && filedata->section_headers != NULL
5166 && filedata->string_table != NULL)
252b5132
RH
5167 {
5168 printf (_("\n Section to Segment mapping:\n"));
5169 printf (_(" Segment Sections...\n"));
5170
dda8d76d 5171 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5172 {
9ad5cbcf 5173 unsigned int j;
2cf0635d 5174 Elf_Internal_Shdr * section;
252b5132 5175
dda8d76d
NC
5176 segment = filedata->program_headers + i;
5177 section = filedata->section_headers + 1;
252b5132
RH
5178
5179 printf (" %2.2d ", i);
5180
dda8d76d 5181 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5182 {
f4638467
AM
5183 if (!ELF_TBSS_SPECIAL (section, segment)
5184 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5185 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5186 }
5187
5188 putc ('\n',stdout);
5189 }
5190 }
5191
32ec8896 5192 return TRUE;
252b5132
RH
5193}
5194
5195
d93f0186
NC
5196/* Find the file offset corresponding to VMA by using the program headers. */
5197
5198static long
dda8d76d 5199offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5200{
2cf0635d 5201 Elf_Internal_Phdr * seg;
d93f0186 5202
dda8d76d 5203 if (! get_program_headers (filedata))
d93f0186
NC
5204 {
5205 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5206 return (long) vma;
5207 }
5208
dda8d76d
NC
5209 for (seg = filedata->program_headers;
5210 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5211 ++seg)
5212 {
5213 if (seg->p_type != PT_LOAD)
5214 continue;
5215
5216 if (vma >= (seg->p_vaddr & -seg->p_align)
5217 && vma + size <= seg->p_vaddr + seg->p_filesz)
5218 return vma - seg->p_vaddr + seg->p_offset;
5219 }
5220
5221 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5222 (unsigned long) vma);
d93f0186
NC
5223 return (long) vma;
5224}
5225
5226
dda8d76d
NC
5227/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5228 If PROBE is true, this is just a probe and we do not generate any error
5229 messages if the load fails. */
049b0c3a
NC
5230
5231static bfd_boolean
dda8d76d 5232get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5233{
2cf0635d
NC
5234 Elf32_External_Shdr * shdrs;
5235 Elf_Internal_Shdr * internal;
dda8d76d
NC
5236 unsigned int i;
5237 unsigned int size = filedata->file_header.e_shentsize;
5238 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5239
5240 /* PR binutils/17531: Cope with unexpected section header sizes. */
5241 if (size == 0 || num == 0)
5242 return FALSE;
5243 if (size < sizeof * shdrs)
5244 {
5245 if (! probe)
5246 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5247 return FALSE;
5248 }
5249 if (!probe && size > sizeof * shdrs)
5250 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5251
dda8d76d 5252 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5253 size, num,
5254 probe ? NULL : _("section headers"));
5255 if (shdrs == NULL)
5256 return FALSE;
252b5132 5257
dda8d76d
NC
5258 free (filedata->section_headers);
5259 filedata->section_headers = (Elf_Internal_Shdr *)
5260 cmalloc (num, sizeof (Elf_Internal_Shdr));
5261 if (filedata->section_headers == NULL)
252b5132 5262 {
049b0c3a 5263 if (!probe)
8b73c356 5264 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 5265 return FALSE;
252b5132
RH
5266 }
5267
dda8d76d 5268 for (i = 0, internal = filedata->section_headers;
560f3c1c 5269 i < num;
b34976b6 5270 i++, internal++)
252b5132
RH
5271 {
5272 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5273 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5274 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5275 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5276 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5277 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5278 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5279 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5280 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5281 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5282 if (!probe && internal->sh_link > num)
5283 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5284 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5285 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5286 }
5287
5288 free (shdrs);
049b0c3a 5289 return TRUE;
252b5132
RH
5290}
5291
dda8d76d
NC
5292/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5293
049b0c3a 5294static bfd_boolean
dda8d76d 5295get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5296{
dda8d76d
NC
5297 Elf64_External_Shdr * shdrs;
5298 Elf_Internal_Shdr * internal;
5299 unsigned int i;
5300 unsigned int size = filedata->file_header.e_shentsize;
5301 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5302
5303 /* PR binutils/17531: Cope with unexpected section header sizes. */
5304 if (size == 0 || num == 0)
5305 return FALSE;
dda8d76d 5306
049b0c3a
NC
5307 if (size < sizeof * shdrs)
5308 {
5309 if (! probe)
5310 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5311 return FALSE;
5312 }
dda8d76d 5313
049b0c3a
NC
5314 if (! probe && size > sizeof * shdrs)
5315 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5316
dda8d76d
NC
5317 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5318 filedata->file_header.e_shoff,
049b0c3a
NC
5319 size, num,
5320 probe ? NULL : _("section headers"));
5321 if (shdrs == NULL)
5322 return FALSE;
9ea033b2 5323
dda8d76d
NC
5324 free (filedata->section_headers);
5325 filedata->section_headers = (Elf_Internal_Shdr *)
5326 cmalloc (num, sizeof (Elf_Internal_Shdr));
5327 if (filedata->section_headers == NULL)
9ea033b2 5328 {
049b0c3a 5329 if (! probe)
8b73c356 5330 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 5331 return FALSE;
9ea033b2
NC
5332 }
5333
dda8d76d 5334 for (i = 0, internal = filedata->section_headers;
560f3c1c 5335 i < num;
b34976b6 5336 i++, internal++)
9ea033b2
NC
5337 {
5338 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5339 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5340 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5341 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5342 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5343 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5344 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5345 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5346 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5347 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5348 if (!probe && internal->sh_link > num)
5349 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5350 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5351 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5352 }
5353
5354 free (shdrs);
049b0c3a 5355 return TRUE;
9ea033b2
NC
5356}
5357
252b5132 5358static Elf_Internal_Sym *
dda8d76d
NC
5359get_32bit_elf_symbols (Filedata * filedata,
5360 Elf_Internal_Shdr * section,
5361 unsigned long * num_syms_return)
252b5132 5362{
ba5cdace 5363 unsigned long number = 0;
dd24e3da 5364 Elf32_External_Sym * esyms = NULL;
ba5cdace 5365 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5366 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5367 Elf_Internal_Sym * psym;
b34976b6 5368 unsigned int j;
252b5132 5369
c9c1d674
EG
5370 if (section->sh_size == 0)
5371 {
5372 if (num_syms_return != NULL)
5373 * num_syms_return = 0;
5374 return NULL;
5375 }
5376
dd24e3da 5377 /* Run some sanity checks first. */
c9c1d674 5378 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5379 {
c9c1d674 5380 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5381 printable_section_name (filedata, section),
5382 (unsigned long) section->sh_entsize);
ba5cdace 5383 goto exit_point;
dd24e3da
NC
5384 }
5385
dda8d76d 5386 if (section->sh_size > filedata->file_size)
f54498b4
NC
5387 {
5388 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5389 printable_section_name (filedata, section),
5390 (unsigned long) section->sh_size);
f54498b4
NC
5391 goto exit_point;
5392 }
5393
dd24e3da
NC
5394 number = section->sh_size / section->sh_entsize;
5395
5396 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5397 {
c9c1d674 5398 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5399 (unsigned long) section->sh_size,
dda8d76d 5400 printable_section_name (filedata, section),
8066deb1 5401 (unsigned long) section->sh_entsize);
ba5cdace 5402 goto exit_point;
dd24e3da
NC
5403 }
5404
dda8d76d 5405 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5406 section->sh_size, _("symbols"));
dd24e3da 5407 if (esyms == NULL)
ba5cdace 5408 goto exit_point;
252b5132 5409
6a40cf0c
NC
5410 {
5411 elf_section_list * entry;
5412
5413 shndx = NULL;
5414 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
dda8d76d 5415 if (entry->hdr->sh_link == (unsigned long) (section - filedata->section_headers))
c9c1d674 5416 {
dda8d76d 5417 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6a40cf0c
NC
5418 entry->hdr->sh_offset,
5419 1, entry->hdr->sh_size,
5420 _("symbol table section indicies"));
5421 if (shndx == NULL)
5422 goto exit_point;
5423 /* PR17531: file: heap-buffer-overflow */
5424 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5425 {
5426 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
dda8d76d 5427 printable_section_name (filedata, entry->hdr),
6a40cf0c
NC
5428 (unsigned long) entry->hdr->sh_size,
5429 (unsigned long) section->sh_size);
5430 goto exit_point;
5431 }
c9c1d674 5432 }
6a40cf0c 5433 }
9ad5cbcf 5434
3f5e193b 5435 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5436
5437 if (isyms == NULL)
5438 {
8b73c356
NC
5439 error (_("Out of memory reading %lu symbols\n"),
5440 (unsigned long) number);
dd24e3da 5441 goto exit_point;
252b5132
RH
5442 }
5443
dd24e3da 5444 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5445 {
5446 psym->st_name = BYTE_GET (esyms[j].st_name);
5447 psym->st_value = BYTE_GET (esyms[j].st_value);
5448 psym->st_size = BYTE_GET (esyms[j].st_size);
5449 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5450 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5451 psym->st_shndx
5452 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5453 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5454 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5455 psym->st_info = BYTE_GET (esyms[j].st_info);
5456 psym->st_other = BYTE_GET (esyms[j].st_other);
5457 }
5458
dd24e3da 5459 exit_point:
ba5cdace 5460 if (shndx != NULL)
9ad5cbcf 5461 free (shndx);
ba5cdace 5462 if (esyms != NULL)
dd24e3da 5463 free (esyms);
252b5132 5464
ba5cdace
NC
5465 if (num_syms_return != NULL)
5466 * num_syms_return = isyms == NULL ? 0 : number;
5467
252b5132
RH
5468 return isyms;
5469}
5470
9ea033b2 5471static Elf_Internal_Sym *
dda8d76d
NC
5472get_64bit_elf_symbols (Filedata * filedata,
5473 Elf_Internal_Shdr * section,
5474 unsigned long * num_syms_return)
9ea033b2 5475{
ba5cdace
NC
5476 unsigned long number = 0;
5477 Elf64_External_Sym * esyms = NULL;
5478 Elf_External_Sym_Shndx * shndx = NULL;
5479 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5480 Elf_Internal_Sym * psym;
b34976b6 5481 unsigned int j;
9ea033b2 5482
c9c1d674
EG
5483 if (section->sh_size == 0)
5484 {
5485 if (num_syms_return != NULL)
5486 * num_syms_return = 0;
5487 return NULL;
5488 }
5489
dd24e3da 5490 /* Run some sanity checks first. */
c9c1d674 5491 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5492 {
c9c1d674 5493 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5494 printable_section_name (filedata, section),
8066deb1 5495 (unsigned long) section->sh_entsize);
ba5cdace 5496 goto exit_point;
dd24e3da
NC
5497 }
5498
dda8d76d 5499 if (section->sh_size > filedata->file_size)
f54498b4
NC
5500 {
5501 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5502 printable_section_name (filedata, section),
8066deb1 5503 (unsigned long) section->sh_size);
f54498b4
NC
5504 goto exit_point;
5505 }
5506
dd24e3da
NC
5507 number = section->sh_size / section->sh_entsize;
5508
5509 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5510 {
c9c1d674 5511 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5512 (unsigned long) section->sh_size,
dda8d76d 5513 printable_section_name (filedata, section),
8066deb1 5514 (unsigned long) section->sh_entsize);
ba5cdace 5515 goto exit_point;
dd24e3da
NC
5516 }
5517
dda8d76d 5518 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5519 section->sh_size, _("symbols"));
a6e9f9df 5520 if (!esyms)
ba5cdace 5521 goto exit_point;
9ea033b2 5522
6a40cf0c
NC
5523 {
5524 elf_section_list * entry;
5525
5526 shndx = NULL;
5527 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
dda8d76d 5528 if (entry->hdr->sh_link == (unsigned long) (section - filedata->section_headers))
c9c1d674 5529 {
dda8d76d 5530 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6a40cf0c
NC
5531 entry->hdr->sh_offset,
5532 1, entry->hdr->sh_size,
5533 _("symbol table section indicies"));
5534 if (shndx == NULL)
5535 goto exit_point;
5536 /* PR17531: file: heap-buffer-overflow */
5537 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5538 {
5539 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
dda8d76d 5540 printable_section_name (filedata, entry->hdr),
6a40cf0c
NC
5541 (unsigned long) entry->hdr->sh_size,
5542 (unsigned long) section->sh_size);
5543 goto exit_point;
5544 }
c9c1d674 5545 }
6a40cf0c 5546 }
9ad5cbcf 5547
3f5e193b 5548 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5549
5550 if (isyms == NULL)
5551 {
8b73c356
NC
5552 error (_("Out of memory reading %lu symbols\n"),
5553 (unsigned long) number);
ba5cdace 5554 goto exit_point;
9ea033b2
NC
5555 }
5556
ba5cdace 5557 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5558 {
5559 psym->st_name = BYTE_GET (esyms[j].st_name);
5560 psym->st_info = BYTE_GET (esyms[j].st_info);
5561 psym->st_other = BYTE_GET (esyms[j].st_other);
5562 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5563
4fbb74a6 5564 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5565 psym->st_shndx
5566 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5567 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5568 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5569
66543521
AM
5570 psym->st_value = BYTE_GET (esyms[j].st_value);
5571 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5572 }
5573
ba5cdace
NC
5574 exit_point:
5575 if (shndx != NULL)
9ad5cbcf 5576 free (shndx);
ba5cdace
NC
5577 if (esyms != NULL)
5578 free (esyms);
5579
5580 if (num_syms_return != NULL)
5581 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5582
5583 return isyms;
5584}
5585
d1133906 5586static const char *
dda8d76d 5587get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5588{
5477e8a0 5589 static char buff[1024];
2cf0635d 5590 char * p = buff;
32ec8896
NC
5591 unsigned int field_size = is_32bit_elf ? 8 : 16;
5592 signed int sindex;
5593 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5594 bfd_vma os_flags = 0;
5595 bfd_vma proc_flags = 0;
5596 bfd_vma unknown_flags = 0;
148b93f2 5597 static const struct
5477e8a0 5598 {
2cf0635d 5599 const char * str;
32ec8896 5600 unsigned int len;
5477e8a0
L
5601 }
5602 flags [] =
5603 {
cfcac11d
NC
5604 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5605 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5606 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5607 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5608 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5609 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5610 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5611 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5612 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5613 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5614 /* IA-64 specific. */
5615 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5616 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5617 /* IA-64 OpenVMS specific. */
5618 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5619 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5620 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5621 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5622 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5623 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5624 /* Generic. */
cfcac11d 5625 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5626 /* SPARC specific. */
77115a4a 5627 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5628 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5629 /* ARM specific. */
5630 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5631 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5632 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5633 /* GNU specific. */
5634 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5635 /* VLE specific. */
5636 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5637 };
5638
5639 if (do_section_details)
5640 {
8d5ff12c
L
5641 sprintf (buff, "[%*.*lx]: ",
5642 field_size, field_size, (unsigned long) sh_flags);
5643 p += field_size + 4;
5477e8a0 5644 }
76da6bbe 5645
d1133906
NC
5646 while (sh_flags)
5647 {
5648 bfd_vma flag;
5649
5650 flag = sh_flags & - sh_flags;
5651 sh_flags &= ~ flag;
76da6bbe 5652
5477e8a0 5653 if (do_section_details)
d1133906 5654 {
5477e8a0
L
5655 switch (flag)
5656 {
91d6fa6a
NC
5657 case SHF_WRITE: sindex = 0; break;
5658 case SHF_ALLOC: sindex = 1; break;
5659 case SHF_EXECINSTR: sindex = 2; break;
5660 case SHF_MERGE: sindex = 3; break;
5661 case SHF_STRINGS: sindex = 4; break;
5662 case SHF_INFO_LINK: sindex = 5; break;
5663 case SHF_LINK_ORDER: sindex = 6; break;
5664 case SHF_OS_NONCONFORMING: sindex = 7; break;
5665 case SHF_GROUP: sindex = 8; break;
5666 case SHF_TLS: sindex = 9; break;
18ae9cc1 5667 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5668 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5669 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 5670
5477e8a0 5671 default:
91d6fa6a 5672 sindex = -1;
dda8d76d 5673 switch (filedata->file_header.e_machine)
148b93f2 5674 {
cfcac11d 5675 case EM_IA_64:
148b93f2 5676 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5677 sindex = 10;
148b93f2 5678 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5679 sindex = 11;
148b93f2 5680#ifdef BFD64
dda8d76d 5681 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
5682 switch (flag)
5683 {
91d6fa6a
NC
5684 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5685 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5686 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5687 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5688 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5689 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5690 default: break;
5691 }
5692#endif
cfcac11d
NC
5693 break;
5694
caa83f8b 5695 case EM_386:
22abe556 5696 case EM_IAMCU:
caa83f8b 5697 case EM_X86_64:
7f502d6c 5698 case EM_L1OM:
7a9068fe 5699 case EM_K1OM:
cfcac11d
NC
5700 case EM_OLD_SPARCV9:
5701 case EM_SPARC32PLUS:
5702 case EM_SPARCV9:
5703 case EM_SPARC:
18ae9cc1 5704 if (flag == SHF_ORDERED)
91d6fa6a 5705 sindex = 19;
cfcac11d 5706 break;
ac4c9b04
MG
5707
5708 case EM_ARM:
5709 switch (flag)
5710 {
5711 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5712 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5713 case SHF_COMDEF: sindex = 23; break;
5714 default: break;
5715 }
5716 break;
83eef883
AFB
5717 case EM_PPC:
5718 if (flag == SHF_PPC_VLE)
5719 sindex = 25;
5720 break;
ac4c9b04 5721
cfcac11d
NC
5722 default:
5723 break;
148b93f2 5724 }
5477e8a0
L
5725 }
5726
91d6fa6a 5727 if (sindex != -1)
5477e8a0 5728 {
8d5ff12c
L
5729 if (p != buff + field_size + 4)
5730 {
5731 if (size < (10 + 2))
bee0ee85
NC
5732 {
5733 warn (_("Internal error: not enough buffer room for section flag info"));
5734 return _("<unknown>");
5735 }
8d5ff12c
L
5736 size -= 2;
5737 *p++ = ',';
5738 *p++ = ' ';
5739 }
5740
91d6fa6a
NC
5741 size -= flags [sindex].len;
5742 p = stpcpy (p, flags [sindex].str);
5477e8a0 5743 }
3b22753a 5744 else if (flag & SHF_MASKOS)
8d5ff12c 5745 os_flags |= flag;
d1133906 5746 else if (flag & SHF_MASKPROC)
8d5ff12c 5747 proc_flags |= flag;
d1133906 5748 else
8d5ff12c 5749 unknown_flags |= flag;
5477e8a0
L
5750 }
5751 else
5752 {
5753 switch (flag)
5754 {
5755 case SHF_WRITE: *p = 'W'; break;
5756 case SHF_ALLOC: *p = 'A'; break;
5757 case SHF_EXECINSTR: *p = 'X'; break;
5758 case SHF_MERGE: *p = 'M'; break;
5759 case SHF_STRINGS: *p = 'S'; break;
5760 case SHF_INFO_LINK: *p = 'I'; break;
5761 case SHF_LINK_ORDER: *p = 'L'; break;
5762 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5763 case SHF_GROUP: *p = 'G'; break;
5764 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5765 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 5766 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 5767 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
5768
5769 default:
dda8d76d
NC
5770 if ((filedata->file_header.e_machine == EM_X86_64
5771 || filedata->file_header.e_machine == EM_L1OM
5772 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
5773 && flag == SHF_X86_64_LARGE)
5774 *p = 'l';
dda8d76d 5775 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 5776 && flag == SHF_ARM_PURECODE)
91f68a68 5777 *p = 'y';
dda8d76d 5778 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
5779 && flag == SHF_PPC_VLE)
5780 *p = 'v';
5477e8a0
L
5781 else if (flag & SHF_MASKOS)
5782 {
5783 *p = 'o';
5784 sh_flags &= ~ SHF_MASKOS;
5785 }
5786 else if (flag & SHF_MASKPROC)
5787 {
5788 *p = 'p';
5789 sh_flags &= ~ SHF_MASKPROC;
5790 }
5791 else
5792 *p = 'x';
5793 break;
5794 }
5795 p++;
d1133906
NC
5796 }
5797 }
76da6bbe 5798
8d5ff12c
L
5799 if (do_section_details)
5800 {
5801 if (os_flags)
5802 {
5803 size -= 5 + field_size;
5804 if (p != buff + field_size + 4)
5805 {
5806 if (size < (2 + 1))
bee0ee85
NC
5807 {
5808 warn (_("Internal error: not enough buffer room for section flag info"));
5809 return _("<unknown>");
5810 }
8d5ff12c
L
5811 size -= 2;
5812 *p++ = ',';
5813 *p++ = ' ';
5814 }
5815 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5816 (unsigned long) os_flags);
5817 p += 5 + field_size;
5818 }
5819 if (proc_flags)
5820 {
5821 size -= 7 + field_size;
5822 if (p != buff + field_size + 4)
5823 {
5824 if (size < (2 + 1))
bee0ee85
NC
5825 {
5826 warn (_("Internal error: not enough buffer room for section flag info"));
5827 return _("<unknown>");
5828 }
8d5ff12c
L
5829 size -= 2;
5830 *p++ = ',';
5831 *p++ = ' ';
5832 }
5833 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5834 (unsigned long) proc_flags);
5835 p += 7 + field_size;
5836 }
5837 if (unknown_flags)
5838 {
5839 size -= 10 + field_size;
5840 if (p != buff + field_size + 4)
5841 {
5842 if (size < (2 + 1))
bee0ee85
NC
5843 {
5844 warn (_("Internal error: not enough buffer room for section flag info"));
5845 return _("<unknown>");
5846 }
8d5ff12c
L
5847 size -= 2;
5848 *p++ = ',';
5849 *p++ = ' ';
5850 }
2b692964 5851 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5852 (unsigned long) unknown_flags);
5853 p += 10 + field_size;
5854 }
5855 }
5856
e9e44622 5857 *p = '\0';
d1133906
NC
5858 return buff;
5859}
5860
77115a4a 5861static unsigned int
ebdf1ebf 5862get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
5863{
5864 if (is_32bit_elf)
5865 {
5866 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 5867
ebdf1ebf
NC
5868 if (size < sizeof (* echdr))
5869 {
5870 error (_("Compressed section is too small even for a compression header\n"));
5871 return 0;
5872 }
5873
77115a4a
L
5874 chdr->ch_type = BYTE_GET (echdr->ch_type);
5875 chdr->ch_size = BYTE_GET (echdr->ch_size);
5876 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5877 return sizeof (*echdr);
5878 }
5879 else
5880 {
5881 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 5882
ebdf1ebf
NC
5883 if (size < sizeof (* echdr))
5884 {
5885 error (_("Compressed section is too small even for a compression header\n"));
5886 return 0;
5887 }
5888
77115a4a
L
5889 chdr->ch_type = BYTE_GET (echdr->ch_type);
5890 chdr->ch_size = BYTE_GET (echdr->ch_size);
5891 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5892 return sizeof (*echdr);
5893 }
5894}
5895
32ec8896 5896static bfd_boolean
dda8d76d 5897process_section_headers (Filedata * filedata)
252b5132 5898{
2cf0635d 5899 Elf_Internal_Shdr * section;
b34976b6 5900 unsigned int i;
252b5132 5901
dda8d76d 5902 filedata->section_headers = NULL;
252b5132 5903
dda8d76d 5904 if (filedata->file_header.e_shnum == 0)
252b5132 5905 {
82f2dbf7 5906 /* PR binutils/12467. */
dda8d76d 5907 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
5908 {
5909 warn (_("possibly corrupt ELF file header - it has a non-zero"
5910 " section header offset, but no section headers\n"));
5911 return FALSE;
5912 }
82f2dbf7 5913 else if (do_sections)
252b5132
RH
5914 printf (_("\nThere are no sections in this file.\n"));
5915
32ec8896 5916 return TRUE;
252b5132
RH
5917 }
5918
5919 if (do_sections && !do_header)
d3a49aa8
AM
5920 printf (ngettext ("There is %d section header, "
5921 "starting at offset 0x%lx:\n",
5922 "There are %d section headers, "
5923 "starting at offset 0x%lx:\n",
dda8d76d
NC
5924 filedata->file_header.e_shnum),
5925 filedata->file_header.e_shnum,
5926 (unsigned long) filedata->file_header.e_shoff);
252b5132 5927
9ea033b2
NC
5928 if (is_32bit_elf)
5929 {
dda8d76d 5930 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
5931 return FALSE;
5932 }
5933 else
5934 {
dda8d76d 5935 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 5936 return FALSE;
9ea033b2 5937 }
252b5132
RH
5938
5939 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
5940 if (filedata->file_header.e_shstrndx != SHN_UNDEF
5941 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 5942 {
dda8d76d 5943 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 5944
c256ffe7
JJ
5945 if (section->sh_size != 0)
5946 {
dda8d76d
NC
5947 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
5948 1, section->sh_size,
5949 _("string table"));
0de14b54 5950
dda8d76d 5951 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 5952 }
252b5132
RH
5953 }
5954
5955 /* Scan the sections for the dynamic symbol table
e3c8793a 5956 and dynamic string table and debug sections. */
252b5132
RH
5957 dynamic_symbols = NULL;
5958 dynamic_strings = NULL;
5959 dynamic_syminfo = NULL;
6a40cf0c 5960 symtab_shndx_list = NULL;
103f02d3 5961
89fac5e3 5962 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 5963 switch (filedata->file_header.e_machine)
89fac5e3
RS
5964 {
5965 case EM_MIPS:
5966 case EM_MIPS_RS3_LE:
5967 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5968 FDE addresses. However, the ABI also has a semi-official ILP32
5969 variant for which the normal FDE address size rules apply.
5970
5971 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5972 section, where XX is the size of longs in bits. Unfortunately,
5973 earlier compilers provided no way of distinguishing ILP32 objects
5974 from LP64 objects, so if there's any doubt, we should assume that
5975 the official LP64 form is being used. */
dda8d76d
NC
5976 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5977 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
5978 eh_addr_size = 8;
5979 break;
0f56a26a
DD
5980
5981 case EM_H8_300:
5982 case EM_H8_300H:
dda8d76d 5983 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
5984 {
5985 case E_H8_MACH_H8300:
5986 case E_H8_MACH_H8300HN:
5987 case E_H8_MACH_H8300SN:
5988 case E_H8_MACH_H8300SXN:
5989 eh_addr_size = 2;
5990 break;
5991 case E_H8_MACH_H8300H:
5992 case E_H8_MACH_H8300S:
5993 case E_H8_MACH_H8300SX:
5994 eh_addr_size = 4;
5995 break;
5996 }
f4236fe4
DD
5997 break;
5998
ff7eeb89 5999 case EM_M32C_OLD:
f4236fe4 6000 case EM_M32C:
dda8d76d 6001 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6002 {
6003 case EF_M32C_CPU_M16C:
6004 eh_addr_size = 2;
6005 break;
6006 }
6007 break;
89fac5e3
RS
6008 }
6009
76ca31c0
NC
6010#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6011 do \
6012 { \
6013 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6014 if (section->sh_entsize != expected_entsize) \
9dd3a467 6015 { \
76ca31c0
NC
6016 char buf[40]; \
6017 sprintf_vma (buf, section->sh_entsize); \
6018 /* Note: coded this way so that there is a single string for \
6019 translation. */ \
6020 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6021 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6022 (unsigned) expected_entsize); \
9dd3a467 6023 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6024 } \
6025 } \
08d8fa11 6026 while (0)
9dd3a467
NC
6027
6028#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
6029 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
6030 sizeof (Elf64_External_##type))
6031
dda8d76d
NC
6032 for (i = 0, section = filedata->section_headers;
6033 i < filedata->file_header.e_shnum;
b34976b6 6034 i++, section++)
252b5132 6035 {
2cf0635d 6036 char * name = SECTION_NAME (section);
252b5132
RH
6037
6038 if (section->sh_type == SHT_DYNSYM)
6039 {
6040 if (dynamic_symbols != NULL)
6041 {
6042 error (_("File contains multiple dynamic symbol tables\n"));
6043 continue;
6044 }
6045
08d8fa11 6046 CHECK_ENTSIZE (section, i, Sym);
dda8d76d 6047 dynamic_symbols = GET_ELF_SYMBOLS (filedata, section, & num_dynamic_syms);
252b5132
RH
6048 }
6049 else if (section->sh_type == SHT_STRTAB
18bd398b 6050 && streq (name, ".dynstr"))
252b5132
RH
6051 {
6052 if (dynamic_strings != NULL)
6053 {
6054 error (_("File contains multiple dynamic string tables\n"));
6055 continue;
6056 }
6057
dda8d76d 6058 dynamic_strings = (char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6059 1, section->sh_size,
6060 _("dynamic strings"));
59245841 6061 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 6062 }
9ad5cbcf
AM
6063 else if (section->sh_type == SHT_SYMTAB_SHNDX)
6064 {
6a40cf0c 6065 elf_section_list * entry = xmalloc (sizeof * entry);
dda8d76d 6066
6a40cf0c
NC
6067 entry->hdr = section;
6068 entry->next = symtab_shndx_list;
6069 symtab_shndx_list = entry;
9ad5cbcf 6070 }
08d8fa11
JJ
6071 else if (section->sh_type == SHT_SYMTAB)
6072 CHECK_ENTSIZE (section, i, Sym);
6073 else if (section->sh_type == SHT_GROUP)
6074 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6075 else if (section->sh_type == SHT_REL)
6076 CHECK_ENTSIZE (section, i, Rel);
6077 else if (section->sh_type == SHT_RELA)
6078 CHECK_ENTSIZE (section, i, Rela);
252b5132 6079 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 6080 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 6081 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47 6082 || do_debug_str || do_debug_loc || do_debug_ranges
d85bf2ba 6083 || do_debug_addr || do_debug_cu_index || do_debug_links)
1b315056
CS
6084 && (const_strneq (name, ".debug_")
6085 || const_strneq (name, ".zdebug_")))
252b5132 6086 {
1b315056
CS
6087 if (name[1] == 'z')
6088 name += sizeof (".zdebug_") - 1;
6089 else
6090 name += sizeof (".debug_") - 1;
252b5132
RH
6091
6092 if (do_debugging
4723351a
CC
6093 || (do_debug_info && const_strneq (name, "info"))
6094 || (do_debug_info && const_strneq (name, "types"))
6095 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6096 || (do_debug_lines && strcmp (name, "line") == 0)
6097 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6098 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6099 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6100 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6101 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6102 || (do_debug_aranges && const_strneq (name, "aranges"))
6103 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6104 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6105 || (do_debug_frames && const_strneq (name, "frame"))
6106 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6107 || (do_debug_macinfo && const_strneq (name, "macro"))
6108 || (do_debug_str && const_strneq (name, "str"))
6109 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6110 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6111 || (do_debug_addr && const_strneq (name, "addr"))
6112 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6113 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6114 )
dda8d76d 6115 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132 6116 }
a262ae96 6117 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6118 else if ((do_debugging || do_debug_info)
0112cd26 6119 && const_strneq (name, ".gnu.linkonce.wi."))
dda8d76d 6120 request_dump_bynumber (filedata, i, DEBUG_DUMP);
18bd398b 6121 else if (do_debug_frames && streq (name, ".eh_frame"))
dda8d76d 6122 request_dump_bynumber (filedata, i, DEBUG_DUMP);
61364358
JK
6123 else if (do_gdb_index && (streq (name, ".gdb_index")
6124 || streq (name, ".debug_names")))
dda8d76d 6125 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884
TG
6126 /* Trace sections for Itanium VMS. */
6127 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6128 || do_trace_aranges)
6129 && const_strneq (name, ".trace_"))
6130 {
6131 name += sizeof (".trace_") - 1;
6132
6133 if (do_debugging
6134 || (do_trace_info && streq (name, "info"))
6135 || (do_trace_abbrevs && streq (name, "abbrev"))
6136 || (do_trace_aranges && streq (name, "aranges"))
6137 )
dda8d76d 6138 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884 6139 }
dda8d76d
NC
6140 else if ((do_debugging || do_debug_links)
6141 && (const_strneq (name, ".gnu_debuglink")
6142 || const_strneq (name, ".gnu_debugaltlink")))
6143 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132
RH
6144 }
6145
6146 if (! do_sections)
32ec8896 6147 return TRUE;
252b5132 6148
dda8d76d 6149 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6150 printf (_("\nSection Headers:\n"));
6151 else
6152 printf (_("\nSection Header:\n"));
76da6bbe 6153
f7a99963 6154 if (is_32bit_elf)
595cf52e 6155 {
5477e8a0 6156 if (do_section_details)
595cf52e
L
6157 {
6158 printf (_(" [Nr] Name\n"));
5477e8a0 6159 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6160 }
6161 else
6162 printf
6163 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6164 }
d974e256 6165 else if (do_wide)
595cf52e 6166 {
5477e8a0 6167 if (do_section_details)
595cf52e
L
6168 {
6169 printf (_(" [Nr] Name\n"));
5477e8a0 6170 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6171 }
6172 else
6173 printf
6174 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6175 }
f7a99963
NC
6176 else
6177 {
5477e8a0 6178 if (do_section_details)
595cf52e
L
6179 {
6180 printf (_(" [Nr] Name\n"));
5477e8a0
L
6181 printf (_(" Type Address Offset Link\n"));
6182 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6183 }
6184 else
6185 {
6186 printf (_(" [Nr] Name Type Address Offset\n"));
6187 printf (_(" Size EntSize Flags Link Info Align\n"));
6188 }
f7a99963 6189 }
252b5132 6190
5477e8a0
L
6191 if (do_section_details)
6192 printf (_(" Flags\n"));
6193
dda8d76d
NC
6194 for (i = 0, section = filedata->section_headers;
6195 i < filedata->file_header.e_shnum;
b34976b6 6196 i++, section++)
252b5132 6197 {
dd905818
NC
6198 /* Run some sanity checks on the section header. */
6199
6200 /* Check the sh_link field. */
6201 switch (section->sh_type)
6202 {
6203 case SHT_SYMTAB_SHNDX:
6204 case SHT_GROUP:
6205 case SHT_HASH:
6206 case SHT_GNU_HASH:
6207 case SHT_GNU_versym:
6208 case SHT_REL:
6209 case SHT_RELA:
6210 if (section->sh_link < 1
dda8d76d
NC
6211 || section->sh_link >= filedata->file_header.e_shnum
6212 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6213 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6214 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6215 i, section->sh_link);
6216 break;
6217
6218 case SHT_DYNAMIC:
6219 case SHT_SYMTAB:
6220 case SHT_DYNSYM:
6221 case SHT_GNU_verneed:
6222 case SHT_GNU_verdef:
6223 case SHT_GNU_LIBLIST:
6224 if (section->sh_link < 1
dda8d76d
NC
6225 || section->sh_link >= filedata->file_header.e_shnum
6226 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6227 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6228 i, section->sh_link);
6229 break;
6230
6231 case SHT_INIT_ARRAY:
6232 case SHT_FINI_ARRAY:
6233 case SHT_PREINIT_ARRAY:
6234 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6235 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6236 i, section->sh_link);
6237 break;
6238
6239 default:
6240 /* FIXME: Add support for target specific section types. */
6241#if 0 /* Currently we do not check other section types as there are too
6242 many special cases. Stab sections for example have a type
6243 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6244 section. */
6245 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6246 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6247 i, section->sh_link);
6248#endif
6249 break;
6250 }
6251
6252 /* Check the sh_info field. */
6253 switch (section->sh_type)
6254 {
6255 case SHT_REL:
6256 case SHT_RELA:
6257 if (section->sh_info < 1
dda8d76d
NC
6258 || section->sh_info >= filedata->file_header.e_shnum
6259 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6260 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6261 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6262 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
dd905818 6263 /* FIXME: Are other section types valid ? */
dda8d76d 6264 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
dd905818
NC
6265 {
6266 if (section->sh_info == 0
bef7475f
NC
6267 && (filedata->file_header.e_type == ET_EXEC
6268 || filedata->file_header.e_type == ET_DYN
6269 /* These next two tests may be redundant, but
6270 they have been left in for paranoia's sake. */
6271 || streq (SECTION_NAME (section), ".rel.dyn")
dd905818 6272 || streq (SECTION_NAME (section), ".rela.dyn")))
bef7475f
NC
6273 /* Dynamic relocations apply to segments, not sections, so
6274 they do not need an sh_info value. */
6275 ;
dd905818
NC
6276 else
6277 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6278 i, section->sh_info);
6279 }
6280 break;
6281
6282 case SHT_DYNAMIC:
6283 case SHT_HASH:
6284 case SHT_SYMTAB_SHNDX:
6285 case SHT_INIT_ARRAY:
6286 case SHT_FINI_ARRAY:
6287 case SHT_PREINIT_ARRAY:
6288 if (section->sh_info != 0)
6289 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6290 i, section->sh_info);
6291 break;
6292
6293 case SHT_GROUP:
6294 case SHT_SYMTAB:
6295 case SHT_DYNSYM:
6296 /* A symbol index - we assume that it is valid. */
6297 break;
6298
6299 default:
6300 /* FIXME: Add support for target specific section types. */
6301 if (section->sh_type == SHT_NOBITS)
6302 /* NOBITS section headers with non-zero sh_info fields can be
6303 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6304 information. The stripped sections have their headers
6305 preserved but their types set to SHT_NOBITS. So do not check
6306 this type of section. */
dd905818
NC
6307 ;
6308 else if (section->sh_flags & SHF_INFO_LINK)
6309 {
dda8d76d 6310 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6311 warn (_("[%2u]: Expected link to another section in info field"), i);
6312 }
a91e1603
L
6313 else if (section->sh_type < SHT_LOOS
6314 && (section->sh_flags & SHF_GNU_MBIND) == 0
6315 && section->sh_info != 0)
dd905818
NC
6316 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6317 i, section->sh_info);
6318 break;
6319 }
6320
3e6b6445 6321 /* Check the sh_size field. */
dda8d76d 6322 if (section->sh_size > filedata->file_size
3e6b6445
NC
6323 && section->sh_type != SHT_NOBITS
6324 && section->sh_type != SHT_NULL
6325 && section->sh_type < SHT_LOOS)
6326 warn (_("Size of section %u is larger than the entire file!\n"), i);
6327
7bfd842d 6328 printf (" [%2u] ", i);
5477e8a0 6329 if (do_section_details)
dda8d76d 6330 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6331 else
74e1a04b 6332 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6333
ea52a088 6334 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6335 get_section_type_name (filedata, section->sh_type));
0b4362b0 6336
f7a99963
NC
6337 if (is_32bit_elf)
6338 {
cfcac11d
NC
6339 const char * link_too_big = NULL;
6340
f7a99963 6341 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6342
f7a99963
NC
6343 printf ( " %6.6lx %6.6lx %2.2lx",
6344 (unsigned long) section->sh_offset,
6345 (unsigned long) section->sh_size,
6346 (unsigned long) section->sh_entsize);
d1133906 6347
5477e8a0
L
6348 if (do_section_details)
6349 fputs (" ", stdout);
6350 else
dda8d76d 6351 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6352
dda8d76d 6353 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6354 {
6355 link_too_big = "";
6356 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6357 an error but it can have special values in Solaris binaries. */
dda8d76d 6358 switch (filedata->file_header.e_machine)
cfcac11d 6359 {
caa83f8b 6360 case EM_386:
22abe556 6361 case EM_IAMCU:
caa83f8b 6362 case EM_X86_64:
7f502d6c 6363 case EM_L1OM:
7a9068fe 6364 case EM_K1OM:
cfcac11d
NC
6365 case EM_OLD_SPARCV9:
6366 case EM_SPARC32PLUS:
6367 case EM_SPARCV9:
6368 case EM_SPARC:
6369 if (section->sh_link == (SHN_BEFORE & 0xffff))
6370 link_too_big = "BEFORE";
6371 else if (section->sh_link == (SHN_AFTER & 0xffff))
6372 link_too_big = "AFTER";
6373 break;
6374 default:
6375 break;
6376 }
6377 }
6378
6379 if (do_section_details)
6380 {
6381 if (link_too_big != NULL && * link_too_big)
6382 printf ("<%s> ", link_too_big);
6383 else
6384 printf ("%2u ", section->sh_link);
6385 printf ("%3u %2lu\n", section->sh_info,
6386 (unsigned long) section->sh_addralign);
6387 }
6388 else
6389 printf ("%2u %3u %2lu\n",
6390 section->sh_link,
6391 section->sh_info,
6392 (unsigned long) section->sh_addralign);
6393
6394 if (link_too_big && ! * link_too_big)
6395 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6396 i, section->sh_link);
f7a99963 6397 }
d974e256
JJ
6398 else if (do_wide)
6399 {
6400 print_vma (section->sh_addr, LONG_HEX);
6401
6402 if ((long) section->sh_offset == section->sh_offset)
6403 printf (" %6.6lx", (unsigned long) section->sh_offset);
6404 else
6405 {
6406 putchar (' ');
6407 print_vma (section->sh_offset, LONG_HEX);
6408 }
6409
6410 if ((unsigned long) section->sh_size == section->sh_size)
6411 printf (" %6.6lx", (unsigned long) section->sh_size);
6412 else
6413 {
6414 putchar (' ');
6415 print_vma (section->sh_size, LONG_HEX);
6416 }
6417
6418 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6419 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6420 else
6421 {
6422 putchar (' ');
6423 print_vma (section->sh_entsize, LONG_HEX);
6424 }
6425
5477e8a0
L
6426 if (do_section_details)
6427 fputs (" ", stdout);
6428 else
dda8d76d 6429 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6430
72de5009 6431 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6432
6433 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6434 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6435 else
6436 {
6437 print_vma (section->sh_addralign, DEC);
6438 putchar ('\n');
6439 }
6440 }
5477e8a0 6441 else if (do_section_details)
595cf52e 6442 {
5477e8a0 6443 printf (" %-15.15s ",
dda8d76d 6444 get_section_type_name (filedata, section->sh_type));
595cf52e
L
6445 print_vma (section->sh_addr, LONG_HEX);
6446 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6447 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6448 else
6449 {
6450 printf (" ");
6451 print_vma (section->sh_offset, LONG_HEX);
6452 }
72de5009 6453 printf (" %u\n ", section->sh_link);
595cf52e 6454 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6455 putchar (' ');
595cf52e
L
6456 print_vma (section->sh_entsize, LONG_HEX);
6457
72de5009
AM
6458 printf (" %-16u %lu\n",
6459 section->sh_info,
595cf52e
L
6460 (unsigned long) section->sh_addralign);
6461 }
f7a99963
NC
6462 else
6463 {
6464 putchar (' ');
6465 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6466 if ((long) section->sh_offset == section->sh_offset)
6467 printf (" %8.8lx", (unsigned long) section->sh_offset);
6468 else
6469 {
6470 printf (" ");
6471 print_vma (section->sh_offset, LONG_HEX);
6472 }
f7a99963
NC
6473 printf ("\n ");
6474 print_vma (section->sh_size, LONG_HEX);
6475 printf (" ");
6476 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6477
dda8d76d 6478 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6479
72de5009
AM
6480 printf (" %2u %3u %lu\n",
6481 section->sh_link,
6482 section->sh_info,
f7a99963
NC
6483 (unsigned long) section->sh_addralign);
6484 }
5477e8a0
L
6485
6486 if (do_section_details)
77115a4a 6487 {
dda8d76d 6488 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6489 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6490 {
6491 /* Minimum section size is 12 bytes for 32-bit compression
6492 header + 12 bytes for compressed data header. */
6493 unsigned char buf[24];
d8024a91 6494
77115a4a 6495 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6496 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6497 sizeof (buf), _("compression header")))
6498 {
6499 Elf_Internal_Chdr chdr;
d8024a91 6500
ebdf1ebf 6501 (void) get_compression_header (&chdr, buf, sizeof (buf));
d8024a91 6502
77115a4a
L
6503 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6504 printf (" ZLIB, ");
6505 else
6506 printf (_(" [<unknown>: 0x%x], "),
6507 chdr.ch_type);
6508 print_vma (chdr.ch_size, LONG_HEX);
6509 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6510 }
6511 }
6512 }
252b5132
RH
6513 }
6514
5477e8a0 6515 if (!do_section_details)
3dbcc61d 6516 {
9fb71ee4
NC
6517 /* The ordering of the letters shown here matches the ordering of the
6518 corresponding SHF_xxx values, and hence the order in which these
6519 letters will be displayed to the user. */
6520 printf (_("Key to Flags:\n\
6521 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6522 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6523 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6524 if (filedata->file_header.e_machine == EM_X86_64
6525 || filedata->file_header.e_machine == EM_L1OM
6526 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6527 printf (_("l (large), "));
dda8d76d 6528 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6529 printf (_("y (purecode), "));
dda8d76d 6530 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6531 printf (_("v (VLE), "));
9fb71ee4 6532 printf ("p (processor specific)\n");
0b4362b0 6533 }
d1133906 6534
32ec8896 6535 return TRUE;
252b5132
RH
6536}
6537
f5842774
L
6538static const char *
6539get_group_flags (unsigned int flags)
6540{
1449284b 6541 static char buff[128];
220453ec 6542
6d913794
NC
6543 if (flags == 0)
6544 return "";
6545 else if (flags == GRP_COMDAT)
6546 return "COMDAT ";
f5842774 6547
6d913794
NC
6548 snprintf (buff, 14, _("[0x%x: "), flags);
6549
6550 flags &= ~ GRP_COMDAT;
6551 if (flags & GRP_MASKOS)
6552 {
6553 strcat (buff, "<OS specific>");
6554 flags &= ~ GRP_MASKOS;
f5842774 6555 }
6d913794
NC
6556
6557 if (flags & GRP_MASKPROC)
6558 {
6559 strcat (buff, "<PROC specific>");
6560 flags &= ~ GRP_MASKPROC;
6561 }
6562
6563 if (flags)
6564 strcat (buff, "<unknown>");
6565
6566 strcat (buff, "]");
f5842774
L
6567 return buff;
6568}
6569
32ec8896 6570static bfd_boolean
dda8d76d 6571process_section_groups (Filedata * filedata)
f5842774 6572{
2cf0635d 6573 Elf_Internal_Shdr * section;
f5842774 6574 unsigned int i;
2cf0635d
NC
6575 struct group * group;
6576 Elf_Internal_Shdr * symtab_sec;
6577 Elf_Internal_Shdr * strtab_sec;
6578 Elf_Internal_Sym * symtab;
ba5cdace 6579 unsigned long num_syms;
2cf0635d 6580 char * strtab;
c256ffe7 6581 size_t strtab_size;
d1f5c6e3
L
6582
6583 /* Don't process section groups unless needed. */
6584 if (!do_unwind && !do_section_groups)
32ec8896 6585 return TRUE;
f5842774 6586
dda8d76d 6587 if (filedata->file_header.e_shnum == 0)
f5842774
L
6588 {
6589 if (do_section_groups)
82f2dbf7 6590 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 6591
32ec8896 6592 return TRUE;
f5842774
L
6593 }
6594
dda8d76d 6595 if (filedata->section_headers == NULL)
f5842774
L
6596 {
6597 error (_("Section headers are not available!\n"));
fa1908fd 6598 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 6599 return FALSE;
f5842774
L
6600 }
6601
dda8d76d 6602 section_headers_groups = (struct group **) calloc (filedata->file_header.e_shnum,
3f5e193b 6603 sizeof (struct group *));
e4b17d5c
L
6604
6605 if (section_headers_groups == NULL)
6606 {
8b73c356 6607 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 6608 filedata->file_header.e_shnum);
32ec8896 6609 return FALSE;
e4b17d5c
L
6610 }
6611
f5842774 6612 /* Scan the sections for the group section. */
d1f5c6e3 6613 group_count = 0;
dda8d76d
NC
6614 for (i = 0, section = filedata->section_headers;
6615 i < filedata->file_header.e_shnum;
f5842774 6616 i++, section++)
e4b17d5c
L
6617 if (section->sh_type == SHT_GROUP)
6618 group_count++;
6619
d1f5c6e3
L
6620 if (group_count == 0)
6621 {
6622 if (do_section_groups)
6623 printf (_("\nThere are no section groups in this file.\n"));
6624
32ec8896 6625 return TRUE;
d1f5c6e3
L
6626 }
6627
3f5e193b 6628 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
6629
6630 if (section_groups == NULL)
6631 {
8b73c356
NC
6632 error (_("Out of memory reading %lu groups\n"),
6633 (unsigned long) group_count);
32ec8896 6634 return FALSE;
e4b17d5c
L
6635 }
6636
d1f5c6e3
L
6637 symtab_sec = NULL;
6638 strtab_sec = NULL;
6639 symtab = NULL;
ba5cdace 6640 num_syms = 0;
d1f5c6e3 6641 strtab = NULL;
c256ffe7 6642 strtab_size = 0;
dda8d76d
NC
6643 for (i = 0, section = filedata->section_headers, group = section_groups;
6644 i < filedata->file_header.e_shnum;
e4b17d5c 6645 i++, section++)
f5842774
L
6646 {
6647 if (section->sh_type == SHT_GROUP)
6648 {
dda8d76d 6649 const char * name = printable_section_name (filedata, section);
74e1a04b 6650 const char * group_name;
2cf0635d
NC
6651 unsigned char * start;
6652 unsigned char * indices;
f5842774 6653 unsigned int entry, j, size;
2cf0635d
NC
6654 Elf_Internal_Shdr * sec;
6655 Elf_Internal_Sym * sym;
f5842774
L
6656
6657 /* Get the symbol table. */
dda8d76d
NC
6658 if (section->sh_link >= filedata->file_header.e_shnum
6659 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 6660 != SHT_SYMTAB))
f5842774
L
6661 {
6662 error (_("Bad sh_link in group section `%s'\n"), name);
6663 continue;
6664 }
d1f5c6e3
L
6665
6666 if (symtab_sec != sec)
6667 {
6668 symtab_sec = sec;
6669 if (symtab)
6670 free (symtab);
dda8d76d 6671 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 6672 }
f5842774 6673
dd24e3da
NC
6674 if (symtab == NULL)
6675 {
6676 error (_("Corrupt header in group section `%s'\n"), name);
6677 continue;
6678 }
6679
ba5cdace
NC
6680 if (section->sh_info >= num_syms)
6681 {
6682 error (_("Bad sh_info in group section `%s'\n"), name);
6683 continue;
6684 }
6685
f5842774
L
6686 sym = symtab + section->sh_info;
6687
6688 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6689 {
4fbb74a6 6690 if (sym->st_shndx == 0
dda8d76d 6691 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
6692 {
6693 error (_("Bad sh_info in group section `%s'\n"), name);
6694 continue;
6695 }
ba2685cc 6696
dda8d76d 6697 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7
JJ
6698 strtab_sec = NULL;
6699 if (strtab)
6700 free (strtab);
f5842774 6701 strtab = NULL;
c256ffe7 6702 strtab_size = 0;
f5842774
L
6703 }
6704 else
6705 {
6706 /* Get the string table. */
dda8d76d 6707 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
6708 {
6709 strtab_sec = NULL;
6710 if (strtab)
6711 free (strtab);
6712 strtab = NULL;
6713 strtab_size = 0;
6714 }
6715 else if (strtab_sec
dda8d76d 6716 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
6717 {
6718 strtab_sec = sec;
6719 if (strtab)
6720 free (strtab);
071436c6 6721
dda8d76d 6722 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
6723 1, strtab_sec->sh_size,
6724 _("string table"));
c256ffe7 6725 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 6726 }
c256ffe7 6727 group_name = sym->st_name < strtab_size
2b692964 6728 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
6729 }
6730
c9c1d674
EG
6731 /* PR 17531: file: loop. */
6732 if (section->sh_entsize > section->sh_size)
6733 {
6734 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 6735 printable_section_name (filedata, section),
8066deb1
AM
6736 (unsigned long) section->sh_entsize,
6737 (unsigned long) section->sh_size);
c9c1d674
EG
6738 break;
6739 }
6740
dda8d76d 6741 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6742 1, section->sh_size,
6743 _("section data"));
59245841
NC
6744 if (start == NULL)
6745 continue;
f5842774
L
6746
6747 indices = start;
6748 size = (section->sh_size / section->sh_entsize) - 1;
6749 entry = byte_get (indices, 4);
6750 indices += 4;
e4b17d5c
L
6751
6752 if (do_section_groups)
6753 {
2b692964 6754 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6755 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6756
e4b17d5c
L
6757 printf (_(" [Index] Name\n"));
6758 }
6759
6760 group->group_index = i;
6761
f5842774
L
6762 for (j = 0; j < size; j++)
6763 {
2cf0635d 6764 struct group_list * g;
e4b17d5c 6765
f5842774
L
6766 entry = byte_get (indices, 4);
6767 indices += 4;
6768
dda8d76d 6769 if (entry >= filedata->file_header.e_shnum)
391cb864 6770 {
57028622
NC
6771 static unsigned num_group_errors = 0;
6772
6773 if (num_group_errors ++ < 10)
6774 {
6775 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 6776 entry, i, filedata->file_header.e_shnum - 1);
57028622 6777 if (num_group_errors == 10)
de194d85 6778 warn (_("Further error messages about overlarge group section indicies suppressed\n"));
57028622 6779 }
391cb864
L
6780 continue;
6781 }
391cb864 6782
4fbb74a6 6783 if (section_headers_groups [entry] != NULL)
e4b17d5c 6784 {
d1f5c6e3
L
6785 if (entry)
6786 {
57028622
NC
6787 static unsigned num_errs = 0;
6788
6789 if (num_errs ++ < 10)
6790 {
6791 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6792 entry, i,
6793 section_headers_groups [entry]->group_index);
6794 if (num_errs == 10)
6795 warn (_("Further error messages about already contained group sections suppressed\n"));
6796 }
d1f5c6e3
L
6797 continue;
6798 }
6799 else
6800 {
6801 /* Intel C/C++ compiler may put section 0 in a
32ec8896 6802 section group. We just warn it the first time
d1f5c6e3 6803 and ignore it afterwards. */
32ec8896 6804 static bfd_boolean warned = FALSE;
d1f5c6e3
L
6805 if (!warned)
6806 {
6807 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6808 section_headers_groups [entry]->group_index);
32ec8896 6809 warned = TRUE;
d1f5c6e3
L
6810 }
6811 }
e4b17d5c
L
6812 }
6813
4fbb74a6 6814 section_headers_groups [entry] = group;
e4b17d5c
L
6815
6816 if (do_section_groups)
6817 {
dda8d76d
NC
6818 sec = filedata->section_headers + entry;
6819 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
6820 }
6821
3f5e193b 6822 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6823 g->section_index = entry;
6824 g->next = group->root;
6825 group->root = g;
f5842774
L
6826 }
6827
f5842774
L
6828 if (start)
6829 free (start);
e4b17d5c
L
6830
6831 group++;
f5842774
L
6832 }
6833 }
6834
d1f5c6e3
L
6835 if (symtab)
6836 free (symtab);
6837 if (strtab)
6838 free (strtab);
32ec8896 6839 return TRUE;
f5842774
L
6840}
6841
28f997cf
TG
6842/* Data used to display dynamic fixups. */
6843
6844struct ia64_vms_dynfixup
6845{
6846 bfd_vma needed_ident; /* Library ident number. */
6847 bfd_vma needed; /* Index in the dstrtab of the library name. */
6848 bfd_vma fixup_needed; /* Index of the library. */
6849 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6850 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6851};
6852
6853/* Data used to display dynamic relocations. */
6854
6855struct ia64_vms_dynimgrela
6856{
6857 bfd_vma img_rela_cnt; /* Number of relocations. */
6858 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6859};
6860
6861/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6862 library). */
6863
32ec8896 6864static bfd_boolean
dda8d76d
NC
6865dump_ia64_vms_dynamic_fixups (Filedata * filedata,
6866 struct ia64_vms_dynfixup * fixup,
6867 const char * strtab,
6868 unsigned int strtab_sz)
28f997cf 6869{
32ec8896 6870 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 6871 long i;
32ec8896 6872 const char * lib_name;
28f997cf 6873
dda8d76d 6874 imfs = get_data (NULL, filedata, dynamic_addr + fixup->fixup_rela_off,
28f997cf
TG
6875 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6876 _("dynamic section image fixups"));
6877 if (!imfs)
32ec8896 6878 return FALSE;
28f997cf
TG
6879
6880 if (fixup->needed < strtab_sz)
6881 lib_name = strtab + fixup->needed;
6882 else
6883 {
32ec8896 6884 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 6885 (unsigned long) fixup->needed);
28f997cf
TG
6886 lib_name = "???";
6887 }
6888 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6889 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6890 printf
6891 (_("Seg Offset Type SymVec DataType\n"));
6892
6893 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6894 {
6895 unsigned int type;
6896 const char *rtype;
6897
6898 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6899 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6900 type = BYTE_GET (imfs [i].type);
6901 rtype = elf_ia64_reloc_type (type);
6902 if (rtype == NULL)
6903 printf (" 0x%08x ", type);
6904 else
6905 printf (" %-32s ", rtype);
6906 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6907 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6908 }
6909
6910 free (imfs);
32ec8896 6911 return TRUE;
28f997cf
TG
6912}
6913
6914/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6915
32ec8896 6916static bfd_boolean
dda8d76d 6917dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
6918{
6919 Elf64_External_VMS_IMAGE_RELA *imrs;
6920 long i;
6921
dda8d76d 6922 imrs = get_data (NULL, filedata, dynamic_addr + imgrela->img_rela_off,
28f997cf 6923 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6924 _("dynamic section image relocations"));
28f997cf 6925 if (!imrs)
32ec8896 6926 return FALSE;
28f997cf
TG
6927
6928 printf (_("\nImage relocs\n"));
6929 printf
6930 (_("Seg Offset Type Addend Seg Sym Off\n"));
6931
6932 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6933 {
6934 unsigned int type;
6935 const char *rtype;
6936
6937 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6938 printf ("%08" BFD_VMA_FMT "x ",
6939 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6940 type = BYTE_GET (imrs [i].type);
6941 rtype = elf_ia64_reloc_type (type);
6942 if (rtype == NULL)
6943 printf ("0x%08x ", type);
6944 else
6945 printf ("%-31s ", rtype);
6946 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6947 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6948 printf ("%08" BFD_VMA_FMT "x\n",
6949 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6950 }
6951
6952 free (imrs);
32ec8896 6953 return TRUE;
28f997cf
TG
6954}
6955
6956/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6957
32ec8896 6958static bfd_boolean
dda8d76d 6959process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
6960{
6961 struct ia64_vms_dynfixup fixup;
6962 struct ia64_vms_dynimgrela imgrela;
6963 Elf_Internal_Dyn *entry;
28f997cf
TG
6964 bfd_vma strtab_off = 0;
6965 bfd_vma strtab_sz = 0;
6966 char *strtab = NULL;
32ec8896 6967 bfd_boolean res = TRUE;
28f997cf
TG
6968
6969 memset (&fixup, 0, sizeof (fixup));
6970 memset (&imgrela, 0, sizeof (imgrela));
6971
6972 /* Note: the order of the entries is specified by the OpenVMS specs. */
6973 for (entry = dynamic_section;
6974 entry < dynamic_section + dynamic_nent;
6975 entry++)
6976 {
6977 switch (entry->d_tag)
6978 {
6979 case DT_IA_64_VMS_STRTAB_OFFSET:
6980 strtab_off = entry->d_un.d_val;
6981 break;
6982 case DT_STRSZ:
6983 strtab_sz = entry->d_un.d_val;
6984 if (strtab == NULL)
dda8d76d 6985 strtab = get_data (NULL, filedata, dynamic_addr + strtab_off,
28f997cf
TG
6986 1, strtab_sz, _("dynamic string section"));
6987 break;
6988
6989 case DT_IA_64_VMS_NEEDED_IDENT:
6990 fixup.needed_ident = entry->d_un.d_val;
6991 break;
6992 case DT_NEEDED:
6993 fixup.needed = entry->d_un.d_val;
6994 break;
6995 case DT_IA_64_VMS_FIXUP_NEEDED:
6996 fixup.fixup_needed = entry->d_un.d_val;
6997 break;
6998 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6999 fixup.fixup_rela_cnt = entry->d_un.d_val;
7000 break;
7001 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7002 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7003 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7004 res = FALSE;
28f997cf 7005 break;
28f997cf
TG
7006 case DT_IA_64_VMS_IMG_RELA_CNT:
7007 imgrela.img_rela_cnt = entry->d_un.d_val;
7008 break;
7009 case DT_IA_64_VMS_IMG_RELA_OFF:
7010 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7011 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7012 res = FALSE;
28f997cf
TG
7013 break;
7014
7015 default:
7016 break;
7017 }
7018 }
7019
7020 if (strtab != NULL)
7021 free (strtab);
7022
7023 return res;
7024}
7025
85b1c36d 7026static struct
566b0d53 7027{
2cf0635d 7028 const char * name;
566b0d53
L
7029 int reloc;
7030 int size;
7031 int rela;
32ec8896
NC
7032}
7033 dynamic_relocations [] =
566b0d53 7034{
32ec8896
NC
7035 { "REL", DT_REL, DT_RELSZ, FALSE },
7036 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7037 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7038};
7039
252b5132 7040/* Process the reloc section. */
18bd398b 7041
32ec8896 7042static bfd_boolean
dda8d76d 7043process_relocs (Filedata * filedata)
252b5132 7044{
b34976b6
AM
7045 unsigned long rel_size;
7046 unsigned long rel_offset;
252b5132 7047
252b5132 7048 if (!do_reloc)
32ec8896 7049 return TRUE;
252b5132
RH
7050
7051 if (do_using_dynamic)
7052 {
32ec8896 7053 int is_rela;
2cf0635d 7054 const char * name;
32ec8896 7055 bfd_boolean has_dynamic_reloc;
566b0d53 7056 unsigned int i;
0de14b54 7057
32ec8896 7058 has_dynamic_reloc = FALSE;
252b5132 7059
566b0d53 7060 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7061 {
566b0d53
L
7062 is_rela = dynamic_relocations [i].rela;
7063 name = dynamic_relocations [i].name;
7064 rel_size = dynamic_info [dynamic_relocations [i].size];
7065 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 7066
32ec8896
NC
7067 if (rel_size)
7068 has_dynamic_reloc = TRUE;
566b0d53
L
7069
7070 if (is_rela == UNKNOWN)
aa903cfb 7071 {
566b0d53
L
7072 if (dynamic_relocations [i].reloc == DT_JMPREL)
7073 switch (dynamic_info[DT_PLTREL])
7074 {
7075 case DT_REL:
7076 is_rela = FALSE;
7077 break;
7078 case DT_RELA:
7079 is_rela = TRUE;
7080 break;
7081 }
aa903cfb 7082 }
252b5132 7083
566b0d53
L
7084 if (rel_size)
7085 {
7086 printf
7087 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7088 name, rel_offset, rel_size);
252b5132 7089
dda8d76d
NC
7090 dump_relocations (filedata,
7091 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7092 rel_size,
566b0d53 7093 dynamic_symbols, num_dynamic_syms,
bb4d2ac2 7094 dynamic_strings, dynamic_strings_length,
32ec8896 7095 is_rela, TRUE /* is_dynamic */);
566b0d53 7096 }
252b5132 7097 }
566b0d53 7098
dda8d76d
NC
7099 if (is_ia64_vms (filedata))
7100 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7101 has_dynamic_reloc = TRUE;
28f997cf 7102
566b0d53 7103 if (! has_dynamic_reloc)
252b5132
RH
7104 printf (_("\nThere are no dynamic relocations in this file.\n"));
7105 }
7106 else
7107 {
2cf0635d 7108 Elf_Internal_Shdr * section;
b34976b6 7109 unsigned long i;
32ec8896 7110 bfd_boolean found = FALSE;
252b5132 7111
dda8d76d
NC
7112 for (i = 0, section = filedata->section_headers;
7113 i < filedata->file_header.e_shnum;
b34976b6 7114 i++, section++)
252b5132
RH
7115 {
7116 if ( section->sh_type != SHT_RELA
7117 && section->sh_type != SHT_REL)
7118 continue;
7119
7120 rel_offset = section->sh_offset;
7121 rel_size = section->sh_size;
7122
7123 if (rel_size)
7124 {
2cf0635d 7125 Elf_Internal_Shdr * strsec;
b34976b6 7126 int is_rela;
d3a49aa8 7127 unsigned long num_rela;
103f02d3 7128
252b5132
RH
7129 printf (_("\nRelocation section "));
7130
dda8d76d 7131 if (filedata->string_table == NULL)
19936277 7132 printf ("%d", section->sh_name);
252b5132 7133 else
dda8d76d 7134 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7135
d3a49aa8
AM
7136 num_rela = rel_size / section->sh_entsize;
7137 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7138 " at offset 0x%lx contains %lu entries:\n",
7139 num_rela),
7140 rel_offset, num_rela);
252b5132 7141
d79b3d50
NC
7142 is_rela = section->sh_type == SHT_RELA;
7143
4fbb74a6 7144 if (section->sh_link != 0
dda8d76d 7145 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7146 {
2cf0635d
NC
7147 Elf_Internal_Shdr * symsec;
7148 Elf_Internal_Sym * symtab;
d79b3d50 7149 unsigned long nsyms;
c256ffe7 7150 unsigned long strtablen = 0;
2cf0635d 7151 char * strtab = NULL;
57346661 7152
dda8d76d 7153 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7154 if (symsec->sh_type != SHT_SYMTAB
7155 && symsec->sh_type != SHT_DYNSYM)
7156 continue;
7157
dda8d76d 7158 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
252b5132 7159
af3fc3bc
AM
7160 if (symtab == NULL)
7161 continue;
252b5132 7162
4fbb74a6 7163 if (symsec->sh_link != 0
dda8d76d 7164 && symsec->sh_link < filedata->file_header.e_shnum)
c256ffe7 7165 {
dda8d76d 7166 strsec = filedata->section_headers + symsec->sh_link;
103f02d3 7167
dda8d76d 7168 strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
071436c6
NC
7169 1, strsec->sh_size,
7170 _("string table"));
c256ffe7
JJ
7171 strtablen = strtab == NULL ? 0 : strsec->sh_size;
7172 }
252b5132 7173
dda8d76d 7174 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7175 symtab, nsyms, strtab, strtablen,
7176 is_rela,
7177 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
7178 if (strtab)
7179 free (strtab);
7180 free (symtab);
7181 }
7182 else
dda8d76d 7183 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7184 NULL, 0, NULL, 0, is_rela,
7185 FALSE /* is_dynamic */);
252b5132 7186
32ec8896 7187 found = TRUE;
252b5132
RH
7188 }
7189 }
7190
7191 if (! found)
45ac8f4f
NC
7192 {
7193 /* Users sometimes forget the -D option, so try to be helpful. */
7194 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7195 {
7196 if (dynamic_info [dynamic_relocations [i].size])
7197 {
7198 printf (_("\nThere are no static relocations in this file."));
7199 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7200
7201 break;
7202 }
7203 }
7204 if (i == ARRAY_SIZE (dynamic_relocations))
7205 printf (_("\nThere are no relocations in this file.\n"));
7206 }
252b5132
RH
7207 }
7208
32ec8896 7209 return TRUE;
252b5132
RH
7210}
7211
4d6ed7c8
NC
7212/* An absolute address consists of a section and an offset. If the
7213 section is NULL, the offset itself is the address, otherwise, the
7214 address equals to LOAD_ADDRESS(section) + offset. */
7215
7216struct absaddr
948f632f
DA
7217{
7218 unsigned short section;
7219 bfd_vma offset;
7220};
4d6ed7c8 7221
1949de15
L
7222#define ABSADDR(a) \
7223 ((a).section \
dda8d76d 7224 ? filedata->section_headers [(a).section].sh_addr + (a).offset \
1949de15
L
7225 : (a).offset)
7226
948f632f
DA
7227/* Find the nearest symbol at or below ADDR. Returns the symbol
7228 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7229
4d6ed7c8 7230static void
dda8d76d
NC
7231find_symbol_for_address (Filedata * filedata,
7232 Elf_Internal_Sym * symtab,
7233 unsigned long nsyms,
7234 const char * strtab,
7235 unsigned long strtab_size,
7236 struct absaddr addr,
7237 const char ** symname,
7238 bfd_vma * offset)
4d6ed7c8 7239{
d3ba0551 7240 bfd_vma dist = 0x100000;
2cf0635d 7241 Elf_Internal_Sym * sym;
948f632f
DA
7242 Elf_Internal_Sym * beg;
7243 Elf_Internal_Sym * end;
2cf0635d 7244 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7245
0b6ae522 7246 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7247 beg = symtab;
7248 end = symtab + nsyms;
0b6ae522 7249
948f632f 7250 while (beg < end)
4d6ed7c8 7251 {
948f632f
DA
7252 bfd_vma value;
7253
7254 sym = beg + (end - beg) / 2;
0b6ae522 7255
948f632f 7256 value = sym->st_value;
0b6ae522
DJ
7257 REMOVE_ARCH_BITS (value);
7258
948f632f 7259 if (sym->st_name != 0
4d6ed7c8 7260 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7261 && addr.offset >= value
7262 && addr.offset - value < dist)
4d6ed7c8
NC
7263 {
7264 best = sym;
0b6ae522 7265 dist = addr.offset - value;
4d6ed7c8
NC
7266 if (!dist)
7267 break;
7268 }
948f632f
DA
7269
7270 if (addr.offset < value)
7271 end = sym;
7272 else
7273 beg = sym + 1;
4d6ed7c8 7274 }
1b31d05e 7275
4d6ed7c8
NC
7276 if (best)
7277 {
57346661 7278 *symname = (best->st_name >= strtab_size
2b692964 7279 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7280 *offset = dist;
7281 return;
7282 }
1b31d05e 7283
4d6ed7c8
NC
7284 *symname = NULL;
7285 *offset = addr.offset;
7286}
7287
32ec8896 7288static /* signed */ int
948f632f
DA
7289symcmp (const void *p, const void *q)
7290{
7291 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7292 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7293
7294 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7295}
7296
7297/* Process the unwind section. */
7298
7299#include "unwind-ia64.h"
7300
7301struct ia64_unw_table_entry
7302{
7303 struct absaddr start;
7304 struct absaddr end;
7305 struct absaddr info;
7306};
7307
7308struct ia64_unw_aux_info
7309{
32ec8896
NC
7310 struct ia64_unw_table_entry * table; /* Unwind table. */
7311 unsigned long table_len; /* Length of unwind table. */
7312 unsigned char * info; /* Unwind info. */
7313 unsigned long info_size; /* Size of unwind info. */
7314 bfd_vma info_addr; /* Starting address of unwind info. */
7315 bfd_vma seg_base; /* Starting address of segment. */
7316 Elf_Internal_Sym * symtab; /* The symbol table. */
7317 unsigned long nsyms; /* Number of symbols. */
7318 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7319 unsigned long nfuns; /* Number of entries in funtab. */
7320 char * strtab; /* The string table. */
7321 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7322};
7323
32ec8896 7324static bfd_boolean
dda8d76d 7325dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7326{
2cf0635d 7327 struct ia64_unw_table_entry * tp;
948f632f 7328 unsigned long j, nfuns;
4d6ed7c8 7329 int in_body;
32ec8896 7330 bfd_boolean res = TRUE;
7036c0e1 7331
948f632f
DA
7332 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7333 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7334 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7335 aux->funtab[nfuns++] = aux->symtab[j];
7336 aux->nfuns = nfuns;
7337 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7338
4d6ed7c8
NC
7339 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7340 {
7341 bfd_vma stamp;
7342 bfd_vma offset;
2cf0635d
NC
7343 const unsigned char * dp;
7344 const unsigned char * head;
53774b7e 7345 const unsigned char * end;
2cf0635d 7346 const char * procname;
4d6ed7c8 7347
dda8d76d 7348 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7349 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7350
7351 fputs ("\n<", stdout);
7352
7353 if (procname)
7354 {
7355 fputs (procname, stdout);
7356
7357 if (offset)
7358 printf ("+%lx", (unsigned long) offset);
7359 }
7360
7361 fputs (">: [", stdout);
7362 print_vma (tp->start.offset, PREFIX_HEX);
7363 fputc ('-', stdout);
7364 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7365 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7366 (unsigned long) (tp->info.offset - aux->seg_base));
7367
53774b7e
NC
7368 /* PR 17531: file: 86232b32. */
7369 if (aux->info == NULL)
7370 continue;
7371
7372 /* PR 17531: file: 0997b4d1. */
7373 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
7374 {
7375 warn (_("Invalid offset %lx in table entry %ld\n"),
7376 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7377 res = FALSE;
53774b7e
NC
7378 continue;
7379 }
7380
1949de15 7381 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 7382 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7383
86f55779 7384 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7385 (unsigned) UNW_VER (stamp),
7386 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7387 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7388 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7389 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7390
7391 if (UNW_VER (stamp) != 1)
7392 {
2b692964 7393 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7394 continue;
7395 }
7396
7397 in_body = 0;
53774b7e
NC
7398 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7399 /* PR 17531: file: 16ceda89. */
7400 if (end > aux->info + aux->info_size)
7401 end = aux->info + aux->info_size;
7402 for (dp = head + 8; dp < end;)
b4477bc8 7403 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7404 }
948f632f
DA
7405
7406 free (aux->funtab);
32ec8896
NC
7407
7408 return res;
4d6ed7c8
NC
7409}
7410
53774b7e 7411static bfd_boolean
dda8d76d
NC
7412slurp_ia64_unwind_table (Filedata * filedata,
7413 struct ia64_unw_aux_info * aux,
7414 Elf_Internal_Shdr * sec)
4d6ed7c8 7415{
89fac5e3 7416 unsigned long size, nrelas, i;
2cf0635d
NC
7417 Elf_Internal_Phdr * seg;
7418 struct ia64_unw_table_entry * tep;
7419 Elf_Internal_Shdr * relsec;
7420 Elf_Internal_Rela * rela;
7421 Elf_Internal_Rela * rp;
7422 unsigned char * table;
7423 unsigned char * tp;
7424 Elf_Internal_Sym * sym;
7425 const char * relname;
4d6ed7c8 7426
53774b7e
NC
7427 aux->table_len = 0;
7428
4d6ed7c8
NC
7429 /* First, find the starting address of the segment that includes
7430 this section: */
7431
dda8d76d 7432 if (filedata->file_header.e_phnum)
4d6ed7c8 7433 {
dda8d76d 7434 if (! get_program_headers (filedata))
53774b7e 7435 return FALSE;
4d6ed7c8 7436
dda8d76d
NC
7437 for (seg = filedata->program_headers;
7438 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7439 ++seg)
4d6ed7c8
NC
7440 {
7441 if (seg->p_type != PT_LOAD)
7442 continue;
7443
7444 if (sec->sh_addr >= seg->p_vaddr
7445 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7446 {
7447 aux->seg_base = seg->p_vaddr;
7448 break;
7449 }
7450 }
4d6ed7c8
NC
7451 }
7452
7453 /* Second, build the unwind table from the contents of the unwind section: */
7454 size = sec->sh_size;
dda8d76d 7455 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7456 _("unwind table"));
a6e9f9df 7457 if (!table)
53774b7e 7458 return FALSE;
4d6ed7c8 7459
53774b7e 7460 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7461 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7462 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7463 tep = aux->table;
53774b7e
NC
7464
7465 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7466 {
7467 tep->start.section = SHN_UNDEF;
7468 tep->end.section = SHN_UNDEF;
7469 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7470 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7471 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7472 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7473 tep->start.offset += aux->seg_base;
7474 tep->end.offset += aux->seg_base;
7475 tep->info.offset += aux->seg_base;
7476 }
7477 free (table);
7478
41e92641 7479 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7480 for (relsec = filedata->section_headers;
7481 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7482 ++relsec)
7483 {
7484 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7485 || relsec->sh_info >= filedata->file_header.e_shnum
7486 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7487 continue;
7488
dda8d76d 7489 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7490 & rela, & nrelas))
53774b7e
NC
7491 {
7492 free (aux->table);
7493 aux->table = NULL;
7494 aux->table_len = 0;
7495 return FALSE;
7496 }
4d6ed7c8
NC
7497
7498 for (rp = rela; rp < rela + nrelas; ++rp)
7499 {
dda8d76d 7500 relname = elf_ia64_reloc_type (get_reloc_type (filedata, rp->r_info));
aca88567 7501 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 7502
82b1b41b
NC
7503 /* PR 17531: file: 9fa67536. */
7504 if (relname == NULL)
7505 {
dda8d76d
NC
7506 warn (_("Skipping unknown relocation type: %u\n"),
7507 get_reloc_type (filedata, rp->r_info));
82b1b41b
NC
7508 continue;
7509 }
948f632f 7510
0112cd26 7511 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7512 {
82b1b41b 7513 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7514 continue;
7515 }
7516
89fac5e3 7517 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7518
53774b7e
NC
7519 /* PR 17531: file: 5bc8d9bf. */
7520 if (i >= aux->table_len)
7521 {
7522 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7523 continue;
7524 }
7525
7526 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7527 {
7528 case 0:
7529 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7530 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7531 break;
7532 case 1:
7533 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7534 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7535 break;
7536 case 2:
7537 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7538 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7539 break;
7540 default:
7541 break;
7542 }
7543 }
7544
7545 free (rela);
7546 }
7547
53774b7e 7548 return TRUE;
4d6ed7c8
NC
7549}
7550
32ec8896 7551static bfd_boolean
dda8d76d 7552ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7553{
2cf0635d
NC
7554 Elf_Internal_Shdr * sec;
7555 Elf_Internal_Shdr * unwsec = NULL;
7556 Elf_Internal_Shdr * strsec;
89fac5e3 7557 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7558 struct ia64_unw_aux_info aux;
32ec8896 7559 bfd_boolean res = TRUE;
f1467e33 7560
4d6ed7c8
NC
7561 memset (& aux, 0, sizeof (aux));
7562
dda8d76d 7563 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7564 {
c256ffe7 7565 if (sec->sh_type == SHT_SYMTAB
dda8d76d 7566 && sec->sh_link < filedata->file_header.e_shnum)
4d6ed7c8 7567 {
dda8d76d 7568 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
4d6ed7c8 7569
dda8d76d 7570 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
7571 if (aux.strtab != NULL)
7572 {
7573 error (_("Multiple auxillary string tables encountered\n"));
7574 free (aux.strtab);
32ec8896 7575 res = FALSE;
4082ef84 7576 }
dda8d76d 7577 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
7578 1, strsec->sh_size,
7579 _("string table"));
c256ffe7 7580 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
7581 }
7582 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7583 unwcount++;
7584 }
7585
7586 if (!unwcount)
7587 printf (_("\nThere are no unwind sections in this file.\n"));
7588
7589 while (unwcount-- > 0)
7590 {
2cf0635d 7591 char * suffix;
579f31ac
JJ
7592 size_t len, len2;
7593
dda8d76d
NC
7594 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
7595 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
7596 if (sec->sh_type == SHT_IA_64_UNWIND)
7597 {
7598 unwsec = sec;
7599 break;
7600 }
4082ef84
NC
7601 /* We have already counted the number of SHT_IA64_UNWIND
7602 sections so the loop above should never fail. */
7603 assert (unwsec != NULL);
579f31ac
JJ
7604
7605 unwstart = i + 1;
7606 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7607
e4b17d5c
L
7608 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7609 {
7610 /* We need to find which section group it is in. */
4082ef84 7611 struct group_list * g;
e4b17d5c 7612
4082ef84
NC
7613 if (section_headers_groups == NULL
7614 || section_headers_groups [i] == NULL)
dda8d76d 7615 i = filedata->file_header.e_shnum;
4082ef84 7616 else
e4b17d5c 7617 {
4082ef84 7618 g = section_headers_groups [i]->root;
18bd398b 7619
4082ef84
NC
7620 for (; g != NULL; g = g->next)
7621 {
dda8d76d 7622 sec = filedata->section_headers + g->section_index;
e4b17d5c 7623
4082ef84
NC
7624 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7625 break;
7626 }
7627
7628 if (g == NULL)
dda8d76d 7629 i = filedata->file_header.e_shnum;
4082ef84 7630 }
e4b17d5c 7631 }
18bd398b 7632 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7633 {
18bd398b 7634 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7635 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7636 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7637 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7638 ++i, ++sec)
18bd398b
NC
7639 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7640 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7641 break;
7642 }
7643 else
7644 {
7645 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7646 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7647 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7648 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7649 suffix = "";
18bd398b 7650 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 7651 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7652 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7653 ++i, ++sec)
18bd398b
NC
7654 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
7655 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7656 break;
7657 }
7658
dda8d76d 7659 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
7660 {
7661 printf (_("\nCould not find unwind info section for "));
7662
dda8d76d 7663 if (filedata->string_table == NULL)
579f31ac
JJ
7664 printf ("%d", unwsec->sh_name);
7665 else
dda8d76d 7666 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
7667 }
7668 else
4d6ed7c8 7669 {
4d6ed7c8 7670 aux.info_addr = sec->sh_addr;
dda8d76d 7671 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
7672 sec->sh_size,
7673 _("unwind info"));
59245841 7674 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 7675
579f31ac 7676 printf (_("\nUnwind section "));
4d6ed7c8 7677
dda8d76d 7678 if (filedata->string_table == NULL)
579f31ac
JJ
7679 printf ("%d", unwsec->sh_name);
7680 else
dda8d76d 7681 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 7682
579f31ac 7683 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 7684 (unsigned long) unwsec->sh_offset,
89fac5e3 7685 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 7686
dda8d76d 7687 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 7688 && aux.table_len > 0)
dda8d76d 7689 dump_ia64_unwind (filedata, & aux);
579f31ac
JJ
7690
7691 if (aux.table)
7692 free ((char *) aux.table);
7693 if (aux.info)
7694 free ((char *) aux.info);
7695 aux.table = NULL;
7696 aux.info = NULL;
7697 }
4d6ed7c8 7698 }
4d6ed7c8 7699
4d6ed7c8
NC
7700 if (aux.symtab)
7701 free (aux.symtab);
7702 if (aux.strtab)
7703 free ((char *) aux.strtab);
32ec8896
NC
7704
7705 return res;
4d6ed7c8
NC
7706}
7707
3f5e193b 7708struct hppa_unw_table_entry
32ec8896
NC
7709{
7710 struct absaddr start;
7711 struct absaddr end;
7712 unsigned int Cannot_unwind:1; /* 0 */
7713 unsigned int Millicode:1; /* 1 */
7714 unsigned int Millicode_save_sr0:1; /* 2 */
7715 unsigned int Region_description:2; /* 3..4 */
7716 unsigned int reserved1:1; /* 5 */
7717 unsigned int Entry_SR:1; /* 6 */
7718 unsigned int Entry_FR:4; /* Number saved 7..10 */
7719 unsigned int Entry_GR:5; /* Number saved 11..15 */
7720 unsigned int Args_stored:1; /* 16 */
7721 unsigned int Variable_Frame:1; /* 17 */
7722 unsigned int Separate_Package_Body:1; /* 18 */
7723 unsigned int Frame_Extension_Millicode:1; /* 19 */
7724 unsigned int Stack_Overflow_Check:1; /* 20 */
7725 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
7726 unsigned int Ada_Region:1; /* 22 */
7727 unsigned int cxx_info:1; /* 23 */
7728 unsigned int cxx_try_catch:1; /* 24 */
7729 unsigned int sched_entry_seq:1; /* 25 */
7730 unsigned int reserved2:1; /* 26 */
7731 unsigned int Save_SP:1; /* 27 */
7732 unsigned int Save_RP:1; /* 28 */
7733 unsigned int Save_MRP_in_frame:1; /* 29 */
7734 unsigned int extn_ptr_defined:1; /* 30 */
7735 unsigned int Cleanup_defined:1; /* 31 */
7736
7737 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
7738 unsigned int HP_UX_interrupt_marker:1; /* 1 */
7739 unsigned int Large_frame:1; /* 2 */
7740 unsigned int Pseudo_SP_Set:1; /* 3 */
7741 unsigned int reserved4:1; /* 4 */
7742 unsigned int Total_frame_size:27; /* 5..31 */
7743};
3f5e193b 7744
57346661 7745struct hppa_unw_aux_info
948f632f 7746{
32ec8896
NC
7747 struct hppa_unw_table_entry * table; /* Unwind table. */
7748 unsigned long table_len; /* Length of unwind table. */
7749 bfd_vma seg_base; /* Starting address of segment. */
7750 Elf_Internal_Sym * symtab; /* The symbol table. */
7751 unsigned long nsyms; /* Number of symbols. */
7752 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7753 unsigned long nfuns; /* Number of entries in funtab. */
7754 char * strtab; /* The string table. */
7755 unsigned long strtab_size; /* Size of string table. */
948f632f 7756};
57346661 7757
32ec8896 7758static bfd_boolean
dda8d76d 7759dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 7760{
2cf0635d 7761 struct hppa_unw_table_entry * tp;
948f632f 7762 unsigned long j, nfuns;
32ec8896 7763 bfd_boolean res = TRUE;
948f632f
DA
7764
7765 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7766 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7767 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7768 aux->funtab[nfuns++] = aux->symtab[j];
7769 aux->nfuns = nfuns;
7770 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 7771
57346661
AM
7772 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7773 {
7774 bfd_vma offset;
2cf0635d 7775 const char * procname;
57346661 7776
dda8d76d 7777 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
7778 aux->strtab_size, tp->start, &procname,
7779 &offset);
7780
7781 fputs ("\n<", stdout);
7782
7783 if (procname)
7784 {
7785 fputs (procname, stdout);
7786
7787 if (offset)
7788 printf ("+%lx", (unsigned long) offset);
7789 }
7790
7791 fputs (">: [", stdout);
7792 print_vma (tp->start.offset, PREFIX_HEX);
7793 fputc ('-', stdout);
7794 print_vma (tp->end.offset, PREFIX_HEX);
7795 printf ("]\n\t");
7796
18bd398b
NC
7797#define PF(_m) if (tp->_m) printf (#_m " ");
7798#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
7799 PF(Cannot_unwind);
7800 PF(Millicode);
7801 PF(Millicode_save_sr0);
18bd398b 7802 /* PV(Region_description); */
57346661
AM
7803 PF(Entry_SR);
7804 PV(Entry_FR);
7805 PV(Entry_GR);
7806 PF(Args_stored);
7807 PF(Variable_Frame);
7808 PF(Separate_Package_Body);
7809 PF(Frame_Extension_Millicode);
7810 PF(Stack_Overflow_Check);
7811 PF(Two_Instruction_SP_Increment);
7812 PF(Ada_Region);
7813 PF(cxx_info);
7814 PF(cxx_try_catch);
7815 PF(sched_entry_seq);
7816 PF(Save_SP);
7817 PF(Save_RP);
7818 PF(Save_MRP_in_frame);
7819 PF(extn_ptr_defined);
7820 PF(Cleanup_defined);
7821 PF(MPE_XL_interrupt_marker);
7822 PF(HP_UX_interrupt_marker);
7823 PF(Large_frame);
7824 PF(Pseudo_SP_Set);
7825 PV(Total_frame_size);
7826#undef PF
7827#undef PV
7828 }
7829
18bd398b 7830 printf ("\n");
948f632f
DA
7831
7832 free (aux->funtab);
32ec8896
NC
7833
7834 return res;
57346661
AM
7835}
7836
32ec8896 7837static bfd_boolean
dda8d76d
NC
7838slurp_hppa_unwind_table (Filedata * filedata,
7839 struct hppa_unw_aux_info * aux,
7840 Elf_Internal_Shdr * sec)
57346661 7841{
1c0751b2 7842 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7843 Elf_Internal_Phdr * seg;
7844 struct hppa_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;
57346661 7852
57346661
AM
7853 /* First, find the starting address of the segment that includes
7854 this section. */
dda8d76d 7855 if (filedata->file_header.e_phnum)
57346661 7856 {
dda8d76d 7857 if (! get_program_headers (filedata))
32ec8896 7858 return FALSE;
57346661 7859
dda8d76d
NC
7860 for (seg = filedata->program_headers;
7861 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
7862 ++seg)
7863 {
7864 if (seg->p_type != PT_LOAD)
7865 continue;
7866
7867 if (sec->sh_addr >= seg->p_vaddr
7868 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7869 {
7870 aux->seg_base = seg->p_vaddr;
7871 break;
7872 }
7873 }
7874 }
7875
7876 /* Second, build the unwind table from the contents of the unwind
7877 section. */
7878 size = sec->sh_size;
dda8d76d 7879 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7880 _("unwind table"));
57346661 7881 if (!table)
32ec8896 7882 return FALSE;
57346661 7883
1c0751b2
DA
7884 unw_ent_size = 16;
7885 nentries = size / unw_ent_size;
7886 size = unw_ent_size * nentries;
57346661 7887
3f5e193b
NC
7888 tep = aux->table = (struct hppa_unw_table_entry *)
7889 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7890
1c0751b2 7891 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7892 {
7893 unsigned int tmp1, tmp2;
7894
7895 tep->start.section = SHN_UNDEF;
7896 tep->end.section = SHN_UNDEF;
7897
1c0751b2
DA
7898 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7899 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7900 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7901 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7902
7903 tep->start.offset += aux->seg_base;
7904 tep->end.offset += aux->seg_base;
57346661
AM
7905
7906 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
7907 tep->Millicode = (tmp1 >> 30) & 0x1;
7908 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
7909 tep->Region_description = (tmp1 >> 27) & 0x3;
7910 tep->reserved1 = (tmp1 >> 26) & 0x1;
7911 tep->Entry_SR = (tmp1 >> 25) & 0x1;
7912 tep->Entry_FR = (tmp1 >> 21) & 0xf;
7913 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7914 tep->Args_stored = (tmp1 >> 15) & 0x1;
7915 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7916 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7917 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7918 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7919 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7920 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7921 tep->cxx_info = (tmp1 >> 8) & 0x1;
7922 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7923 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7924 tep->reserved2 = (tmp1 >> 5) & 0x1;
7925 tep->Save_SP = (tmp1 >> 4) & 0x1;
7926 tep->Save_RP = (tmp1 >> 3) & 0x1;
7927 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7928 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7929 tep->Cleanup_defined = tmp1 & 0x1;
7930
7931 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7932 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7933 tep->Large_frame = (tmp2 >> 29) & 0x1;
7934 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7935 tep->reserved4 = (tmp2 >> 27) & 0x1;
7936 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7937 }
7938 free (table);
7939
7940 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
7941 for (relsec = filedata->section_headers;
7942 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
7943 ++relsec)
7944 {
7945 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7946 || relsec->sh_info >= filedata->file_header.e_shnum
7947 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
7948 continue;
7949
dda8d76d 7950 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 7951 & rela, & nrelas))
32ec8896 7952 return FALSE;
57346661
AM
7953
7954 for (rp = rela; rp < rela + nrelas; ++rp)
7955 {
dda8d76d 7956 relname = elf_hppa_reloc_type (get_reloc_type (filedata, rp->r_info));
aca88567 7957 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
7958
7959 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 7960 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
7961 {
7962 warn (_("Skipping unexpected relocation type %s\n"), relname);
7963 continue;
7964 }
7965
7966 i = rp->r_offset / unw_ent_size;
7967
89fac5e3 7968 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
7969 {
7970 case 0:
7971 aux->table[i].start.section = sym->st_shndx;
1e456d54 7972 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
7973 break;
7974 case 1:
7975 aux->table[i].end.section = sym->st_shndx;
1e456d54 7976 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
7977 break;
7978 default:
7979 break;
7980 }
7981 }
7982
7983 free (rela);
7984 }
7985
1c0751b2 7986 aux->table_len = nentries;
57346661 7987
32ec8896 7988 return TRUE;
57346661
AM
7989}
7990
32ec8896 7991static bfd_boolean
dda8d76d 7992hppa_process_unwind (Filedata * filedata)
57346661 7993{
57346661 7994 struct hppa_unw_aux_info aux;
2cf0635d
NC
7995 Elf_Internal_Shdr * unwsec = NULL;
7996 Elf_Internal_Shdr * strsec;
7997 Elf_Internal_Shdr * sec;
18bd398b 7998 unsigned long i;
32ec8896 7999 bfd_boolean res = TRUE;
57346661 8000
dda8d76d 8001 if (filedata->string_table == NULL)
32ec8896 8002 return FALSE;
1b31d05e
NC
8003
8004 memset (& aux, 0, sizeof (aux));
57346661 8005
dda8d76d 8006 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8007 {
c256ffe7 8008 if (sec->sh_type == SHT_SYMTAB
dda8d76d 8009 && sec->sh_link < filedata->file_header.e_shnum)
57346661 8010 {
dda8d76d 8011 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
57346661 8012
dda8d76d 8013 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
8014 if (aux.strtab != NULL)
8015 {
8016 error (_("Multiple auxillary string tables encountered\n"));
8017 free (aux.strtab);
32ec8896 8018 res = FALSE;
4082ef84 8019 }
dda8d76d 8020 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
8021 1, strsec->sh_size,
8022 _("string table"));
c256ffe7 8023 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 8024 }
18bd398b 8025 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8026 unwsec = sec;
8027 }
8028
8029 if (!unwsec)
8030 printf (_("\nThere are no unwind sections in this file.\n"));
8031
dda8d76d 8032 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8033 {
18bd398b 8034 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8035 {
d3a49aa8 8036 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size + 8);
dda8d76d 8037
d3a49aa8
AM
8038 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8039 "contains %lu entry:\n",
8040 "\nUnwind section '%s' at offset 0x%lx "
8041 "contains %lu entries:\n",
8042 num_unwind),
dda8d76d 8043 printable_section_name (filedata, sec),
57346661 8044 (unsigned long) sec->sh_offset,
d3a49aa8 8045 num_unwind);
57346661 8046
dda8d76d 8047 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896
NC
8048 res = FALSE;
8049
57346661 8050 if (aux.table_len > 0)
32ec8896 8051 {
dda8d76d 8052 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8053 res = FALSE;
8054 }
57346661
AM
8055
8056 if (aux.table)
8057 free ((char *) aux.table);
8058 aux.table = NULL;
8059 }
8060 }
8061
8062 if (aux.symtab)
8063 free (aux.symtab);
8064 if (aux.strtab)
8065 free ((char *) aux.strtab);
32ec8896
NC
8066
8067 return res;
57346661
AM
8068}
8069
0b6ae522
DJ
8070struct arm_section
8071{
a734115a
NC
8072 unsigned char * data; /* The unwind data. */
8073 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8074 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8075 unsigned long nrelas; /* The number of relocations. */
8076 unsigned int rel_type; /* REL or RELA ? */
8077 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8078};
8079
8080struct arm_unw_aux_info
8081{
dda8d76d 8082 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8083 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8084 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8085 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8086 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8087 char * strtab; /* The file's string table. */
8088 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8089};
8090
8091static const char *
dda8d76d
NC
8092arm_print_vma_and_name (Filedata * filedata,
8093 struct arm_unw_aux_info * aux,
8094 bfd_vma fn,
8095 struct absaddr addr)
0b6ae522
DJ
8096{
8097 const char *procname;
8098 bfd_vma sym_offset;
8099
8100 if (addr.section == SHN_UNDEF)
8101 addr.offset = fn;
8102
dda8d76d 8103 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8104 aux->strtab_size, addr, &procname,
8105 &sym_offset);
8106
8107 print_vma (fn, PREFIX_HEX);
8108
8109 if (procname)
8110 {
8111 fputs (" <", stdout);
8112 fputs (procname, stdout);
8113
8114 if (sym_offset)
8115 printf ("+0x%lx", (unsigned long) sym_offset);
8116 fputc ('>', stdout);
8117 }
8118
8119 return procname;
8120}
8121
8122static void
8123arm_free_section (struct arm_section *arm_sec)
8124{
8125 if (arm_sec->data != NULL)
8126 free (arm_sec->data);
8127
8128 if (arm_sec->rela != NULL)
8129 free (arm_sec->rela);
8130}
8131
a734115a
NC
8132/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8133 cached section and install SEC instead.
8134 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8135 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8136 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8137 relocation's offset in ADDR.
1b31d05e
NC
8138 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8139 into the string table of the symbol associated with the reloc. If no
8140 reloc was applied store -1 there.
8141 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8142
8143static bfd_boolean
dda8d76d
NC
8144get_unwind_section_word (Filedata * filedata,
8145 struct arm_unw_aux_info * aux,
1b31d05e
NC
8146 struct arm_section * arm_sec,
8147 Elf_Internal_Shdr * sec,
8148 bfd_vma word_offset,
8149 unsigned int * wordp,
8150 struct absaddr * addr,
8151 bfd_vma * sym_name)
0b6ae522
DJ
8152{
8153 Elf_Internal_Rela *rp;
8154 Elf_Internal_Sym *sym;
8155 const char * relname;
8156 unsigned int word;
8157 bfd_boolean wrapped;
8158
e0a31db1
NC
8159 if (sec == NULL || arm_sec == NULL)
8160 return FALSE;
8161
0b6ae522
DJ
8162 addr->section = SHN_UNDEF;
8163 addr->offset = 0;
8164
1b31d05e
NC
8165 if (sym_name != NULL)
8166 *sym_name = (bfd_vma) -1;
8167
a734115a 8168 /* If necessary, update the section cache. */
0b6ae522
DJ
8169 if (sec != arm_sec->sec)
8170 {
8171 Elf_Internal_Shdr *relsec;
8172
8173 arm_free_section (arm_sec);
8174
8175 arm_sec->sec = sec;
dda8d76d 8176 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8177 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8178 arm_sec->rela = NULL;
8179 arm_sec->nrelas = 0;
8180
dda8d76d
NC
8181 for (relsec = filedata->section_headers;
8182 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8183 ++relsec)
8184 {
dda8d76d
NC
8185 if (relsec->sh_info >= filedata->file_header.e_shnum
8186 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8187 /* PR 15745: Check the section type as well. */
8188 || (relsec->sh_type != SHT_REL
8189 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8190 continue;
8191
a734115a 8192 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8193 if (relsec->sh_type == SHT_REL)
8194 {
dda8d76d 8195 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8196 relsec->sh_size,
8197 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8198 return FALSE;
0b6ae522 8199 }
1ae40aa4 8200 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8201 {
dda8d76d 8202 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8203 relsec->sh_size,
8204 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8205 return FALSE;
0b6ae522 8206 }
1ae40aa4 8207 break;
0b6ae522
DJ
8208 }
8209
8210 arm_sec->next_rela = arm_sec->rela;
8211 }
8212
a734115a 8213 /* If there is no unwind data we can do nothing. */
0b6ae522 8214 if (arm_sec->data == NULL)
a734115a 8215 return FALSE;
0b6ae522 8216
e0a31db1 8217 /* If the offset is invalid then fail. */
f32ba729
NC
8218 if (/* PR 21343 *//* PR 18879 */
8219 sec->sh_size < 4
8220 || word_offset > (sec->sh_size - 4)
1a915552 8221 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8222 return FALSE;
8223
a734115a 8224 /* Get the word at the required offset. */
0b6ae522
DJ
8225 word = byte_get (arm_sec->data + word_offset, 4);
8226
0eff7165
NC
8227 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8228 if (arm_sec->rela == NULL)
8229 {
8230 * wordp = word;
8231 return TRUE;
8232 }
8233
a734115a 8234 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8235 wrapped = FALSE;
8236 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8237 {
8238 bfd_vma prelval, offset;
8239
8240 if (rp->r_offset > word_offset && !wrapped)
8241 {
8242 rp = arm_sec->rela;
8243 wrapped = TRUE;
8244 }
8245 if (rp->r_offset > word_offset)
8246 break;
8247
8248 if (rp->r_offset & 3)
8249 {
8250 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8251 (unsigned long) rp->r_offset);
8252 continue;
8253 }
8254
8255 if (rp->r_offset < word_offset)
8256 continue;
8257
74e1a04b
NC
8258 /* PR 17531: file: 027-161405-0.004 */
8259 if (aux->symtab == NULL)
8260 continue;
8261
0b6ae522
DJ
8262 if (arm_sec->rel_type == SHT_REL)
8263 {
8264 offset = word & 0x7fffffff;
8265 if (offset & 0x40000000)
8266 offset |= ~ (bfd_vma) 0x7fffffff;
8267 }
a734115a 8268 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8269 offset = rp->r_addend;
a734115a 8270 else
74e1a04b
NC
8271 {
8272 error (_("Unknown section relocation type %d encountered\n"),
8273 arm_sec->rel_type);
8274 break;
8275 }
0b6ae522 8276
071436c6
NC
8277 /* PR 17531 file: 027-1241568-0.004. */
8278 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8279 {
8280 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8281 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8282 break;
8283 }
8284
8285 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8286 offset += sym->st_value;
8287 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8288
a734115a 8289 /* Check that we are processing the expected reloc type. */
dda8d76d 8290 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8291 {
8292 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8293 if (relname == NULL)
8294 {
8295 warn (_("Skipping unknown ARM relocation type: %d\n"),
8296 (int) ELF32_R_TYPE (rp->r_info));
8297 continue;
8298 }
a734115a
NC
8299
8300 if (streq (relname, "R_ARM_NONE"))
8301 continue;
0b4362b0 8302
a734115a
NC
8303 if (! streq (relname, "R_ARM_PREL31"))
8304 {
071436c6 8305 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8306 continue;
8307 }
8308 }
dda8d76d 8309 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8310 {
8311 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8312 if (relname == NULL)
8313 {
8314 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8315 (int) ELF32_R_TYPE (rp->r_info));
8316 continue;
8317 }
0b4362b0 8318
a734115a
NC
8319 if (streq (relname, "R_C6000_NONE"))
8320 continue;
8321
8322 if (! streq (relname, "R_C6000_PREL31"))
8323 {
071436c6 8324 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8325 continue;
8326 }
8327
8328 prelval >>= 1;
8329 }
8330 else
74e1a04b
NC
8331 {
8332 /* This function currently only supports ARM and TI unwinders. */
8333 warn (_("Only TI and ARM unwinders are currently supported\n"));
8334 break;
8335 }
fa197c1c 8336
0b6ae522
DJ
8337 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8338 addr->section = sym->st_shndx;
8339 addr->offset = offset;
74e1a04b 8340
1b31d05e
NC
8341 if (sym_name)
8342 * sym_name = sym->st_name;
0b6ae522
DJ
8343 break;
8344 }
8345
8346 *wordp = word;
8347 arm_sec->next_rela = rp;
8348
a734115a 8349 return TRUE;
0b6ae522
DJ
8350}
8351
a734115a
NC
8352static const char *tic6x_unwind_regnames[16] =
8353{
0b4362b0
RM
8354 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8355 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8356 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8357};
fa197c1c 8358
0b6ae522 8359static void
fa197c1c 8360decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8361{
fa197c1c
PB
8362 int i;
8363
8364 for (i = 12; mask; mask >>= 1, i--)
8365 {
8366 if (mask & 1)
8367 {
8368 fputs (tic6x_unwind_regnames[i], stdout);
8369 if (mask > 1)
8370 fputs (", ", stdout);
8371 }
8372 }
8373}
0b6ae522
DJ
8374
8375#define ADVANCE \
8376 if (remaining == 0 && more_words) \
8377 { \
8378 data_offset += 4; \
dda8d76d 8379 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8380 data_offset, & word, & addr, NULL)) \
32ec8896 8381 return FALSE; \
0b6ae522
DJ
8382 remaining = 4; \
8383 more_words--; \
8384 } \
8385
8386#define GET_OP(OP) \
8387 ADVANCE; \
8388 if (remaining) \
8389 { \
8390 remaining--; \
8391 (OP) = word >> 24; \
8392 word <<= 8; \
8393 } \
8394 else \
8395 { \
2b692964 8396 printf (_("[Truncated opcode]\n")); \
32ec8896 8397 return FALSE; \
0b6ae522 8398 } \
cc5914eb 8399 printf ("0x%02x ", OP)
0b6ae522 8400
32ec8896 8401static bfd_boolean
dda8d76d
NC
8402decode_arm_unwind_bytecode (Filedata * filedata,
8403 struct arm_unw_aux_info * aux,
948f632f
DA
8404 unsigned int word,
8405 unsigned int remaining,
8406 unsigned int more_words,
8407 bfd_vma data_offset,
8408 Elf_Internal_Shdr * data_sec,
8409 struct arm_section * data_arm_sec)
fa197c1c
PB
8410{
8411 struct absaddr addr;
32ec8896 8412 bfd_boolean res = TRUE;
0b6ae522
DJ
8413
8414 /* Decode the unwinding instructions. */
8415 while (1)
8416 {
8417 unsigned int op, op2;
8418
8419 ADVANCE;
8420 if (remaining == 0)
8421 break;
8422 remaining--;
8423 op = word >> 24;
8424 word <<= 8;
8425
cc5914eb 8426 printf (" 0x%02x ", op);
0b6ae522
DJ
8427
8428 if ((op & 0xc0) == 0x00)
8429 {
8430 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8431
cc5914eb 8432 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8433 }
8434 else if ((op & 0xc0) == 0x40)
8435 {
8436 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8437
cc5914eb 8438 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8439 }
8440 else if ((op & 0xf0) == 0x80)
8441 {
8442 GET_OP (op2);
8443 if (op == 0x80 && op2 == 0)
8444 printf (_("Refuse to unwind"));
8445 else
8446 {
8447 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8448 bfd_boolean first = TRUE;
0b6ae522 8449 int i;
2b692964 8450
0b6ae522
DJ
8451 printf ("pop {");
8452 for (i = 0; i < 12; i++)
8453 if (mask & (1 << i))
8454 {
8455 if (first)
32ec8896 8456 first = FALSE;
0b6ae522
DJ
8457 else
8458 printf (", ");
8459 printf ("r%d", 4 + i);
8460 }
8461 printf ("}");
8462 }
8463 }
8464 else if ((op & 0xf0) == 0x90)
8465 {
8466 if (op == 0x9d || op == 0x9f)
8467 printf (_(" [Reserved]"));
8468 else
cc5914eb 8469 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8470 }
8471 else if ((op & 0xf0) == 0xa0)
8472 {
8473 int end = 4 + (op & 0x07);
32ec8896 8474 bfd_boolean first = TRUE;
0b6ae522 8475 int i;
61865e30 8476
0b6ae522
DJ
8477 printf (" pop {");
8478 for (i = 4; i <= end; i++)
8479 {
8480 if (first)
32ec8896 8481 first = FALSE;
0b6ae522
DJ
8482 else
8483 printf (", ");
8484 printf ("r%d", i);
8485 }
8486 if (op & 0x08)
8487 {
1b31d05e 8488 if (!first)
0b6ae522
DJ
8489 printf (", ");
8490 printf ("r14");
8491 }
8492 printf ("}");
8493 }
8494 else if (op == 0xb0)
8495 printf (_(" finish"));
8496 else if (op == 0xb1)
8497 {
8498 GET_OP (op2);
8499 if (op2 == 0 || (op2 & 0xf0) != 0)
8500 printf (_("[Spare]"));
8501 else
8502 {
8503 unsigned int mask = op2 & 0x0f;
32ec8896 8504 bfd_boolean first = TRUE;
0b6ae522 8505 int i;
61865e30 8506
0b6ae522
DJ
8507 printf ("pop {");
8508 for (i = 0; i < 12; i++)
8509 if (mask & (1 << i))
8510 {
8511 if (first)
32ec8896 8512 first = FALSE;
0b6ae522
DJ
8513 else
8514 printf (", ");
8515 printf ("r%d", i);
8516 }
8517 printf ("}");
8518 }
8519 }
8520 else if (op == 0xb2)
8521 {
b115cf96 8522 unsigned char buf[9];
0b6ae522
DJ
8523 unsigned int i, len;
8524 unsigned long offset;
61865e30 8525
b115cf96 8526 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8527 {
8528 GET_OP (buf[i]);
8529 if ((buf[i] & 0x80) == 0)
8530 break;
8531 }
4082ef84 8532 if (i == sizeof (buf))
32ec8896
NC
8533 {
8534 error (_("corrupt change to vsp"));
8535 res = FALSE;
8536 }
4082ef84
NC
8537 else
8538 {
8539 offset = read_uleb128 (buf, &len, buf + i + 1);
8540 assert (len == i + 1);
8541 offset = offset * 4 + 0x204;
8542 printf ("vsp = vsp + %ld", offset);
8543 }
0b6ae522 8544 }
61865e30 8545 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8546 {
61865e30
NC
8547 unsigned int first, last;
8548
8549 GET_OP (op2);
8550 first = op2 >> 4;
8551 last = op2 & 0x0f;
8552 if (op == 0xc8)
8553 first = first + 16;
8554 printf ("pop {D%d", first);
8555 if (last)
8556 printf ("-D%d", first + last);
8557 printf ("}");
8558 }
8559 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8560 {
8561 unsigned int count = op & 0x07;
8562
8563 printf ("pop {D8");
8564 if (count)
8565 printf ("-D%d", 8 + count);
8566 printf ("}");
8567 }
8568 else if (op >= 0xc0 && op <= 0xc5)
8569 {
8570 unsigned int count = op & 0x07;
8571
8572 printf (" pop {wR10");
8573 if (count)
8574 printf ("-wR%d", 10 + count);
8575 printf ("}");
8576 }
8577 else if (op == 0xc6)
8578 {
8579 unsigned int first, last;
8580
8581 GET_OP (op2);
8582 first = op2 >> 4;
8583 last = op2 & 0x0f;
8584 printf ("pop {wR%d", first);
8585 if (last)
8586 printf ("-wR%d", first + last);
8587 printf ("}");
8588 }
8589 else if (op == 0xc7)
8590 {
8591 GET_OP (op2);
8592 if (op2 == 0 || (op2 & 0xf0) != 0)
8593 printf (_("[Spare]"));
0b6ae522
DJ
8594 else
8595 {
61865e30 8596 unsigned int mask = op2 & 0x0f;
32ec8896 8597 bfd_boolean first = TRUE;
61865e30
NC
8598 int i;
8599
8600 printf ("pop {");
8601 for (i = 0; i < 4; i++)
8602 if (mask & (1 << i))
8603 {
8604 if (first)
32ec8896 8605 first = FALSE;
61865e30
NC
8606 else
8607 printf (", ");
8608 printf ("wCGR%d", i);
8609 }
8610 printf ("}");
0b6ae522
DJ
8611 }
8612 }
61865e30 8613 else
32ec8896
NC
8614 {
8615 printf (_(" [unsupported opcode]"));
8616 res = FALSE;
8617 }
8618
0b6ae522
DJ
8619 printf ("\n");
8620 }
32ec8896
NC
8621
8622 return res;
fa197c1c
PB
8623}
8624
32ec8896 8625static bfd_boolean
dda8d76d
NC
8626decode_tic6x_unwind_bytecode (Filedata * filedata,
8627 struct arm_unw_aux_info * aux,
948f632f
DA
8628 unsigned int word,
8629 unsigned int remaining,
8630 unsigned int more_words,
8631 bfd_vma data_offset,
8632 Elf_Internal_Shdr * data_sec,
8633 struct arm_section * data_arm_sec)
fa197c1c
PB
8634{
8635 struct absaddr addr;
8636
8637 /* Decode the unwinding instructions. */
8638 while (1)
8639 {
8640 unsigned int op, op2;
8641
8642 ADVANCE;
8643 if (remaining == 0)
8644 break;
8645 remaining--;
8646 op = word >> 24;
8647 word <<= 8;
8648
9cf03b7e 8649 printf (" 0x%02x ", op);
fa197c1c
PB
8650
8651 if ((op & 0xc0) == 0x00)
8652 {
8653 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 8654 printf (" sp = sp + %d", offset);
fa197c1c
PB
8655 }
8656 else if ((op & 0xc0) == 0x80)
8657 {
8658 GET_OP (op2);
8659 if (op == 0x80 && op2 == 0)
8660 printf (_("Refuse to unwind"));
8661 else
8662 {
8663 unsigned int mask = ((op & 0x1f) << 8) | op2;
8664 if (op & 0x20)
8665 printf ("pop compact {");
8666 else
8667 printf ("pop {");
8668
8669 decode_tic6x_unwind_regmask (mask);
8670 printf("}");
8671 }
8672 }
8673 else if ((op & 0xf0) == 0xc0)
8674 {
8675 unsigned int reg;
8676 unsigned int nregs;
8677 unsigned int i;
8678 const char *name;
a734115a
NC
8679 struct
8680 {
32ec8896
NC
8681 unsigned int offset;
8682 unsigned int reg;
fa197c1c
PB
8683 } regpos[16];
8684
8685 /* Scan entire instruction first so that GET_OP output is not
8686 interleaved with disassembly. */
8687 nregs = 0;
8688 for (i = 0; nregs < (op & 0xf); i++)
8689 {
8690 GET_OP (op2);
8691 reg = op2 >> 4;
8692 if (reg != 0xf)
8693 {
8694 regpos[nregs].offset = i * 2;
8695 regpos[nregs].reg = reg;
8696 nregs++;
8697 }
8698
8699 reg = op2 & 0xf;
8700 if (reg != 0xf)
8701 {
8702 regpos[nregs].offset = i * 2 + 1;
8703 regpos[nregs].reg = reg;
8704 nregs++;
8705 }
8706 }
8707
8708 printf (_("pop frame {"));
8709 reg = nregs - 1;
8710 for (i = i * 2; i > 0; i--)
8711 {
8712 if (regpos[reg].offset == i - 1)
8713 {
8714 name = tic6x_unwind_regnames[regpos[reg].reg];
8715 if (reg > 0)
8716 reg--;
8717 }
8718 else
8719 name = _("[pad]");
8720
8721 fputs (name, stdout);
8722 if (i > 1)
8723 printf (", ");
8724 }
8725
8726 printf ("}");
8727 }
8728 else if (op == 0xd0)
8729 printf (" MOV FP, SP");
8730 else if (op == 0xd1)
8731 printf (" __c6xabi_pop_rts");
8732 else if (op == 0xd2)
8733 {
8734 unsigned char buf[9];
8735 unsigned int i, len;
8736 unsigned long offset;
a734115a 8737
fa197c1c
PB
8738 for (i = 0; i < sizeof (buf); i++)
8739 {
8740 GET_OP (buf[i]);
8741 if ((buf[i] & 0x80) == 0)
8742 break;
8743 }
0eff7165
NC
8744 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
8745 if (i == sizeof (buf))
8746 {
0eff7165 8747 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 8748 return FALSE;
0eff7165 8749 }
948f632f 8750
f6f0e17b 8751 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
8752 assert (len == i + 1);
8753 offset = offset * 8 + 0x408;
8754 printf (_("sp = sp + %ld"), offset);
8755 }
8756 else if ((op & 0xf0) == 0xe0)
8757 {
8758 if ((op & 0x0f) == 7)
8759 printf (" RETURN");
8760 else
8761 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
8762 }
8763 else
8764 {
8765 printf (_(" [unsupported opcode]"));
8766 }
8767 putchar ('\n');
8768 }
32ec8896
NC
8769
8770 return TRUE;
fa197c1c
PB
8771}
8772
8773static bfd_vma
dda8d76d 8774arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
8775{
8776 bfd_vma offset;
8777
8778 offset = word & 0x7fffffff;
8779 if (offset & 0x40000000)
8780 offset |= ~ (bfd_vma) 0x7fffffff;
8781
dda8d76d 8782 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
8783 offset <<= 1;
8784
8785 return offset + where;
8786}
8787
32ec8896 8788static bfd_boolean
dda8d76d
NC
8789decode_arm_unwind (Filedata * filedata,
8790 struct arm_unw_aux_info * aux,
1b31d05e
NC
8791 unsigned int word,
8792 unsigned int remaining,
8793 bfd_vma data_offset,
8794 Elf_Internal_Shdr * data_sec,
8795 struct arm_section * data_arm_sec)
fa197c1c
PB
8796{
8797 int per_index;
8798 unsigned int more_words = 0;
37e14bc3 8799 struct absaddr addr;
1b31d05e 8800 bfd_vma sym_name = (bfd_vma) -1;
97953bab 8801 bfd_boolean res = TRUE;
fa197c1c
PB
8802
8803 if (remaining == 0)
8804 {
1b31d05e
NC
8805 /* Fetch the first word.
8806 Note - when decoding an object file the address extracted
8807 here will always be 0. So we also pass in the sym_name
8808 parameter so that we can find the symbol associated with
8809 the personality routine. */
dda8d76d 8810 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 8811 & word, & addr, & sym_name))
32ec8896 8812 return FALSE;
1b31d05e 8813
fa197c1c
PB
8814 remaining = 4;
8815 }
8816
8817 if ((word & 0x80000000) == 0)
8818 {
8819 /* Expand prel31 for personality routine. */
8820 bfd_vma fn;
8821 const char *procname;
8822
dda8d76d 8823 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 8824 printf (_(" Personality routine: "));
1b31d05e
NC
8825 if (fn == 0
8826 && addr.section == SHN_UNDEF && addr.offset == 0
8827 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
8828 {
8829 procname = aux->strtab + sym_name;
8830 print_vma (fn, PREFIX_HEX);
8831 if (procname)
8832 {
8833 fputs (" <", stdout);
8834 fputs (procname, stdout);
8835 fputc ('>', stdout);
8836 }
8837 }
8838 else
dda8d76d 8839 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
8840 fputc ('\n', stdout);
8841
8842 /* The GCC personality routines use the standard compact
8843 encoding, starting with one byte giving the number of
8844 words. */
8845 if (procname != NULL
8846 && (const_strneq (procname, "__gcc_personality_v0")
8847 || const_strneq (procname, "__gxx_personality_v0")
8848 || const_strneq (procname, "__gcj_personality_v0")
8849 || const_strneq (procname, "__gnu_objc_personality_v0")))
8850 {
8851 remaining = 0;
8852 more_words = 1;
8853 ADVANCE;
8854 if (!remaining)
8855 {
8856 printf (_(" [Truncated data]\n"));
32ec8896 8857 return FALSE;
fa197c1c
PB
8858 }
8859 more_words = word >> 24;
8860 word <<= 8;
8861 remaining--;
8862 per_index = -1;
8863 }
8864 else
32ec8896 8865 return TRUE;
fa197c1c
PB
8866 }
8867 else
8868 {
1b31d05e 8869 /* ARM EHABI Section 6.3:
0b4362b0 8870
1b31d05e 8871 An exception-handling table entry for the compact model looks like:
0b4362b0 8872
1b31d05e
NC
8873 31 30-28 27-24 23-0
8874 -- ----- ----- ----
8875 1 0 index Data for personalityRoutine[index] */
8876
dda8d76d 8877 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 8878 && (word & 0x70000000))
32ec8896
NC
8879 {
8880 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
8881 res = FALSE;
8882 }
1b31d05e 8883
fa197c1c 8884 per_index = (word >> 24) & 0x7f;
1b31d05e 8885 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
8886 if (per_index == 0)
8887 {
8888 more_words = 0;
8889 word <<= 8;
8890 remaining--;
8891 }
8892 else if (per_index < 3)
8893 {
8894 more_words = (word >> 16) & 0xff;
8895 word <<= 16;
8896 remaining -= 2;
8897 }
8898 }
8899
dda8d76d 8900 switch (filedata->file_header.e_machine)
fa197c1c
PB
8901 {
8902 case EM_ARM:
8903 if (per_index < 3)
8904 {
dda8d76d 8905 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
8906 data_offset, data_sec, data_arm_sec))
8907 res = FALSE;
fa197c1c
PB
8908 }
8909 else
1b31d05e
NC
8910 {
8911 warn (_("Unknown ARM compact model index encountered\n"));
8912 printf (_(" [reserved]\n"));
32ec8896 8913 res = FALSE;
1b31d05e 8914 }
fa197c1c
PB
8915 break;
8916
8917 case EM_TI_C6000:
8918 if (per_index < 3)
8919 {
dda8d76d 8920 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
8921 data_offset, data_sec, data_arm_sec))
8922 res = FALSE;
fa197c1c
PB
8923 }
8924 else if (per_index < 5)
8925 {
8926 if (((word >> 17) & 0x7f) == 0x7f)
8927 printf (_(" Restore stack from frame pointer\n"));
8928 else
8929 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
8930 printf (_(" Registers restored: "));
8931 if (per_index == 4)
8932 printf (" (compact) ");
8933 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
8934 putchar ('\n');
8935 printf (_(" Return register: %s\n"),
8936 tic6x_unwind_regnames[word & 0xf]);
8937 }
8938 else
1b31d05e 8939 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
8940 break;
8941
8942 default:
74e1a04b 8943 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 8944 filedata->file_header.e_machine);
32ec8896 8945 res = FALSE;
fa197c1c 8946 }
0b6ae522
DJ
8947
8948 /* Decode the descriptors. Not implemented. */
32ec8896
NC
8949
8950 return res;
0b6ae522
DJ
8951}
8952
32ec8896 8953static bfd_boolean
dda8d76d
NC
8954dump_arm_unwind (Filedata * filedata,
8955 struct arm_unw_aux_info * aux,
8956 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
8957{
8958 struct arm_section exidx_arm_sec, extab_arm_sec;
8959 unsigned int i, exidx_len;
948f632f 8960 unsigned long j, nfuns;
32ec8896 8961 bfd_boolean res = TRUE;
0b6ae522
DJ
8962
8963 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
8964 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
8965 exidx_len = exidx_sec->sh_size / 8;
8966
948f632f
DA
8967 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8968 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8969 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8970 aux->funtab[nfuns++] = aux->symtab[j];
8971 aux->nfuns = nfuns;
8972 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8973
0b6ae522
DJ
8974 for (i = 0; i < exidx_len; i++)
8975 {
8976 unsigned int exidx_fn, exidx_entry;
8977 struct absaddr fn_addr, entry_addr;
8978 bfd_vma fn;
8979
8980 fputc ('\n', stdout);
8981
dda8d76d 8982 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 8983 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 8984 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 8985 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 8986 {
948f632f 8987 free (aux->funtab);
1b31d05e
NC
8988 arm_free_section (& exidx_arm_sec);
8989 arm_free_section (& extab_arm_sec);
32ec8896 8990 return FALSE;
0b6ae522
DJ
8991 }
8992
83c257ca
NC
8993 /* ARM EHABI, Section 5:
8994 An index table entry consists of 2 words.
8995 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
8996 if (exidx_fn & 0x80000000)
32ec8896
NC
8997 {
8998 warn (_("corrupt index table entry: %x\n"), exidx_fn);
8999 res = FALSE;
9000 }
83c257ca 9001
dda8d76d 9002 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9003
dda8d76d 9004 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9005 fputs (": ", stdout);
9006
9007 if (exidx_entry == 1)
9008 {
9009 print_vma (exidx_entry, PREFIX_HEX);
9010 fputs (" [cantunwind]\n", stdout);
9011 }
9012 else if (exidx_entry & 0x80000000)
9013 {
9014 print_vma (exidx_entry, PREFIX_HEX);
9015 fputc ('\n', stdout);
dda8d76d 9016 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9017 }
9018 else
9019 {
8f73510c 9020 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9021 Elf_Internal_Shdr *table_sec;
9022
9023 fputs ("@", stdout);
dda8d76d 9024 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9025 print_vma (table, PREFIX_HEX);
9026 printf ("\n");
9027
9028 /* Locate the matching .ARM.extab. */
9029 if (entry_addr.section != SHN_UNDEF
dda8d76d 9030 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9031 {
dda8d76d 9032 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9033 table_offset = entry_addr.offset;
1a915552
NC
9034 /* PR 18879 */
9035 if (table_offset > table_sec->sh_size
9036 || ((bfd_signed_vma) table_offset) < 0)
9037 {
9038 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9039 (unsigned long) table_offset,
dda8d76d 9040 printable_section_name (filedata, table_sec));
32ec8896 9041 res = FALSE;
1a915552
NC
9042 continue;
9043 }
0b6ae522
DJ
9044 }
9045 else
9046 {
dda8d76d 9047 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9048 if (table_sec != NULL)
9049 table_offset = table - table_sec->sh_addr;
9050 }
32ec8896 9051
0b6ae522
DJ
9052 if (table_sec == NULL)
9053 {
9054 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9055 (unsigned long) table);
32ec8896 9056 res = FALSE;
0b6ae522
DJ
9057 continue;
9058 }
32ec8896 9059
dda8d76d 9060 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9061 &extab_arm_sec))
9062 res = FALSE;
0b6ae522
DJ
9063 }
9064 }
9065
9066 printf ("\n");
9067
948f632f 9068 free (aux->funtab);
0b6ae522
DJ
9069 arm_free_section (&exidx_arm_sec);
9070 arm_free_section (&extab_arm_sec);
32ec8896
NC
9071
9072 return res;
0b6ae522
DJ
9073}
9074
fa197c1c 9075/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9076
32ec8896 9077static bfd_boolean
dda8d76d 9078arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9079{
9080 struct arm_unw_aux_info aux;
9081 Elf_Internal_Shdr *unwsec = NULL;
9082 Elf_Internal_Shdr *strsec;
9083 Elf_Internal_Shdr *sec;
9084 unsigned long i;
fa197c1c 9085 unsigned int sec_type;
32ec8896 9086 bfd_boolean res = TRUE;
0b6ae522 9087
dda8d76d 9088 switch (filedata->file_header.e_machine)
fa197c1c
PB
9089 {
9090 case EM_ARM:
9091 sec_type = SHT_ARM_EXIDX;
9092 break;
9093
9094 case EM_TI_C6000:
9095 sec_type = SHT_C6000_UNWIND;
9096 break;
9097
0b4362b0 9098 default:
74e1a04b 9099 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9100 filedata->file_header.e_machine);
32ec8896 9101 return FALSE;
fa197c1c
PB
9102 }
9103
dda8d76d 9104 if (filedata->string_table == NULL)
32ec8896 9105 return FALSE;
1b31d05e
NC
9106
9107 memset (& aux, 0, sizeof (aux));
dda8d76d 9108 aux.filedata = filedata;
0b6ae522 9109
dda8d76d 9110 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9111 {
dda8d76d 9112 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < filedata->file_header.e_shnum)
0b6ae522 9113 {
dda8d76d 9114 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
0b6ae522 9115
dda8d76d 9116 strsec = filedata->section_headers + sec->sh_link;
74e1a04b
NC
9117
9118 /* PR binutils/17531 file: 011-12666-0.004. */
9119 if (aux.strtab != NULL)
9120 {
4082ef84 9121 error (_("Multiple string tables found in file.\n"));
74e1a04b 9122 free (aux.strtab);
32ec8896 9123 res = FALSE;
74e1a04b 9124 }
dda8d76d 9125 aux.strtab = get_data (NULL, filedata, strsec->sh_offset,
0b6ae522
DJ
9126 1, strsec->sh_size, _("string table"));
9127 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
9128 }
fa197c1c 9129 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9130 unwsec = sec;
9131 }
9132
1b31d05e 9133 if (unwsec == NULL)
0b6ae522 9134 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9135 else
dda8d76d 9136 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9137 {
9138 if (sec->sh_type == sec_type)
9139 {
d3a49aa8
AM
9140 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9141 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9142 "contains %lu entry:\n",
9143 "\nUnwind section '%s' at offset 0x%lx "
9144 "contains %lu entries:\n",
9145 num_unwind),
dda8d76d 9146 printable_section_name (filedata, sec),
1b31d05e 9147 (unsigned long) sec->sh_offset,
d3a49aa8 9148 num_unwind);
0b6ae522 9149
dda8d76d 9150 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9151 res = FALSE;
1b31d05e
NC
9152 }
9153 }
0b6ae522
DJ
9154
9155 if (aux.symtab)
9156 free (aux.symtab);
9157 if (aux.strtab)
9158 free ((char *) aux.strtab);
32ec8896
NC
9159
9160 return res;
0b6ae522
DJ
9161}
9162
32ec8896 9163static bfd_boolean
dda8d76d 9164process_unwind (Filedata * filedata)
57346661 9165{
2cf0635d
NC
9166 struct unwind_handler
9167 {
32ec8896 9168 unsigned int machtype;
dda8d76d 9169 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9170 } handlers[] =
9171 {
0b6ae522 9172 { EM_ARM, arm_process_unwind },
57346661
AM
9173 { EM_IA_64, ia64_process_unwind },
9174 { EM_PARISC, hppa_process_unwind },
fa197c1c 9175 { EM_TI_C6000, arm_process_unwind },
32ec8896 9176 { 0, NULL }
57346661
AM
9177 };
9178 int i;
9179
9180 if (!do_unwind)
32ec8896 9181 return TRUE;
57346661
AM
9182
9183 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9184 if (filedata->file_header.e_machine == handlers[i].machtype)
9185 return handlers[i].handler (filedata);
57346661 9186
1b31d05e 9187 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9188 get_machine_name (filedata->file_header.e_machine));
32ec8896 9189 return TRUE;
57346661
AM
9190}
9191
252b5132 9192static void
2cf0635d 9193dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
9194{
9195 switch (entry->d_tag)
9196 {
9197 case DT_MIPS_FLAGS:
9198 if (entry->d_un.d_val == 0)
4b68bca3 9199 printf (_("NONE"));
252b5132
RH
9200 else
9201 {
9202 static const char * opts[] =
9203 {
9204 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9205 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9206 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9207 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9208 "RLD_ORDER_SAFE"
9209 };
9210 unsigned int cnt;
32ec8896 9211 bfd_boolean first = TRUE;
2b692964 9212
60bca95a 9213 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9214 if (entry->d_un.d_val & (1 << cnt))
9215 {
9216 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9217 first = FALSE;
252b5132 9218 }
252b5132
RH
9219 }
9220 break;
103f02d3 9221
252b5132 9222 case DT_MIPS_IVERSION:
d79b3d50 9223 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 9224 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9225 else
76ca31c0
NC
9226 {
9227 char buf[40];
9228 sprintf_vma (buf, entry->d_un.d_ptr);
9229 /* Note: coded this way so that there is a single string for translation. */
9230 printf (_("<corrupt: %s>"), buf);
9231 }
252b5132 9232 break;
103f02d3 9233
252b5132
RH
9234 case DT_MIPS_TIME_STAMP:
9235 {
d5b07ef4 9236 char timebuf[128];
2cf0635d 9237 struct tm * tmp;
91d6fa6a 9238 time_t atime = entry->d_un.d_val;
82b1b41b 9239
91d6fa6a 9240 tmp = gmtime (&atime);
82b1b41b
NC
9241 /* PR 17531: file: 6accc532. */
9242 if (tmp == NULL)
9243 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9244 else
9245 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9246 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9247 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9248 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9249 }
9250 break;
103f02d3 9251
252b5132
RH
9252 case DT_MIPS_RLD_VERSION:
9253 case DT_MIPS_LOCAL_GOTNO:
9254 case DT_MIPS_CONFLICTNO:
9255 case DT_MIPS_LIBLISTNO:
9256 case DT_MIPS_SYMTABNO:
9257 case DT_MIPS_UNREFEXTNO:
9258 case DT_MIPS_HIPAGENO:
9259 case DT_MIPS_DELTA_CLASS_NO:
9260 case DT_MIPS_DELTA_INSTANCE_NO:
9261 case DT_MIPS_DELTA_RELOC_NO:
9262 case DT_MIPS_DELTA_SYM_NO:
9263 case DT_MIPS_DELTA_CLASSSYM_NO:
9264 case DT_MIPS_COMPACT_SIZE:
c69075ac 9265 print_vma (entry->d_un.d_val, DEC);
252b5132 9266 break;
103f02d3
UD
9267
9268 default:
4b68bca3 9269 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9270 }
4b68bca3 9271 putchar ('\n');
103f02d3
UD
9272}
9273
103f02d3 9274static void
2cf0635d 9275dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9276{
9277 switch (entry->d_tag)
9278 {
9279 case DT_HP_DLD_FLAGS:
9280 {
9281 static struct
9282 {
9283 long int bit;
2cf0635d 9284 const char * str;
5e220199
NC
9285 }
9286 flags[] =
9287 {
9288 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9289 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9290 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9291 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9292 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9293 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9294 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9295 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9296 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9297 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9298 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9299 { DT_HP_GST, "HP_GST" },
9300 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9301 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9302 { DT_HP_NODELETE, "HP_NODELETE" },
9303 { DT_HP_GROUP, "HP_GROUP" },
9304 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9305 };
32ec8896 9306 bfd_boolean first = TRUE;
5e220199 9307 size_t cnt;
f7a99963 9308 bfd_vma val = entry->d_un.d_val;
103f02d3 9309
60bca95a 9310 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9311 if (val & flags[cnt].bit)
30800947
NC
9312 {
9313 if (! first)
9314 putchar (' ');
9315 fputs (flags[cnt].str, stdout);
32ec8896 9316 first = FALSE;
30800947
NC
9317 val ^= flags[cnt].bit;
9318 }
76da6bbe 9319
103f02d3 9320 if (val != 0 || first)
f7a99963
NC
9321 {
9322 if (! first)
9323 putchar (' ');
9324 print_vma (val, HEX);
9325 }
103f02d3
UD
9326 }
9327 break;
76da6bbe 9328
252b5132 9329 default:
f7a99963
NC
9330 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9331 break;
252b5132 9332 }
35b1837e 9333 putchar ('\n');
252b5132
RH
9334}
9335
28f997cf
TG
9336#ifdef BFD64
9337
9338/* VMS vs Unix time offset and factor. */
9339
9340#define VMS_EPOCH_OFFSET 35067168000000000LL
9341#define VMS_GRANULARITY_FACTOR 10000000
9342
9343/* Display a VMS time in a human readable format. */
9344
9345static void
9346print_vms_time (bfd_int64_t vmstime)
9347{
9348 struct tm *tm;
9349 time_t unxtime;
9350
9351 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9352 tm = gmtime (&unxtime);
9353 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9354 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9355 tm->tm_hour, tm->tm_min, tm->tm_sec);
9356}
9357#endif /* BFD64 */
9358
ecc51f48 9359static void
2cf0635d 9360dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9361{
9362 switch (entry->d_tag)
9363 {
0de14b54 9364 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9365 /* First 3 slots reserved. */
ecc51f48
NC
9366 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9367 printf (" -- ");
9368 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9369 break;
9370
28f997cf
TG
9371 case DT_IA_64_VMS_LINKTIME:
9372#ifdef BFD64
9373 print_vms_time (entry->d_un.d_val);
9374#endif
9375 break;
9376
9377 case DT_IA_64_VMS_LNKFLAGS:
9378 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9379 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9380 printf (" CALL_DEBUG");
9381 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9382 printf (" NOP0BUFS");
9383 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9384 printf (" P0IMAGE");
9385 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9386 printf (" MKTHREADS");
9387 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9388 printf (" UPCALLS");
9389 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9390 printf (" IMGSTA");
9391 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9392 printf (" INITIALIZE");
9393 if (entry->d_un.d_val & VMS_LF_MAIN)
9394 printf (" MAIN");
9395 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9396 printf (" EXE_INIT");
9397 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9398 printf (" TBK_IN_IMG");
9399 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9400 printf (" DBG_IN_IMG");
9401 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9402 printf (" TBK_IN_DSF");
9403 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9404 printf (" DBG_IN_DSF");
9405 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9406 printf (" SIGNATURES");
9407 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9408 printf (" REL_SEG_OFF");
9409 break;
9410
bdf4d63a
JJ
9411 default:
9412 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9413 break;
ecc51f48 9414 }
bdf4d63a 9415 putchar ('\n');
ecc51f48
NC
9416}
9417
32ec8896 9418static bfd_boolean
dda8d76d 9419get_32bit_dynamic_section (Filedata * filedata)
252b5132 9420{
2cf0635d
NC
9421 Elf32_External_Dyn * edyn;
9422 Elf32_External_Dyn * ext;
9423 Elf_Internal_Dyn * entry;
103f02d3 9424
dda8d76d 9425 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9426 dynamic_size, _("dynamic section"));
a6e9f9df 9427 if (!edyn)
32ec8896 9428 return FALSE;
103f02d3 9429
071436c6
NC
9430 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9431 might not have the luxury of section headers. Look for the DT_NULL
9432 terminator to determine the number of entries. */
ba2685cc 9433 for (ext = edyn, dynamic_nent = 0;
53c3012c 9434 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9435 ext++)
9436 {
9437 dynamic_nent++;
9438 if (BYTE_GET (ext->d_tag) == DT_NULL)
9439 break;
9440 }
252b5132 9441
3f5e193b
NC
9442 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9443 sizeof (* entry));
b2d38a17 9444 if (dynamic_section == NULL)
252b5132 9445 {
8b73c356
NC
9446 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9447 (unsigned long) dynamic_nent);
9ea033b2 9448 free (edyn);
32ec8896 9449 return FALSE;
9ea033b2 9450 }
252b5132 9451
fb514b26 9452 for (ext = edyn, entry = dynamic_section;
ba2685cc 9453 entry < dynamic_section + dynamic_nent;
fb514b26 9454 ext++, entry++)
9ea033b2 9455 {
fb514b26
AM
9456 entry->d_tag = BYTE_GET (ext->d_tag);
9457 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9458 }
9459
9ea033b2
NC
9460 free (edyn);
9461
32ec8896 9462 return TRUE;
9ea033b2
NC
9463}
9464
32ec8896 9465static bfd_boolean
dda8d76d 9466get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9467{
2cf0635d
NC
9468 Elf64_External_Dyn * edyn;
9469 Elf64_External_Dyn * ext;
9470 Elf_Internal_Dyn * entry;
103f02d3 9471
071436c6 9472 /* Read in the data. */
dda8d76d 9473 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9474 dynamic_size, _("dynamic section"));
a6e9f9df 9475 if (!edyn)
32ec8896 9476 return FALSE;
103f02d3 9477
071436c6
NC
9478 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9479 might not have the luxury of section headers. Look for the DT_NULL
9480 terminator to determine the number of entries. */
ba2685cc 9481 for (ext = edyn, dynamic_nent = 0;
53c3012c
AM
9482 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
9483 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9484 ext++)
9485 {
9486 dynamic_nent++;
66543521 9487 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9488 break;
9489 }
252b5132 9490
3f5e193b
NC
9491 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9492 sizeof (* entry));
b2d38a17 9493 if (dynamic_section == NULL)
252b5132 9494 {
8b73c356
NC
9495 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9496 (unsigned long) dynamic_nent);
252b5132 9497 free (edyn);
32ec8896 9498 return FALSE;
252b5132
RH
9499 }
9500
071436c6 9501 /* Convert from external to internal formats. */
fb514b26 9502 for (ext = edyn, entry = dynamic_section;
ba2685cc 9503 entry < dynamic_section + dynamic_nent;
fb514b26 9504 ext++, entry++)
252b5132 9505 {
66543521
AM
9506 entry->d_tag = BYTE_GET (ext->d_tag);
9507 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9508 }
9509
9510 free (edyn);
9511
32ec8896 9512 return TRUE;
9ea033b2
NC
9513}
9514
e9e44622
JJ
9515static void
9516print_dynamic_flags (bfd_vma flags)
d1133906 9517{
32ec8896 9518 bfd_boolean first = TRUE;
13ae64f3 9519
d1133906
NC
9520 while (flags)
9521 {
9522 bfd_vma flag;
9523
9524 flag = flags & - flags;
9525 flags &= ~ flag;
9526
e9e44622 9527 if (first)
32ec8896 9528 first = FALSE;
e9e44622
JJ
9529 else
9530 putc (' ', stdout);
13ae64f3 9531
d1133906
NC
9532 switch (flag)
9533 {
e9e44622
JJ
9534 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9535 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9536 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9537 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9538 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9539 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9540 }
9541 }
e9e44622 9542 puts ("");
d1133906
NC
9543}
9544
b2d38a17
NC
9545/* Parse and display the contents of the dynamic section. */
9546
32ec8896 9547static bfd_boolean
dda8d76d 9548process_dynamic_section (Filedata * filedata)
9ea033b2 9549{
2cf0635d 9550 Elf_Internal_Dyn * entry;
9ea033b2
NC
9551
9552 if (dynamic_size == 0)
9553 {
9554 if (do_dynamic)
b2d38a17 9555 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 9556
32ec8896 9557 return TRUE;
9ea033b2
NC
9558 }
9559
9560 if (is_32bit_elf)
9561 {
dda8d76d 9562 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
9563 return FALSE;
9564 }
9565 else
9566 {
dda8d76d 9567 if (! get_64bit_dynamic_section (filedata))
32ec8896 9568 return FALSE;
9ea033b2 9569 }
9ea033b2 9570
252b5132
RH
9571 /* Find the appropriate symbol table. */
9572 if (dynamic_symbols == NULL)
9573 {
86dba8ee
AM
9574 for (entry = dynamic_section;
9575 entry < dynamic_section + dynamic_nent;
9576 ++entry)
252b5132 9577 {
c8286bd1 9578 Elf_Internal_Shdr section;
252b5132
RH
9579
9580 if (entry->d_tag != DT_SYMTAB)
9581 continue;
9582
9583 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
9584
9585 /* Since we do not know how big the symbol table is,
9586 we default to reading in the entire file (!) and
9587 processing that. This is overkill, I know, but it
e3c8793a 9588 should work. */
dda8d76d
NC
9589 section.sh_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
9590 if ((bfd_size_type) section.sh_offset > filedata->file_size)
7296a62a
NC
9591 {
9592 /* See PR 21379 for a reproducer. */
9593 error (_("Invalid DT_SYMTAB entry: %lx"), (long) section.sh_offset);
9594 return FALSE;
9595 }
252b5132 9596
fb52b2f4
NC
9597 if (archive_file_offset != 0)
9598 section.sh_size = archive_file_size - section.sh_offset;
9599 else
dda8d76d 9600 section.sh_size = filedata->file_size - section.sh_offset;
252b5132 9601
9ea033b2 9602 if (is_32bit_elf)
9ad5cbcf 9603 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 9604 else
9ad5cbcf 9605 section.sh_entsize = sizeof (Elf64_External_Sym);
dda8d76d 9606 section.sh_name = filedata->string_table_length;
252b5132 9607
dda8d76d 9608 dynamic_symbols = GET_ELF_SYMBOLS (filedata, &section, & num_dynamic_syms);
19936277 9609 if (num_dynamic_syms < 1)
252b5132
RH
9610 {
9611 error (_("Unable to determine the number of symbols to load\n"));
9612 continue;
9613 }
252b5132
RH
9614 }
9615 }
9616
9617 /* Similarly find a string table. */
9618 if (dynamic_strings == NULL)
9619 {
86dba8ee
AM
9620 for (entry = dynamic_section;
9621 entry < dynamic_section + dynamic_nent;
9622 ++entry)
252b5132
RH
9623 {
9624 unsigned long offset;
b34976b6 9625 long str_tab_len;
252b5132
RH
9626
9627 if (entry->d_tag != DT_STRTAB)
9628 continue;
9629
9630 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
9631
9632 /* Since we do not know how big the string table is,
9633 we default to reading in the entire file (!) and
9634 processing that. This is overkill, I know, but it
e3c8793a 9635 should work. */
252b5132 9636
dda8d76d 9637 offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
fb52b2f4
NC
9638
9639 if (archive_file_offset != 0)
9640 str_tab_len = archive_file_size - offset;
9641 else
86c6c6df 9642 str_tab_len = filedata->file_size - offset;
252b5132
RH
9643
9644 if (str_tab_len < 1)
9645 {
9646 error
9647 (_("Unable to determine the length of the dynamic string table\n"));
9648 continue;
9649 }
9650
dda8d76d 9651 dynamic_strings = (char *) get_data (NULL, filedata, offset, 1,
3f5e193b
NC
9652 str_tab_len,
9653 _("dynamic string table"));
59245841 9654 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
9655 break;
9656 }
9657 }
9658
9659 /* And find the syminfo section if available. */
9660 if (dynamic_syminfo == NULL)
9661 {
3e8bba36 9662 unsigned long syminsz = 0;
252b5132 9663
86dba8ee
AM
9664 for (entry = dynamic_section;
9665 entry < dynamic_section + dynamic_nent;
9666 ++entry)
252b5132
RH
9667 {
9668 if (entry->d_tag == DT_SYMINENT)
9669 {
9670 /* Note: these braces are necessary to avoid a syntax
9671 error from the SunOS4 C compiler. */
049b0c3a
NC
9672 /* PR binutils/17531: A corrupt file can trigger this test.
9673 So do not use an assert, instead generate an error message. */
9674 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 9675 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 9676 (int) entry->d_un.d_val);
252b5132
RH
9677 }
9678 else if (entry->d_tag == DT_SYMINSZ)
9679 syminsz = entry->d_un.d_val;
9680 else if (entry->d_tag == DT_SYMINFO)
dda8d76d 9681 dynamic_syminfo_offset = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 9682 syminsz);
252b5132
RH
9683 }
9684
9685 if (dynamic_syminfo_offset != 0 && syminsz != 0)
9686 {
2cf0635d
NC
9687 Elf_External_Syminfo * extsyminfo;
9688 Elf_External_Syminfo * extsym;
9689 Elf_Internal_Syminfo * syminfo;
252b5132
RH
9690
9691 /* There is a syminfo section. Read the data. */
3f5e193b 9692 extsyminfo = (Elf_External_Syminfo *)
dda8d76d 9693 get_data (NULL, filedata, dynamic_syminfo_offset, 1, syminsz,
3f5e193b 9694 _("symbol information"));
a6e9f9df 9695 if (!extsyminfo)
32ec8896 9696 return FALSE;
252b5132 9697
3f5e193b 9698 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
9699 if (dynamic_syminfo == NULL)
9700 {
8b73c356
NC
9701 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
9702 (unsigned long) syminsz);
32ec8896 9703 return FALSE;
252b5132
RH
9704 }
9705
9706 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
9707 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
9708 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
9709 ++syminfo, ++extsym)
252b5132 9710 {
86dba8ee
AM
9711 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
9712 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
9713 }
9714
9715 free (extsyminfo);
9716 }
9717 }
9718
9719 if (do_dynamic && dynamic_addr)
d3a49aa8
AM
9720 printf (ngettext ("\nDynamic section at offset 0x%lx "
9721 "contains %lu entry:\n",
9722 "\nDynamic section at offset 0x%lx "
9723 "contains %lu entries:\n",
9724 dynamic_nent),
8b73c356 9725 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
9726 if (do_dynamic)
9727 printf (_(" Tag Type Name/Value\n"));
9728
86dba8ee
AM
9729 for (entry = dynamic_section;
9730 entry < dynamic_section + dynamic_nent;
9731 entry++)
252b5132
RH
9732 {
9733 if (do_dynamic)
f7a99963 9734 {
2cf0635d 9735 const char * dtype;
e699b9ff 9736
f7a99963
NC
9737 putchar (' ');
9738 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 9739 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 9740 printf (" (%s)%*s", dtype,
32ec8896 9741 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 9742 }
252b5132
RH
9743
9744 switch (entry->d_tag)
9745 {
d1133906
NC
9746 case DT_FLAGS:
9747 if (do_dynamic)
e9e44622 9748 print_dynamic_flags (entry->d_un.d_val);
d1133906 9749 break;
76da6bbe 9750
252b5132
RH
9751 case DT_AUXILIARY:
9752 case DT_FILTER:
019148e4
L
9753 case DT_CONFIG:
9754 case DT_DEPAUDIT:
9755 case DT_AUDIT:
252b5132
RH
9756 if (do_dynamic)
9757 {
019148e4 9758 switch (entry->d_tag)
b34976b6 9759 {
019148e4
L
9760 case DT_AUXILIARY:
9761 printf (_("Auxiliary library"));
9762 break;
9763
9764 case DT_FILTER:
9765 printf (_("Filter library"));
9766 break;
9767
b34976b6 9768 case DT_CONFIG:
019148e4
L
9769 printf (_("Configuration file"));
9770 break;
9771
9772 case DT_DEPAUDIT:
9773 printf (_("Dependency audit library"));
9774 break;
9775
9776 case DT_AUDIT:
9777 printf (_("Audit library"));
9778 break;
9779 }
252b5132 9780
d79b3d50
NC
9781 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9782 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9783 else
f7a99963
NC
9784 {
9785 printf (": ");
9786 print_vma (entry->d_un.d_val, PREFIX_HEX);
9787 putchar ('\n');
9788 }
252b5132
RH
9789 }
9790 break;
9791
dcefbbbd 9792 case DT_FEATURE:
252b5132
RH
9793 if (do_dynamic)
9794 {
9795 printf (_("Flags:"));
86f55779 9796
252b5132
RH
9797 if (entry->d_un.d_val == 0)
9798 printf (_(" None\n"));
9799 else
9800 {
9801 unsigned long int val = entry->d_un.d_val;
86f55779 9802
252b5132
RH
9803 if (val & DTF_1_PARINIT)
9804 {
9805 printf (" PARINIT");
9806 val ^= DTF_1_PARINIT;
9807 }
dcefbbbd
L
9808 if (val & DTF_1_CONFEXP)
9809 {
9810 printf (" CONFEXP");
9811 val ^= DTF_1_CONFEXP;
9812 }
252b5132
RH
9813 if (val != 0)
9814 printf (" %lx", val);
9815 puts ("");
9816 }
9817 }
9818 break;
9819
9820 case DT_POSFLAG_1:
9821 if (do_dynamic)
9822 {
9823 printf (_("Flags:"));
86f55779 9824
252b5132
RH
9825 if (entry->d_un.d_val == 0)
9826 printf (_(" None\n"));
9827 else
9828 {
9829 unsigned long int val = entry->d_un.d_val;
86f55779 9830
252b5132
RH
9831 if (val & DF_P1_LAZYLOAD)
9832 {
9833 printf (" LAZYLOAD");
9834 val ^= DF_P1_LAZYLOAD;
9835 }
9836 if (val & DF_P1_GROUPPERM)
9837 {
9838 printf (" GROUPPERM");
9839 val ^= DF_P1_GROUPPERM;
9840 }
9841 if (val != 0)
9842 printf (" %lx", val);
9843 puts ("");
9844 }
9845 }
9846 break;
9847
9848 case DT_FLAGS_1:
9849 if (do_dynamic)
9850 {
9851 printf (_("Flags:"));
9852 if (entry->d_un.d_val == 0)
9853 printf (_(" None\n"));
9854 else
9855 {
9856 unsigned long int val = entry->d_un.d_val;
86f55779 9857
252b5132
RH
9858 if (val & DF_1_NOW)
9859 {
9860 printf (" NOW");
9861 val ^= DF_1_NOW;
9862 }
9863 if (val & DF_1_GLOBAL)
9864 {
9865 printf (" GLOBAL");
9866 val ^= DF_1_GLOBAL;
9867 }
9868 if (val & DF_1_GROUP)
9869 {
9870 printf (" GROUP");
9871 val ^= DF_1_GROUP;
9872 }
9873 if (val & DF_1_NODELETE)
9874 {
9875 printf (" NODELETE");
9876 val ^= DF_1_NODELETE;
9877 }
9878 if (val & DF_1_LOADFLTR)
9879 {
9880 printf (" LOADFLTR");
9881 val ^= DF_1_LOADFLTR;
9882 }
9883 if (val & DF_1_INITFIRST)
9884 {
9885 printf (" INITFIRST");
9886 val ^= DF_1_INITFIRST;
9887 }
9888 if (val & DF_1_NOOPEN)
9889 {
9890 printf (" NOOPEN");
9891 val ^= DF_1_NOOPEN;
9892 }
9893 if (val & DF_1_ORIGIN)
9894 {
9895 printf (" ORIGIN");
9896 val ^= DF_1_ORIGIN;
9897 }
9898 if (val & DF_1_DIRECT)
9899 {
9900 printf (" DIRECT");
9901 val ^= DF_1_DIRECT;
9902 }
9903 if (val & DF_1_TRANS)
9904 {
9905 printf (" TRANS");
9906 val ^= DF_1_TRANS;
9907 }
9908 if (val & DF_1_INTERPOSE)
9909 {
9910 printf (" INTERPOSE");
9911 val ^= DF_1_INTERPOSE;
9912 }
f7db6139 9913 if (val & DF_1_NODEFLIB)
dcefbbbd 9914 {
f7db6139
L
9915 printf (" NODEFLIB");
9916 val ^= DF_1_NODEFLIB;
dcefbbbd
L
9917 }
9918 if (val & DF_1_NODUMP)
9919 {
9920 printf (" NODUMP");
9921 val ^= DF_1_NODUMP;
9922 }
34b60028 9923 if (val & DF_1_CONFALT)
dcefbbbd 9924 {
34b60028
L
9925 printf (" CONFALT");
9926 val ^= DF_1_CONFALT;
9927 }
9928 if (val & DF_1_ENDFILTEE)
9929 {
9930 printf (" ENDFILTEE");
9931 val ^= DF_1_ENDFILTEE;
9932 }
9933 if (val & DF_1_DISPRELDNE)
9934 {
9935 printf (" DISPRELDNE");
9936 val ^= DF_1_DISPRELDNE;
9937 }
9938 if (val & DF_1_DISPRELPND)
9939 {
9940 printf (" DISPRELPND");
9941 val ^= DF_1_DISPRELPND;
9942 }
9943 if (val & DF_1_NODIRECT)
9944 {
9945 printf (" NODIRECT");
9946 val ^= DF_1_NODIRECT;
9947 }
9948 if (val & DF_1_IGNMULDEF)
9949 {
9950 printf (" IGNMULDEF");
9951 val ^= DF_1_IGNMULDEF;
9952 }
9953 if (val & DF_1_NOKSYMS)
9954 {
9955 printf (" NOKSYMS");
9956 val ^= DF_1_NOKSYMS;
9957 }
9958 if (val & DF_1_NOHDR)
9959 {
9960 printf (" NOHDR");
9961 val ^= DF_1_NOHDR;
9962 }
9963 if (val & DF_1_EDITED)
9964 {
9965 printf (" EDITED");
9966 val ^= DF_1_EDITED;
9967 }
9968 if (val & DF_1_NORELOC)
9969 {
9970 printf (" NORELOC");
9971 val ^= DF_1_NORELOC;
9972 }
9973 if (val & DF_1_SYMINTPOSE)
9974 {
9975 printf (" SYMINTPOSE");
9976 val ^= DF_1_SYMINTPOSE;
9977 }
9978 if (val & DF_1_GLOBAUDIT)
9979 {
9980 printf (" GLOBAUDIT");
9981 val ^= DF_1_GLOBAUDIT;
9982 }
9983 if (val & DF_1_SINGLETON)
9984 {
9985 printf (" SINGLETON");
9986 val ^= DF_1_SINGLETON;
dcefbbbd 9987 }
5c383f02
RO
9988 if (val & DF_1_STUB)
9989 {
9990 printf (" STUB");
9991 val ^= DF_1_STUB;
9992 }
9993 if (val & DF_1_PIE)
9994 {
9995 printf (" PIE");
9996 val ^= DF_1_PIE;
9997 }
b1202ffa
L
9998 if (val & DF_1_KMOD)
9999 {
10000 printf (" KMOD");
10001 val ^= DF_1_KMOD;
10002 }
10003 if (val & DF_1_WEAKFILTER)
10004 {
10005 printf (" WEAKFILTER");
10006 val ^= DF_1_WEAKFILTER;
10007 }
10008 if (val & DF_1_NOCOMMON)
10009 {
10010 printf (" NOCOMMON");
10011 val ^= DF_1_NOCOMMON;
10012 }
252b5132
RH
10013 if (val != 0)
10014 printf (" %lx", val);
10015 puts ("");
10016 }
10017 }
10018 break;
10019
10020 case DT_PLTREL:
566b0d53 10021 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10022 if (do_dynamic)
dda8d76d 10023 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10024 break;
10025
10026 case DT_NULL :
10027 case DT_NEEDED :
10028 case DT_PLTGOT :
10029 case DT_HASH :
10030 case DT_STRTAB :
10031 case DT_SYMTAB :
10032 case DT_RELA :
10033 case DT_INIT :
10034 case DT_FINI :
10035 case DT_SONAME :
10036 case DT_RPATH :
10037 case DT_SYMBOLIC:
10038 case DT_REL :
10039 case DT_DEBUG :
10040 case DT_TEXTREL :
10041 case DT_JMPREL :
019148e4 10042 case DT_RUNPATH :
252b5132
RH
10043 dynamic_info[entry->d_tag] = entry->d_un.d_val;
10044
10045 if (do_dynamic)
10046 {
2cf0635d 10047 char * name;
252b5132 10048
d79b3d50
NC
10049 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
10050 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10051 else
d79b3d50 10052 name = NULL;
252b5132
RH
10053
10054 if (name)
10055 {
10056 switch (entry->d_tag)
10057 {
10058 case DT_NEEDED:
10059 printf (_("Shared library: [%s]"), name);
10060
18bd398b 10061 if (streq (name, program_interpreter))
f7a99963 10062 printf (_(" program interpreter"));
252b5132
RH
10063 break;
10064
10065 case DT_SONAME:
f7a99963 10066 printf (_("Library soname: [%s]"), name);
252b5132
RH
10067 break;
10068
10069 case DT_RPATH:
f7a99963 10070 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10071 break;
10072
019148e4
L
10073 case DT_RUNPATH:
10074 printf (_("Library runpath: [%s]"), name);
10075 break;
10076
252b5132 10077 default:
f7a99963
NC
10078 print_vma (entry->d_un.d_val, PREFIX_HEX);
10079 break;
252b5132
RH
10080 }
10081 }
10082 else
f7a99963
NC
10083 print_vma (entry->d_un.d_val, PREFIX_HEX);
10084
10085 putchar ('\n');
252b5132
RH
10086 }
10087 break;
10088
10089 case DT_PLTRELSZ:
10090 case DT_RELASZ :
10091 case DT_STRSZ :
10092 case DT_RELSZ :
10093 case DT_RELAENT :
10094 case DT_SYMENT :
10095 case DT_RELENT :
566b0d53 10096 dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10097 /* Fall through. */
252b5132
RH
10098 case DT_PLTPADSZ:
10099 case DT_MOVEENT :
10100 case DT_MOVESZ :
10101 case DT_INIT_ARRAYSZ:
10102 case DT_FINI_ARRAYSZ:
047b2264
JJ
10103 case DT_GNU_CONFLICTSZ:
10104 case DT_GNU_LIBLISTSZ:
252b5132 10105 if (do_dynamic)
f7a99963
NC
10106 {
10107 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10108 printf (_(" (bytes)\n"));
f7a99963 10109 }
252b5132
RH
10110 break;
10111
10112 case DT_VERDEFNUM:
10113 case DT_VERNEEDNUM:
10114 case DT_RELACOUNT:
10115 case DT_RELCOUNT:
10116 if (do_dynamic)
f7a99963
NC
10117 {
10118 print_vma (entry->d_un.d_val, UNSIGNED);
10119 putchar ('\n');
10120 }
252b5132
RH
10121 break;
10122
10123 case DT_SYMINSZ:
10124 case DT_SYMINENT:
10125 case DT_SYMINFO:
10126 case DT_USED:
10127 case DT_INIT_ARRAY:
10128 case DT_FINI_ARRAY:
10129 if (do_dynamic)
10130 {
d79b3d50
NC
10131 if (entry->d_tag == DT_USED
10132 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 10133 {
2cf0635d 10134 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10135
b34976b6 10136 if (*name)
252b5132
RH
10137 {
10138 printf (_("Not needed object: [%s]\n"), name);
10139 break;
10140 }
10141 }
103f02d3 10142
f7a99963
NC
10143 print_vma (entry->d_un.d_val, PREFIX_HEX);
10144 putchar ('\n');
252b5132
RH
10145 }
10146 break;
10147
10148 case DT_BIND_NOW:
10149 /* The value of this entry is ignored. */
35b1837e
AM
10150 if (do_dynamic)
10151 putchar ('\n');
252b5132 10152 break;
103f02d3 10153
047b2264
JJ
10154 case DT_GNU_PRELINKED:
10155 if (do_dynamic)
10156 {
2cf0635d 10157 struct tm * tmp;
91d6fa6a 10158 time_t atime = entry->d_un.d_val;
047b2264 10159
91d6fa6a 10160 tmp = gmtime (&atime);
071436c6
NC
10161 /* PR 17533 file: 041-1244816-0.004. */
10162 if (tmp == NULL)
5a2cbcf4
L
10163 printf (_("<corrupt time val: %lx"),
10164 (unsigned long) atime);
071436c6
NC
10165 else
10166 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10167 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10168 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10169
10170 }
10171 break;
10172
fdc90cb4
JJ
10173 case DT_GNU_HASH:
10174 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10175 if (do_dynamic)
10176 {
10177 print_vma (entry->d_un.d_val, PREFIX_HEX);
10178 putchar ('\n');
10179 }
10180 break;
10181
252b5132
RH
10182 default:
10183 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 10184 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
10185 entry->d_un.d_val;
10186
10187 if (do_dynamic)
10188 {
dda8d76d 10189 switch (filedata->file_header.e_machine)
252b5132
RH
10190 {
10191 case EM_MIPS:
4fe85591 10192 case EM_MIPS_RS3_LE:
b2d38a17 10193 dynamic_section_mips_val (entry);
252b5132 10194 break;
103f02d3 10195 case EM_PARISC:
b2d38a17 10196 dynamic_section_parisc_val (entry);
103f02d3 10197 break;
ecc51f48 10198 case EM_IA_64:
b2d38a17 10199 dynamic_section_ia64_val (entry);
ecc51f48 10200 break;
252b5132 10201 default:
f7a99963
NC
10202 print_vma (entry->d_un.d_val, PREFIX_HEX);
10203 putchar ('\n');
252b5132
RH
10204 }
10205 }
10206 break;
10207 }
10208 }
10209
32ec8896 10210 return TRUE;
252b5132
RH
10211}
10212
10213static char *
d3ba0551 10214get_ver_flags (unsigned int flags)
252b5132 10215{
6d4f21f6 10216 static char buff[128];
252b5132
RH
10217
10218 buff[0] = 0;
10219
10220 if (flags == 0)
10221 return _("none");
10222
10223 if (flags & VER_FLG_BASE)
7bb1ad17 10224 strcat (buff, "BASE");
252b5132
RH
10225
10226 if (flags & VER_FLG_WEAK)
10227 {
10228 if (flags & VER_FLG_BASE)
7bb1ad17 10229 strcat (buff, " | ");
252b5132 10230
7bb1ad17 10231 strcat (buff, "WEAK");
252b5132
RH
10232 }
10233
44ec90b9
RO
10234 if (flags & VER_FLG_INFO)
10235 {
10236 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 10237 strcat (buff, " | ");
44ec90b9 10238
7bb1ad17 10239 strcat (buff, "INFO");
44ec90b9
RO
10240 }
10241
10242 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
10243 {
10244 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
10245 strcat (buff, " | ");
10246
10247 strcat (buff, _("<unknown>"));
10248 }
252b5132
RH
10249
10250 return buff;
10251}
10252
10253/* Display the contents of the version sections. */
98fb390a 10254
32ec8896 10255static bfd_boolean
dda8d76d 10256process_version_sections (Filedata * filedata)
252b5132 10257{
2cf0635d 10258 Elf_Internal_Shdr * section;
b34976b6 10259 unsigned i;
32ec8896 10260 bfd_boolean found = FALSE;
252b5132
RH
10261
10262 if (! do_version)
32ec8896 10263 return TRUE;
252b5132 10264
dda8d76d
NC
10265 for (i = 0, section = filedata->section_headers;
10266 i < filedata->file_header.e_shnum;
b34976b6 10267 i++, section++)
252b5132
RH
10268 {
10269 switch (section->sh_type)
10270 {
10271 case SHT_GNU_verdef:
10272 {
2cf0635d 10273 Elf_External_Verdef * edefs;
452bf675
AM
10274 unsigned long idx;
10275 unsigned long cnt;
2cf0635d 10276 char * endbuf;
252b5132 10277
32ec8896 10278 found = TRUE;
252b5132 10279
d3a49aa8
AM
10280 printf (ngettext ("\nVersion definition section '%s' "
10281 "contains %u entry:\n",
10282 "\nVersion definition section '%s' "
10283 "contains %u entries:\n",
10284 section->sh_info),
dda8d76d 10285 printable_section_name (filedata, section),
74e1a04b 10286 section->sh_info);
252b5132
RH
10287
10288 printf (_(" Addr: 0x"));
10289 printf_vma (section->sh_addr);
233f82cf 10290 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10291 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10292 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10293
3f5e193b 10294 edefs = (Elf_External_Verdef *)
dda8d76d 10295 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 10296 _("version definition section"));
a6e9f9df
AM
10297 if (!edefs)
10298 break;
59245841 10299 endbuf = (char *) edefs + section->sh_size;
252b5132 10300
1445030f 10301 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 10302 {
2cf0635d
NC
10303 char * vstart;
10304 Elf_External_Verdef * edef;
b34976b6 10305 Elf_Internal_Verdef ent;
2cf0635d 10306 Elf_External_Verdaux * eaux;
b34976b6 10307 Elf_Internal_Verdaux aux;
452bf675 10308 unsigned long isum;
b34976b6 10309 int j;
103f02d3 10310
252b5132 10311 vstart = ((char *) edefs) + idx;
54806181
AM
10312 if (vstart + sizeof (*edef) > endbuf)
10313 break;
252b5132
RH
10314
10315 edef = (Elf_External_Verdef *) vstart;
10316
10317 ent.vd_version = BYTE_GET (edef->vd_version);
10318 ent.vd_flags = BYTE_GET (edef->vd_flags);
10319 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
10320 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
10321 ent.vd_hash = BYTE_GET (edef->vd_hash);
10322 ent.vd_aux = BYTE_GET (edef->vd_aux);
10323 ent.vd_next = BYTE_GET (edef->vd_next);
10324
452bf675 10325 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
10326 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
10327
10328 printf (_(" Index: %d Cnt: %d "),
10329 ent.vd_ndx, ent.vd_cnt);
10330
452bf675 10331 /* Check for overflow. */
1445030f 10332 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
10333 break;
10334
252b5132
RH
10335 vstart += ent.vd_aux;
10336
1445030f
AM
10337 if (vstart + sizeof (*eaux) > endbuf)
10338 break;
252b5132
RH
10339 eaux = (Elf_External_Verdaux *) vstart;
10340
10341 aux.vda_name = BYTE_GET (eaux->vda_name);
10342 aux.vda_next = BYTE_GET (eaux->vda_next);
10343
d79b3d50
NC
10344 if (VALID_DYNAMIC_NAME (aux.vda_name))
10345 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
10346 else
10347 printf (_("Name index: %ld\n"), aux.vda_name);
10348
10349 isum = idx + ent.vd_aux;
10350
b34976b6 10351 for (j = 1; j < ent.vd_cnt; j++)
252b5132 10352 {
1445030f
AM
10353 if (aux.vda_next < sizeof (*eaux)
10354 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
10355 {
10356 warn (_("Invalid vda_next field of %lx\n"),
10357 aux.vda_next);
10358 j = ent.vd_cnt;
10359 break;
10360 }
dd24e3da 10361 /* Check for overflow. */
7e26601c 10362 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
10363 break;
10364
252b5132
RH
10365 isum += aux.vda_next;
10366 vstart += aux.vda_next;
10367
54806181
AM
10368 if (vstart + sizeof (*eaux) > endbuf)
10369 break;
1445030f 10370 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
10371
10372 aux.vda_name = BYTE_GET (eaux->vda_name);
10373 aux.vda_next = BYTE_GET (eaux->vda_next);
10374
d79b3d50 10375 if (VALID_DYNAMIC_NAME (aux.vda_name))
452bf675 10376 printf (_(" %#06lx: Parent %d: %s\n"),
d79b3d50 10377 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132 10378 else
452bf675 10379 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
10380 isum, j, aux.vda_name);
10381 }
dd24e3da 10382
54806181
AM
10383 if (j < ent.vd_cnt)
10384 printf (_(" Version def aux past end of section\n"));
252b5132 10385
c9f02c3e
MR
10386 /* PR 17531:
10387 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
10388 if (ent.vd_next < sizeof (*edef)
10389 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
10390 {
10391 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
10392 cnt = section->sh_info;
10393 break;
10394 }
452bf675 10395 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
10396 break;
10397
252b5132
RH
10398 idx += ent.vd_next;
10399 }
dd24e3da 10400
54806181
AM
10401 if (cnt < section->sh_info)
10402 printf (_(" Version definition past end of section\n"));
252b5132
RH
10403
10404 free (edefs);
10405 }
10406 break;
103f02d3 10407
252b5132
RH
10408 case SHT_GNU_verneed:
10409 {
2cf0635d 10410 Elf_External_Verneed * eneed;
452bf675
AM
10411 unsigned long idx;
10412 unsigned long cnt;
2cf0635d 10413 char * endbuf;
252b5132 10414
32ec8896 10415 found = TRUE;
252b5132 10416
d3a49aa8
AM
10417 printf (ngettext ("\nVersion needs section '%s' "
10418 "contains %u entry:\n",
10419 "\nVersion needs section '%s' "
10420 "contains %u entries:\n",
10421 section->sh_info),
dda8d76d 10422 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
10423
10424 printf (_(" Addr: 0x"));
10425 printf_vma (section->sh_addr);
72de5009 10426 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10427 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10428 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10429
dda8d76d 10430 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
10431 section->sh_offset, 1,
10432 section->sh_size,
9cf03b7e 10433 _("Version Needs section"));
a6e9f9df
AM
10434 if (!eneed)
10435 break;
59245841 10436 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
10437
10438 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
10439 {
2cf0635d 10440 Elf_External_Verneed * entry;
b34976b6 10441 Elf_Internal_Verneed ent;
452bf675 10442 unsigned long isum;
b34976b6 10443 int j;
2cf0635d 10444 char * vstart;
252b5132
RH
10445
10446 vstart = ((char *) eneed) + idx;
54806181
AM
10447 if (vstart + sizeof (*entry) > endbuf)
10448 break;
252b5132
RH
10449
10450 entry = (Elf_External_Verneed *) vstart;
10451
10452 ent.vn_version = BYTE_GET (entry->vn_version);
10453 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
10454 ent.vn_file = BYTE_GET (entry->vn_file);
10455 ent.vn_aux = BYTE_GET (entry->vn_aux);
10456 ent.vn_next = BYTE_GET (entry->vn_next);
10457
452bf675 10458 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 10459
d79b3d50
NC
10460 if (VALID_DYNAMIC_NAME (ent.vn_file))
10461 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
10462 else
10463 printf (_(" File: %lx"), ent.vn_file);
10464
10465 printf (_(" Cnt: %d\n"), ent.vn_cnt);
10466
dd24e3da 10467 /* Check for overflow. */
7e26601c 10468 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 10469 break;
252b5132
RH
10470 vstart += ent.vn_aux;
10471
10472 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
10473 {
2cf0635d 10474 Elf_External_Vernaux * eaux;
b34976b6 10475 Elf_Internal_Vernaux aux;
252b5132 10476
54806181
AM
10477 if (vstart + sizeof (*eaux) > endbuf)
10478 break;
252b5132
RH
10479 eaux = (Elf_External_Vernaux *) vstart;
10480
10481 aux.vna_hash = BYTE_GET (eaux->vna_hash);
10482 aux.vna_flags = BYTE_GET (eaux->vna_flags);
10483 aux.vna_other = BYTE_GET (eaux->vna_other);
10484 aux.vna_name = BYTE_GET (eaux->vna_name);
10485 aux.vna_next = BYTE_GET (eaux->vna_next);
10486
d79b3d50 10487 if (VALID_DYNAMIC_NAME (aux.vna_name))
452bf675 10488 printf (_(" %#06lx: Name: %s"),
d79b3d50 10489 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 10490 else
452bf675 10491 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
10492 isum, aux.vna_name);
10493
10494 printf (_(" Flags: %s Version: %d\n"),
10495 get_ver_flags (aux.vna_flags), aux.vna_other);
10496
1445030f
AM
10497 if (aux.vna_next < sizeof (*eaux)
10498 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
10499 {
10500 warn (_("Invalid vna_next field of %lx\n"),
10501 aux.vna_next);
10502 j = ent.vn_cnt;
10503 break;
10504 }
1445030f
AM
10505 /* Check for overflow. */
10506 if (aux.vna_next > (size_t) (endbuf - vstart))
10507 break;
252b5132
RH
10508 isum += aux.vna_next;
10509 vstart += aux.vna_next;
10510 }
9cf03b7e 10511
54806181 10512 if (j < ent.vn_cnt)
9cf03b7e 10513 warn (_("Missing Version Needs auxillary information\n"));
252b5132 10514
1445030f
AM
10515 if (ent.vn_next < sizeof (*entry)
10516 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 10517 {
452bf675 10518 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
10519 cnt = section->sh_info;
10520 break;
10521 }
1445030f
AM
10522 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
10523 break;
252b5132
RH
10524 idx += ent.vn_next;
10525 }
9cf03b7e 10526
54806181 10527 if (cnt < section->sh_info)
9cf03b7e 10528 warn (_("Missing Version Needs information\n"));
103f02d3 10529
252b5132
RH
10530 free (eneed);
10531 }
10532 break;
10533
10534 case SHT_GNU_versym:
10535 {
2cf0635d 10536 Elf_Internal_Shdr * link_section;
8b73c356
NC
10537 size_t total;
10538 unsigned int cnt;
2cf0635d
NC
10539 unsigned char * edata;
10540 unsigned short * data;
10541 char * strtab;
10542 Elf_Internal_Sym * symbols;
10543 Elf_Internal_Shdr * string_sec;
ba5cdace 10544 unsigned long num_syms;
d3ba0551 10545 long off;
252b5132 10546
dda8d76d 10547 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10548 break;
10549
dda8d76d 10550 link_section = filedata->section_headers + section->sh_link;
08d8fa11 10551 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 10552
dda8d76d 10553 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10554 break;
10555
32ec8896 10556 found = TRUE;
252b5132 10557
dda8d76d 10558 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
10559 if (symbols == NULL)
10560 break;
252b5132 10561
dda8d76d 10562 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 10563
dda8d76d 10564 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
10565 string_sec->sh_size,
10566 _("version string table"));
a6e9f9df 10567 if (!strtab)
0429c154
MS
10568 {
10569 free (symbols);
10570 break;
10571 }
252b5132 10572
d3a49aa8
AM
10573 printf (ngettext ("\nVersion symbols section '%s' "
10574 "contains %lu entry:\n",
10575 "\nVersion symbols section '%s' "
10576 "contains %lu entries:\n",
10577 total),
dda8d76d 10578 printable_section_name (filedata, section), (unsigned long) total);
252b5132
RH
10579
10580 printf (_(" Addr: "));
10581 printf_vma (section->sh_addr);
72de5009 10582 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10583 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10584 printable_section_name (filedata, link_section));
252b5132 10585
dda8d76d 10586 off = offset_from_vma (filedata,
d3ba0551
AM
10587 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10588 total * sizeof (short));
dda8d76d 10589 edata = (unsigned char *) get_data (NULL, filedata, off, total,
3f5e193b
NC
10590 sizeof (short),
10591 _("version symbol data"));
a6e9f9df
AM
10592 if (!edata)
10593 {
10594 free (strtab);
0429c154 10595 free (symbols);
a6e9f9df
AM
10596 break;
10597 }
252b5132 10598
3f5e193b 10599 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
10600
10601 for (cnt = total; cnt --;)
b34976b6
AM
10602 data[cnt] = byte_get (edata + cnt * sizeof (short),
10603 sizeof (short));
252b5132
RH
10604
10605 free (edata);
10606
10607 for (cnt = 0; cnt < total; cnt += 4)
10608 {
10609 int j, nn;
ab273396
AM
10610 char *name;
10611 char *invalid = _("*invalid*");
252b5132
RH
10612
10613 printf (" %03x:", cnt);
10614
10615 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 10616 switch (data[cnt + j])
252b5132
RH
10617 {
10618 case 0:
10619 fputs (_(" 0 (*local*) "), stdout);
10620 break;
10621
10622 case 1:
10623 fputs (_(" 1 (*global*) "), stdout);
10624 break;
10625
10626 default:
c244d050
NC
10627 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
10628 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 10629
dd24e3da 10630 /* If this index value is greater than the size of the symbols
ba5cdace
NC
10631 array, break to avoid an out-of-bounds read. */
10632 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
10633 {
10634 warn (_("invalid index into symbol array\n"));
10635 break;
10636 }
10637
ab273396
AM
10638 name = NULL;
10639 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 10640 {
b34976b6
AM
10641 Elf_Internal_Verneed ivn;
10642 unsigned long offset;
252b5132 10643
d93f0186 10644 offset = offset_from_vma
dda8d76d 10645 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 10646 sizeof (Elf_External_Verneed));
252b5132 10647
b34976b6 10648 do
252b5132 10649 {
b34976b6
AM
10650 Elf_Internal_Vernaux ivna;
10651 Elf_External_Verneed evn;
10652 Elf_External_Vernaux evna;
10653 unsigned long a_off;
252b5132 10654
dda8d76d 10655 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
10656 _("version need")) == NULL)
10657 break;
0b4362b0 10658
252b5132
RH
10659 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10660 ivn.vn_next = BYTE_GET (evn.vn_next);
10661
10662 a_off = offset + ivn.vn_aux;
10663
10664 do
10665 {
dda8d76d 10666 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
10667 1, _("version need aux (2)")) == NULL)
10668 {
10669 ivna.vna_next = 0;
10670 ivna.vna_other = 0;
10671 }
10672 else
10673 {
10674 ivna.vna_next = BYTE_GET (evna.vna_next);
10675 ivna.vna_other = BYTE_GET (evna.vna_other);
10676 }
252b5132
RH
10677
10678 a_off += ivna.vna_next;
10679 }
b34976b6 10680 while (ivna.vna_other != data[cnt + j]
252b5132
RH
10681 && ivna.vna_next != 0);
10682
b34976b6 10683 if (ivna.vna_other == data[cnt + j])
252b5132
RH
10684 {
10685 ivna.vna_name = BYTE_GET (evna.vna_name);
10686
54806181 10687 if (ivna.vna_name >= string_sec->sh_size)
ab273396 10688 name = invalid;
54806181
AM
10689 else
10690 name = strtab + ivna.vna_name;
252b5132
RH
10691 break;
10692 }
10693
10694 offset += ivn.vn_next;
10695 }
10696 while (ivn.vn_next);
10697 }
00d93f34 10698
ab273396 10699 if (data[cnt + j] != 0x8001
b34976b6 10700 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10701 {
b34976b6
AM
10702 Elf_Internal_Verdef ivd;
10703 Elf_External_Verdef evd;
10704 unsigned long offset;
252b5132 10705
d93f0186 10706 offset = offset_from_vma
dda8d76d 10707 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 10708 sizeof evd);
252b5132
RH
10709
10710 do
10711 {
dda8d76d 10712 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
10713 _("version def")) == NULL)
10714 {
10715 ivd.vd_next = 0;
948f632f 10716 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
10717 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
10718 break;
59245841
NC
10719 }
10720 else
10721 {
10722 ivd.vd_next = BYTE_GET (evd.vd_next);
10723 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10724 }
252b5132
RH
10725
10726 offset += ivd.vd_next;
10727 }
c244d050 10728 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
10729 && ivd.vd_next != 0);
10730
c244d050 10731 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 10732 {
b34976b6
AM
10733 Elf_External_Verdaux evda;
10734 Elf_Internal_Verdaux ivda;
252b5132
RH
10735
10736 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10737
dda8d76d 10738 if (get_data (&evda, filedata,
59245841
NC
10739 offset - ivd.vd_next + ivd.vd_aux,
10740 sizeof (evda), 1,
10741 _("version def aux")) == NULL)
10742 break;
252b5132
RH
10743
10744 ivda.vda_name = BYTE_GET (evda.vda_name);
10745
54806181 10746 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
10747 name = invalid;
10748 else if (name != NULL && name != invalid)
10749 name = _("*both*");
54806181
AM
10750 else
10751 name = strtab + ivda.vda_name;
252b5132
RH
10752 }
10753 }
ab273396
AM
10754 if (name != NULL)
10755 nn += printf ("(%s%-*s",
10756 name,
10757 12 - (int) strlen (name),
10758 ")");
252b5132
RH
10759
10760 if (nn < 18)
10761 printf ("%*c", 18 - nn, ' ');
10762 }
10763
10764 putchar ('\n');
10765 }
10766
10767 free (data);
10768 free (strtab);
10769 free (symbols);
10770 }
10771 break;
103f02d3 10772
252b5132
RH
10773 default:
10774 break;
10775 }
10776 }
10777
10778 if (! found)
10779 printf (_("\nNo version information found in this file.\n"));
10780
32ec8896 10781 return TRUE;
252b5132
RH
10782}
10783
d1133906 10784static const char *
dda8d76d 10785get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 10786{
b34976b6 10787 static char buff[32];
252b5132
RH
10788
10789 switch (binding)
10790 {
b34976b6
AM
10791 case STB_LOCAL: return "LOCAL";
10792 case STB_GLOBAL: return "GLOBAL";
10793 case STB_WEAK: return "WEAK";
252b5132
RH
10794 default:
10795 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
10796 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
10797 binding);
252b5132 10798 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
10799 {
10800 if (binding == STB_GNU_UNIQUE
dda8d76d 10801 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9c55345c 10802 /* GNU is still using the default value 0. */
dda8d76d 10803 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
3e7a7d11
NC
10804 return "UNIQUE";
10805 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
10806 }
252b5132 10807 else
e9e44622 10808 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
10809 return buff;
10810 }
10811}
10812
d1133906 10813static const char *
dda8d76d 10814get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 10815{
b34976b6 10816 static char buff[32];
252b5132
RH
10817
10818 switch (type)
10819 {
b34976b6
AM
10820 case STT_NOTYPE: return "NOTYPE";
10821 case STT_OBJECT: return "OBJECT";
10822 case STT_FUNC: return "FUNC";
10823 case STT_SECTION: return "SECTION";
10824 case STT_FILE: return "FILE";
10825 case STT_COMMON: return "COMMON";
10826 case STT_TLS: return "TLS";
15ab5209
DB
10827 case STT_RELC: return "RELC";
10828 case STT_SRELC: return "SRELC";
252b5132
RH
10829 default:
10830 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 10831 {
dda8d76d 10832 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 10833 return "THUMB_FUNC";
103f02d3 10834
dda8d76d 10835 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
10836 return "REGISTER";
10837
dda8d76d 10838 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
10839 return "PARISC_MILLI";
10840
e9e44622 10841 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 10842 }
252b5132 10843 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 10844 {
dda8d76d 10845 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
10846 {
10847 if (type == STT_HP_OPAQUE)
10848 return "HP_OPAQUE";
10849 if (type == STT_HP_STUB)
10850 return "HP_STUB";
10851 }
10852
d8045f23 10853 if (type == STT_GNU_IFUNC
dda8d76d
NC
10854 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
10855 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 10856 /* GNU is still using the default value 0. */
dda8d76d 10857 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
d8045f23
NC
10858 return "IFUNC";
10859
e9e44622 10860 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 10861 }
252b5132 10862 else
e9e44622 10863 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
10864 return buff;
10865 }
10866}
10867
d1133906 10868static const char *
d3ba0551 10869get_symbol_visibility (unsigned int visibility)
d1133906
NC
10870{
10871 switch (visibility)
10872 {
b34976b6
AM
10873 case STV_DEFAULT: return "DEFAULT";
10874 case STV_INTERNAL: return "INTERNAL";
10875 case STV_HIDDEN: return "HIDDEN";
d1133906 10876 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
10877 default:
10878 error (_("Unrecognized visibility value: %u"), visibility);
10879 return _("<unknown>");
d1133906
NC
10880 }
10881}
10882
fd85a6a1
NC
10883static const char *
10884get_solaris_symbol_visibility (unsigned int visibility)
10885{
10886 switch (visibility)
10887 {
10888 case 4: return "EXPORTED";
10889 case 5: return "SINGLETON";
10890 case 6: return "ELIMINATE";
10891 default: return get_symbol_visibility (visibility);
10892 }
10893}
10894
5e2b0d47
NC
10895static const char *
10896get_mips_symbol_other (unsigned int other)
10897{
10898 switch (other)
10899 {
32ec8896
NC
10900 case STO_OPTIONAL: return "OPTIONAL";
10901 case STO_MIPS_PLT: return "MIPS PLT";
10902 case STO_MIPS_PIC: return "MIPS PIC";
10903 case STO_MICROMIPS: return "MICROMIPS";
10904 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
10905 case STO_MIPS16: return "MIPS16";
10906 default: return NULL;
5e2b0d47
NC
10907 }
10908}
10909
28f997cf 10910static const char *
dda8d76d 10911get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 10912{
dda8d76d 10913 if (is_ia64_vms (filedata))
28f997cf
TG
10914 {
10915 static char res[32];
10916
10917 res[0] = 0;
10918
10919 /* Function types is for images and .STB files only. */
dda8d76d 10920 switch (filedata->file_header.e_type)
28f997cf
TG
10921 {
10922 case ET_DYN:
10923 case ET_EXEC:
10924 switch (VMS_ST_FUNC_TYPE (other))
10925 {
10926 case VMS_SFT_CODE_ADDR:
10927 strcat (res, " CA");
10928 break;
10929 case VMS_SFT_SYMV_IDX:
10930 strcat (res, " VEC");
10931 break;
10932 case VMS_SFT_FD:
10933 strcat (res, " FD");
10934 break;
10935 case VMS_SFT_RESERVE:
10936 strcat (res, " RSV");
10937 break;
10938 default:
bee0ee85
NC
10939 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
10940 VMS_ST_FUNC_TYPE (other));
10941 strcat (res, " <unknown>");
10942 break;
28f997cf
TG
10943 }
10944 break;
10945 default:
10946 break;
10947 }
10948 switch (VMS_ST_LINKAGE (other))
10949 {
10950 case VMS_STL_IGNORE:
10951 strcat (res, " IGN");
10952 break;
10953 case VMS_STL_RESERVE:
10954 strcat (res, " RSV");
10955 break;
10956 case VMS_STL_STD:
10957 strcat (res, " STD");
10958 break;
10959 case VMS_STL_LNK:
10960 strcat (res, " LNK");
10961 break;
10962 default:
bee0ee85
NC
10963 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
10964 VMS_ST_LINKAGE (other));
10965 strcat (res, " <unknown>");
10966 break;
28f997cf
TG
10967 }
10968
10969 if (res[0] != 0)
10970 return res + 1;
10971 else
10972 return res;
10973 }
10974 return NULL;
10975}
10976
6911b7dc
AM
10977static const char *
10978get_ppc64_symbol_other (unsigned int other)
10979{
10980 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
10981 {
10982 static char buf[32];
10983 snprintf (buf, sizeof buf, _("<localentry>: %d"),
10984 PPC64_LOCAL_ENTRY_OFFSET (other));
10985 return buf;
10986 }
10987 return NULL;
10988}
10989
5e2b0d47 10990static const char *
dda8d76d 10991get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
10992{
10993 const char * result = NULL;
10994 static char buff [32];
10995
10996 if (other == 0)
10997 return "";
10998
dda8d76d 10999 switch (filedata->file_header.e_machine)
5e2b0d47
NC
11000 {
11001 case EM_MIPS:
11002 result = get_mips_symbol_other (other);
28f997cf
TG
11003 break;
11004 case EM_IA_64:
dda8d76d 11005 result = get_ia64_symbol_other (filedata, other);
28f997cf 11006 break;
6911b7dc
AM
11007 case EM_PPC64:
11008 result = get_ppc64_symbol_other (other);
11009 break;
5e2b0d47 11010 default:
fd85a6a1 11011 result = NULL;
5e2b0d47
NC
11012 break;
11013 }
11014
11015 if (result)
11016 return result;
11017
11018 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11019 return buff;
11020}
11021
d1133906 11022static const char *
dda8d76d 11023get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11024{
b34976b6 11025 static char buff[32];
5cf1065c 11026
252b5132
RH
11027 switch (type)
11028 {
b34976b6
AM
11029 case SHN_UNDEF: return "UND";
11030 case SHN_ABS: return "ABS";
11031 case SHN_COMMON: return "COM";
252b5132 11032 default:
9ce701e2 11033 if (type == SHN_IA_64_ANSI_COMMON
dda8d76d
NC
11034 && filedata->file_header.e_machine == EM_IA_64
11035 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9ce701e2 11036 return "ANSI_COM";
dda8d76d
NC
11037 else if ((filedata->file_header.e_machine == EM_X86_64
11038 || filedata->file_header.e_machine == EM_L1OM
11039 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
11040 && type == SHN_X86_64_LCOMMON)
11041 return "LARGE_COM";
ac145307 11042 else if ((type == SHN_MIPS_SCOMMON
dda8d76d 11043 && filedata->file_header.e_machine == EM_MIPS)
ac145307 11044 || (type == SHN_TIC6X_SCOMMON
dda8d76d 11045 && filedata->file_header.e_machine == EM_TI_C6000))
172553c7
TS
11046 return "SCOM";
11047 else if (type == SHN_MIPS_SUNDEFINED
dda8d76d 11048 && filedata->file_header.e_machine == EM_MIPS)
172553c7 11049 return "SUND";
9ce701e2 11050 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 11051 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 11052 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
11053 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11054 else if (type >= SHN_LORESERVE)
11055 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
dda8d76d 11056 else if (type >= filedata->file_header.e_shnum)
e0a31db1 11057 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 11058 else
232e7cb8 11059 sprintf (buff, "%3d", type);
5cf1065c 11060 break;
252b5132 11061 }
5cf1065c
NC
11062
11063 return buff;
252b5132
RH
11064}
11065
66543521 11066static bfd_vma *
dda8d76d 11067get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
252b5132 11068{
2cf0635d
NC
11069 unsigned char * e_data;
11070 bfd_vma * i_data;
252b5132 11071
57028622
NC
11072 /* If the size_t type is smaller than the bfd_size_type, eg because
11073 you are building a 32-bit tool on a 64-bit host, then make sure
11074 that when (number) is cast to (size_t) no information is lost. */
11075 if (sizeof (size_t) < sizeof (bfd_size_type)
11076 && (bfd_size_type) ((size_t) number) != number)
11077 {
66cfc0fd
AM
11078 error (_("Size truncation prevents reading %s elements of size %u\n"),
11079 bfd_vmatoa ("u", number), ent_size);
57028622
NC
11080 return NULL;
11081 }
948f632f 11082
3102e897
NC
11083 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
11084 attempting to allocate memory when the read is bound to fail. */
dda8d76d 11085 if (ent_size * number > filedata->file_size)
3102e897 11086 {
66cfc0fd
AM
11087 error (_("Invalid number of dynamic entries: %s\n"),
11088 bfd_vmatoa ("u", number));
3102e897
NC
11089 return NULL;
11090 }
11091
57028622 11092 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
11093 if (e_data == NULL)
11094 {
66cfc0fd
AM
11095 error (_("Out of memory reading %s dynamic entries\n"),
11096 bfd_vmatoa ("u", number));
252b5132
RH
11097 return NULL;
11098 }
11099
dda8d76d 11100 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
252b5132 11101 {
66cfc0fd
AM
11102 error (_("Unable to read in %s bytes of dynamic data\n"),
11103 bfd_vmatoa ("u", number * ent_size));
3102e897 11104 free (e_data);
252b5132
RH
11105 return NULL;
11106 }
11107
57028622 11108 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
11109 if (i_data == NULL)
11110 {
66cfc0fd
AM
11111 error (_("Out of memory allocating space for %s dynamic entries\n"),
11112 bfd_vmatoa ("u", number));
252b5132
RH
11113 free (e_data);
11114 return NULL;
11115 }
11116
11117 while (number--)
66543521 11118 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
11119
11120 free (e_data);
11121
11122 return i_data;
11123}
11124
6bd1a22c 11125static void
dda8d76d 11126print_dynamic_symbol (Filedata * filedata, bfd_vma si, unsigned long hn)
6bd1a22c 11127{
2cf0635d 11128 Elf_Internal_Sym * psym;
6bd1a22c
L
11129 int n;
11130
6bd1a22c
L
11131 n = print_vma (si, DEC_5);
11132 if (n < 5)
0b4362b0 11133 fputs (&" "[n], stdout);
6bd1a22c 11134 printf (" %3lu: ", hn);
e0a31db1
NC
11135
11136 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
11137 {
3102e897
NC
11138 printf (_("<No info available for dynamic symbol number %lu>\n"),
11139 (unsigned long) si);
e0a31db1
NC
11140 return;
11141 }
11142
11143 psym = dynamic_symbols + si;
6bd1a22c
L
11144 print_vma (psym->st_value, LONG_HEX);
11145 putchar (' ');
11146 print_vma (psym->st_size, DEC_5);
11147
dda8d76d
NC
11148 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11149 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
fd85a6a1 11150
dda8d76d 11151 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11152 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11153 else
11154 {
11155 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11156
11157 printf (" %-7s", get_symbol_visibility (vis));
11158 /* Check to see if any other bits in the st_other field are set.
11159 Note - displaying this information disrupts the layout of the
11160 table being generated, but for the moment this case is very
11161 rare. */
11162 if (psym->st_other ^ vis)
dda8d76d 11163 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1
NC
11164 }
11165
dda8d76d 11166 printf (" %3.3s ", get_symbol_index_type (filedata, psym->st_shndx));
6bd1a22c
L
11167 if (VALID_DYNAMIC_NAME (psym->st_name))
11168 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11169 else
2b692964 11170 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
11171 putchar ('\n');
11172}
11173
bb4d2ac2 11174static const char *
dda8d76d 11175get_symbol_version_string (Filedata * filedata,
1449284b
NC
11176 bfd_boolean is_dynsym,
11177 const char * strtab,
11178 unsigned long int strtab_size,
11179 unsigned int si,
11180 Elf_Internal_Sym * psym,
11181 enum versioned_symbol_info * sym_info,
11182 unsigned short * vna_other)
bb4d2ac2 11183{
ab273396
AM
11184 unsigned char data[2];
11185 unsigned short vers_data;
11186 unsigned long offset;
bb4d2ac2 11187
ab273396
AM
11188 if (!is_dynsym
11189 || version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
11190 return NULL;
bb4d2ac2 11191
dda8d76d 11192 offset = offset_from_vma (filedata, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11193 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11194
dda8d76d 11195 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11196 sizeof (data), 1, _("version data")) == NULL)
11197 return NULL;
11198
11199 vers_data = byte_get (data, 2);
bb4d2ac2 11200
ab273396
AM
11201 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data <= 1)
11202 return NULL;
bb4d2ac2 11203
ab273396
AM
11204 /* Usually we'd only see verdef for defined symbols, and verneed for
11205 undefined symbols. However, symbols defined by the linker in
11206 .dynbss for variables copied from a shared library in order to
11207 avoid text relocations are defined yet have verneed. We could
11208 use a heuristic to detect the special case, for example, check
11209 for verneed first on symbols defined in SHT_NOBITS sections, but
11210 it is simpler and more reliable to just look for both verdef and
11211 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11212
ab273396
AM
11213 if (psym->st_shndx != SHN_UNDEF
11214 && vers_data != 0x8001
11215 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
11216 {
11217 Elf_Internal_Verdef ivd;
11218 Elf_Internal_Verdaux ivda;
11219 Elf_External_Verdaux evda;
11220 unsigned long off;
bb4d2ac2 11221
dda8d76d 11222 off = offset_from_vma (filedata,
ab273396
AM
11223 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
11224 sizeof (Elf_External_Verdef));
11225
11226 do
bb4d2ac2 11227 {
ab273396
AM
11228 Elf_External_Verdef evd;
11229
dda8d76d 11230 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11231 _("version def")) == NULL)
11232 {
11233 ivd.vd_ndx = 0;
11234 ivd.vd_aux = 0;
11235 ivd.vd_next = 0;
11236 }
11237 else
bb4d2ac2 11238 {
ab273396
AM
11239 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11240 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11241 ivd.vd_next = BYTE_GET (evd.vd_next);
11242 }
bb4d2ac2 11243
ab273396
AM
11244 off += ivd.vd_next;
11245 }
11246 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11247
ab273396
AM
11248 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11249 {
11250 off -= ivd.vd_next;
11251 off += ivd.vd_aux;
bb4d2ac2 11252
dda8d76d 11253 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
11254 _("version def aux")) != NULL)
11255 {
11256 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 11257
ab273396
AM
11258 if (psym->st_name != ivda.vda_name)
11259 {
11260 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
11261 ? symbol_hidden : symbol_public);
11262 return (ivda.vda_name < strtab_size
11263 ? strtab + ivda.vda_name : _("<corrupt>"));
11264 }
11265 }
11266 }
11267 }
bb4d2ac2 11268
ab273396
AM
11269 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
11270 {
11271 Elf_External_Verneed evn;
11272 Elf_Internal_Verneed ivn;
11273 Elf_Internal_Vernaux ivna;
bb4d2ac2 11274
dda8d76d 11275 offset = offset_from_vma (filedata,
ab273396
AM
11276 version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
11277 sizeof evn);
11278 do
11279 {
11280 unsigned long vna_off;
bb4d2ac2 11281
dda8d76d 11282 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
11283 _("version need")) == NULL)
11284 {
11285 ivna.vna_next = 0;
11286 ivna.vna_other = 0;
11287 ivna.vna_name = 0;
11288 break;
11289 }
bb4d2ac2 11290
ab273396
AM
11291 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11292 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 11293
ab273396 11294 vna_off = offset + ivn.vn_aux;
bb4d2ac2 11295
ab273396
AM
11296 do
11297 {
11298 Elf_External_Vernaux evna;
bb4d2ac2 11299
dda8d76d 11300 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 11301 _("version need aux (3)")) == NULL)
bb4d2ac2 11302 {
ab273396
AM
11303 ivna.vna_next = 0;
11304 ivna.vna_other = 0;
11305 ivna.vna_name = 0;
bb4d2ac2 11306 }
bb4d2ac2 11307 else
bb4d2ac2 11308 {
ab273396
AM
11309 ivna.vna_other = BYTE_GET (evna.vna_other);
11310 ivna.vna_next = BYTE_GET (evna.vna_next);
11311 ivna.vna_name = BYTE_GET (evna.vna_name);
11312 }
bb4d2ac2 11313
ab273396
AM
11314 vna_off += ivna.vna_next;
11315 }
11316 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 11317
ab273396
AM
11318 if (ivna.vna_other == vers_data)
11319 break;
bb4d2ac2 11320
ab273396
AM
11321 offset += ivn.vn_next;
11322 }
11323 while (ivn.vn_next != 0);
bb4d2ac2 11324
ab273396
AM
11325 if (ivna.vna_other == vers_data)
11326 {
11327 *sym_info = symbol_undefined;
11328 *vna_other = ivna.vna_other;
11329 return (ivna.vna_name < strtab_size
11330 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2
L
11331 }
11332 }
ab273396 11333 return NULL;
bb4d2ac2
L
11334}
11335
e3c8793a 11336/* Dump the symbol table. */
32ec8896 11337static bfd_boolean
dda8d76d 11338process_symbol_table (Filedata * filedata)
252b5132 11339{
2cf0635d 11340 Elf_Internal_Shdr * section;
8b73c356
NC
11341 bfd_size_type nbuckets = 0;
11342 bfd_size_type nchains = 0;
2cf0635d
NC
11343 bfd_vma * buckets = NULL;
11344 bfd_vma * chains = NULL;
fdc90cb4 11345 bfd_vma ngnubuckets = 0;
2cf0635d
NC
11346 bfd_vma * gnubuckets = NULL;
11347 bfd_vma * gnuchains = NULL;
6bd1a22c 11348 bfd_vma gnusymidx = 0;
071436c6 11349 bfd_size_type ngnuchains = 0;
252b5132 11350
2c610e4b 11351 if (!do_syms && !do_dyn_syms && !do_histogram)
32ec8896 11352 return TRUE;
252b5132 11353
6bd1a22c
L
11354 if (dynamic_info[DT_HASH]
11355 && (do_histogram
2c610e4b
L
11356 || (do_using_dynamic
11357 && !do_dyn_syms
11358 && dynamic_strings != NULL)))
252b5132 11359 {
66543521
AM
11360 unsigned char nb[8];
11361 unsigned char nc[8];
8b73c356 11362 unsigned int hash_ent_size = 4;
66543521 11363
dda8d76d
NC
11364 if ((filedata->file_header.e_machine == EM_ALPHA
11365 || filedata->file_header.e_machine == EM_S390
11366 || filedata->file_header.e_machine == EM_S390_OLD)
11367 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
66543521
AM
11368 hash_ent_size = 8;
11369
dda8d76d 11370 if (fseek (filedata->handle,
fb52b2f4 11371 (archive_file_offset
dda8d76d 11372 + offset_from_vma (filedata, dynamic_info[DT_HASH],
fb52b2f4 11373 sizeof nb + sizeof nc)),
d93f0186 11374 SEEK_SET))
252b5132 11375 {
591a748a 11376 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11377 goto no_hash;
252b5132
RH
11378 }
11379
dda8d76d 11380 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11381 {
11382 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11383 goto no_hash;
252b5132
RH
11384 }
11385
dda8d76d 11386 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11387 {
11388 error (_("Failed to read in number of chains\n"));
d3a44ec6 11389 goto no_hash;
252b5132
RH
11390 }
11391
66543521
AM
11392 nbuckets = byte_get (nb, hash_ent_size);
11393 nchains = byte_get (nc, hash_ent_size);
252b5132 11394
dda8d76d
NC
11395 buckets = get_dynamic_data (filedata, nbuckets, hash_ent_size);
11396 chains = get_dynamic_data (filedata, nchains, hash_ent_size);
252b5132 11397
d3a44ec6 11398 no_hash:
252b5132 11399 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
11400 {
11401 if (do_using_dynamic)
32ec8896 11402 return FALSE;
d3a44ec6
JJ
11403 free (buckets);
11404 free (chains);
11405 buckets = NULL;
11406 chains = NULL;
11407 nbuckets = 0;
11408 nchains = 0;
11409 }
252b5132
RH
11410 }
11411
6bd1a22c
L
11412 if (dynamic_info_DT_GNU_HASH
11413 && (do_histogram
2c610e4b
L
11414 || (do_using_dynamic
11415 && !do_dyn_syms
11416 && dynamic_strings != NULL)))
252b5132 11417 {
6bd1a22c
L
11418 unsigned char nb[16];
11419 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11420 bfd_vma buckets_vma;
11421
dda8d76d 11422 if (fseek (filedata->handle,
6bd1a22c 11423 (archive_file_offset
dda8d76d 11424 + offset_from_vma (filedata, dynamic_info_DT_GNU_HASH,
6bd1a22c
L
11425 sizeof nb)),
11426 SEEK_SET))
11427 {
11428 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11429 goto no_gnu_hash;
6bd1a22c 11430 }
252b5132 11431
dda8d76d 11432 if (fread (nb, 16, 1, filedata->handle) != 1)
6bd1a22c
L
11433 {
11434 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11435 goto no_gnu_hash;
6bd1a22c
L
11436 }
11437
11438 ngnubuckets = byte_get (nb, 4);
11439 gnusymidx = byte_get (nb + 4, 4);
11440 bitmaskwords = byte_get (nb + 8, 4);
11441 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 11442 if (is_32bit_elf)
6bd1a22c 11443 buckets_vma += bitmaskwords * 4;
f7a99963 11444 else
6bd1a22c 11445 buckets_vma += bitmaskwords * 8;
252b5132 11446
dda8d76d 11447 if (fseek (filedata->handle,
6bd1a22c 11448 (archive_file_offset
dda8d76d 11449 + offset_from_vma (filedata, buckets_vma, 4)),
6bd1a22c 11450 SEEK_SET))
252b5132 11451 {
6bd1a22c 11452 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11453 goto no_gnu_hash;
6bd1a22c
L
11454 }
11455
dda8d76d 11456 gnubuckets = get_dynamic_data (filedata, ngnubuckets, 4);
252b5132 11457
6bd1a22c 11458 if (gnubuckets == NULL)
d3a44ec6 11459 goto no_gnu_hash;
6bd1a22c
L
11460
11461 for (i = 0; i < ngnubuckets; i++)
11462 if (gnubuckets[i] != 0)
11463 {
11464 if (gnubuckets[i] < gnusymidx)
32ec8896 11465 return FALSE;
6bd1a22c
L
11466
11467 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
11468 maxchain = gnubuckets[i];
11469 }
11470
11471 if (maxchain == 0xffffffff)
d3a44ec6 11472 goto no_gnu_hash;
6bd1a22c
L
11473
11474 maxchain -= gnusymidx;
11475
dda8d76d 11476 if (fseek (filedata->handle,
6bd1a22c 11477 (archive_file_offset
dda8d76d 11478 + offset_from_vma (filedata, buckets_vma
6bd1a22c
L
11479 + 4 * (ngnubuckets + maxchain), 4)),
11480 SEEK_SET))
11481 {
11482 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11483 goto no_gnu_hash;
6bd1a22c
L
11484 }
11485
11486 do
11487 {
dda8d76d 11488 if (fread (nb, 4, 1, filedata->handle) != 1)
252b5132 11489 {
6bd1a22c 11490 error (_("Failed to determine last chain length\n"));
d3a44ec6 11491 goto no_gnu_hash;
6bd1a22c 11492 }
252b5132 11493
6bd1a22c 11494 if (maxchain + 1 == 0)
d3a44ec6 11495 goto no_gnu_hash;
252b5132 11496
6bd1a22c
L
11497 ++maxchain;
11498 }
11499 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 11500
dda8d76d 11501 if (fseek (filedata->handle,
6bd1a22c 11502 (archive_file_offset
dda8d76d 11503 + offset_from_vma (filedata, buckets_vma + 4 * ngnubuckets, 4)),
6bd1a22c
L
11504 SEEK_SET))
11505 {
11506 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11507 goto no_gnu_hash;
6bd1a22c
L
11508 }
11509
dda8d76d 11510 gnuchains = get_dynamic_data (filedata, maxchain, 4);
071436c6 11511 ngnuchains = maxchain;
6bd1a22c 11512
d3a44ec6 11513 no_gnu_hash:
6bd1a22c 11514 if (gnuchains == NULL)
d3a44ec6
JJ
11515 {
11516 free (gnubuckets);
d3a44ec6
JJ
11517 gnubuckets = NULL;
11518 ngnubuckets = 0;
f64fddf1 11519 if (do_using_dynamic)
32ec8896 11520 return FALSE;
d3a44ec6 11521 }
6bd1a22c
L
11522 }
11523
11524 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
11525 && do_syms
11526 && do_using_dynamic
3102e897
NC
11527 && dynamic_strings != NULL
11528 && dynamic_symbols != NULL)
6bd1a22c
L
11529 {
11530 unsigned long hn;
11531
11532 if (dynamic_info[DT_HASH])
11533 {
11534 bfd_vma si;
6bd6a03d 11535 char *visited;
6bd1a22c
L
11536
11537 printf (_("\nSymbol table for image:\n"));
11538 if (is_32bit_elf)
11539 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11540 else
11541 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11542
6bd6a03d
AM
11543 visited = xcmalloc (nchains, 1);
11544 memset (visited, 0, nchains);
6bd1a22c
L
11545 for (hn = 0; hn < nbuckets; hn++)
11546 {
6bd6a03d
AM
11547 for (si = buckets[hn]; si > 0; si = chains[si])
11548 {
dda8d76d 11549 print_dynamic_symbol (filedata, si, hn);
6bd6a03d
AM
11550 if (si >= nchains || visited[si])
11551 {
11552 error (_("histogram chain is corrupt\n"));
11553 break;
11554 }
11555 visited[si] = 1;
11556 }
252b5132 11557 }
6bd6a03d 11558 free (visited);
252b5132 11559 }
6bd1a22c
L
11560
11561 if (dynamic_info_DT_GNU_HASH)
11562 {
11563 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
11564 if (is_32bit_elf)
11565 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11566 else
11567 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11568
11569 for (hn = 0; hn < ngnubuckets; ++hn)
11570 if (gnubuckets[hn] != 0)
11571 {
11572 bfd_vma si = gnubuckets[hn];
11573 bfd_vma off = si - gnusymidx;
11574
11575 do
11576 {
dda8d76d 11577 print_dynamic_symbol (filedata, si, hn);
6bd1a22c
L
11578 si++;
11579 }
071436c6 11580 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
11581 }
11582 }
252b5132 11583 }
8b73c356 11584 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 11585 && filedata->section_headers != NULL)
252b5132 11586 {
b34976b6 11587 unsigned int i;
252b5132 11588
dda8d76d
NC
11589 for (i = 0, section = filedata->section_headers;
11590 i < filedata->file_header.e_shnum;
252b5132
RH
11591 i++, section++)
11592 {
b34976b6 11593 unsigned int si;
2cf0635d 11594 char * strtab = NULL;
c256ffe7 11595 unsigned long int strtab_size = 0;
2cf0635d
NC
11596 Elf_Internal_Sym * symtab;
11597 Elf_Internal_Sym * psym;
ba5cdace 11598 unsigned long num_syms;
252b5132 11599
2c610e4b
L
11600 if ((section->sh_type != SHT_SYMTAB
11601 && section->sh_type != SHT_DYNSYM)
11602 || (!do_syms
11603 && section->sh_type == SHT_SYMTAB))
252b5132
RH
11604 continue;
11605
dd24e3da
NC
11606 if (section->sh_entsize == 0)
11607 {
11608 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 11609 printable_section_name (filedata, section));
dd24e3da
NC
11610 continue;
11611 }
11612
d3a49aa8
AM
11613 num_syms = section->sh_size / section->sh_entsize;
11614 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
11615 "\nSymbol table '%s' contains %lu entries:\n",
11616 num_syms),
dda8d76d 11617 printable_section_name (filedata, section),
d3a49aa8 11618 num_syms);
dd24e3da 11619
f7a99963 11620 if (is_32bit_elf)
ca47b30c 11621 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 11622 else
ca47b30c 11623 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 11624
dda8d76d 11625 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
11626 if (symtab == NULL)
11627 continue;
11628
dda8d76d 11629 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 11630 {
dda8d76d
NC
11631 strtab = filedata->string_table;
11632 strtab_size = filedata->string_table_length;
c256ffe7 11633 }
dda8d76d 11634 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 11635 {
2cf0635d 11636 Elf_Internal_Shdr * string_sec;
252b5132 11637
dda8d76d 11638 string_sec = filedata->section_headers + section->sh_link;
252b5132 11639
dda8d76d 11640 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
11641 1, string_sec->sh_size,
11642 _("string table"));
c256ffe7 11643 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
11644 }
11645
ba5cdace 11646 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 11647 {
bb4d2ac2
L
11648 const char *version_string;
11649 enum versioned_symbol_info sym_info;
11650 unsigned short vna_other;
11651
5e220199 11652 printf ("%6d: ", si);
f7a99963
NC
11653 print_vma (psym->st_value, LONG_HEX);
11654 putchar (' ');
11655 print_vma (psym->st_size, DEC_5);
dda8d76d
NC
11656 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11657 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
11658 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11659 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11660 else
11661 {
11662 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11663
11664 printf (" %-7s", get_symbol_visibility (vis));
11665 /* Check to see if any other bits in the st_other field are set.
11666 Note - displaying this information disrupts the layout of the
11667 table being generated, but for the moment this case is very rare. */
11668 if (psym->st_other ^ vis)
dda8d76d 11669 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1 11670 }
dda8d76d 11671 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
c256ffe7 11672 print_symbol (25, psym->st_name < strtab_size
2b692964 11673 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 11674
bb4d2ac2 11675 version_string
dda8d76d 11676 = get_symbol_version_string (filedata,
bb4d2ac2
L
11677 section->sh_type == SHT_DYNSYM,
11678 strtab, strtab_size, si,
11679 psym, &sym_info, &vna_other);
11680 if (version_string)
252b5132 11681 {
bb4d2ac2
L
11682 if (sym_info == symbol_undefined)
11683 printf ("@%s (%d)", version_string, vna_other);
11684 else
11685 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
11686 version_string);
252b5132
RH
11687 }
11688
11689 putchar ('\n');
52c3c391
NC
11690
11691 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
dd905818
NC
11692 && si >= section->sh_info
11693 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
dda8d76d 11694 && filedata->file_header.e_machine != EM_MIPS
dd905818
NC
11695 /* Solaris binaries have been found to violate this requirement as
11696 well. Not sure if this is a bug or an ABI requirement. */
dda8d76d 11697 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
52c3c391 11698 warn (_("local symbol %u found at index >= %s's sh_info value of %u\n"),
dda8d76d 11699 si, printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11700 }
11701
11702 free (symtab);
dda8d76d 11703 if (strtab != filedata->string_table)
252b5132
RH
11704 free (strtab);
11705 }
11706 }
11707 else if (do_syms)
11708 printf
11709 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
11710
11711 if (do_histogram && buckets != NULL)
11712 {
2cf0635d
NC
11713 unsigned long * lengths;
11714 unsigned long * counts;
66543521
AM
11715 unsigned long hn;
11716 bfd_vma si;
11717 unsigned long maxlength = 0;
11718 unsigned long nzero_counts = 0;
11719 unsigned long nsyms = 0;
6bd6a03d 11720 char *visited;
252b5132 11721
d3a49aa8
AM
11722 printf (ngettext ("\nHistogram for bucket list length "
11723 "(total of %lu bucket):\n",
11724 "\nHistogram for bucket list length "
11725 "(total of %lu buckets):\n",
11726 (unsigned long) nbuckets),
66543521 11727 (unsigned long) nbuckets);
252b5132 11728
3f5e193b 11729 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
11730 if (lengths == NULL)
11731 {
8b73c356 11732 error (_("Out of memory allocating space for histogram buckets\n"));
32ec8896 11733 return FALSE;
252b5132 11734 }
6bd6a03d
AM
11735 visited = xcmalloc (nchains, 1);
11736 memset (visited, 0, nchains);
8b73c356
NC
11737
11738 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
11739 for (hn = 0; hn < nbuckets; ++hn)
11740 {
6bd6a03d 11741 for (si = buckets[hn]; si > 0; si = chains[si])
252b5132 11742 {
b34976b6 11743 ++nsyms;
252b5132 11744 if (maxlength < ++lengths[hn])
b34976b6 11745 ++maxlength;
6bd6a03d
AM
11746 if (si >= nchains || visited[si])
11747 {
11748 error (_("histogram chain is corrupt\n"));
11749 break;
11750 }
11751 visited[si] = 1;
252b5132
RH
11752 }
11753 }
6bd6a03d 11754 free (visited);
252b5132 11755
3f5e193b 11756 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
11757 if (counts == NULL)
11758 {
b2e951ec 11759 free (lengths);
8b73c356 11760 error (_("Out of memory allocating space for histogram counts\n"));
32ec8896 11761 return FALSE;
252b5132
RH
11762 }
11763
11764 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 11765 ++counts[lengths[hn]];
252b5132 11766
103f02d3 11767 if (nbuckets > 0)
252b5132 11768 {
66543521
AM
11769 unsigned long i;
11770 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 11771 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 11772 for (i = 1; i <= maxlength; ++i)
103f02d3 11773 {
66543521
AM
11774 nzero_counts += counts[i] * i;
11775 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11776 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
11777 (nzero_counts * 100.0) / nsyms);
11778 }
252b5132
RH
11779 }
11780
11781 free (counts);
11782 free (lengths);
11783 }
11784
11785 if (buckets != NULL)
11786 {
11787 free (buckets);
11788 free (chains);
11789 }
11790
d3a44ec6 11791 if (do_histogram && gnubuckets != NULL)
fdc90cb4 11792 {
2cf0635d
NC
11793 unsigned long * lengths;
11794 unsigned long * counts;
fdc90cb4
JJ
11795 unsigned long hn;
11796 unsigned long maxlength = 0;
11797 unsigned long nzero_counts = 0;
11798 unsigned long nsyms = 0;
fdc90cb4 11799
d3a49aa8
AM
11800 printf (ngettext ("\nHistogram for `.gnu.hash' bucket list length "
11801 "(total of %lu bucket):\n",
11802 "\nHistogram for `.gnu.hash' bucket list length "
11803 "(total of %lu buckets):\n",
11804 (unsigned long) ngnubuckets),
8b73c356
NC
11805 (unsigned long) ngnubuckets);
11806
3f5e193b 11807 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
11808 if (lengths == NULL)
11809 {
8b73c356 11810 error (_("Out of memory allocating space for gnu histogram buckets\n"));
32ec8896 11811 return FALSE;
fdc90cb4
JJ
11812 }
11813
fdc90cb4
JJ
11814 printf (_(" Length Number %% of total Coverage\n"));
11815
11816 for (hn = 0; hn < ngnubuckets; ++hn)
11817 if (gnubuckets[hn] != 0)
11818 {
11819 bfd_vma off, length = 1;
11820
6bd1a22c 11821 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
11822 /* PR 17531 file: 010-77222-0.004. */
11823 off < ngnuchains && (gnuchains[off] & 1) == 0;
11824 ++off)
fdc90cb4
JJ
11825 ++length;
11826 lengths[hn] = length;
11827 if (length > maxlength)
11828 maxlength = length;
11829 nsyms += length;
11830 }
11831
3f5e193b 11832 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
11833 if (counts == NULL)
11834 {
b2e951ec 11835 free (lengths);
8b73c356 11836 error (_("Out of memory allocating space for gnu histogram counts\n"));
32ec8896 11837 return FALSE;
fdc90cb4
JJ
11838 }
11839
11840 for (hn = 0; hn < ngnubuckets; ++hn)
11841 ++counts[lengths[hn]];
11842
11843 if (ngnubuckets > 0)
11844 {
11845 unsigned long j;
11846 printf (" 0 %-10lu (%5.1f%%)\n",
11847 counts[0], (counts[0] * 100.0) / ngnubuckets);
11848 for (j = 1; j <= maxlength; ++j)
11849 {
11850 nzero_counts += counts[j] * j;
11851 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11852 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
11853 (nzero_counts * 100.0) / nsyms);
11854 }
11855 }
11856
11857 free (counts);
11858 free (lengths);
11859 free (gnubuckets);
11860 free (gnuchains);
11861 }
11862
32ec8896 11863 return TRUE;
252b5132
RH
11864}
11865
32ec8896 11866static bfd_boolean
dda8d76d 11867process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 11868{
b4c96d0d 11869 unsigned int i;
252b5132
RH
11870
11871 if (dynamic_syminfo == NULL
11872 || !do_dynamic)
11873 /* No syminfo, this is ok. */
32ec8896 11874 return TRUE;
252b5132
RH
11875
11876 /* There better should be a dynamic symbol section. */
11877 if (dynamic_symbols == NULL || dynamic_strings == NULL)
32ec8896 11878 return FALSE;
252b5132
RH
11879
11880 if (dynamic_addr)
d3a49aa8
AM
11881 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
11882 "contains %d entry:\n",
11883 "\nDynamic info segment at offset 0x%lx "
11884 "contains %d entries:\n",
11885 dynamic_syminfo_nent),
252b5132
RH
11886 dynamic_syminfo_offset, dynamic_syminfo_nent);
11887
11888 printf (_(" Num: Name BoundTo Flags\n"));
11889 for (i = 0; i < dynamic_syminfo_nent; ++i)
11890 {
11891 unsigned short int flags = dynamic_syminfo[i].si_flags;
11892
31104126 11893 printf ("%4d: ", i);
4082ef84
NC
11894 if (i >= num_dynamic_syms)
11895 printf (_("<corrupt index>"));
11896 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
11897 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
11898 else
2b692964 11899 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 11900 putchar (' ');
252b5132
RH
11901
11902 switch (dynamic_syminfo[i].si_boundto)
11903 {
11904 case SYMINFO_BT_SELF:
11905 fputs ("SELF ", stdout);
11906 break;
11907 case SYMINFO_BT_PARENT:
11908 fputs ("PARENT ", stdout);
11909 break;
11910 default:
11911 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
11912 && dynamic_syminfo[i].si_boundto < dynamic_nent
11913 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 11914 {
d79b3d50 11915 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
11916 putchar (' ' );
11917 }
252b5132
RH
11918 else
11919 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
11920 break;
11921 }
11922
11923 if (flags & SYMINFO_FLG_DIRECT)
11924 printf (" DIRECT");
11925 if (flags & SYMINFO_FLG_PASSTHRU)
11926 printf (" PASSTHRU");
11927 if (flags & SYMINFO_FLG_COPY)
11928 printf (" COPY");
11929 if (flags & SYMINFO_FLG_LAZYLOAD)
11930 printf (" LAZYLOAD");
11931
11932 puts ("");
11933 }
11934
32ec8896 11935 return TRUE;
252b5132
RH
11936}
11937
b32e566b
NC
11938#define IN_RANGE(START,END,ADDR,OFF) \
11939 (((ADDR) >= (START)) && ((ADDR) + (OFF) < (END)))
11940
cf13d699
NC
11941/* Check to see if the given reloc needs to be handled in a target specific
11942 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
11943 FALSE.
11944
11945 If called with reloc == NULL, then this is a signal that reloc processing
11946 for the current section has finished, and any saved state should be
11947 discarded. */
09c11c86 11948
cf13d699 11949static bfd_boolean
dda8d76d
NC
11950target_specific_reloc_handling (Filedata * filedata,
11951 Elf_Internal_Rela * reloc,
11952 unsigned char * start,
11953 unsigned char * end,
11954 Elf_Internal_Sym * symtab,
11955 unsigned long num_syms)
252b5132 11956{
f84ce13b
NC
11957 unsigned int reloc_type = 0;
11958 unsigned long sym_index = 0;
11959
11960 if (reloc)
11961 {
dda8d76d 11962 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
11963 sym_index = get_reloc_symindex (reloc->r_info);
11964 }
252b5132 11965
dda8d76d 11966 switch (filedata->file_header.e_machine)
252b5132 11967 {
13761a11
NC
11968 case EM_MSP430:
11969 case EM_MSP430_OLD:
11970 {
11971 static Elf_Internal_Sym * saved_sym = NULL;
11972
f84ce13b
NC
11973 if (reloc == NULL)
11974 {
11975 saved_sym = NULL;
11976 return TRUE;
11977 }
11978
13761a11
NC
11979 switch (reloc_type)
11980 {
11981 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 11982 if (uses_msp430x_relocs (filedata))
13761a11 11983 break;
1a0670f3 11984 /* Fall through. */
13761a11 11985 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
11986 /* PR 21139. */
11987 if (sym_index >= num_syms)
11988 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
11989 sym_index);
11990 else
11991 saved_sym = symtab + sym_index;
13761a11
NC
11992 return TRUE;
11993
11994 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
11995 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
11996 goto handle_sym_diff;
0b4362b0 11997
13761a11
NC
11998 case 5: /* R_MSP430_16_BYTE */
11999 case 9: /* R_MSP430_8 */
dda8d76d 12000 if (uses_msp430x_relocs (filedata))
13761a11
NC
12001 break;
12002 goto handle_sym_diff;
12003
12004 case 2: /* R_MSP430_ABS16 */
12005 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12006 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12007 break;
12008 goto handle_sym_diff;
0b4362b0 12009
13761a11
NC
12010 handle_sym_diff:
12011 if (saved_sym != NULL)
12012 {
03f7786e 12013 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12014 bfd_vma value;
12015
f84ce13b
NC
12016 if (sym_index >= num_syms)
12017 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12018 sym_index);
03f7786e 12019 else
f84ce13b
NC
12020 {
12021 value = reloc->r_addend + (symtab[sym_index].st_value
12022 - saved_sym->st_value);
12023
b32e566b 12024 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12025 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12026 else
12027 /* PR 21137 */
12028 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12029 (long) reloc->r_offset);
f84ce13b 12030 }
13761a11
NC
12031
12032 saved_sym = NULL;
12033 return TRUE;
12034 }
12035 break;
12036
12037 default:
12038 if (saved_sym != NULL)
071436c6 12039 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12040 break;
12041 }
12042 break;
12043 }
12044
cf13d699
NC
12045 case EM_MN10300:
12046 case EM_CYGNUS_MN10300:
12047 {
12048 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12049
f84ce13b
NC
12050 if (reloc == NULL)
12051 {
12052 saved_sym = NULL;
12053 return TRUE;
12054 }
12055
cf13d699
NC
12056 switch (reloc_type)
12057 {
12058 case 34: /* R_MN10300_ALIGN */
12059 return TRUE;
12060 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12061 if (sym_index >= num_syms)
12062 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12063 sym_index);
12064 else
12065 saved_sym = symtab + sym_index;
cf13d699 12066 return TRUE;
f84ce13b 12067
cf13d699
NC
12068 case 1: /* R_MN10300_32 */
12069 case 2: /* R_MN10300_16 */
12070 if (saved_sym != NULL)
12071 {
03f7786e 12072 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12073 bfd_vma value;
252b5132 12074
f84ce13b
NC
12075 if (sym_index >= num_syms)
12076 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12077 sym_index);
03f7786e 12078 else
f84ce13b
NC
12079 {
12080 value = reloc->r_addend + (symtab[sym_index].st_value
12081 - saved_sym->st_value);
12082
b32e566b 12083 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12084 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12085 else
12086 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12087 (long) reloc->r_offset);
f84ce13b 12088 }
252b5132 12089
cf13d699
NC
12090 saved_sym = NULL;
12091 return TRUE;
12092 }
12093 break;
12094 default:
12095 if (saved_sym != NULL)
071436c6 12096 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12097 break;
12098 }
12099 break;
12100 }
6ff71e76
NC
12101
12102 case EM_RL78:
12103 {
12104 static bfd_vma saved_sym1 = 0;
12105 static bfd_vma saved_sym2 = 0;
12106 static bfd_vma value;
12107
f84ce13b
NC
12108 if (reloc == NULL)
12109 {
12110 saved_sym1 = saved_sym2 = 0;
12111 return TRUE;
12112 }
12113
6ff71e76
NC
12114 switch (reloc_type)
12115 {
12116 case 0x80: /* R_RL78_SYM. */
12117 saved_sym1 = saved_sym2;
f84ce13b
NC
12118 if (sym_index >= num_syms)
12119 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12120 sym_index);
12121 else
12122 {
12123 saved_sym2 = symtab[sym_index].st_value;
12124 saved_sym2 += reloc->r_addend;
12125 }
6ff71e76
NC
12126 return TRUE;
12127
12128 case 0x83: /* R_RL78_OPsub. */
12129 value = saved_sym1 - saved_sym2;
12130 saved_sym2 = saved_sym1 = 0;
12131 return TRUE;
12132 break;
12133
12134 case 0x41: /* R_RL78_ABS32. */
b32e566b 12135 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12136 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12137 else
12138 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12139 (long) reloc->r_offset);
6ff71e76
NC
12140 value = 0;
12141 return TRUE;
12142
12143 case 0x43: /* R_RL78_ABS16. */
b32e566b 12144 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12145 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12146 else
12147 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12148 (long) reloc->r_offset);
6ff71e76
NC
12149 value = 0;
12150 return TRUE;
12151
12152 default:
12153 break;
12154 }
12155 break;
12156 }
252b5132
RH
12157 }
12158
cf13d699 12159 return FALSE;
252b5132
RH
12160}
12161
aca88567
NC
12162/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12163 DWARF debug sections. This is a target specific test. Note - we do not
12164 go through the whole including-target-headers-multiple-times route, (as
12165 we have already done with <elf/h8.h>) because this would become very
12166 messy and even then this function would have to contain target specific
12167 information (the names of the relocs instead of their numeric values).
12168 FIXME: This is not the correct way to solve this problem. The proper way
12169 is to have target specific reloc sizing and typing functions created by
12170 the reloc-macros.h header, in the same way that it already creates the
12171 reloc naming functions. */
12172
12173static bfd_boolean
dda8d76d 12174is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12175{
d347c9df 12176 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12177 switch (filedata->file_header.e_machine)
aca88567 12178 {
41e92641 12179 case EM_386:
22abe556 12180 case EM_IAMCU:
41e92641 12181 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12182 case EM_68K:
12183 return reloc_type == 1; /* R_68K_32. */
a06ea964 12184 case EM_AARCH64:
9282b95a
JW
12185 return (reloc_type == 258
12186 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
d347c9df
PS
12187 case EM_ADAPTEVA_EPIPHANY:
12188 return reloc_type == 3;
aca88567 12189 case EM_ALPHA:
137b6b5f 12190 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12191 case EM_ARC:
12192 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12193 case EM_ARC_COMPACT:
12194 case EM_ARC_COMPACT2:
12195 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12196 case EM_ARM:
12197 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12198 case EM_AVR_OLD:
aca88567
NC
12199 case EM_AVR:
12200 return reloc_type == 1;
12201 case EM_BLACKFIN:
12202 return reloc_type == 0x12; /* R_byte4_data. */
12203 case EM_CRIS:
12204 return reloc_type == 3; /* R_CRIS_32. */
12205 case EM_CR16:
12206 return reloc_type == 3; /* R_CR16_NUM32. */
12207 case EM_CRX:
12208 return reloc_type == 15; /* R_CRX_NUM32. */
12209 case EM_CYGNUS_FRV:
12210 return reloc_type == 1;
41e92641
NC
12211 case EM_CYGNUS_D10V:
12212 case EM_D10V:
12213 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12214 case EM_CYGNUS_D30V:
12215 case EM_D30V:
12216 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12217 case EM_DLX:
12218 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12219 case EM_CYGNUS_FR30:
12220 case EM_FR30:
12221 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12222 case EM_FT32:
12223 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12224 case EM_H8S:
12225 case EM_H8_300:
12226 case EM_H8_300H:
12227 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12228 case EM_IA_64:
262cdac7
AM
12229 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12230 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12231 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12232 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12233 case EM_IP2K_OLD:
12234 case EM_IP2K:
12235 return reloc_type == 2; /* R_IP2K_32. */
12236 case EM_IQ2000:
12237 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12238 case EM_LATTICEMICO32:
12239 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12240 case EM_M32C_OLD:
aca88567
NC
12241 case EM_M32C:
12242 return reloc_type == 3; /* R_M32C_32. */
12243 case EM_M32R:
12244 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12245 case EM_68HC11:
12246 case EM_68HC12:
12247 return reloc_type == 6; /* R_M68HC11_32. */
aca88567
NC
12248 case EM_MCORE:
12249 return reloc_type == 1; /* R_MCORE_ADDR32. */
12250 case EM_CYGNUS_MEP:
12251 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12252 case EM_METAG:
12253 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12254 case EM_MICROBLAZE:
12255 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12256 case EM_MIPS:
12257 return reloc_type == 2; /* R_MIPS_32. */
12258 case EM_MMIX:
12259 return reloc_type == 4; /* R_MMIX_32. */
12260 case EM_CYGNUS_MN10200:
12261 case EM_MN10200:
12262 return reloc_type == 1; /* R_MN10200_32. */
12263 case EM_CYGNUS_MN10300:
12264 case EM_MN10300:
12265 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12266 case EM_MOXIE:
12267 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12268 case EM_MSP430_OLD:
12269 case EM_MSP430:
13761a11 12270 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12271 case EM_MT:
12272 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12273 case EM_NDS32:
12274 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12275 case EM_ALTERA_NIOS2:
36591ba1 12276 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12277 case EM_NIOS32:
12278 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12279 case EM_OR1K:
12280 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12281 case EM_PARISC:
5fda8eca
NC
12282 return (reloc_type == 1 /* R_PARISC_DIR32. */
12283 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12284 case EM_PJ:
12285 case EM_PJ_OLD:
12286 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12287 case EM_PPC64:
12288 return reloc_type == 1; /* R_PPC64_ADDR32. */
12289 case EM_PPC:
12290 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12291 case EM_TI_PRU:
12292 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12293 case EM_RISCV:
12294 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12295 case EM_RL78:
12296 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12297 case EM_RX:
12298 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
12299 case EM_S370:
12300 return reloc_type == 1; /* R_I370_ADDR31. */
12301 case EM_S390_OLD:
12302 case EM_S390:
12303 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12304 case EM_SCORE:
12305 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12306 case EM_SH:
12307 return reloc_type == 1; /* R_SH_DIR32. */
12308 case EM_SPARC32PLUS:
12309 case EM_SPARCV9:
12310 case EM_SPARC:
12311 return reloc_type == 3 /* R_SPARC_32. */
12312 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12313 case EM_SPU:
12314 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12315 case EM_TI_C6000:
12316 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12317 case EM_TILEGX:
12318 return reloc_type == 2; /* R_TILEGX_32. */
12319 case EM_TILEPRO:
12320 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12321 case EM_CYGNUS_V850:
12322 case EM_V850:
12323 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12324 case EM_V800:
12325 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12326 case EM_VAX:
12327 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12328 case EM_VISIUM:
12329 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12330 case EM_WEBASSEMBLY:
12331 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12332 case EM_X86_64:
8a9036a4 12333 case EM_L1OM:
7a9068fe 12334 case EM_K1OM:
aca88567 12335 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12336 case EM_XC16X:
12337 case EM_C166:
12338 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12339 case EM_XGATE:
12340 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12341 case EM_XSTORMY16:
12342 return reloc_type == 1; /* R_XSTROMY16_32. */
12343 case EM_XTENSA_OLD:
12344 case EM_XTENSA:
12345 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 12346 default:
bee0ee85
NC
12347 {
12348 static unsigned int prev_warn = 0;
12349
12350 /* Avoid repeating the same warning multiple times. */
dda8d76d 12351 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12352 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12353 filedata->file_header.e_machine);
12354 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12355 return FALSE;
12356 }
aca88567
NC
12357 }
12358}
12359
12360/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12361 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12362
12363static bfd_boolean
dda8d76d 12364is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12365{
dda8d76d 12366 switch (filedata->file_header.e_machine)
d347c9df 12367 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12368 {
41e92641 12369 case EM_386:
22abe556 12370 case EM_IAMCU:
3e0873ac 12371 return reloc_type == 2; /* R_386_PC32. */
aca88567 12372 case EM_68K:
3e0873ac 12373 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12374 case EM_AARCH64:
12375 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12376 case EM_ADAPTEVA_EPIPHANY:
12377 return reloc_type == 6;
aca88567
NC
12378 case EM_ALPHA:
12379 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12380 case EM_ARC_COMPACT:
12381 case EM_ARC_COMPACT2:
12382 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12383 case EM_ARM:
3e0873ac 12384 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12385 case EM_AVR_OLD:
12386 case EM_AVR:
12387 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12388 case EM_MICROBLAZE:
12389 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12390 case EM_OR1K:
12391 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 12392 case EM_PARISC:
85acf597 12393 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
12394 case EM_PPC:
12395 return reloc_type == 26; /* R_PPC_REL32. */
12396 case EM_PPC64:
3e0873ac 12397 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
12398 case EM_S390_OLD:
12399 case EM_S390:
3e0873ac 12400 return reloc_type == 5; /* R_390_PC32. */
aca88567 12401 case EM_SH:
3e0873ac 12402 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
12403 case EM_SPARC32PLUS:
12404 case EM_SPARCV9:
12405 case EM_SPARC:
3e0873ac 12406 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
12407 case EM_SPU:
12408 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
12409 case EM_TILEGX:
12410 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
12411 case EM_TILEPRO:
12412 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
12413 case EM_VISIUM:
12414 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 12415 case EM_X86_64:
8a9036a4 12416 case EM_L1OM:
7a9068fe 12417 case EM_K1OM:
3e0873ac 12418 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
12419 case EM_XTENSA_OLD:
12420 case EM_XTENSA:
12421 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
12422 default:
12423 /* Do not abort or issue an error message here. Not all targets use
12424 pc-relative 32-bit relocs in their DWARF debug information and we
12425 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
12426 more helpful warning message will be generated by apply_relocations
12427 anyway, so just return. */
aca88567
NC
12428 return FALSE;
12429 }
12430}
12431
12432/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12433 a 64-bit absolute RELA relocation used in DWARF debug sections. */
12434
12435static bfd_boolean
dda8d76d 12436is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12437{
dda8d76d 12438 switch (filedata->file_header.e_machine)
aca88567 12439 {
a06ea964
NC
12440 case EM_AARCH64:
12441 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
12442 case EM_ALPHA:
12443 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 12444 case EM_IA_64:
262cdac7
AM
12445 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
12446 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
12447 case EM_PARISC:
12448 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
12449 case EM_PPC64:
12450 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
12451 case EM_RISCV:
12452 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
12453 case EM_SPARC32PLUS:
12454 case EM_SPARCV9:
12455 case EM_SPARC:
714da62f
NC
12456 return reloc_type == 32 /* R_SPARC_64. */
12457 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 12458 case EM_X86_64:
8a9036a4 12459 case EM_L1OM:
7a9068fe 12460 case EM_K1OM:
aca88567 12461 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
12462 case EM_S390_OLD:
12463 case EM_S390:
aa137e4d
NC
12464 return reloc_type == 22; /* R_S390_64. */
12465 case EM_TILEGX:
12466 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 12467 case EM_MIPS:
aa137e4d 12468 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
12469 default:
12470 return FALSE;
12471 }
12472}
12473
85acf597
RH
12474/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
12475 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
12476
12477static bfd_boolean
dda8d76d 12478is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 12479{
dda8d76d 12480 switch (filedata->file_header.e_machine)
85acf597 12481 {
a06ea964
NC
12482 case EM_AARCH64:
12483 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 12484 case EM_ALPHA:
aa137e4d 12485 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 12486 case EM_IA_64:
262cdac7
AM
12487 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
12488 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 12489 case EM_PARISC:
aa137e4d 12490 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 12491 case EM_PPC64:
aa137e4d 12492 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
12493 case EM_SPARC32PLUS:
12494 case EM_SPARCV9:
12495 case EM_SPARC:
aa137e4d 12496 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 12497 case EM_X86_64:
8a9036a4 12498 case EM_L1OM:
7a9068fe 12499 case EM_K1OM:
aa137e4d 12500 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
12501 case EM_S390_OLD:
12502 case EM_S390:
aa137e4d
NC
12503 return reloc_type == 23; /* R_S390_PC64. */
12504 case EM_TILEGX:
12505 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
12506 default:
12507 return FALSE;
12508 }
12509}
12510
4dc3c23d
AM
12511/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12512 a 24-bit absolute RELA relocation used in DWARF debug sections. */
12513
12514static bfd_boolean
dda8d76d 12515is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 12516{
dda8d76d 12517 switch (filedata->file_header.e_machine)
4dc3c23d
AM
12518 {
12519 case EM_CYGNUS_MN10200:
12520 case EM_MN10200:
12521 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
12522 case EM_FT32:
12523 return reloc_type == 5; /* R_FT32_20. */
4dc3c23d
AM
12524 default:
12525 return FALSE;
12526 }
12527}
12528
aca88567
NC
12529/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12530 a 16-bit absolute RELA relocation used in DWARF debug sections. */
12531
12532static bfd_boolean
dda8d76d 12533is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 12534{
d347c9df 12535 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12536 switch (filedata->file_header.e_machine)
4b78141a 12537 {
886a2506
NC
12538 case EM_ARC:
12539 case EM_ARC_COMPACT:
12540 case EM_ARC_COMPACT2:
12541 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
12542 case EM_ADAPTEVA_EPIPHANY:
12543 return reloc_type == 5;
aca88567
NC
12544 case EM_AVR_OLD:
12545 case EM_AVR:
12546 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
12547 case EM_CYGNUS_D10V:
12548 case EM_D10V:
12549 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
12550 case EM_FT32:
12551 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
12552 case EM_H8S:
12553 case EM_H8_300:
12554 case EM_H8_300H:
aca88567
NC
12555 return reloc_type == R_H8_DIR16;
12556 case EM_IP2K_OLD:
12557 case EM_IP2K:
12558 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 12559 case EM_M32C_OLD:
f4236fe4
DD
12560 case EM_M32C:
12561 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
12562 case EM_CYGNUS_MN10200:
12563 case EM_MN10200:
12564 return reloc_type == 2; /* R_MN10200_16. */
12565 case EM_CYGNUS_MN10300:
12566 case EM_MN10300:
12567 return reloc_type == 2; /* R_MN10300_16. */
aca88567 12568 case EM_MSP430:
dda8d76d 12569 if (uses_msp430x_relocs (filedata))
13761a11 12570 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 12571 /* Fall through. */
78c8d46c 12572 case EM_MSP430_OLD:
aca88567 12573 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
12574 case EM_NDS32:
12575 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 12576 case EM_ALTERA_NIOS2:
36591ba1 12577 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
12578 case EM_NIOS32:
12579 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
12580 case EM_OR1K:
12581 return reloc_type == 2; /* R_OR1K_16. */
2b100bb5
DD
12582 case EM_TI_PRU:
12583 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
12584 case EM_TI_C6000:
12585 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
12586 case EM_VISIUM:
12587 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
12588 case EM_XC16X:
12589 case EM_C166:
12590 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
12591 case EM_XGATE:
12592 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 12593 default:
aca88567 12594 return FALSE;
4b78141a
NC
12595 }
12596}
12597
03336641
JW
12598/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12599 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
12600
12601static bfd_boolean
12602is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12603{
12604 /* Please keep this table alpha-sorted for ease of visual lookup. */
12605 switch (filedata->file_header.e_machine)
12606 {
12607 case EM_RISCV:
12608 return reloc_type == 35; /* R_RISCV_ADD32. */
12609 default:
12610 return FALSE;
12611 }
12612}
12613
12614/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12615 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
12616
12617static bfd_boolean
12618is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12619{
12620 /* Please keep this table alpha-sorted for ease of visual lookup. */
12621 switch (filedata->file_header.e_machine)
12622 {
12623 case EM_RISCV:
12624 return reloc_type == 39; /* R_RISCV_SUB32. */
12625 default:
12626 return FALSE;
12627 }
12628}
12629
12630/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12631 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
12632
12633static bfd_boolean
12634is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12635{
12636 /* Please keep this table alpha-sorted for ease of visual lookup. */
12637 switch (filedata->file_header.e_machine)
12638 {
12639 case EM_RISCV:
12640 return reloc_type == 36; /* R_RISCV_ADD64. */
12641 default:
12642 return FALSE;
12643 }
12644}
12645
12646/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12647 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
12648
12649static bfd_boolean
12650is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12651{
12652 /* Please keep this table alpha-sorted for ease of visual lookup. */
12653 switch (filedata->file_header.e_machine)
12654 {
12655 case EM_RISCV:
12656 return reloc_type == 40; /* R_RISCV_SUB64. */
12657 default:
12658 return FALSE;
12659 }
12660}
12661
12662/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12663 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
12664
12665static bfd_boolean
12666is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12667{
12668 /* Please keep this table alpha-sorted for ease of visual lookup. */
12669 switch (filedata->file_header.e_machine)
12670 {
12671 case EM_RISCV:
12672 return reloc_type == 34; /* R_RISCV_ADD16. */
12673 default:
12674 return FALSE;
12675 }
12676}
12677
12678/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12679 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
12680
12681static bfd_boolean
12682is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12683{
12684 /* Please keep this table alpha-sorted for ease of visual lookup. */
12685 switch (filedata->file_header.e_machine)
12686 {
12687 case EM_RISCV:
12688 return reloc_type == 38; /* R_RISCV_SUB16. */
12689 default:
12690 return FALSE;
12691 }
12692}
12693
12694/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12695 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
12696
12697static bfd_boolean
12698is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12699{
12700 /* Please keep this table alpha-sorted for ease of visual lookup. */
12701 switch (filedata->file_header.e_machine)
12702 {
12703 case EM_RISCV:
12704 return reloc_type == 33; /* R_RISCV_ADD8. */
12705 default:
12706 return FALSE;
12707 }
12708}
12709
12710/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12711 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
12712
12713static bfd_boolean
12714is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12715{
12716 /* Please keep this table alpha-sorted for ease of visual lookup. */
12717 switch (filedata->file_header.e_machine)
12718 {
12719 case EM_RISCV:
12720 return reloc_type == 37; /* R_RISCV_SUB8. */
12721 default:
12722 return FALSE;
12723 }
12724}
12725
2a7b2e88
JK
12726/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
12727 relocation entries (possibly formerly used for SHT_GROUP sections). */
12728
12729static bfd_boolean
dda8d76d 12730is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 12731{
dda8d76d 12732 switch (filedata->file_header.e_machine)
2a7b2e88 12733 {
cb8f3167 12734 case EM_386: /* R_386_NONE. */
d347c9df 12735 case EM_68K: /* R_68K_NONE. */
cfb8c092 12736 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
12737 case EM_ALPHA: /* R_ALPHA_NONE. */
12738 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 12739 case EM_ARC: /* R_ARC_NONE. */
886a2506 12740 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 12741 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 12742 case EM_ARM: /* R_ARM_NONE. */
d347c9df 12743 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 12744 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
12745 case EM_FT32: /* R_FT32_NONE. */
12746 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 12747 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
12748 case EM_L1OM: /* R_X86_64_NONE. */
12749 case EM_M32R: /* R_M32R_NONE. */
12750 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 12751 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 12752 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
12753 case EM_NIOS32: /* R_NIOS_NONE. */
12754 case EM_OR1K: /* R_OR1K_NONE. */
12755 case EM_PARISC: /* R_PARISC_NONE. */
12756 case EM_PPC64: /* R_PPC64_NONE. */
12757 case EM_PPC: /* R_PPC_NONE. */
e23eba97 12758 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
12759 case EM_S390: /* R_390_NONE. */
12760 case EM_S390_OLD:
12761 case EM_SH: /* R_SH_NONE. */
12762 case EM_SPARC32PLUS:
12763 case EM_SPARC: /* R_SPARC_NONE. */
12764 case EM_SPARCV9:
aa137e4d
NC
12765 case EM_TILEGX: /* R_TILEGX_NONE. */
12766 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
12767 case EM_TI_C6000:/* R_C6000_NONE. */
12768 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 12769 case EM_XC16X:
f96bd6c2 12770 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 12771 return reloc_type == 0;
d347c9df 12772
a06ea964
NC
12773 case EM_AARCH64:
12774 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
12775 case EM_AVR_OLD:
12776 case EM_AVR:
12777 return (reloc_type == 0 /* R_AVR_NONE. */
12778 || reloc_type == 30 /* R_AVR_DIFF8. */
12779 || reloc_type == 31 /* R_AVR_DIFF16. */
12780 || reloc_type == 32 /* R_AVR_DIFF32. */);
12781 case EM_METAG:
12782 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
12783 case EM_NDS32:
12784 return (reloc_type == 0 /* R_XTENSA_NONE. */
12785 || reloc_type == 204 /* R_NDS32_DIFF8. */
12786 || reloc_type == 205 /* R_NDS32_DIFF16. */
12787 || reloc_type == 206 /* R_NDS32_DIFF32. */
12788 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
12789 case EM_TI_PRU:
12790 return (reloc_type == 0 /* R_PRU_NONE. */
12791 || reloc_type == 65 /* R_PRU_DIFF8. */
12792 || reloc_type == 66 /* R_PRU_DIFF16. */
12793 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
12794 case EM_XTENSA_OLD:
12795 case EM_XTENSA:
4dc3c23d
AM
12796 return (reloc_type == 0 /* R_XTENSA_NONE. */
12797 || reloc_type == 17 /* R_XTENSA_DIFF8. */
12798 || reloc_type == 18 /* R_XTENSA_DIFF16. */
12799 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
12800 }
12801 return FALSE;
12802}
12803
d1c4b12b
NC
12804/* Returns TRUE if there is a relocation against
12805 section NAME at OFFSET bytes. */
12806
12807bfd_boolean
12808reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
12809{
12810 Elf_Internal_Rela * relocs;
12811 Elf_Internal_Rela * rp;
12812
12813 if (dsec == NULL || dsec->reloc_info == NULL)
12814 return FALSE;
12815
12816 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
12817
12818 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
12819 if (rp->r_offset == offset)
12820 return TRUE;
12821
12822 return FALSE;
12823}
12824
cf13d699 12825/* Apply relocations to a section.
32ec8896
NC
12826 Returns TRUE upon success, FALSE otherwise.
12827 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
12828 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
12829 will be set to the number of relocs loaded.
12830
cf13d699 12831 Note: So far support has been added only for those relocations
32ec8896
NC
12832 which can be found in debug sections. FIXME: Add support for
12833 more relocations ? */
1b315056 12834
32ec8896 12835static bfd_boolean
dda8d76d 12836apply_relocations (Filedata * filedata,
d1c4b12b
NC
12837 const Elf_Internal_Shdr * section,
12838 unsigned char * start,
12839 bfd_size_type size,
1449284b 12840 void ** relocs_return,
d1c4b12b 12841 unsigned long * num_relocs_return)
1b315056 12842{
cf13d699 12843 Elf_Internal_Shdr * relsec;
0d2a7a93 12844 unsigned char * end = start + size;
32ec8896 12845 bfd_boolean res = TRUE;
cb8f3167 12846
d1c4b12b
NC
12847 if (relocs_return != NULL)
12848 {
12849 * (Elf_Internal_Rela **) relocs_return = NULL;
12850 * num_relocs_return = 0;
12851 }
12852
dda8d76d 12853 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
12854 /* No relocs to apply. */
12855 return TRUE;
1b315056 12856
cf13d699 12857 /* Find the reloc section associated with the section. */
dda8d76d
NC
12858 for (relsec = filedata->section_headers;
12859 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 12860 ++relsec)
252b5132 12861 {
41e92641
NC
12862 bfd_boolean is_rela;
12863 unsigned long num_relocs;
2cf0635d
NC
12864 Elf_Internal_Rela * relocs;
12865 Elf_Internal_Rela * rp;
12866 Elf_Internal_Shdr * symsec;
12867 Elf_Internal_Sym * symtab;
ba5cdace 12868 unsigned long num_syms;
2cf0635d 12869 Elf_Internal_Sym * sym;
252b5132 12870
41e92641 12871 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
12872 || relsec->sh_info >= filedata->file_header.e_shnum
12873 || filedata->section_headers + relsec->sh_info != section
c256ffe7 12874 || relsec->sh_size == 0
dda8d76d 12875 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 12876 continue;
428409d5 12877
41e92641
NC
12878 is_rela = relsec->sh_type == SHT_RELA;
12879
12880 if (is_rela)
12881 {
dda8d76d 12882 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 12883 relsec->sh_size, & relocs, & num_relocs))
32ec8896 12884 return FALSE;
41e92641
NC
12885 }
12886 else
12887 {
dda8d76d 12888 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 12889 relsec->sh_size, & relocs, & num_relocs))
32ec8896 12890 return FALSE;
41e92641
NC
12891 }
12892
12893 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 12894 if (filedata->file_header.e_machine == EM_SH)
41e92641 12895 is_rela = FALSE;
428409d5 12896
dda8d76d 12897 symsec = filedata->section_headers + relsec->sh_link;
1449284b
NC
12898 if (symsec->sh_type != SHT_SYMTAB
12899 && symsec->sh_type != SHT_DYNSYM)
32ec8896 12900 return FALSE;
dda8d76d 12901 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 12902
41e92641 12903 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 12904 {
41e92641
NC
12905 bfd_vma addend;
12906 unsigned int reloc_type;
12907 unsigned int reloc_size;
03336641
JW
12908 bfd_boolean reloc_inplace = FALSE;
12909 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 12910 unsigned char * rloc;
ba5cdace 12911 unsigned long sym_index;
4b78141a 12912
dda8d76d 12913 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 12914
dda8d76d 12915 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 12916 continue;
dda8d76d 12917 else if (is_none_reloc (filedata, reloc_type))
98fb390a 12918 continue;
dda8d76d
NC
12919 else if (is_32bit_abs_reloc (filedata, reloc_type)
12920 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 12921 reloc_size = 4;
dda8d76d
NC
12922 else if (is_64bit_abs_reloc (filedata, reloc_type)
12923 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 12924 reloc_size = 8;
dda8d76d 12925 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 12926 reloc_size = 3;
dda8d76d 12927 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 12928 reloc_size = 2;
03336641
JW
12929 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
12930 reloc_type))
12931 || is_32bit_inplace_add_reloc (filedata, reloc_type))
12932 {
12933 reloc_size = 4;
12934 reloc_inplace = TRUE;
12935 }
12936 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
12937 reloc_type))
12938 || is_64bit_inplace_add_reloc (filedata, reloc_type))
12939 {
12940 reloc_size = 8;
12941 reloc_inplace = TRUE;
12942 }
12943 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
12944 reloc_type))
12945 || is_16bit_inplace_add_reloc (filedata, reloc_type))
12946 {
12947 reloc_size = 2;
12948 reloc_inplace = TRUE;
12949 }
12950 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
12951 reloc_type))
12952 || is_8bit_inplace_add_reloc (filedata, reloc_type))
12953 {
12954 reloc_size = 1;
12955 reloc_inplace = TRUE;
12956 }
aca88567 12957 else
4b78141a 12958 {
bee0ee85 12959 static unsigned int prev_reloc = 0;
dda8d76d 12960
bee0ee85
NC
12961 if (reloc_type != prev_reloc)
12962 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 12963 reloc_type, printable_section_name (filedata, section));
bee0ee85 12964 prev_reloc = reloc_type;
32ec8896 12965 res = FALSE;
4b78141a
NC
12966 continue;
12967 }
103f02d3 12968
91d6fa6a 12969 rloc = start + rp->r_offset;
c8da6823 12970 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
12971 {
12972 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
12973 (unsigned long) rp->r_offset,
dda8d76d 12974 printable_section_name (filedata, section));
32ec8896 12975 res = FALSE;
700dd8b7
L
12976 continue;
12977 }
103f02d3 12978
ba5cdace
NC
12979 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
12980 if (sym_index >= num_syms)
12981 {
12982 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 12983 sym_index, printable_section_name (filedata, section));
32ec8896 12984 res = FALSE;
ba5cdace
NC
12985 continue;
12986 }
12987 sym = symtab + sym_index;
41e92641
NC
12988
12989 /* If the reloc has a symbol associated with it,
55f25fc3
L
12990 make sure that it is of an appropriate type.
12991
12992 Relocations against symbols without type can happen.
12993 Gcc -feliminate-dwarf2-dups may generate symbols
12994 without type for debug info.
12995
12996 Icc generates relocations against function symbols
12997 instead of local labels.
12998
12999 Relocations against object symbols can happen, eg when
13000 referencing a global array. For an example of this see
13001 the _clz.o binary in libgcc.a. */
aca88567 13002 if (sym != symtab
b8871f35 13003 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13004 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13005 {
d3a49aa8 13006 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13007 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13008 printable_section_name (filedata, relsec),
d3a49aa8 13009 (long int)(rp - relocs));
32ec8896 13010 res = FALSE;
aca88567 13011 continue;
5b18a4bc 13012 }
252b5132 13013
4dc3c23d
AM
13014 addend = 0;
13015 if (is_rela)
13016 addend += rp->r_addend;
c47320c3
AM
13017 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13018 partial_inplace. */
4dc3c23d 13019 if (!is_rela
dda8d76d 13020 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13021 && reloc_type == 1)
dda8d76d
NC
13022 || ((filedata->file_header.e_machine == EM_PJ
13023 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13024 && reloc_type == 1)
dda8d76d
NC
13025 || ((filedata->file_header.e_machine == EM_D30V
13026 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13027 && reloc_type == 12)
13028 || reloc_inplace)
91d6fa6a 13029 addend += byte_get (rloc, reloc_size);
cb8f3167 13030
dda8d76d
NC
13031 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13032 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13033 {
13034 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13035 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13036 addend -= 8;
91d6fa6a 13037 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13038 reloc_size);
13039 }
03336641
JW
13040 else if (reloc_subtract)
13041 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13042 else
91d6fa6a 13043 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13044 }
252b5132 13045
5b18a4bc 13046 free (symtab);
f84ce13b
NC
13047 /* Let the target specific reloc processing code know that
13048 we have finished with these relocs. */
dda8d76d 13049 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13050
13051 if (relocs_return)
13052 {
13053 * (Elf_Internal_Rela **) relocs_return = relocs;
13054 * num_relocs_return = num_relocs;
13055 }
13056 else
13057 free (relocs);
13058
5b18a4bc
NC
13059 break;
13060 }
32ec8896
NC
13061
13062 return res;
5b18a4bc 13063}
103f02d3 13064
cf13d699 13065#ifdef SUPPORT_DISASSEMBLY
32ec8896 13066static bfd_boolean
dda8d76d 13067disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13068{
dda8d76d 13069 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13070
74e1a04b 13071 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13072
32ec8896 13073 return TRUE;
cf13d699
NC
13074}
13075#endif
13076
13077/* Reads in the contents of SECTION from FILE, returning a pointer
13078 to a malloc'ed buffer or NULL if something went wrong. */
13079
13080static char *
dda8d76d 13081get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13082{
dda8d76d 13083 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13084
13085 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13086 {
c6b78c96 13087 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13088 printable_section_name (filedata, section));
cf13d699
NC
13089 return NULL;
13090 }
13091
dda8d76d 13092 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13093 _("section contents"));
cf13d699
NC
13094}
13095
0e602686
NC
13096/* Uncompresses a section that was compressed using zlib, in place. */
13097
13098static bfd_boolean
dda8d76d
NC
13099uncompress_section_contents (unsigned char ** buffer,
13100 dwarf_size_type uncompressed_size,
13101 dwarf_size_type * size)
0e602686
NC
13102{
13103 dwarf_size_type compressed_size = *size;
13104 unsigned char * compressed_buffer = *buffer;
13105 unsigned char * uncompressed_buffer;
13106 z_stream strm;
13107 int rc;
13108
13109 /* It is possible the section consists of several compressed
13110 buffers concatenated together, so we uncompress in a loop. */
13111 /* PR 18313: The state field in the z_stream structure is supposed
13112 to be invisible to the user (ie us), but some compilers will
13113 still complain about it being used without initialisation. So
13114 we first zero the entire z_stream structure and then set the fields
13115 that we need. */
13116 memset (& strm, 0, sizeof strm);
13117 strm.avail_in = compressed_size;
13118 strm.next_in = (Bytef *) compressed_buffer;
13119 strm.avail_out = uncompressed_size;
13120 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13121
13122 rc = inflateInit (& strm);
13123 while (strm.avail_in > 0)
13124 {
13125 if (rc != Z_OK)
13126 goto fail;
13127 strm.next_out = ((Bytef *) uncompressed_buffer
13128 + (uncompressed_size - strm.avail_out));
13129 rc = inflate (&strm, Z_FINISH);
13130 if (rc != Z_STREAM_END)
13131 goto fail;
13132 rc = inflateReset (& strm);
13133 }
13134 rc = inflateEnd (& strm);
13135 if (rc != Z_OK
13136 || strm.avail_out != 0)
13137 goto fail;
13138
13139 *buffer = uncompressed_buffer;
13140 *size = uncompressed_size;
13141 return TRUE;
13142
13143 fail:
13144 free (uncompressed_buffer);
13145 /* Indicate decompression failure. */
13146 *buffer = NULL;
13147 return FALSE;
13148}
dd24e3da 13149
32ec8896 13150static bfd_boolean
dda8d76d 13151dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13152{
0e602686
NC
13153 Elf_Internal_Shdr * relsec;
13154 bfd_size_type num_bytes;
fd8008d8
L
13155 unsigned char * data;
13156 unsigned char * end;
13157 unsigned char * real_start;
13158 unsigned char * start;
0e602686 13159 bfd_boolean some_strings_shown;
cf13d699 13160
dda8d76d 13161 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13162 if (start == NULL)
c6b78c96
NC
13163 /* PR 21820: Do not fail if the section was empty. */
13164 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13165
0e602686 13166 num_bytes = section->sh_size;
cf13d699 13167
dda8d76d 13168 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13169
0e602686
NC
13170 if (decompress_dumps)
13171 {
13172 dwarf_size_type new_size = num_bytes;
13173 dwarf_size_type uncompressed_size = 0;
13174
13175 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13176 {
13177 Elf_Internal_Chdr chdr;
13178 unsigned int compression_header_size
ebdf1ebf
NC
13179 = get_compression_header (& chdr, (unsigned char *) start,
13180 num_bytes);
0e602686 13181
813dabb9 13182 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13183 {
813dabb9 13184 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13185 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13186 return FALSE;
813dabb9
L
13187 }
13188 else if (chdr.ch_addralign != section->sh_addralign)
13189 {
13190 warn (_("compressed section '%s' is corrupted\n"),
dda8d76d 13191 printable_section_name (filedata, section));
32ec8896 13192 return FALSE;
0e602686 13193 }
813dabb9
L
13194 uncompressed_size = chdr.ch_size;
13195 start += compression_header_size;
13196 new_size -= compression_header_size;
0e602686
NC
13197 }
13198 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13199 {
13200 /* Read the zlib header. In this case, it should be "ZLIB"
13201 followed by the uncompressed section size, 8 bytes in
13202 big-endian order. */
13203 uncompressed_size = start[4]; uncompressed_size <<= 8;
13204 uncompressed_size += start[5]; uncompressed_size <<= 8;
13205 uncompressed_size += start[6]; uncompressed_size <<= 8;
13206 uncompressed_size += start[7]; uncompressed_size <<= 8;
13207 uncompressed_size += start[8]; uncompressed_size <<= 8;
13208 uncompressed_size += start[9]; uncompressed_size <<= 8;
13209 uncompressed_size += start[10]; uncompressed_size <<= 8;
13210 uncompressed_size += start[11];
13211 start += 12;
13212 new_size -= 12;
13213 }
13214
1835f746
NC
13215 if (uncompressed_size)
13216 {
13217 if (uncompress_section_contents (& start,
13218 uncompressed_size, & new_size))
13219 num_bytes = new_size;
13220 else
13221 {
13222 error (_("Unable to decompress section %s\n"),
dda8d76d 13223 printable_section_name (filedata, section));
32ec8896 13224 return FALSE;
1835f746
NC
13225 }
13226 }
bc303e5d
NC
13227 else
13228 start = real_start;
0e602686 13229 }
fd8008d8 13230
cf13d699
NC
13231 /* If the section being dumped has relocations against it the user might
13232 be expecting these relocations to have been applied. Check for this
13233 case and issue a warning message in order to avoid confusion.
13234 FIXME: Maybe we ought to have an option that dumps a section with
13235 relocs applied ? */
dda8d76d
NC
13236 for (relsec = filedata->section_headers;
13237 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13238 ++relsec)
13239 {
13240 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13241 || relsec->sh_info >= filedata->file_header.e_shnum
13242 || filedata->section_headers + relsec->sh_info != section
cf13d699 13243 || relsec->sh_size == 0
dda8d76d 13244 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13245 continue;
13246
13247 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13248 break;
13249 }
13250
cf13d699
NC
13251 data = start;
13252 end = start + num_bytes;
13253 some_strings_shown = FALSE;
13254
13255 while (data < end)
13256 {
13257 while (!ISPRINT (* data))
13258 if (++ data >= end)
13259 break;
13260
13261 if (data < end)
13262 {
071436c6
NC
13263 size_t maxlen = end - data;
13264
cf13d699 13265#ifndef __MSVCRT__
c975cc98
NC
13266 /* PR 11128: Use two separate invocations in order to work
13267 around bugs in the Solaris 8 implementation of printf. */
13268 printf (" [%6tx] ", data - start);
cf13d699 13269#else
071436c6 13270 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 13271#endif
4082ef84
NC
13272 if (maxlen > 0)
13273 {
fd8008d8 13274 print_symbol ((int) maxlen, (const char *) data);
4082ef84 13275 putchar ('\n');
fd8008d8 13276 data += strnlen ((const char *) data, maxlen);
4082ef84
NC
13277 }
13278 else
13279 {
13280 printf (_("<corrupt>\n"));
13281 data = end;
13282 }
cf13d699
NC
13283 some_strings_shown = TRUE;
13284 }
13285 }
13286
13287 if (! some_strings_shown)
13288 printf (_(" No strings found in this section."));
13289
0e602686 13290 free (real_start);
cf13d699
NC
13291
13292 putchar ('\n');
32ec8896 13293 return TRUE;
cf13d699
NC
13294}
13295
32ec8896 13296static bfd_boolean
dda8d76d
NC
13297dump_section_as_bytes (Elf_Internal_Shdr * section,
13298 Filedata * filedata,
13299 bfd_boolean relocate)
cf13d699
NC
13300{
13301 Elf_Internal_Shdr * relsec;
0e602686
NC
13302 bfd_size_type bytes;
13303 bfd_size_type section_size;
13304 bfd_vma addr;
13305 unsigned char * data;
13306 unsigned char * real_start;
13307 unsigned char * start;
13308
dda8d76d 13309 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13310 if (start == NULL)
c6b78c96
NC
13311 /* PR 21820: Do not fail if the section was empty. */
13312 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 13313
0e602686 13314 section_size = section->sh_size;
cf13d699 13315
dda8d76d 13316 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13317
0e602686
NC
13318 if (decompress_dumps)
13319 {
13320 dwarf_size_type new_size = section_size;
13321 dwarf_size_type uncompressed_size = 0;
13322
13323 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13324 {
13325 Elf_Internal_Chdr chdr;
13326 unsigned int compression_header_size
ebdf1ebf 13327 = get_compression_header (& chdr, start, section_size);
0e602686 13328
813dabb9 13329 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13330 {
813dabb9 13331 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13332 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13333 return FALSE;
0e602686 13334 }
813dabb9
L
13335 else if (chdr.ch_addralign != section->sh_addralign)
13336 {
13337 warn (_("compressed section '%s' is corrupted\n"),
dda8d76d 13338 printable_section_name (filedata, section));
32ec8896 13339 return FALSE;
813dabb9
L
13340 }
13341 uncompressed_size = chdr.ch_size;
13342 start += compression_header_size;
13343 new_size -= compression_header_size;
0e602686
NC
13344 }
13345 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13346 {
13347 /* Read the zlib header. In this case, it should be "ZLIB"
13348 followed by the uncompressed section size, 8 bytes in
13349 big-endian order. */
13350 uncompressed_size = start[4]; uncompressed_size <<= 8;
13351 uncompressed_size += start[5]; uncompressed_size <<= 8;
13352 uncompressed_size += start[6]; uncompressed_size <<= 8;
13353 uncompressed_size += start[7]; uncompressed_size <<= 8;
13354 uncompressed_size += start[8]; uncompressed_size <<= 8;
13355 uncompressed_size += start[9]; uncompressed_size <<= 8;
13356 uncompressed_size += start[10]; uncompressed_size <<= 8;
13357 uncompressed_size += start[11];
13358 start += 12;
13359 new_size -= 12;
13360 }
13361
f055032e
NC
13362 if (uncompressed_size)
13363 {
13364 if (uncompress_section_contents (& start, uncompressed_size,
13365 & new_size))
bc303e5d
NC
13366 {
13367 section_size = new_size;
13368 }
f055032e
NC
13369 else
13370 {
13371 error (_("Unable to decompress section %s\n"),
dda8d76d 13372 printable_section_name (filedata, section));
bc303e5d 13373 /* FIXME: Print the section anyway ? */
32ec8896 13374 return FALSE;
f055032e
NC
13375 }
13376 }
bc303e5d
NC
13377 else
13378 start = real_start;
0e602686 13379 }
14ae95f2 13380
cf13d699
NC
13381 if (relocate)
13382 {
dda8d76d 13383 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
32ec8896 13384 return FALSE;
cf13d699
NC
13385 }
13386 else
13387 {
13388 /* If the section being dumped has relocations against it the user might
13389 be expecting these relocations to have been applied. Check for this
13390 case and issue a warning message in order to avoid confusion.
13391 FIXME: Maybe we ought to have an option that dumps a section with
13392 relocs applied ? */
dda8d76d
NC
13393 for (relsec = filedata->section_headers;
13394 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13395 ++relsec)
13396 {
13397 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13398 || relsec->sh_info >= filedata->file_header.e_shnum
13399 || filedata->section_headers + relsec->sh_info != section
cf13d699 13400 || relsec->sh_size == 0
dda8d76d 13401 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13402 continue;
13403
13404 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13405 break;
13406 }
13407 }
13408
13409 addr = section->sh_addr;
0e602686 13410 bytes = section_size;
cf13d699
NC
13411 data = start;
13412
13413 while (bytes)
13414 {
13415 int j;
13416 int k;
13417 int lbytes;
13418
13419 lbytes = (bytes > 16 ? 16 : bytes);
13420
13421 printf (" 0x%8.8lx ", (unsigned long) addr);
13422
13423 for (j = 0; j < 16; j++)
13424 {
13425 if (j < lbytes)
13426 printf ("%2.2x", data[j]);
13427 else
13428 printf (" ");
13429
13430 if ((j & 3) == 3)
13431 printf (" ");
13432 }
13433
13434 for (j = 0; j < lbytes; j++)
13435 {
13436 k = data[j];
13437 if (k >= ' ' && k < 0x7f)
13438 printf ("%c", k);
13439 else
13440 printf (".");
13441 }
13442
13443 putchar ('\n');
13444
13445 data += lbytes;
13446 addr += lbytes;
13447 bytes -= lbytes;
13448 }
13449
0e602686 13450 free (real_start);
cf13d699
NC
13451
13452 putchar ('\n');
32ec8896 13453 return TRUE;
cf13d699
NC
13454}
13455
32ec8896 13456static bfd_boolean
dda8d76d
NC
13457load_specific_debug_section (enum dwarf_section_display_enum debug,
13458 const Elf_Internal_Shdr * sec,
13459 void * data)
1007acb3 13460{
2cf0635d 13461 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 13462 char buf [64];
dda8d76d
NC
13463 Filedata * filedata = (Filedata *) data;
13464
19e6b90e 13465 if (section->start != NULL)
dda8d76d
NC
13466 {
13467 /* If it is already loaded, do nothing. */
13468 if (streq (section->filename, filedata->file_name))
13469 return TRUE;
13470 free (section->start);
13471 }
1007acb3 13472
19e6b90e
L
13473 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
13474 section->address = sec->sh_addr;
06614111 13475 section->user_data = NULL;
dda8d76d
NC
13476 section->filename = filedata->file_name;
13477 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
13478 sec->sh_offset, 1,
13479 sec->sh_size, buf);
59245841
NC
13480 if (section->start == NULL)
13481 section->size = 0;
13482 else
13483 {
77115a4a
L
13484 unsigned char *start = section->start;
13485 dwarf_size_type size = sec->sh_size;
dab394de 13486 dwarf_size_type uncompressed_size = 0;
77115a4a
L
13487
13488 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
13489 {
13490 Elf_Internal_Chdr chdr;
d8024a91
NC
13491 unsigned int compression_header_size;
13492
f53be977
L
13493 if (size < (is_32bit_elf
13494 ? sizeof (Elf32_External_Chdr)
13495 : sizeof (Elf64_External_Chdr)))
d8024a91
NC
13496 {
13497 warn (_("compressed section %s is too small to contain a compression header"),
13498 section->name);
32ec8896 13499 return FALSE;
d8024a91
NC
13500 }
13501
ebdf1ebf 13502 compression_header_size = get_compression_header (&chdr, start, size);
d8024a91 13503
813dabb9
L
13504 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
13505 {
13506 warn (_("section '%s' has unsupported compress type: %d\n"),
13507 section->name, chdr.ch_type);
32ec8896 13508 return FALSE;
813dabb9
L
13509 }
13510 else if (chdr.ch_addralign != sec->sh_addralign)
13511 {
13512 warn (_("compressed section '%s' is corrupted\n"),
13513 section->name);
32ec8896 13514 return FALSE;
813dabb9 13515 }
dab394de 13516 uncompressed_size = chdr.ch_size;
77115a4a
L
13517 start += compression_header_size;
13518 size -= compression_header_size;
13519 }
dab394de
L
13520 else if (size > 12 && streq ((char *) start, "ZLIB"))
13521 {
13522 /* Read the zlib header. In this case, it should be "ZLIB"
13523 followed by the uncompressed section size, 8 bytes in
13524 big-endian order. */
13525 uncompressed_size = start[4]; uncompressed_size <<= 8;
13526 uncompressed_size += start[5]; uncompressed_size <<= 8;
13527 uncompressed_size += start[6]; uncompressed_size <<= 8;
13528 uncompressed_size += start[7]; uncompressed_size <<= 8;
13529 uncompressed_size += start[8]; uncompressed_size <<= 8;
13530 uncompressed_size += start[9]; uncompressed_size <<= 8;
13531 uncompressed_size += start[10]; uncompressed_size <<= 8;
13532 uncompressed_size += start[11];
13533 start += 12;
13534 size -= 12;
13535 }
13536
1835f746 13537 if (uncompressed_size)
77115a4a 13538 {
1835f746
NC
13539 if (uncompress_section_contents (&start, uncompressed_size,
13540 &size))
13541 {
13542 /* Free the compressed buffer, update the section buffer
13543 and the section size if uncompress is successful. */
13544 free (section->start);
13545 section->start = start;
13546 }
13547 else
13548 {
13549 error (_("Unable to decompress section %s\n"),
dda8d76d 13550 printable_section_name (filedata, sec));
32ec8896 13551 return FALSE;
1835f746 13552 }
77115a4a 13553 }
bc303e5d 13554
77115a4a 13555 section->size = size;
59245841 13556 }
4a114e3e 13557
1b315056 13558 if (section->start == NULL)
32ec8896 13559 return FALSE;
1b315056 13560
19e6b90e 13561 if (debug_displays [debug].relocate)
32ec8896 13562 {
dda8d76d 13563 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
13564 & section->reloc_info, & section->num_relocs))
13565 return FALSE;
13566 }
d1c4b12b
NC
13567 else
13568 {
13569 section->reloc_info = NULL;
13570 section->num_relocs = 0;
13571 }
1007acb3 13572
32ec8896 13573 return TRUE;
1007acb3
L
13574}
13575
657d0d47
CC
13576/* If this is not NULL, load_debug_section will only look for sections
13577 within the list of sections given here. */
32ec8896 13578static unsigned int * section_subset = NULL;
657d0d47 13579
32ec8896 13580bfd_boolean
dda8d76d 13581load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 13582{
2cf0635d
NC
13583 struct dwarf_section * section = &debug_displays [debug].section;
13584 Elf_Internal_Shdr * sec;
dda8d76d
NC
13585 Filedata * filedata = (Filedata *) data;
13586
f425ec66
NC
13587 /* Without section headers we cannot find any sections. */
13588 if (filedata->section_headers == NULL)
13589 return FALSE;
13590
9c1ce108
AM
13591 if (filedata->string_table == NULL
13592 && filedata->file_header.e_shstrndx != SHN_UNDEF
13593 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
13594 {
13595 Elf_Internal_Shdr * strs;
13596
13597 /* Read in the string table, so that we have section names to scan. */
13598 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
13599
4dff97b2 13600 if (strs != NULL && strs->sh_size != 0)
dda8d76d 13601 {
9c1ce108
AM
13602 filedata->string_table
13603 = (char *) get_data (NULL, filedata, strs->sh_offset,
13604 1, strs->sh_size, _("string table"));
dda8d76d 13605
9c1ce108
AM
13606 filedata->string_table_length
13607 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
13608 }
13609 }
d966045b
DJ
13610
13611 /* Locate the debug section. */
dda8d76d 13612 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
13613 if (sec != NULL)
13614 section->name = section->uncompressed_name;
13615 else
13616 {
dda8d76d 13617 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
13618 if (sec != NULL)
13619 section->name = section->compressed_name;
13620 }
13621 if (sec == NULL)
32ec8896 13622 return FALSE;
d966045b 13623
657d0d47
CC
13624 /* If we're loading from a subset of sections, and we've loaded
13625 a section matching this name before, it's likely that it's a
13626 different one. */
13627 if (section_subset != NULL)
13628 free_debug_section (debug);
13629
dda8d76d 13630 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
13631}
13632
19e6b90e
L
13633void
13634free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 13635{
2cf0635d 13636 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 13637
19e6b90e
L
13638 if (section->start == NULL)
13639 return;
1007acb3 13640
19e6b90e
L
13641 free ((char *) section->start);
13642 section->start = NULL;
13643 section->address = 0;
13644 section->size = 0;
1007acb3
L
13645}
13646
32ec8896 13647static bfd_boolean
dda8d76d 13648display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 13649{
2cf0635d 13650 char * name = SECTION_NAME (section);
dda8d76d 13651 const char * print_name = printable_section_name (filedata, section);
19e6b90e 13652 bfd_size_type length;
32ec8896 13653 bfd_boolean result = TRUE;
3f5e193b 13654 int i;
1007acb3 13655
19e6b90e
L
13656 length = section->sh_size;
13657 if (length == 0)
1007acb3 13658 {
74e1a04b 13659 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 13660 return TRUE;
1007acb3 13661 }
5dff79d8
NC
13662 if (section->sh_type == SHT_NOBITS)
13663 {
13664 /* There is no point in dumping the contents of a debugging section
13665 which has the NOBITS type - the bits in the file will be random.
13666 This can happen when a file containing a .eh_frame section is
13667 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
13668 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
13669 print_name);
32ec8896 13670 return FALSE;
5dff79d8 13671 }
1007acb3 13672
0112cd26 13673 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 13674 name = ".debug_info";
1007acb3 13675
19e6b90e
L
13676 /* See if we know how to display the contents of this section. */
13677 for (i = 0; i < max; i++)
d85bf2ba
NC
13678 {
13679 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
13680 struct dwarf_section_display * display = debug_displays + i;
13681 struct dwarf_section * sec = & display->section;
d966045b 13682
d85bf2ba
NC
13683 if (streq (sec->uncompressed_name, name)
13684 || (id == line && const_strneq (name, ".debug_line."))
13685 || streq (sec->compressed_name, name))
13686 {
13687 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 13688
d85bf2ba
NC
13689 if (secondary)
13690 free_debug_section (id);
dda8d76d 13691
d85bf2ba
NC
13692 if (i == line && const_strneq (name, ".debug_line."))
13693 sec->name = name;
13694 else if (streq (sec->uncompressed_name, name))
13695 sec->name = sec->uncompressed_name;
13696 else
13697 sec->name = sec->compressed_name;
657d0d47 13698
d85bf2ba
NC
13699 if (load_specific_debug_section (id, section, filedata))
13700 {
13701 /* If this debug section is part of a CU/TU set in a .dwp file,
13702 restrict load_debug_section to the sections in that set. */
13703 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 13704
d85bf2ba 13705 result &= display->display (sec, filedata);
657d0d47 13706
d85bf2ba 13707 section_subset = NULL;
1007acb3 13708
d85bf2ba
NC
13709 if (secondary || (id != info && id != abbrev))
13710 free_debug_section (id);
13711 }
13712 break;
13713 }
13714 }
1007acb3 13715
19e6b90e 13716 if (i == max)
1007acb3 13717 {
74e1a04b 13718 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 13719 result = FALSE;
1007acb3
L
13720 }
13721
19e6b90e 13722 return result;
5b18a4bc 13723}
103f02d3 13724
aef1f6d0
DJ
13725/* Set DUMP_SECTS for all sections where dumps were requested
13726 based on section name. */
13727
13728static void
dda8d76d 13729initialise_dumps_byname (Filedata * filedata)
aef1f6d0 13730{
2cf0635d 13731 struct dump_list_entry * cur;
aef1f6d0
DJ
13732
13733 for (cur = dump_sects_byname; cur; cur = cur->next)
13734 {
13735 unsigned int i;
32ec8896 13736 bfd_boolean any = FALSE;
aef1f6d0 13737
dda8d76d
NC
13738 for (i = 0; i < filedata->file_header.e_shnum; i++)
13739 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 13740 {
dda8d76d 13741 request_dump_bynumber (filedata, i, cur->type);
32ec8896 13742 any = TRUE;
aef1f6d0
DJ
13743 }
13744
13745 if (!any)
13746 warn (_("Section '%s' was not dumped because it does not exist!\n"),
13747 cur->name);
13748 }
13749}
13750
32ec8896 13751static bfd_boolean
dda8d76d 13752process_section_contents (Filedata * filedata)
5b18a4bc 13753{
2cf0635d 13754 Elf_Internal_Shdr * section;
19e6b90e 13755 unsigned int i;
32ec8896 13756 bfd_boolean res = TRUE;
103f02d3 13757
19e6b90e 13758 if (! do_dump)
32ec8896 13759 return TRUE;
103f02d3 13760
dda8d76d 13761 initialise_dumps_byname (filedata);
aef1f6d0 13762
dda8d76d
NC
13763 for (i = 0, section = filedata->section_headers;
13764 i < filedata->file_header.e_shnum && i < filedata->num_dump_sects;
19e6b90e
L
13765 i++, section++)
13766 {
dda8d76d
NC
13767 dump_type dump = filedata->dump_sects[i];
13768
19e6b90e 13769#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
13770 if (dump & DISASS_DUMP)
13771 {
13772 if (! disassemble_section (section, filedata))
13773 res = FALSE;
13774 }
19e6b90e 13775#endif
dda8d76d 13776 if (dump & HEX_DUMP)
32ec8896 13777 {
dda8d76d 13778 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
13779 res = FALSE;
13780 }
103f02d3 13781
dda8d76d 13782 if (dump & RELOC_DUMP)
32ec8896 13783 {
dda8d76d 13784 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
13785 res = FALSE;
13786 }
09c11c86 13787
dda8d76d 13788 if (dump & STRING_DUMP)
32ec8896 13789 {
dda8d76d 13790 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
13791 res = FALSE;
13792 }
cf13d699 13793
dda8d76d 13794 if (dump & DEBUG_DUMP)
32ec8896 13795 {
dda8d76d 13796 if (! display_debug_section (i, section, filedata))
32ec8896
NC
13797 res = FALSE;
13798 }
5b18a4bc 13799 }
103f02d3 13800
19e6b90e
L
13801 /* Check to see if the user requested a
13802 dump of a section that does not exist. */
dda8d76d 13803 while (i < filedata->num_dump_sects)
0ee3043f 13804 {
dda8d76d 13805 if (filedata->dump_sects[i])
32ec8896
NC
13806 {
13807 warn (_("Section %d was not dumped because it does not exist!\n"), i);
13808 res = FALSE;
13809 }
0ee3043f
NC
13810 i++;
13811 }
32ec8896
NC
13812
13813 return res;
5b18a4bc 13814}
103f02d3 13815
5b18a4bc 13816static void
19e6b90e 13817process_mips_fpe_exception (int mask)
5b18a4bc 13818{
19e6b90e
L
13819 if (mask)
13820 {
32ec8896
NC
13821 bfd_boolean first = TRUE;
13822
19e6b90e 13823 if (mask & OEX_FPU_INEX)
32ec8896 13824 fputs ("INEX", stdout), first = FALSE;
19e6b90e 13825 if (mask & OEX_FPU_UFLO)
32ec8896 13826 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 13827 if (mask & OEX_FPU_OFLO)
32ec8896 13828 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 13829 if (mask & OEX_FPU_DIV0)
32ec8896 13830 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
13831 if (mask & OEX_FPU_INVAL)
13832 printf ("%sINVAL", first ? "" : "|");
13833 }
5b18a4bc 13834 else
19e6b90e 13835 fputs ("0", stdout);
5b18a4bc 13836}
103f02d3 13837
f6f0e17b
NC
13838/* Display's the value of TAG at location P. If TAG is
13839 greater than 0 it is assumed to be an unknown tag, and
13840 a message is printed to this effect. Otherwise it is
13841 assumed that a message has already been printed.
13842
13843 If the bottom bit of TAG is set it assumed to have a
13844 string value, otherwise it is assumed to have an integer
13845 value.
13846
13847 Returns an updated P pointing to the first unread byte
13848 beyond the end of TAG's value.
13849
13850 Reads at or beyond END will not be made. */
13851
13852static unsigned char *
60abdbed 13853display_tag_value (signed int tag,
f6f0e17b
NC
13854 unsigned char * p,
13855 const unsigned char * const end)
13856{
13857 unsigned long val;
13858
13859 if (tag > 0)
13860 printf (" Tag_unknown_%d: ", tag);
13861
13862 if (p >= end)
13863 {
4082ef84 13864 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
13865 }
13866 else if (tag & 1)
13867 {
071436c6
NC
13868 /* PR 17531 file: 027-19978-0.004. */
13869 size_t maxlen = (end - p) - 1;
13870
13871 putchar ('"');
4082ef84
NC
13872 if (maxlen > 0)
13873 {
13874 print_symbol ((int) maxlen, (const char *) p);
13875 p += strnlen ((char *) p, maxlen) + 1;
13876 }
13877 else
13878 {
13879 printf (_("<corrupt string tag>"));
13880 p = (unsigned char *) end;
13881 }
071436c6 13882 printf ("\"\n");
f6f0e17b
NC
13883 }
13884 else
13885 {
13886 unsigned int len;
13887
13888 val = read_uleb128 (p, &len, end);
13889 p += len;
13890 printf ("%ld (0x%lx)\n", val, val);
13891 }
13892
4082ef84 13893 assert (p <= end);
f6f0e17b
NC
13894 return p;
13895}
13896
53a346d8
CZ
13897/* ARC ABI attributes section. */
13898
13899static unsigned char *
13900display_arc_attribute (unsigned char * p,
13901 const unsigned char * const end)
13902{
13903 unsigned int tag;
13904 unsigned int len;
13905 unsigned int val;
13906
13907 tag = read_uleb128 (p, &len, end);
13908 p += len;
13909
13910 switch (tag)
13911 {
13912 case Tag_ARC_PCS_config:
13913 val = read_uleb128 (p, &len, end);
13914 p += len;
13915 printf (" Tag_ARC_PCS_config: ");
13916 switch (val)
13917 {
13918 case 0:
13919 printf (_("Absent/Non standard\n"));
13920 break;
13921 case 1:
13922 printf (_("Bare metal/mwdt\n"));
13923 break;
13924 case 2:
13925 printf (_("Bare metal/newlib\n"));
13926 break;
13927 case 3:
13928 printf (_("Linux/uclibc\n"));
13929 break;
13930 case 4:
13931 printf (_("Linux/glibc\n"));
13932 break;
13933 default:
13934 printf (_("Unknown\n"));
13935 break;
13936 }
13937 break;
13938
13939 case Tag_ARC_CPU_base:
13940 val = read_uleb128 (p, &len, end);
13941 p += len;
13942 printf (" Tag_ARC_CPU_base: ");
13943 switch (val)
13944 {
13945 default:
13946 case TAG_CPU_NONE:
13947 printf (_("Absent\n"));
13948 break;
13949 case TAG_CPU_ARC6xx:
13950 printf ("ARC6xx\n");
13951 break;
13952 case TAG_CPU_ARC7xx:
13953 printf ("ARC7xx\n");
13954 break;
13955 case TAG_CPU_ARCEM:
13956 printf ("ARCEM\n");
13957 break;
13958 case TAG_CPU_ARCHS:
13959 printf ("ARCHS\n");
13960 break;
13961 }
13962 break;
13963
13964 case Tag_ARC_CPU_variation:
13965 val = read_uleb128 (p, &len, end);
13966 p += len;
13967 printf (" Tag_ARC_CPU_variation: ");
13968 switch (val)
13969 {
13970 default:
13971 if (val > 0 && val < 16)
53a346d8 13972 printf ("Core%d\n", val);
d8cbc93b
JL
13973 else
13974 printf ("Unknown\n");
13975 break;
13976
53a346d8
CZ
13977 case 0:
13978 printf (_("Absent\n"));
13979 break;
13980 }
13981 break;
13982
13983 case Tag_ARC_CPU_name:
13984 printf (" Tag_ARC_CPU_name: ");
13985 p = display_tag_value (-1, p, end);
13986 break;
13987
13988 case Tag_ARC_ABI_rf16:
13989 val = read_uleb128 (p, &len, end);
13990 p += len;
13991 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
13992 break;
13993
13994 case Tag_ARC_ABI_osver:
13995 val = read_uleb128 (p, &len, end);
13996 p += len;
13997 printf (" Tag_ARC_ABI_osver: v%d\n", val);
13998 break;
13999
14000 case Tag_ARC_ABI_pic:
14001 case Tag_ARC_ABI_sda:
14002 val = read_uleb128 (p, &len, end);
14003 p += len;
14004 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
14005 : " Tag_ARC_ABI_pic: ");
14006 switch (val)
14007 {
14008 case 0:
14009 printf (_("Absent\n"));
14010 break;
14011 case 1:
14012 printf ("MWDT\n");
14013 break;
14014 case 2:
14015 printf ("GNU\n");
14016 break;
14017 default:
14018 printf (_("Unknown\n"));
14019 break;
14020 }
14021 break;
14022
14023 case Tag_ARC_ABI_tls:
14024 val = read_uleb128 (p, &len, end);
14025 p += len;
14026 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
14027 break;
14028
14029 case Tag_ARC_ABI_enumsize:
14030 val = read_uleb128 (p, &len, end);
14031 p += len;
14032 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
14033 _("smallest"));
14034 break;
14035
14036 case Tag_ARC_ABI_exceptions:
14037 val = read_uleb128 (p, &len, end);
14038 p += len;
14039 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
14040 : _("default"));
14041 break;
14042
14043 case Tag_ARC_ABI_double_size:
14044 val = read_uleb128 (p, &len, end);
14045 p += len;
14046 printf (" Tag_ARC_ABI_double_size: %d\n", val);
14047 break;
14048
14049 case Tag_ARC_ISA_config:
14050 printf (" Tag_ARC_ISA_config: ");
14051 p = display_tag_value (-1, p, end);
14052 break;
14053
14054 case Tag_ARC_ISA_apex:
14055 printf (" Tag_ARC_ISA_apex: ");
14056 p = display_tag_value (-1, p, end);
14057 break;
14058
14059 case Tag_ARC_ISA_mpy_option:
14060 val = read_uleb128 (p, &len, end);
14061 p += len;
14062 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
14063 break;
14064
14065 default:
14066 return display_tag_value (tag & 1, p, end);
14067 }
14068
14069 return p;
14070}
14071
11c1ff18
PB
14072/* ARM EABI attributes section. */
14073typedef struct
14074{
70e99720 14075 unsigned int tag;
2cf0635d 14076 const char * name;
11c1ff18 14077 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 14078 unsigned int type;
2cf0635d 14079 const char ** table;
11c1ff18
PB
14080} arm_attr_public_tag;
14081
2cf0635d 14082static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 14083 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 14084 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
ff8646ee 14085 "v8-M.mainline"};
2cf0635d
NC
14086static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
14087static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 14088 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 14089static const char * arm_attr_tag_FP_arch[] =
bca38921 14090 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 14091 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 14092static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 14093static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
14094 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
14095 "NEON for ARMv8.1"};
2cf0635d 14096static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
14097 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
14098 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 14099static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 14100 {"V6", "SB", "TLS", "Unused"};
2cf0635d 14101static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 14102 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 14103static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 14104 {"Absolute", "PC-relative", "None"};
2cf0635d 14105static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 14106 {"None", "direct", "GOT-indirect"};
2cf0635d 14107static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 14108 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
14109static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
14110static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 14111 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
14112static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
14113static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
14114static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 14115 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 14116static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 14117 {"Unused", "small", "int", "forced to int"};
2cf0635d 14118static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 14119 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 14120static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 14121 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 14122static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 14123 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 14124static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
14125 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14126 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 14127static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
14128 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14129 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 14130static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 14131static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 14132 {"Not Allowed", "Allowed"};
2cf0635d 14133static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 14134 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
14135static const char * arm_attr_tag_DSP_extension[] =
14136 {"Follow architecture", "Allowed"};
dd24e3da 14137static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
14138 {"Not Allowed", "Allowed"};
14139static const char * arm_attr_tag_DIV_use[] =
dd24e3da 14140 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 14141 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
14142static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
14143static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 14144 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 14145 "TrustZone and Virtualization Extensions"};
dd24e3da 14146static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 14147 {"Not Allowed", "Allowed"};
11c1ff18
PB
14148
14149#define LOOKUP(id, name) \
14150 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 14151static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
14152{
14153 {4, "CPU_raw_name", 1, NULL},
14154 {5, "CPU_name", 1, NULL},
14155 LOOKUP(6, CPU_arch),
14156 {7, "CPU_arch_profile", 0, NULL},
14157 LOOKUP(8, ARM_ISA_use),
14158 LOOKUP(9, THUMB_ISA_use),
75375b3e 14159 LOOKUP(10, FP_arch),
11c1ff18 14160 LOOKUP(11, WMMX_arch),
f5f53991
AS
14161 LOOKUP(12, Advanced_SIMD_arch),
14162 LOOKUP(13, PCS_config),
11c1ff18
PB
14163 LOOKUP(14, ABI_PCS_R9_use),
14164 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 14165 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
14166 LOOKUP(17, ABI_PCS_GOT_use),
14167 LOOKUP(18, ABI_PCS_wchar_t),
14168 LOOKUP(19, ABI_FP_rounding),
14169 LOOKUP(20, ABI_FP_denormal),
14170 LOOKUP(21, ABI_FP_exceptions),
14171 LOOKUP(22, ABI_FP_user_exceptions),
14172 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
14173 {24, "ABI_align_needed", 0, NULL},
14174 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
14175 LOOKUP(26, ABI_enum_size),
14176 LOOKUP(27, ABI_HardFP_use),
14177 LOOKUP(28, ABI_VFP_args),
14178 LOOKUP(29, ABI_WMMX_args),
14179 LOOKUP(30, ABI_optimization_goals),
14180 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 14181 {32, "compatibility", 0, NULL},
f5f53991 14182 LOOKUP(34, CPU_unaligned_access),
75375b3e 14183 LOOKUP(36, FP_HP_extension),
8e79c3df 14184 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
14185 LOOKUP(42, MPextension_use),
14186 LOOKUP(44, DIV_use),
15afaa63 14187 LOOKUP(46, DSP_extension),
f5f53991
AS
14188 {64, "nodefaults", 0, NULL},
14189 {65, "also_compatible_with", 0, NULL},
14190 LOOKUP(66, T2EE_use),
14191 {67, "conformance", 1, NULL},
14192 LOOKUP(68, Virtualization_use),
cd21e546 14193 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
14194};
14195#undef LOOKUP
14196
11c1ff18 14197static unsigned char *
f6f0e17b
NC
14198display_arm_attribute (unsigned char * p,
14199 const unsigned char * const end)
11c1ff18 14200{
70e99720 14201 unsigned int tag;
11c1ff18 14202 unsigned int len;
70e99720 14203 unsigned int val;
2cf0635d 14204 arm_attr_public_tag * attr;
11c1ff18 14205 unsigned i;
70e99720 14206 unsigned int type;
11c1ff18 14207
f6f0e17b 14208 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
14209 p += len;
14210 attr = NULL;
2cf0635d 14211 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
14212 {
14213 if (arm_attr_public_tags[i].tag == tag)
14214 {
14215 attr = &arm_attr_public_tags[i];
14216 break;
14217 }
14218 }
14219
14220 if (attr)
14221 {
14222 printf (" Tag_%s: ", attr->name);
14223 switch (attr->type)
14224 {
14225 case 0:
14226 switch (tag)
14227 {
14228 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 14229 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14230 p += len;
14231 switch (val)
14232 {
2b692964
NC
14233 case 0: printf (_("None\n")); break;
14234 case 'A': printf (_("Application\n")); break;
14235 case 'R': printf (_("Realtime\n")); break;
14236 case 'M': printf (_("Microcontroller\n")); break;
14237 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
14238 default: printf ("??? (%d)\n", val); break;
14239 }
14240 break;
14241
75375b3e 14242 case 24: /* Tag_align_needed. */
f6f0e17b 14243 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14244 p += len;
14245 switch (val)
14246 {
2b692964
NC
14247 case 0: printf (_("None\n")); break;
14248 case 1: printf (_("8-byte\n")); break;
14249 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
14250 case 3: printf ("??? 3\n"); break;
14251 default:
14252 if (val <= 12)
dd24e3da 14253 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14254 1 << val);
14255 else
14256 printf ("??? (%d)\n", val);
14257 break;
14258 }
14259 break;
14260
14261 case 25: /* Tag_align_preserved. */
f6f0e17b 14262 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14263 p += len;
14264 switch (val)
14265 {
2b692964
NC
14266 case 0: printf (_("None\n")); break;
14267 case 1: printf (_("8-byte, except leaf SP\n")); break;
14268 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
14269 case 3: printf ("??? 3\n"); break;
14270 default:
14271 if (val <= 12)
dd24e3da 14272 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14273 1 << val);
14274 else
14275 printf ("??? (%d)\n", val);
14276 break;
14277 }
14278 break;
14279
11c1ff18 14280 case 32: /* Tag_compatibility. */
071436c6 14281 {
071436c6
NC
14282 val = read_uleb128 (p, &len, end);
14283 p += len;
071436c6 14284 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
14285 if (p < end - 1)
14286 {
14287 size_t maxlen = (end - p) - 1;
14288
14289 print_symbol ((int) maxlen, (const char *) p);
14290 p += strnlen ((char *) p, maxlen) + 1;
14291 }
14292 else
14293 {
14294 printf (_("<corrupt>"));
14295 p = (unsigned char *) end;
14296 }
071436c6 14297 putchar ('\n');
071436c6 14298 }
11c1ff18
PB
14299 break;
14300
f5f53991 14301 case 64: /* Tag_nodefaults. */
541a3cbd
NC
14302 /* PR 17531: file: 001-505008-0.01. */
14303 if (p < end)
14304 p++;
2b692964 14305 printf (_("True\n"));
f5f53991
AS
14306 break;
14307
14308 case 65: /* Tag_also_compatible_with. */
f6f0e17b 14309 val = read_uleb128 (p, &len, end);
f5f53991
AS
14310 p += len;
14311 if (val == 6 /* Tag_CPU_arch. */)
14312 {
f6f0e17b 14313 val = read_uleb128 (p, &len, end);
f5f53991 14314 p += len;
071436c6 14315 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
14316 printf ("??? (%d)\n", val);
14317 else
14318 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
14319 }
14320 else
14321 printf ("???\n");
071436c6
NC
14322 while (p < end && *(p++) != '\0' /* NUL terminator. */)
14323 ;
f5f53991
AS
14324 break;
14325
11c1ff18 14326 default:
bee0ee85
NC
14327 printf (_("<unknown: %d>\n"), tag);
14328 break;
11c1ff18
PB
14329 }
14330 return p;
14331
14332 case 1:
f6f0e17b 14333 return display_tag_value (-1, p, end);
11c1ff18 14334 case 2:
f6f0e17b 14335 return display_tag_value (0, p, end);
11c1ff18
PB
14336
14337 default:
14338 assert (attr->type & 0x80);
f6f0e17b 14339 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14340 p += len;
14341 type = attr->type & 0x7f;
14342 if (val >= type)
14343 printf ("??? (%d)\n", val);
14344 else
14345 printf ("%s\n", attr->table[val]);
14346 return p;
14347 }
14348 }
11c1ff18 14349
f6f0e17b 14350 return display_tag_value (tag, p, end);
11c1ff18
PB
14351}
14352
104d59d1 14353static unsigned char *
60bca95a 14354display_gnu_attribute (unsigned char * p,
60abdbed 14355 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 14356 const unsigned char * const end)
104d59d1
JM
14357{
14358 int tag;
14359 unsigned int len;
60abdbed 14360 unsigned int val;
104d59d1 14361
f6f0e17b 14362 tag = read_uleb128 (p, &len, end);
104d59d1
JM
14363 p += len;
14364
14365 /* Tag_compatibility is the only generic GNU attribute defined at
14366 present. */
14367 if (tag == 32)
14368 {
f6f0e17b 14369 val = read_uleb128 (p, &len, end);
104d59d1 14370 p += len;
071436c6
NC
14371
14372 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
14373 if (p == end)
14374 {
071436c6 14375 printf (_("<corrupt>\n"));
f6f0e17b
NC
14376 warn (_("corrupt vendor attribute\n"));
14377 }
14378 else
14379 {
4082ef84
NC
14380 if (p < end - 1)
14381 {
14382 size_t maxlen = (end - p) - 1;
071436c6 14383
4082ef84
NC
14384 print_symbol ((int) maxlen, (const char *) p);
14385 p += strnlen ((char *) p, maxlen) + 1;
14386 }
14387 else
14388 {
14389 printf (_("<corrupt>"));
14390 p = (unsigned char *) end;
14391 }
071436c6 14392 putchar ('\n');
f6f0e17b 14393 }
104d59d1
JM
14394 return p;
14395 }
14396
14397 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 14398 return display_proc_gnu_attribute (p, tag, end);
104d59d1 14399
f6f0e17b 14400 return display_tag_value (tag, p, end);
104d59d1
JM
14401}
14402
34c8bcba 14403static unsigned char *
f6f0e17b 14404display_power_gnu_attribute (unsigned char * p,
60abdbed 14405 unsigned int tag,
f6f0e17b 14406 const unsigned char * const end)
34c8bcba 14407{
34c8bcba 14408 unsigned int len;
005d79fd 14409 unsigned int val;
34c8bcba
JM
14410
14411 if (tag == Tag_GNU_Power_ABI_FP)
14412 {
f6f0e17b 14413 val = read_uleb128 (p, &len, end);
34c8bcba
JM
14414 p += len;
14415 printf (" Tag_GNU_Power_ABI_FP: ");
005d79fd
AM
14416 if (len == 0)
14417 {
14418 printf (_("<corrupt>\n"));
14419 return p;
14420 }
60bca95a 14421
005d79fd
AM
14422 if (val > 15)
14423 printf ("(%#x), ", val);
14424
14425 switch (val & 3)
34c8bcba
JM
14426 {
14427 case 0:
005d79fd 14428 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
14429 break;
14430 case 1:
005d79fd 14431 printf (_("hard float, "));
34c8bcba
JM
14432 break;
14433 case 2:
005d79fd 14434 printf (_("soft float, "));
34c8bcba 14435 break;
3c7b9897 14436 case 3:
005d79fd 14437 printf (_("single-precision hard float, "));
3c7b9897 14438 break;
005d79fd
AM
14439 }
14440
14441 switch (val & 0xC)
14442 {
14443 case 0:
14444 printf (_("unspecified long double\n"));
14445 break;
14446 case 4:
14447 printf (_("128-bit IBM long double\n"));
14448 break;
14449 case 8:
14450 printf (_("64-bit long double\n"));
14451 break;
14452 case 12:
14453 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
14454 break;
14455 }
14456 return p;
005d79fd 14457 }
34c8bcba 14458
c6e65352
DJ
14459 if (tag == Tag_GNU_Power_ABI_Vector)
14460 {
f6f0e17b 14461 val = read_uleb128 (p, &len, end);
c6e65352
DJ
14462 p += len;
14463 printf (" Tag_GNU_Power_ABI_Vector: ");
005d79fd
AM
14464 if (len == 0)
14465 {
14466 printf (_("<corrupt>\n"));
14467 return p;
14468 }
14469
14470 if (val > 3)
14471 printf ("(%#x), ", val);
14472
14473 switch (val & 3)
c6e65352
DJ
14474 {
14475 case 0:
005d79fd 14476 printf (_("unspecified\n"));
c6e65352
DJ
14477 break;
14478 case 1:
005d79fd 14479 printf (_("generic\n"));
c6e65352
DJ
14480 break;
14481 case 2:
14482 printf ("AltiVec\n");
14483 break;
14484 case 3:
14485 printf ("SPE\n");
14486 break;
c6e65352
DJ
14487 }
14488 return p;
005d79fd 14489 }
c6e65352 14490
f82e0623
NF
14491 if (tag == Tag_GNU_Power_ABI_Struct_Return)
14492 {
005d79fd
AM
14493 val = read_uleb128 (p, &len, end);
14494 p += len;
14495 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
14496 if (len == 0)
f6f0e17b 14497 {
005d79fd 14498 printf (_("<corrupt>\n"));
f6f0e17b
NC
14499 return p;
14500 }
0b4362b0 14501
005d79fd
AM
14502 if (val > 2)
14503 printf ("(%#x), ", val);
14504
14505 switch (val & 3)
14506 {
14507 case 0:
14508 printf (_("unspecified\n"));
14509 break;
14510 case 1:
14511 printf ("r3/r4\n");
14512 break;
14513 case 2:
14514 printf (_("memory\n"));
14515 break;
14516 case 3:
14517 printf ("???\n");
14518 break;
14519 }
f82e0623
NF
14520 return p;
14521 }
14522
f6f0e17b 14523 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
14524}
14525
643f7afb
AK
14526static unsigned char *
14527display_s390_gnu_attribute (unsigned char * p,
60abdbed 14528 unsigned int tag,
643f7afb
AK
14529 const unsigned char * const end)
14530{
14531 unsigned int len;
14532 int val;
14533
14534 if (tag == Tag_GNU_S390_ABI_Vector)
14535 {
14536 val = read_uleb128 (p, &len, end);
14537 p += len;
14538 printf (" Tag_GNU_S390_ABI_Vector: ");
14539
14540 switch (val)
14541 {
14542 case 0:
14543 printf (_("any\n"));
14544 break;
14545 case 1:
14546 printf (_("software\n"));
14547 break;
14548 case 2:
14549 printf (_("hardware\n"));
14550 break;
14551 default:
14552 printf ("??? (%d)\n", val);
14553 break;
14554 }
14555 return p;
14556 }
14557
14558 return display_tag_value (tag & 1, p, end);
14559}
14560
9e8c70f9 14561static void
60abdbed 14562display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
14563{
14564 if (mask)
14565 {
32ec8896 14566 bfd_boolean first = TRUE;
071436c6 14567
9e8c70f9 14568 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 14569 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 14570 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 14571 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 14572 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 14573 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 14574 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 14575 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 14576 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 14577 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 14578 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 14579 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 14580 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 14581 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 14582 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 14583 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 14584 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 14585 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 14586 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 14587 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 14588 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 14589 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 14590 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 14591 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 14592 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 14593 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 14594 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 14595 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 14596 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 14597 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 14598 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 14599 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
14600 }
14601 else
071436c6
NC
14602 fputc ('0', stdout);
14603 fputc ('\n', stdout);
9e8c70f9
DM
14604}
14605
3d68f91c 14606static void
60abdbed 14607display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
14608{
14609 if (mask)
14610 {
32ec8896 14611 bfd_boolean first = TRUE;
071436c6 14612
3d68f91c 14613 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 14614 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 14615 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 14616 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 14617 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 14618 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 14619 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 14620 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 14621 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 14622 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 14623 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 14624 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 14625 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 14626 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 14627 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 14628 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 14629 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 14630 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 14631 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 14632 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 14633 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 14634 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
14635 }
14636 else
071436c6
NC
14637 fputc ('0', stdout);
14638 fputc ('\n', stdout);
3d68f91c
JM
14639}
14640
9e8c70f9 14641static unsigned char *
f6f0e17b 14642display_sparc_gnu_attribute (unsigned char * p,
60abdbed 14643 unsigned int tag,
f6f0e17b 14644 const unsigned char * const end)
9e8c70f9 14645{
3d68f91c
JM
14646 unsigned int len;
14647 int val;
14648
9e8c70f9
DM
14649 if (tag == Tag_GNU_Sparc_HWCAPS)
14650 {
f6f0e17b 14651 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
14652 p += len;
14653 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
14654 display_sparc_hwcaps (val);
14655 return p;
3d68f91c
JM
14656 }
14657 if (tag == Tag_GNU_Sparc_HWCAPS2)
14658 {
14659 val = read_uleb128 (p, &len, end);
14660 p += len;
14661 printf (" Tag_GNU_Sparc_HWCAPS2: ");
14662 display_sparc_hwcaps2 (val);
14663 return p;
14664 }
9e8c70f9 14665
f6f0e17b 14666 return display_tag_value (tag, p, end);
9e8c70f9
DM
14667}
14668
351cdf24 14669static void
32ec8896 14670print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
14671{
14672 switch (val)
14673 {
14674 case Val_GNU_MIPS_ABI_FP_ANY:
14675 printf (_("Hard or soft float\n"));
14676 break;
14677 case Val_GNU_MIPS_ABI_FP_DOUBLE:
14678 printf (_("Hard float (double precision)\n"));
14679 break;
14680 case Val_GNU_MIPS_ABI_FP_SINGLE:
14681 printf (_("Hard float (single precision)\n"));
14682 break;
14683 case Val_GNU_MIPS_ABI_FP_SOFT:
14684 printf (_("Soft float\n"));
14685 break;
14686 case Val_GNU_MIPS_ABI_FP_OLD_64:
14687 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
14688 break;
14689 case Val_GNU_MIPS_ABI_FP_XX:
14690 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
14691 break;
14692 case Val_GNU_MIPS_ABI_FP_64:
14693 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
14694 break;
14695 case Val_GNU_MIPS_ABI_FP_64A:
14696 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
14697 break;
3350cc01
CM
14698 case Val_GNU_MIPS_ABI_FP_NAN2008:
14699 printf (_("NaN 2008 compatibility\n"));
14700 break;
351cdf24
MF
14701 default:
14702 printf ("??? (%d)\n", val);
14703 break;
14704 }
14705}
14706
2cf19d5c 14707static unsigned char *
f6f0e17b 14708display_mips_gnu_attribute (unsigned char * p,
60abdbed 14709 unsigned int tag,
f6f0e17b 14710 const unsigned char * const end)
2cf19d5c 14711{
2cf19d5c
JM
14712 if (tag == Tag_GNU_MIPS_ABI_FP)
14713 {
f6f0e17b 14714 unsigned int len;
32ec8896 14715 unsigned int val;
f6f0e17b
NC
14716
14717 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
14718 p += len;
14719 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 14720
351cdf24
MF
14721 print_mips_fp_abi_value (val);
14722
2cf19d5c
JM
14723 return p;
14724 }
14725
a9f58168
CF
14726 if (tag == Tag_GNU_MIPS_ABI_MSA)
14727 {
14728 unsigned int len;
32ec8896 14729 unsigned int val;
a9f58168
CF
14730
14731 val = read_uleb128 (p, &len, end);
14732 p += len;
14733 printf (" Tag_GNU_MIPS_ABI_MSA: ");
14734
14735 switch (val)
14736 {
14737 case Val_GNU_MIPS_ABI_MSA_ANY:
14738 printf (_("Any MSA or not\n"));
14739 break;
14740 case Val_GNU_MIPS_ABI_MSA_128:
14741 printf (_("128-bit MSA\n"));
14742 break;
14743 default:
14744 printf ("??? (%d)\n", val);
14745 break;
14746 }
14747 return p;
14748 }
14749
f6f0e17b 14750 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
14751}
14752
59e6276b 14753static unsigned char *
f6f0e17b
NC
14754display_tic6x_attribute (unsigned char * p,
14755 const unsigned char * const end)
59e6276b 14756{
60abdbed 14757 unsigned int tag;
59e6276b
JM
14758 unsigned int len;
14759 int val;
14760
f6f0e17b 14761 tag = read_uleb128 (p, &len, end);
59e6276b
JM
14762 p += len;
14763
14764 switch (tag)
14765 {
75fa6dc1 14766 case Tag_ISA:
f6f0e17b 14767 val = read_uleb128 (p, &len, end);
59e6276b 14768 p += len;
75fa6dc1 14769 printf (" Tag_ISA: ");
59e6276b
JM
14770
14771 switch (val)
14772 {
75fa6dc1 14773 case C6XABI_Tag_ISA_none:
59e6276b
JM
14774 printf (_("None\n"));
14775 break;
75fa6dc1 14776 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
14777 printf ("C62x\n");
14778 break;
75fa6dc1 14779 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
14780 printf ("C67x\n");
14781 break;
75fa6dc1 14782 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
14783 printf ("C67x+\n");
14784 break;
75fa6dc1 14785 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
14786 printf ("C64x\n");
14787 break;
75fa6dc1 14788 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
14789 printf ("C64x+\n");
14790 break;
75fa6dc1 14791 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
14792 printf ("C674x\n");
14793 break;
14794 default:
14795 printf ("??? (%d)\n", val);
14796 break;
14797 }
14798 return p;
14799
87779176 14800 case Tag_ABI_wchar_t:
f6f0e17b 14801 val = read_uleb128 (p, &len, end);
87779176
JM
14802 p += len;
14803 printf (" Tag_ABI_wchar_t: ");
14804 switch (val)
14805 {
14806 case 0:
14807 printf (_("Not used\n"));
14808 break;
14809 case 1:
14810 printf (_("2 bytes\n"));
14811 break;
14812 case 2:
14813 printf (_("4 bytes\n"));
14814 break;
14815 default:
14816 printf ("??? (%d)\n", val);
14817 break;
14818 }
14819 return p;
14820
14821 case Tag_ABI_stack_align_needed:
f6f0e17b 14822 val = read_uleb128 (p, &len, end);
87779176
JM
14823 p += len;
14824 printf (" Tag_ABI_stack_align_needed: ");
14825 switch (val)
14826 {
14827 case 0:
14828 printf (_("8-byte\n"));
14829 break;
14830 case 1:
14831 printf (_("16-byte\n"));
14832 break;
14833 default:
14834 printf ("??? (%d)\n", val);
14835 break;
14836 }
14837 return p;
14838
14839 case Tag_ABI_stack_align_preserved:
f6f0e17b 14840 val = read_uleb128 (p, &len, end);
87779176
JM
14841 p += len;
14842 printf (" Tag_ABI_stack_align_preserved: ");
14843 switch (val)
14844 {
14845 case 0:
14846 printf (_("8-byte\n"));
14847 break;
14848 case 1:
14849 printf (_("16-byte\n"));
14850 break;
14851 default:
14852 printf ("??? (%d)\n", val);
14853 break;
14854 }
14855 return p;
14856
b5593623 14857 case Tag_ABI_DSBT:
f6f0e17b 14858 val = read_uleb128 (p, &len, end);
b5593623
JM
14859 p += len;
14860 printf (" Tag_ABI_DSBT: ");
14861 switch (val)
14862 {
14863 case 0:
14864 printf (_("DSBT addressing not used\n"));
14865 break;
14866 case 1:
14867 printf (_("DSBT addressing used\n"));
14868 break;
14869 default:
14870 printf ("??? (%d)\n", val);
14871 break;
14872 }
14873 return p;
14874
87779176 14875 case Tag_ABI_PID:
f6f0e17b 14876 val = read_uleb128 (p, &len, end);
87779176
JM
14877 p += len;
14878 printf (" Tag_ABI_PID: ");
14879 switch (val)
14880 {
14881 case 0:
14882 printf (_("Data addressing position-dependent\n"));
14883 break;
14884 case 1:
14885 printf (_("Data addressing position-independent, GOT near DP\n"));
14886 break;
14887 case 2:
14888 printf (_("Data addressing position-independent, GOT far from DP\n"));
14889 break;
14890 default:
14891 printf ("??? (%d)\n", val);
14892 break;
14893 }
14894 return p;
14895
14896 case Tag_ABI_PIC:
f6f0e17b 14897 val = read_uleb128 (p, &len, end);
87779176
JM
14898 p += len;
14899 printf (" Tag_ABI_PIC: ");
14900 switch (val)
14901 {
14902 case 0:
14903 printf (_("Code addressing position-dependent\n"));
14904 break;
14905 case 1:
14906 printf (_("Code addressing position-independent\n"));
14907 break;
14908 default:
14909 printf ("??? (%d)\n", val);
14910 break;
14911 }
14912 return p;
14913
14914 case Tag_ABI_array_object_alignment:
f6f0e17b 14915 val = read_uleb128 (p, &len, end);
87779176
JM
14916 p += len;
14917 printf (" Tag_ABI_array_object_alignment: ");
14918 switch (val)
14919 {
14920 case 0:
14921 printf (_("8-byte\n"));
14922 break;
14923 case 1:
14924 printf (_("4-byte\n"));
14925 break;
14926 case 2:
14927 printf (_("16-byte\n"));
14928 break;
14929 default:
14930 printf ("??? (%d)\n", val);
14931 break;
14932 }
14933 return p;
14934
14935 case Tag_ABI_array_object_align_expected:
f6f0e17b 14936 val = read_uleb128 (p, &len, end);
87779176
JM
14937 p += len;
14938 printf (" Tag_ABI_array_object_align_expected: ");
14939 switch (val)
14940 {
14941 case 0:
14942 printf (_("8-byte\n"));
14943 break;
14944 case 1:
14945 printf (_("4-byte\n"));
14946 break;
14947 case 2:
14948 printf (_("16-byte\n"));
14949 break;
14950 default:
14951 printf ("??? (%d)\n", val);
14952 break;
14953 }
14954 return p;
14955
3cbd1c06 14956 case Tag_ABI_compatibility:
071436c6 14957 {
071436c6
NC
14958 val = read_uleb128 (p, &len, end);
14959 p += len;
14960 printf (" Tag_ABI_compatibility: ");
071436c6 14961 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
14962 if (p < end - 1)
14963 {
14964 size_t maxlen = (end - p) - 1;
14965
14966 print_symbol ((int) maxlen, (const char *) p);
14967 p += strnlen ((char *) p, maxlen) + 1;
14968 }
14969 else
14970 {
14971 printf (_("<corrupt>"));
14972 p = (unsigned char *) end;
14973 }
071436c6 14974 putchar ('\n');
071436c6
NC
14975 return p;
14976 }
87779176
JM
14977
14978 case Tag_ABI_conformance:
071436c6 14979 {
4082ef84
NC
14980 printf (" Tag_ABI_conformance: \"");
14981 if (p < end - 1)
14982 {
14983 size_t maxlen = (end - p) - 1;
071436c6 14984
4082ef84
NC
14985 print_symbol ((int) maxlen, (const char *) p);
14986 p += strnlen ((char *) p, maxlen) + 1;
14987 }
14988 else
14989 {
14990 printf (_("<corrupt>"));
14991 p = (unsigned char *) end;
14992 }
071436c6 14993 printf ("\"\n");
071436c6
NC
14994 return p;
14995 }
59e6276b
JM
14996 }
14997
f6f0e17b
NC
14998 return display_tag_value (tag, p, end);
14999}
59e6276b 15000
f6f0e17b 15001static void
60abdbed 15002display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
15003{
15004 unsigned long addr = 0;
15005 size_t bytes = end - p;
15006
e0a31db1 15007 assert (end > p);
f6f0e17b 15008 while (bytes)
87779176 15009 {
f6f0e17b
NC
15010 int j;
15011 int k;
15012 int lbytes = (bytes > 16 ? 16 : bytes);
15013
15014 printf (" 0x%8.8lx ", addr);
15015
15016 for (j = 0; j < 16; j++)
15017 {
15018 if (j < lbytes)
15019 printf ("%2.2x", p[j]);
15020 else
15021 printf (" ");
15022
15023 if ((j & 3) == 3)
15024 printf (" ");
15025 }
15026
15027 for (j = 0; j < lbytes; j++)
15028 {
15029 k = p[j];
15030 if (k >= ' ' && k < 0x7f)
15031 printf ("%c", k);
15032 else
15033 printf (".");
15034 }
15035
15036 putchar ('\n');
15037
15038 p += lbytes;
15039 bytes -= lbytes;
15040 addr += lbytes;
87779176 15041 }
59e6276b 15042
f6f0e17b 15043 putchar ('\n');
59e6276b
JM
15044}
15045
13761a11
NC
15046static unsigned char *
15047display_msp430x_attribute (unsigned char * p,
15048 const unsigned char * const end)
15049{
15050 unsigned int len;
60abdbed
NC
15051 unsigned int val;
15052 unsigned int tag;
13761a11
NC
15053
15054 tag = read_uleb128 (p, & len, end);
15055 p += len;
0b4362b0 15056
13761a11
NC
15057 switch (tag)
15058 {
15059 case OFBA_MSPABI_Tag_ISA:
15060 val = read_uleb128 (p, &len, end);
15061 p += len;
15062 printf (" Tag_ISA: ");
15063 switch (val)
15064 {
15065 case 0: printf (_("None\n")); break;
15066 case 1: printf (_("MSP430\n")); break;
15067 case 2: printf (_("MSP430X\n")); break;
15068 default: printf ("??? (%d)\n", val); break;
15069 }
15070 break;
15071
15072 case OFBA_MSPABI_Tag_Code_Model:
15073 val = read_uleb128 (p, &len, end);
15074 p += len;
15075 printf (" Tag_Code_Model: ");
15076 switch (val)
15077 {
15078 case 0: printf (_("None\n")); break;
15079 case 1: printf (_("Small\n")); break;
15080 case 2: printf (_("Large\n")); break;
15081 default: printf ("??? (%d)\n", val); break;
15082 }
15083 break;
15084
15085 case OFBA_MSPABI_Tag_Data_Model:
15086 val = read_uleb128 (p, &len, end);
15087 p += len;
15088 printf (" Tag_Data_Model: ");
15089 switch (val)
15090 {
15091 case 0: printf (_("None\n")); break;
15092 case 1: printf (_("Small\n")); break;
15093 case 2: printf (_("Large\n")); break;
15094 case 3: printf (_("Restricted Large\n")); break;
15095 default: printf ("??? (%d)\n", val); break;
15096 }
15097 break;
15098
15099 default:
15100 printf (_(" <unknown tag %d>: "), tag);
15101
15102 if (tag & 1)
15103 {
071436c6 15104 putchar ('"');
4082ef84
NC
15105 if (p < end - 1)
15106 {
15107 size_t maxlen = (end - p) - 1;
15108
15109 print_symbol ((int) maxlen, (const char *) p);
15110 p += strnlen ((char *) p, maxlen) + 1;
15111 }
15112 else
15113 {
15114 printf (_("<corrupt>"));
15115 p = (unsigned char *) end;
15116 }
071436c6 15117 printf ("\"\n");
13761a11
NC
15118 }
15119 else
15120 {
15121 val = read_uleb128 (p, &len, end);
15122 p += len;
15123 printf ("%d (0x%x)\n", val, val);
15124 }
15125 break;
15126 }
15127
4082ef84 15128 assert (p <= end);
13761a11
NC
15129 return p;
15130}
15131
32ec8896 15132static bfd_boolean
dda8d76d 15133process_attributes (Filedata * filedata,
60bca95a 15134 const char * public_name,
104d59d1 15135 unsigned int proc_type,
f6f0e17b 15136 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 15137 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 15138{
2cf0635d 15139 Elf_Internal_Shdr * sect;
11c1ff18 15140 unsigned i;
32ec8896 15141 bfd_boolean res = TRUE;
11c1ff18
PB
15142
15143 /* Find the section header so that we get the size. */
dda8d76d
NC
15144 for (i = 0, sect = filedata->section_headers;
15145 i < filedata->file_header.e_shnum;
11c1ff18
PB
15146 i++, sect++)
15147 {
071436c6
NC
15148 unsigned char * contents;
15149 unsigned char * p;
15150
104d59d1 15151 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
15152 continue;
15153
dda8d76d 15154 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 15155 sect->sh_size, _("attributes"));
60bca95a 15156 if (contents == NULL)
32ec8896
NC
15157 {
15158 res = FALSE;
15159 continue;
15160 }
60bca95a 15161
11c1ff18 15162 p = contents;
60abdbed
NC
15163 /* The first character is the version of the attributes.
15164 Currently only version 1, (aka 'A') is recognised here. */
15165 if (*p != 'A')
32ec8896
NC
15166 {
15167 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
15168 res = FALSE;
15169 }
60abdbed 15170 else
11c1ff18 15171 {
071436c6
NC
15172 bfd_vma section_len;
15173
15174 section_len = sect->sh_size - 1;
11c1ff18 15175 p++;
60bca95a 15176
071436c6 15177 while (section_len > 0)
11c1ff18 15178 {
071436c6 15179 bfd_vma attr_len;
e9847026 15180 unsigned int namelen;
11c1ff18 15181 bfd_boolean public_section;
104d59d1 15182 bfd_boolean gnu_section;
11c1ff18 15183
071436c6 15184 if (section_len <= 4)
e0a31db1
NC
15185 {
15186 error (_("Tag section ends prematurely\n"));
32ec8896 15187 res = FALSE;
e0a31db1
NC
15188 break;
15189 }
071436c6 15190 attr_len = byte_get (p, 4);
11c1ff18 15191 p += 4;
60bca95a 15192
071436c6 15193 if (attr_len > section_len)
11c1ff18 15194 {
071436c6
NC
15195 error (_("Bad attribute length (%u > %u)\n"),
15196 (unsigned) attr_len, (unsigned) section_len);
15197 attr_len = section_len;
32ec8896 15198 res = FALSE;
11c1ff18 15199 }
74e1a04b 15200 /* PR 17531: file: 001-101425-0.004 */
071436c6 15201 else if (attr_len < 5)
74e1a04b 15202 {
071436c6 15203 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 15204 res = FALSE;
74e1a04b
NC
15205 break;
15206 }
e9847026 15207
071436c6
NC
15208 section_len -= attr_len;
15209 attr_len -= 4;
15210
15211 namelen = strnlen ((char *) p, attr_len) + 1;
15212 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
15213 {
15214 error (_("Corrupt attribute section name\n"));
32ec8896 15215 res = FALSE;
e9847026
NC
15216 break;
15217 }
15218
071436c6
NC
15219 printf (_("Attribute Section: "));
15220 print_symbol (INT_MAX, (const char *) p);
15221 putchar ('\n');
60bca95a
NC
15222
15223 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
15224 public_section = TRUE;
15225 else
15226 public_section = FALSE;
60bca95a
NC
15227
15228 if (streq ((char *) p, "gnu"))
104d59d1
JM
15229 gnu_section = TRUE;
15230 else
15231 gnu_section = FALSE;
60bca95a 15232
11c1ff18 15233 p += namelen;
071436c6 15234 attr_len -= namelen;
e0a31db1 15235
071436c6 15236 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 15237 {
e0a31db1 15238 int tag;
11c1ff18
PB
15239 int val;
15240 bfd_vma size;
071436c6 15241 unsigned char * end;
60bca95a 15242
e0a31db1 15243 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 15244 if (attr_len < 6)
e0a31db1
NC
15245 {
15246 error (_("Unused bytes at end of section\n"));
32ec8896 15247 res = FALSE;
e0a31db1
NC
15248 section_len = 0;
15249 break;
15250 }
15251
15252 tag = *(p++);
11c1ff18 15253 size = byte_get (p, 4);
071436c6 15254 if (size > attr_len)
11c1ff18 15255 {
e9847026 15256 error (_("Bad subsection length (%u > %u)\n"),
071436c6 15257 (unsigned) size, (unsigned) attr_len);
32ec8896 15258 res = FALSE;
071436c6 15259 size = attr_len;
11c1ff18 15260 }
e0a31db1
NC
15261 /* PR binutils/17531: Safe handling of corrupt files. */
15262 if (size < 6)
15263 {
15264 error (_("Bad subsection length (%u < 6)\n"),
15265 (unsigned) size);
32ec8896 15266 res = FALSE;
e0a31db1
NC
15267 section_len = 0;
15268 break;
15269 }
60bca95a 15270
071436c6 15271 attr_len -= size;
11c1ff18 15272 end = p + size - 1;
071436c6 15273 assert (end <= contents + sect->sh_size);
11c1ff18 15274 p += 4;
60bca95a 15275
11c1ff18
PB
15276 switch (tag)
15277 {
15278 case 1:
2b692964 15279 printf (_("File Attributes\n"));
11c1ff18
PB
15280 break;
15281 case 2:
2b692964 15282 printf (_("Section Attributes:"));
11c1ff18
PB
15283 goto do_numlist;
15284 case 3:
2b692964 15285 printf (_("Symbol Attributes:"));
1a0670f3 15286 /* Fall through. */
11c1ff18
PB
15287 do_numlist:
15288 for (;;)
15289 {
91d6fa6a 15290 unsigned int j;
60bca95a 15291
f6f0e17b 15292 val = read_uleb128 (p, &j, end);
91d6fa6a 15293 p += j;
11c1ff18
PB
15294 if (val == 0)
15295 break;
15296 printf (" %d", val);
15297 }
15298 printf ("\n");
15299 break;
15300 default:
2b692964 15301 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
15302 public_section = FALSE;
15303 break;
15304 }
60bca95a 15305
071436c6 15306 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
15307 {
15308 while (p < end)
f6f0e17b 15309 p = display_pub_attribute (p, end);
60abdbed 15310 assert (p == end);
104d59d1 15311 }
071436c6 15312 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
15313 {
15314 while (p < end)
15315 p = display_gnu_attribute (p,
f6f0e17b
NC
15316 display_proc_gnu_attribute,
15317 end);
60abdbed 15318 assert (p == end);
11c1ff18 15319 }
071436c6 15320 else if (p < end)
11c1ff18 15321 {
071436c6 15322 printf (_(" Unknown attribute:\n"));
f6f0e17b 15323 display_raw_attribute (p, end);
11c1ff18
PB
15324 p = end;
15325 }
071436c6
NC
15326 else
15327 attr_len = 0;
11c1ff18
PB
15328 }
15329 }
15330 }
d70c5fc7 15331
60bca95a 15332 free (contents);
11c1ff18 15333 }
32ec8896
NC
15334
15335 return res;
11c1ff18
PB
15336}
15337
ccb4c951
RS
15338/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
15339 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
15340 and return the VMA of the next entry, or -1 if there was a problem.
15341 Does not read from DATA_END or beyond. */
ccb4c951
RS
15342
15343static bfd_vma
82b1b41b
NC
15344print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
15345 unsigned char * data_end)
ccb4c951
RS
15346{
15347 printf (" ");
15348 print_vma (addr, LONG_HEX);
15349 printf (" ");
15350 if (addr < pltgot + 0xfff0)
15351 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
15352 else
15353 printf ("%10s", "");
15354 printf (" ");
15355 if (data == NULL)
2b692964 15356 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
15357 else
15358 {
15359 bfd_vma entry;
82b1b41b 15360 unsigned char * from = data + addr - pltgot;
ccb4c951 15361
82b1b41b
NC
15362 if (from + (is_32bit_elf ? 4 : 8) > data_end)
15363 {
15364 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
15365 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
15366 return (bfd_vma) -1;
15367 }
15368 else
15369 {
15370 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15371 print_vma (entry, LONG_HEX);
15372 }
ccb4c951
RS
15373 }
15374 return addr + (is_32bit_elf ? 4 : 8);
15375}
15376
861fb55a
DJ
15377/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
15378 PLTGOT. Print the Address and Initial fields of an entry at VMA
15379 ADDR and return the VMA of the next entry. */
15380
15381static bfd_vma
2cf0635d 15382print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
15383{
15384 printf (" ");
15385 print_vma (addr, LONG_HEX);
15386 printf (" ");
15387 if (data == NULL)
2b692964 15388 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
15389 else
15390 {
15391 bfd_vma entry;
15392
15393 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15394 print_vma (entry, LONG_HEX);
15395 }
15396 return addr + (is_32bit_elf ? 4 : 8);
15397}
15398
351cdf24
MF
15399static void
15400print_mips_ases (unsigned int mask)
15401{
15402 if (mask & AFL_ASE_DSP)
15403 fputs ("\n\tDSP ASE", stdout);
15404 if (mask & AFL_ASE_DSPR2)
15405 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
15406 if (mask & AFL_ASE_DSPR3)
15407 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
15408 if (mask & AFL_ASE_EVA)
15409 fputs ("\n\tEnhanced VA Scheme", stdout);
15410 if (mask & AFL_ASE_MCU)
15411 fputs ("\n\tMCU (MicroController) ASE", stdout);
15412 if (mask & AFL_ASE_MDMX)
15413 fputs ("\n\tMDMX ASE", stdout);
15414 if (mask & AFL_ASE_MIPS3D)
15415 fputs ("\n\tMIPS-3D ASE", stdout);
15416 if (mask & AFL_ASE_MT)
15417 fputs ("\n\tMT ASE", stdout);
15418 if (mask & AFL_ASE_SMARTMIPS)
15419 fputs ("\n\tSmartMIPS ASE", stdout);
15420 if (mask & AFL_ASE_VIRT)
15421 fputs ("\n\tVZ ASE", stdout);
15422 if (mask & AFL_ASE_MSA)
15423 fputs ("\n\tMSA ASE", stdout);
15424 if (mask & AFL_ASE_MIPS16)
15425 fputs ("\n\tMIPS16 ASE", stdout);
15426 if (mask & AFL_ASE_MICROMIPS)
15427 fputs ("\n\tMICROMIPS ASE", stdout);
15428 if (mask & AFL_ASE_XPA)
15429 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
15430 if (mask & AFL_ASE_MIPS16E2)
15431 fputs ("\n\tMIPS16e2 ASE", stdout);
351cdf24
MF
15432 if (mask == 0)
15433 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
15434 else if ((mask & ~AFL_ASE_MASK) != 0)
15435 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
15436}
15437
15438static void
15439print_mips_isa_ext (unsigned int isa_ext)
15440{
15441 switch (isa_ext)
15442 {
15443 case 0:
15444 fputs (_("None"), stdout);
15445 break;
15446 case AFL_EXT_XLR:
15447 fputs ("RMI XLR", stdout);
15448 break;
2c629856
N
15449 case AFL_EXT_OCTEON3:
15450 fputs ("Cavium Networks Octeon3", stdout);
15451 break;
351cdf24
MF
15452 case AFL_EXT_OCTEON2:
15453 fputs ("Cavium Networks Octeon2", stdout);
15454 break;
15455 case AFL_EXT_OCTEONP:
15456 fputs ("Cavium Networks OcteonP", stdout);
15457 break;
15458 case AFL_EXT_LOONGSON_3A:
15459 fputs ("Loongson 3A", stdout);
15460 break;
15461 case AFL_EXT_OCTEON:
15462 fputs ("Cavium Networks Octeon", stdout);
15463 break;
15464 case AFL_EXT_5900:
15465 fputs ("Toshiba R5900", stdout);
15466 break;
15467 case AFL_EXT_4650:
15468 fputs ("MIPS R4650", stdout);
15469 break;
15470 case AFL_EXT_4010:
15471 fputs ("LSI R4010", stdout);
15472 break;
15473 case AFL_EXT_4100:
15474 fputs ("NEC VR4100", stdout);
15475 break;
15476 case AFL_EXT_3900:
15477 fputs ("Toshiba R3900", stdout);
15478 break;
15479 case AFL_EXT_10000:
15480 fputs ("MIPS R10000", stdout);
15481 break;
15482 case AFL_EXT_SB1:
15483 fputs ("Broadcom SB-1", stdout);
15484 break;
15485 case AFL_EXT_4111:
15486 fputs ("NEC VR4111/VR4181", stdout);
15487 break;
15488 case AFL_EXT_4120:
15489 fputs ("NEC VR4120", stdout);
15490 break;
15491 case AFL_EXT_5400:
15492 fputs ("NEC VR5400", stdout);
15493 break;
15494 case AFL_EXT_5500:
15495 fputs ("NEC VR5500", stdout);
15496 break;
15497 case AFL_EXT_LOONGSON_2E:
15498 fputs ("ST Microelectronics Loongson 2E", stdout);
15499 break;
15500 case AFL_EXT_LOONGSON_2F:
15501 fputs ("ST Microelectronics Loongson 2F", stdout);
15502 break;
38bf472a
MR
15503 case AFL_EXT_INTERAPTIV_MR2:
15504 fputs ("Imagination interAptiv MR2", stdout);
15505 break;
351cdf24 15506 default:
00ac7aa0 15507 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
15508 }
15509}
15510
32ec8896 15511static signed int
351cdf24
MF
15512get_mips_reg_size (int reg_size)
15513{
15514 return (reg_size == AFL_REG_NONE) ? 0
15515 : (reg_size == AFL_REG_32) ? 32
15516 : (reg_size == AFL_REG_64) ? 64
15517 : (reg_size == AFL_REG_128) ? 128
15518 : -1;
15519}
15520
32ec8896 15521static bfd_boolean
dda8d76d 15522process_mips_specific (Filedata * filedata)
5b18a4bc 15523{
2cf0635d 15524 Elf_Internal_Dyn * entry;
351cdf24 15525 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
15526 size_t liblist_offset = 0;
15527 size_t liblistno = 0;
15528 size_t conflictsno = 0;
15529 size_t options_offset = 0;
15530 size_t conflicts_offset = 0;
861fb55a
DJ
15531 size_t pltrelsz = 0;
15532 size_t pltrel = 0;
ccb4c951 15533 bfd_vma pltgot = 0;
861fb55a
DJ
15534 bfd_vma mips_pltgot = 0;
15535 bfd_vma jmprel = 0;
ccb4c951
RS
15536 bfd_vma local_gotno = 0;
15537 bfd_vma gotsym = 0;
15538 bfd_vma symtabno = 0;
32ec8896 15539 bfd_boolean res = TRUE;
103f02d3 15540
dda8d76d 15541 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
15542 display_mips_gnu_attribute))
15543 res = FALSE;
2cf19d5c 15544
dda8d76d 15545 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
15546
15547 if (sect != NULL)
15548 {
15549 Elf_External_ABIFlags_v0 *abiflags_ext;
15550 Elf_Internal_ABIFlags_v0 abiflags_in;
15551
15552 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
15553 {
15554 error (_("Corrupt MIPS ABI Flags section.\n"));
15555 res = FALSE;
15556 }
351cdf24
MF
15557 else
15558 {
dda8d76d 15559 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
15560 sect->sh_size, _("MIPS ABI Flags section"));
15561 if (abiflags_ext)
15562 {
15563 abiflags_in.version = BYTE_GET (abiflags_ext->version);
15564 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
15565 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
15566 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
15567 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
15568 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
15569 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
15570 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
15571 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
15572 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
15573 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
15574
15575 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
15576 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
15577 if (abiflags_in.isa_rev > 1)
15578 printf ("r%d", abiflags_in.isa_rev);
15579 printf ("\nGPR size: %d",
15580 get_mips_reg_size (abiflags_in.gpr_size));
15581 printf ("\nCPR1 size: %d",
15582 get_mips_reg_size (abiflags_in.cpr1_size));
15583 printf ("\nCPR2 size: %d",
15584 get_mips_reg_size (abiflags_in.cpr2_size));
15585 fputs ("\nFP ABI: ", stdout);
15586 print_mips_fp_abi_value (abiflags_in.fp_abi);
15587 fputs ("ISA Extension: ", stdout);
15588 print_mips_isa_ext (abiflags_in.isa_ext);
15589 fputs ("\nASEs:", stdout);
15590 print_mips_ases (abiflags_in.ases);
15591 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
15592 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
15593 fputc ('\n', stdout);
15594 free (abiflags_ext);
15595 }
15596 }
15597 }
15598
19e6b90e
L
15599 /* We have a lot of special sections. Thanks SGI! */
15600 if (dynamic_section == NULL)
bbdd9a68
MR
15601 {
15602 /* No dynamic information available. See if there is static GOT. */
dda8d76d 15603 sect = find_section (filedata, ".got");
bbdd9a68
MR
15604 if (sect != NULL)
15605 {
15606 unsigned char *data_end;
15607 unsigned char *data;
15608 bfd_vma ent, end;
15609 int addr_size;
15610
15611 pltgot = sect->sh_addr;
15612
15613 ent = pltgot;
15614 addr_size = (is_32bit_elf ? 4 : 8);
15615 end = pltgot + sect->sh_size;
15616
dda8d76d 15617 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
15618 end - pltgot, 1,
15619 _("Global Offset Table data"));
15620 /* PR 12855: Null data is handled gracefully throughout. */
15621 data_end = data + (end - pltgot);
15622
15623 printf (_("\nStatic GOT:\n"));
15624 printf (_(" Canonical gp value: "));
15625 print_vma (ent + 0x7ff0, LONG_HEX);
15626 printf ("\n\n");
15627
15628 /* In a dynamic binary GOT[0] is reserved for the dynamic
15629 loader to store the lazy resolver pointer, however in
15630 a static binary it may well have been omitted and GOT
15631 reduced to a table of addresses.
15632 PR 21344: Check for the entry being fully available
15633 before fetching it. */
15634 if (data
15635 && data + ent - pltgot + addr_size <= data_end
15636 && byte_get (data + ent - pltgot, addr_size) == 0)
15637 {
15638 printf (_(" Reserved entries:\n"));
15639 printf (_(" %*s %10s %*s\n"),
15640 addr_size * 2, _("Address"), _("Access"),
15641 addr_size * 2, _("Value"));
15642 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15643 printf ("\n");
15644 if (ent == (bfd_vma) -1)
15645 goto sgot_print_fail;
15646
15647 /* Check for the MSB of GOT[1] being set, identifying a
15648 GNU object. This entry will be used by some runtime
15649 loaders, to store the module pointer. Otherwise this
15650 is an ordinary local entry.
15651 PR 21344: Check for the entry being fully available
15652 before fetching it. */
15653 if (data
15654 && data + ent - pltgot + addr_size <= data_end
15655 && (byte_get (data + ent - pltgot, addr_size)
15656 >> (addr_size * 8 - 1)) != 0)
15657 {
15658 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15659 printf ("\n");
15660 if (ent == (bfd_vma) -1)
15661 goto sgot_print_fail;
15662 }
15663 printf ("\n");
15664 }
15665
f17e9d8a 15666 if (data != NULL && ent < end)
bbdd9a68
MR
15667 {
15668 printf (_(" Local entries:\n"));
15669 printf (" %*s %10s %*s\n",
15670 addr_size * 2, _("Address"), _("Access"),
15671 addr_size * 2, _("Value"));
15672 while (ent < end)
15673 {
15674 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15675 printf ("\n");
15676 if (ent == (bfd_vma) -1)
15677 goto sgot_print_fail;
15678 }
15679 printf ("\n");
15680 }
15681
15682 sgot_print_fail:
15683 if (data)
15684 free (data);
15685 }
15686 return res;
15687 }
252b5132 15688
071436c6
NC
15689 for (entry = dynamic_section;
15690 /* PR 17531 file: 012-50589-0.004. */
15691 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
15692 ++entry)
252b5132
RH
15693 switch (entry->d_tag)
15694 {
15695 case DT_MIPS_LIBLIST:
d93f0186 15696 liblist_offset
dda8d76d 15697 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 15698 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
15699 break;
15700 case DT_MIPS_LIBLISTNO:
15701 liblistno = entry->d_un.d_val;
15702 break;
15703 case DT_MIPS_OPTIONS:
dda8d76d 15704 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
15705 break;
15706 case DT_MIPS_CONFLICT:
d93f0186 15707 conflicts_offset
dda8d76d 15708 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 15709 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
15710 break;
15711 case DT_MIPS_CONFLICTNO:
15712 conflictsno = entry->d_un.d_val;
15713 break;
ccb4c951 15714 case DT_PLTGOT:
861fb55a
DJ
15715 pltgot = entry->d_un.d_ptr;
15716 break;
ccb4c951
RS
15717 case DT_MIPS_LOCAL_GOTNO:
15718 local_gotno = entry->d_un.d_val;
15719 break;
15720 case DT_MIPS_GOTSYM:
15721 gotsym = entry->d_un.d_val;
15722 break;
15723 case DT_MIPS_SYMTABNO:
15724 symtabno = entry->d_un.d_val;
15725 break;
861fb55a
DJ
15726 case DT_MIPS_PLTGOT:
15727 mips_pltgot = entry->d_un.d_ptr;
15728 break;
15729 case DT_PLTREL:
15730 pltrel = entry->d_un.d_val;
15731 break;
15732 case DT_PLTRELSZ:
15733 pltrelsz = entry->d_un.d_val;
15734 break;
15735 case DT_JMPREL:
15736 jmprel = entry->d_un.d_ptr;
15737 break;
252b5132
RH
15738 default:
15739 break;
15740 }
15741
15742 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
15743 {
2cf0635d 15744 Elf32_External_Lib * elib;
252b5132
RH
15745 size_t cnt;
15746
dda8d76d 15747 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
3f5e193b
NC
15748 liblistno,
15749 sizeof (Elf32_External_Lib),
9cf03b7e 15750 _("liblist section data"));
a6e9f9df 15751 if (elib)
252b5132 15752 {
d3a49aa8
AM
15753 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
15754 "\nSection '.liblist' contains %lu entries:\n",
15755 (unsigned long) liblistno),
a6e9f9df 15756 (unsigned long) liblistno);
2b692964 15757 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
15758 stdout);
15759
15760 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 15761 {
a6e9f9df 15762 Elf32_Lib liblist;
91d6fa6a 15763 time_t atime;
d5b07ef4 15764 char timebuf[128];
2cf0635d 15765 struct tm * tmp;
a6e9f9df
AM
15766
15767 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 15768 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
15769 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
15770 liblist.l_version = BYTE_GET (elib[cnt].l_version);
15771 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
15772
91d6fa6a 15773 tmp = gmtime (&atime);
e9e44622
JJ
15774 snprintf (timebuf, sizeof (timebuf),
15775 "%04u-%02u-%02uT%02u:%02u:%02u",
15776 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
15777 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 15778
31104126 15779 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
15780 if (VALID_DYNAMIC_NAME (liblist.l_name))
15781 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
15782 else
2b692964 15783 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
15784 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
15785 liblist.l_version);
a6e9f9df
AM
15786
15787 if (liblist.l_flags == 0)
2b692964 15788 puts (_(" NONE"));
a6e9f9df
AM
15789 else
15790 {
15791 static const struct
252b5132 15792 {
2cf0635d 15793 const char * name;
a6e9f9df 15794 int bit;
252b5132 15795 }
a6e9f9df
AM
15796 l_flags_vals[] =
15797 {
15798 { " EXACT_MATCH", LL_EXACT_MATCH },
15799 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
15800 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
15801 { " EXPORTS", LL_EXPORTS },
15802 { " DELAY_LOAD", LL_DELAY_LOAD },
15803 { " DELTA", LL_DELTA }
15804 };
15805 int flags = liblist.l_flags;
15806 size_t fcnt;
15807
60bca95a 15808 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
15809 if ((flags & l_flags_vals[fcnt].bit) != 0)
15810 {
15811 fputs (l_flags_vals[fcnt].name, stdout);
15812 flags ^= l_flags_vals[fcnt].bit;
15813 }
15814 if (flags != 0)
15815 printf (" %#x", (unsigned int) flags);
252b5132 15816
a6e9f9df
AM
15817 puts ("");
15818 }
252b5132 15819 }
252b5132 15820
a6e9f9df
AM
15821 free (elib);
15822 }
32ec8896
NC
15823 else
15824 res = FALSE;
252b5132
RH
15825 }
15826
15827 if (options_offset != 0)
15828 {
2cf0635d 15829 Elf_External_Options * eopt;
2cf0635d
NC
15830 Elf_Internal_Options * iopt;
15831 Elf_Internal_Options * option;
252b5132
RH
15832 size_t offset;
15833 int cnt;
dda8d76d 15834 sect = filedata->section_headers;
252b5132
RH
15835
15836 /* Find the section header so that we get the size. */
dda8d76d 15837 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 15838 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
15839 if (sect == NULL)
15840 {
15841 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 15842 return FALSE;
071436c6 15843 }
252b5132 15844
dda8d76d 15845 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 15846 sect->sh_size, _("options"));
a6e9f9df 15847 if (eopt)
252b5132 15848 {
3f5e193b
NC
15849 iopt = (Elf_Internal_Options *)
15850 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
15851 if (iopt == NULL)
15852 {
fb324ee9 15853 error (_("Out of memory allocating space for MIPS options\n"));
32ec8896 15854 return FALSE;
a6e9f9df 15855 }
76da6bbe 15856
a6e9f9df
AM
15857 offset = cnt = 0;
15858 option = iopt;
252b5132 15859
82b1b41b 15860 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 15861 {
2cf0635d 15862 Elf_External_Options * eoption;
252b5132 15863
a6e9f9df 15864 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 15865
a6e9f9df
AM
15866 option->kind = BYTE_GET (eoption->kind);
15867 option->size = BYTE_GET (eoption->size);
15868 option->section = BYTE_GET (eoption->section);
15869 option->info = BYTE_GET (eoption->info);
76da6bbe 15870
82b1b41b
NC
15871 /* PR 17531: file: ffa0fa3b. */
15872 if (option->size < sizeof (* eopt)
15873 || offset + option->size > sect->sh_size)
15874 {
55325047 15875 error (_("Invalid size (%u) for MIPS option\n"), option->size);
32ec8896 15876 return FALSE;
82b1b41b 15877 }
a6e9f9df 15878 offset += option->size;
14ae95f2 15879
a6e9f9df
AM
15880 ++option;
15881 ++cnt;
15882 }
252b5132 15883
d3a49aa8
AM
15884 printf (ngettext ("\nSection '%s' contains %d entry:\n",
15885 "\nSection '%s' contains %d entries:\n",
15886 cnt),
dda8d76d 15887 printable_section_name (filedata, sect), cnt);
76da6bbe 15888
a6e9f9df 15889 option = iopt;
82b1b41b 15890 offset = 0;
252b5132 15891
a6e9f9df 15892 while (cnt-- > 0)
252b5132 15893 {
a6e9f9df
AM
15894 size_t len;
15895
15896 switch (option->kind)
252b5132 15897 {
a6e9f9df
AM
15898 case ODK_NULL:
15899 /* This shouldn't happen. */
15900 printf (" NULL %d %lx", option->section, option->info);
15901 break;
15902 case ODK_REGINFO:
15903 printf (" REGINFO ");
dda8d76d 15904 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df
AM
15905 {
15906 /* 32bit form. */
2cf0635d 15907 Elf32_External_RegInfo * ereg;
b34976b6 15908 Elf32_RegInfo reginfo;
a6e9f9df
AM
15909
15910 ereg = (Elf32_External_RegInfo *) (option + 1);
15911 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
15912 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
15913 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
15914 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
15915 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
15916 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
15917
15918 printf ("GPR %08lx GP 0x%lx\n",
15919 reginfo.ri_gprmask,
15920 (unsigned long) reginfo.ri_gp_value);
15921 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
15922 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
15923 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
15924 }
15925 else
15926 {
15927 /* 64 bit form. */
2cf0635d 15928 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
15929 Elf64_Internal_RegInfo reginfo;
15930
15931 ereg = (Elf64_External_RegInfo *) (option + 1);
15932 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
15933 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
15934 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
15935 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
15936 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 15937 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
15938
15939 printf ("GPR %08lx GP 0x",
15940 reginfo.ri_gprmask);
15941 printf_vma (reginfo.ri_gp_value);
15942 printf ("\n");
15943
15944 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
15945 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
15946 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
15947 }
15948 ++option;
15949 continue;
15950 case ODK_EXCEPTIONS:
15951 fputs (" EXCEPTIONS fpe_min(", stdout);
15952 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
15953 fputs (") fpe_max(", stdout);
15954 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
15955 fputs (")", stdout);
15956
15957 if (option->info & OEX_PAGE0)
15958 fputs (" PAGE0", stdout);
15959 if (option->info & OEX_SMM)
15960 fputs (" SMM", stdout);
15961 if (option->info & OEX_FPDBUG)
15962 fputs (" FPDBUG", stdout);
15963 if (option->info & OEX_DISMISS)
15964 fputs (" DISMISS", stdout);
15965 break;
15966 case ODK_PAD:
15967 fputs (" PAD ", stdout);
15968 if (option->info & OPAD_PREFIX)
15969 fputs (" PREFIX", stdout);
15970 if (option->info & OPAD_POSTFIX)
15971 fputs (" POSTFIX", stdout);
15972 if (option->info & OPAD_SYMBOL)
15973 fputs (" SYMBOL", stdout);
15974 break;
15975 case ODK_HWPATCH:
15976 fputs (" HWPATCH ", stdout);
15977 if (option->info & OHW_R4KEOP)
15978 fputs (" R4KEOP", stdout);
15979 if (option->info & OHW_R8KPFETCH)
15980 fputs (" R8KPFETCH", stdout);
15981 if (option->info & OHW_R5KEOP)
15982 fputs (" R5KEOP", stdout);
15983 if (option->info & OHW_R5KCVTL)
15984 fputs (" R5KCVTL", stdout);
15985 break;
15986 case ODK_FILL:
15987 fputs (" FILL ", stdout);
15988 /* XXX Print content of info word? */
15989 break;
15990 case ODK_TAGS:
15991 fputs (" TAGS ", stdout);
15992 /* XXX Print content of info word? */
15993 break;
15994 case ODK_HWAND:
15995 fputs (" HWAND ", stdout);
15996 if (option->info & OHWA0_R4KEOP_CHECKED)
15997 fputs (" R4KEOP_CHECKED", stdout);
15998 if (option->info & OHWA0_R4KEOP_CLEAN)
15999 fputs (" R4KEOP_CLEAN", stdout);
16000 break;
16001 case ODK_HWOR:
16002 fputs (" HWOR ", stdout);
16003 if (option->info & OHWA0_R4KEOP_CHECKED)
16004 fputs (" R4KEOP_CHECKED", stdout);
16005 if (option->info & OHWA0_R4KEOP_CLEAN)
16006 fputs (" R4KEOP_CLEAN", stdout);
16007 break;
16008 case ODK_GP_GROUP:
16009 printf (" GP_GROUP %#06lx self-contained %#06lx",
16010 option->info & OGP_GROUP,
16011 (option->info & OGP_SELF) >> 16);
16012 break;
16013 case ODK_IDENT:
16014 printf (" IDENT %#06lx self-contained %#06lx",
16015 option->info & OGP_GROUP,
16016 (option->info & OGP_SELF) >> 16);
16017 break;
16018 default:
16019 /* This shouldn't happen. */
16020 printf (" %3d ??? %d %lx",
16021 option->kind, option->section, option->info);
16022 break;
252b5132 16023 }
a6e9f9df 16024
2cf0635d 16025 len = sizeof (* eopt);
a6e9f9df 16026 while (len < option->size)
82b1b41b 16027 {
7e27a9d5 16028 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 16029
82b1b41b
NC
16030 if (ISPRINT (datum))
16031 printf ("%c", datum);
16032 else
16033 printf ("\\%03o", datum);
16034 len ++;
16035 }
a6e9f9df 16036 fputs ("\n", stdout);
82b1b41b
NC
16037
16038 offset += option->size;
252b5132 16039 ++option;
252b5132
RH
16040 }
16041
a6e9f9df 16042 free (eopt);
252b5132 16043 }
32ec8896
NC
16044 else
16045 res = FALSE;
252b5132
RH
16046 }
16047
16048 if (conflicts_offset != 0 && conflictsno != 0)
16049 {
2cf0635d 16050 Elf32_Conflict * iconf;
252b5132
RH
16051 size_t cnt;
16052
16053 if (dynamic_symbols == NULL)
16054 {
591a748a 16055 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 16056 return FALSE;
252b5132
RH
16057 }
16058
7296a62a
NC
16059 /* PR 21345 - print a slightly more helpful error message
16060 if we are sure that the cmalloc will fail. */
dda8d76d 16061 if (conflictsno * sizeof (* iconf) > filedata->file_size)
7296a62a
NC
16062 {
16063 error (_("Overlarge number of conflicts detected: %lx\n"),
16064 (long) conflictsno);
16065 return FALSE;
16066 }
16067
3f5e193b 16068 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
16069 if (iconf == NULL)
16070 {
8b73c356 16071 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 16072 return FALSE;
252b5132
RH
16073 }
16074
9ea033b2 16075 if (is_32bit_elf)
252b5132 16076 {
2cf0635d 16077 Elf32_External_Conflict * econf32;
a6e9f9df 16078
3f5e193b 16079 econf32 = (Elf32_External_Conflict *)
dda8d76d 16080 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16081 sizeof (* econf32), _("conflict"));
a6e9f9df 16082 if (!econf32)
32ec8896 16083 return FALSE;
252b5132
RH
16084
16085 for (cnt = 0; cnt < conflictsno; ++cnt)
16086 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
16087
16088 free (econf32);
252b5132
RH
16089 }
16090 else
16091 {
2cf0635d 16092 Elf64_External_Conflict * econf64;
a6e9f9df 16093
3f5e193b 16094 econf64 = (Elf64_External_Conflict *)
dda8d76d 16095 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16096 sizeof (* econf64), _("conflict"));
a6e9f9df 16097 if (!econf64)
32ec8896 16098 return FALSE;
252b5132
RH
16099
16100 for (cnt = 0; cnt < conflictsno; ++cnt)
16101 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
16102
16103 free (econf64);
252b5132
RH
16104 }
16105
d3a49aa8
AM
16106 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
16107 "\nSection '.conflict' contains %lu entries:\n",
16108 (unsigned long) conflictsno),
c7e7ca54 16109 (unsigned long) conflictsno);
252b5132
RH
16110 puts (_(" Num: Index Value Name"));
16111
16112 for (cnt = 0; cnt < conflictsno; ++cnt)
16113 {
b34976b6 16114 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
16115
16116 if (iconf[cnt] >= num_dynamic_syms)
16117 printf (_("<corrupt symbol index>"));
d79b3d50 16118 else
e0a31db1
NC
16119 {
16120 Elf_Internal_Sym * psym;
16121
16122 psym = & dynamic_symbols[iconf[cnt]];
16123 print_vma (psym->st_value, FULL_HEX);
16124 putchar (' ');
16125 if (VALID_DYNAMIC_NAME (psym->st_name))
16126 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
16127 else
16128 printf (_("<corrupt: %14ld>"), psym->st_name);
16129 }
31104126 16130 putchar ('\n');
252b5132
RH
16131 }
16132
252b5132
RH
16133 free (iconf);
16134 }
16135
ccb4c951
RS
16136 if (pltgot != 0 && local_gotno != 0)
16137 {
91d6fa6a 16138 bfd_vma ent, local_end, global_end;
bbeee7ea 16139 size_t i, offset;
2cf0635d 16140 unsigned char * data;
82b1b41b 16141 unsigned char * data_end;
bbeee7ea 16142 int addr_size;
ccb4c951 16143
91d6fa6a 16144 ent = pltgot;
ccb4c951
RS
16145 addr_size = (is_32bit_elf ? 4 : 8);
16146 local_end = pltgot + local_gotno * addr_size;
ccb4c951 16147
74e1a04b
NC
16148 /* PR binutils/17533 file: 012-111227-0.004 */
16149 if (symtabno < gotsym)
16150 {
16151 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 16152 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 16153 return FALSE;
74e1a04b 16154 }
82b1b41b 16155
74e1a04b 16156 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
16157 /* PR 17531: file: 54c91a34. */
16158 if (global_end < local_end)
16159 {
16160 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 16161 return FALSE;
82b1b41b 16162 }
948f632f 16163
dda8d76d
NC
16164 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
16165 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
16166 global_end - pltgot, 1,
16167 _("Global Offset Table data"));
919383ac 16168 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 16169 data_end = data + (global_end - pltgot);
59245841 16170
ccb4c951
RS
16171 printf (_("\nPrimary GOT:\n"));
16172 printf (_(" Canonical gp value: "));
16173 print_vma (pltgot + 0x7ff0, LONG_HEX);
16174 printf ("\n\n");
16175
16176 printf (_(" Reserved entries:\n"));
16177 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
16178 addr_size * 2, _("Address"), _("Access"),
16179 addr_size * 2, _("Initial"));
82b1b41b 16180 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 16181 printf (_(" Lazy resolver\n"));
82b1b41b
NC
16182 if (ent == (bfd_vma) -1)
16183 goto got_print_fail;
75ec1fdb 16184
c4ab9505
MR
16185 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
16186 This entry will be used by some runtime loaders, to store the
16187 module pointer. Otherwise this is an ordinary local entry.
16188 PR 21344: Check for the entry being fully available before
16189 fetching it. */
16190 if (data
16191 && data + ent - pltgot + addr_size <= data_end
16192 && (byte_get (data + ent - pltgot, addr_size)
16193 >> (addr_size * 8 - 1)) != 0)
16194 {
16195 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16196 printf (_(" Module pointer (GNU extension)\n"));
16197 if (ent == (bfd_vma) -1)
16198 goto got_print_fail;
ccb4c951
RS
16199 }
16200 printf ("\n");
16201
f17e9d8a 16202 if (data != NULL && ent < local_end)
ccb4c951
RS
16203 {
16204 printf (_(" Local entries:\n"));
cc5914eb 16205 printf (" %*s %10s %*s\n",
2b692964
NC
16206 addr_size * 2, _("Address"), _("Access"),
16207 addr_size * 2, _("Initial"));
91d6fa6a 16208 while (ent < local_end)
ccb4c951 16209 {
82b1b41b 16210 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16211 printf ("\n");
82b1b41b
NC
16212 if (ent == (bfd_vma) -1)
16213 goto got_print_fail;
ccb4c951
RS
16214 }
16215 printf ("\n");
16216 }
16217
f17e9d8a 16218 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
16219 {
16220 int sym_width;
16221
16222 printf (_(" Global entries:\n"));
cc5914eb 16223 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
16224 addr_size * 2, _("Address"),
16225 _("Access"),
2b692964 16226 addr_size * 2, _("Initial"),
9cf03b7e
NC
16227 addr_size * 2, _("Sym.Val."),
16228 _("Type"),
16229 /* Note for translators: "Ndx" = abbreviated form of "Index". */
16230 _("Ndx"), _("Name"));
0b4362b0 16231
ccb4c951 16232 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 16233
ccb4c951
RS
16234 for (i = gotsym; i < symtabno; i++)
16235 {
82b1b41b 16236 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16237 printf (" ");
e0a31db1
NC
16238
16239 if (dynamic_symbols == NULL)
16240 printf (_("<no dynamic symbols>"));
16241 else if (i < num_dynamic_syms)
16242 {
16243 Elf_Internal_Sym * psym = dynamic_symbols + i;
16244
16245 print_vma (psym->st_value, LONG_HEX);
16246 printf (" %-7s %3s ",
dda8d76d
NC
16247 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16248 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16249
16250 if (VALID_DYNAMIC_NAME (psym->st_name))
16251 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16252 else
16253 printf (_("<corrupt: %14ld>"), psym->st_name);
16254 }
ccb4c951 16255 else
7fc5ac57
JBG
16256 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
16257 (unsigned long) i);
e0a31db1 16258
ccb4c951 16259 printf ("\n");
82b1b41b
NC
16260 if (ent == (bfd_vma) -1)
16261 break;
ccb4c951
RS
16262 }
16263 printf ("\n");
16264 }
16265
82b1b41b 16266 got_print_fail:
ccb4c951
RS
16267 if (data)
16268 free (data);
16269 }
16270
861fb55a
DJ
16271 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
16272 {
91d6fa6a 16273 bfd_vma ent, end;
861fb55a
DJ
16274 size_t offset, rel_offset;
16275 unsigned long count, i;
2cf0635d 16276 unsigned char * data;
861fb55a 16277 int addr_size, sym_width;
2cf0635d 16278 Elf_Internal_Rela * rels;
861fb55a 16279
dda8d76d 16280 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
16281 if (pltrel == DT_RELA)
16282 {
dda8d76d 16283 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16284 return FALSE;
861fb55a
DJ
16285 }
16286 else
16287 {
dda8d76d 16288 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16289 return FALSE;
861fb55a
DJ
16290 }
16291
91d6fa6a 16292 ent = mips_pltgot;
861fb55a
DJ
16293 addr_size = (is_32bit_elf ? 4 : 8);
16294 end = mips_pltgot + (2 + count) * addr_size;
16295
dda8d76d
NC
16296 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
16297 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 16298 1, _("Procedure Linkage Table data"));
59245841 16299 if (data == NULL)
32ec8896 16300 return FALSE;
59245841 16301
9cf03b7e 16302 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
16303 printf (_(" Reserved entries:\n"));
16304 printf (_(" %*s %*s Purpose\n"),
2b692964 16305 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 16306 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16307 printf (_(" PLT lazy resolver\n"));
91d6fa6a 16308 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16309 printf (_(" Module pointer\n"));
861fb55a
DJ
16310 printf ("\n");
16311
16312 printf (_(" Entries:\n"));
cc5914eb 16313 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
16314 addr_size * 2, _("Address"),
16315 addr_size * 2, _("Initial"),
16316 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
16317 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
16318 for (i = 0; i < count; i++)
16319 {
df97ab2a 16320 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 16321
91d6fa6a 16322 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 16323 printf (" ");
e0a31db1 16324
df97ab2a
MF
16325 if (idx >= num_dynamic_syms)
16326 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 16327 else
e0a31db1 16328 {
df97ab2a 16329 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
16330
16331 print_vma (psym->st_value, LONG_HEX);
16332 printf (" %-7s %3s ",
dda8d76d
NC
16333 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16334 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16335 if (VALID_DYNAMIC_NAME (psym->st_name))
16336 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16337 else
16338 printf (_("<corrupt: %14ld>"), psym->st_name);
16339 }
861fb55a
DJ
16340 printf ("\n");
16341 }
16342 printf ("\n");
16343
16344 if (data)
16345 free (data);
16346 free (rels);
16347 }
16348
32ec8896 16349 return res;
252b5132
RH
16350}
16351
32ec8896 16352static bfd_boolean
dda8d76d 16353process_nds32_specific (Filedata * filedata)
35c08157
KLC
16354{
16355 Elf_Internal_Shdr *sect = NULL;
16356
dda8d76d 16357 sect = find_section (filedata, ".nds32_e_flags");
35c08157
KLC
16358 if (sect != NULL)
16359 {
16360 unsigned int *flag;
16361
16362 printf ("\nNDS32 elf flags section:\n");
dda8d76d 16363 flag = get_data (NULL, filedata, sect->sh_offset, 1,
35c08157
KLC
16364 sect->sh_size, _("NDS32 elf flags section"));
16365
32ec8896
NC
16366 if (! flag)
16367 return FALSE;
16368
35c08157
KLC
16369 switch ((*flag) & 0x3)
16370 {
16371 case 0:
16372 printf ("(VEC_SIZE):\tNo entry.\n");
16373 break;
16374 case 1:
16375 printf ("(VEC_SIZE):\t4 bytes\n");
16376 break;
16377 case 2:
16378 printf ("(VEC_SIZE):\t16 bytes\n");
16379 break;
16380 case 3:
16381 printf ("(VEC_SIZE):\treserved\n");
16382 break;
16383 }
16384 }
16385
16386 return TRUE;
16387}
16388
32ec8896 16389static bfd_boolean
dda8d76d 16390process_gnu_liblist (Filedata * filedata)
047b2264 16391{
2cf0635d
NC
16392 Elf_Internal_Shdr * section;
16393 Elf_Internal_Shdr * string_sec;
16394 Elf32_External_Lib * elib;
16395 char * strtab;
c256ffe7 16396 size_t strtab_size;
047b2264 16397 size_t cnt;
d3a49aa8 16398 unsigned long num_liblist;
047b2264 16399 unsigned i;
32ec8896 16400 bfd_boolean res = TRUE;
047b2264
JJ
16401
16402 if (! do_arch)
32ec8896 16403 return TRUE;
047b2264 16404
dda8d76d
NC
16405 for (i = 0, section = filedata->section_headers;
16406 i < filedata->file_header.e_shnum;
b34976b6 16407 i++, section++)
047b2264
JJ
16408 {
16409 switch (section->sh_type)
16410 {
16411 case SHT_GNU_LIBLIST:
dda8d76d 16412 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
16413 break;
16414
3f5e193b 16415 elib = (Elf32_External_Lib *)
dda8d76d 16416 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 16417 _("liblist section data"));
047b2264
JJ
16418
16419 if (elib == NULL)
32ec8896
NC
16420 {
16421 res = FALSE;
16422 break;
16423 }
047b2264 16424
dda8d76d
NC
16425 string_sec = filedata->section_headers + section->sh_link;
16426 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
16427 string_sec->sh_size,
16428 _("liblist string table"));
047b2264
JJ
16429 if (strtab == NULL
16430 || section->sh_entsize != sizeof (Elf32_External_Lib))
16431 {
16432 free (elib);
2842702f 16433 free (strtab);
32ec8896 16434 res = FALSE;
047b2264
JJ
16435 break;
16436 }
59245841 16437 strtab_size = string_sec->sh_size;
047b2264 16438
d3a49aa8
AM
16439 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
16440 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
16441 "\nLibrary list section '%s' contains %lu entries:\n",
16442 num_liblist),
dda8d76d 16443 printable_section_name (filedata, section),
d3a49aa8 16444 num_liblist);
047b2264 16445
2b692964 16446 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
16447
16448 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
16449 ++cnt)
16450 {
16451 Elf32_Lib liblist;
91d6fa6a 16452 time_t atime;
d5b07ef4 16453 char timebuf[128];
2cf0635d 16454 struct tm * tmp;
047b2264
JJ
16455
16456 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16457 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
16458 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16459 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16460 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16461
91d6fa6a 16462 tmp = gmtime (&atime);
e9e44622
JJ
16463 snprintf (timebuf, sizeof (timebuf),
16464 "%04u-%02u-%02uT%02u:%02u:%02u",
16465 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16466 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
16467
16468 printf ("%3lu: ", (unsigned long) cnt);
16469 if (do_wide)
c256ffe7 16470 printf ("%-20s", liblist.l_name < strtab_size
2b692964 16471 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 16472 else
c256ffe7 16473 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 16474 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
16475 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
16476 liblist.l_version, liblist.l_flags);
16477 }
16478
16479 free (elib);
2842702f 16480 free (strtab);
047b2264
JJ
16481 }
16482 }
16483
32ec8896 16484 return res;
047b2264
JJ
16485}
16486
9437c45b 16487static const char *
dda8d76d 16488get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
16489{
16490 static char buff[64];
103f02d3 16491
dda8d76d 16492 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
16493 switch (e_type)
16494 {
57346661 16495 case NT_AUXV:
1ec5cd37 16496 return _("NT_AUXV (auxiliary vector)");
57346661 16497 case NT_PRSTATUS:
1ec5cd37 16498 return _("NT_PRSTATUS (prstatus structure)");
57346661 16499 case NT_FPREGSET:
1ec5cd37 16500 return _("NT_FPREGSET (floating point registers)");
57346661 16501 case NT_PRPSINFO:
1ec5cd37 16502 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 16503 case NT_TASKSTRUCT:
1ec5cd37 16504 return _("NT_TASKSTRUCT (task structure)");
57346661 16505 case NT_PRXFPREG:
1ec5cd37 16506 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
16507 case NT_PPC_VMX:
16508 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
16509 case NT_PPC_VSX:
16510 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
16511 case NT_PPC_TAR:
16512 return _("NT_PPC_TAR (ppc TAR register)");
16513 case NT_PPC_PPR:
16514 return _("NT_PPC_PPR (ppc PPR register)");
16515 case NT_PPC_DSCR:
16516 return _("NT_PPC_DSCR (ppc DSCR register)");
16517 case NT_PPC_EBB:
16518 return _("NT_PPC_EBB (ppc EBB registers)");
16519 case NT_PPC_PMU:
16520 return _("NT_PPC_PMU (ppc PMU registers)");
16521 case NT_PPC_TM_CGPR:
16522 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
16523 case NT_PPC_TM_CFPR:
16524 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
16525 case NT_PPC_TM_CVMX:
16526 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
16527 case NT_PPC_TM_CVSX:
16528 return _("NT_PPC_TM_VSX (ppc checkpointed VSX registers)");
16529 case NT_PPC_TM_SPR:
16530 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
16531 case NT_PPC_TM_CTAR:
16532 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
16533 case NT_PPC_TM_CPPR:
16534 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
16535 case NT_PPC_TM_CDSCR:
16536 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
16537 case NT_386_TLS:
16538 return _("NT_386_TLS (x86 TLS information)");
16539 case NT_386_IOPERM:
16540 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
16541 case NT_X86_XSTATE:
16542 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
16543 case NT_S390_HIGH_GPRS:
16544 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
16545 case NT_S390_TIMER:
16546 return _("NT_S390_TIMER (s390 timer register)");
16547 case NT_S390_TODCMP:
16548 return _("NT_S390_TODCMP (s390 TOD comparator register)");
16549 case NT_S390_TODPREG:
16550 return _("NT_S390_TODPREG (s390 TOD programmable register)");
16551 case NT_S390_CTRS:
16552 return _("NT_S390_CTRS (s390 control registers)");
16553 case NT_S390_PREFIX:
16554 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
16555 case NT_S390_LAST_BREAK:
16556 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
16557 case NT_S390_SYSTEM_CALL:
16558 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
16559 case NT_S390_TDB:
16560 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
16561 case NT_S390_VXRS_LOW:
16562 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
16563 case NT_S390_VXRS_HIGH:
16564 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
16565 case NT_S390_GS_CB:
16566 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
16567 case NT_S390_GS_BC:
16568 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
16569 case NT_ARM_VFP:
16570 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
16571 case NT_ARM_TLS:
16572 return _("NT_ARM_TLS (AArch TLS registers)");
16573 case NT_ARM_HW_BREAK:
16574 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
16575 case NT_ARM_HW_WATCH:
16576 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 16577 case NT_PSTATUS:
1ec5cd37 16578 return _("NT_PSTATUS (pstatus structure)");
57346661 16579 case NT_FPREGS:
1ec5cd37 16580 return _("NT_FPREGS (floating point registers)");
57346661 16581 case NT_PSINFO:
1ec5cd37 16582 return _("NT_PSINFO (psinfo structure)");
57346661 16583 case NT_LWPSTATUS:
1ec5cd37 16584 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 16585 case NT_LWPSINFO:
1ec5cd37 16586 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 16587 case NT_WIN32PSTATUS:
1ec5cd37 16588 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
16589 case NT_SIGINFO:
16590 return _("NT_SIGINFO (siginfo_t data)");
16591 case NT_FILE:
16592 return _("NT_FILE (mapped files)");
1ec5cd37
NC
16593 default:
16594 break;
16595 }
16596 else
16597 switch (e_type)
16598 {
16599 case NT_VERSION:
16600 return _("NT_VERSION (version)");
16601 case NT_ARCH:
16602 return _("NT_ARCH (architecture)");
9ef920e9 16603 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 16604 return _("OPEN");
9ef920e9 16605 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 16606 return _("func");
1ec5cd37
NC
16607 default:
16608 break;
16609 }
16610
e9e44622 16611 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 16612 return buff;
779fe533
NC
16613}
16614
32ec8896 16615static bfd_boolean
9ece1fa9
TT
16616print_core_note (Elf_Internal_Note *pnote)
16617{
16618 unsigned int addr_size = is_32bit_elf ? 4 : 8;
16619 bfd_vma count, page_size;
16620 unsigned char *descdata, *filenames, *descend;
16621
16622 if (pnote->type != NT_FILE)
04ac15ab
AS
16623 {
16624 if (do_wide)
16625 printf ("\n");
16626 return TRUE;
16627 }
9ece1fa9
TT
16628
16629#ifndef BFD64
16630 if (!is_32bit_elf)
16631 {
16632 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
16633 /* Still "successful". */
32ec8896 16634 return TRUE;
9ece1fa9
TT
16635 }
16636#endif
16637
16638 if (pnote->descsz < 2 * addr_size)
16639 {
32ec8896
NC
16640 error (_(" Malformed note - too short for header\n"));
16641 return FALSE;
9ece1fa9
TT
16642 }
16643
16644 descdata = (unsigned char *) pnote->descdata;
16645 descend = descdata + pnote->descsz;
16646
16647 if (descdata[pnote->descsz - 1] != '\0')
16648 {
32ec8896
NC
16649 error (_(" Malformed note - does not end with \\0\n"));
16650 return FALSE;
9ece1fa9
TT
16651 }
16652
16653 count = byte_get (descdata, addr_size);
16654 descdata += addr_size;
16655
16656 page_size = byte_get (descdata, addr_size);
16657 descdata += addr_size;
16658
5396a86e
AM
16659 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
16660 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 16661 {
32ec8896
NC
16662 error (_(" Malformed note - too short for supplied file count\n"));
16663 return FALSE;
9ece1fa9
TT
16664 }
16665
16666 printf (_(" Page size: "));
16667 print_vma (page_size, DEC);
16668 printf ("\n");
16669
16670 printf (_(" %*s%*s%*s\n"),
16671 (int) (2 + 2 * addr_size), _("Start"),
16672 (int) (4 + 2 * addr_size), _("End"),
16673 (int) (4 + 2 * addr_size), _("Page Offset"));
16674 filenames = descdata + count * 3 * addr_size;
595712bb 16675 while (count-- > 0)
9ece1fa9
TT
16676 {
16677 bfd_vma start, end, file_ofs;
16678
16679 if (filenames == descend)
16680 {
32ec8896
NC
16681 error (_(" Malformed note - filenames end too early\n"));
16682 return FALSE;
9ece1fa9
TT
16683 }
16684
16685 start = byte_get (descdata, addr_size);
16686 descdata += addr_size;
16687 end = byte_get (descdata, addr_size);
16688 descdata += addr_size;
16689 file_ofs = byte_get (descdata, addr_size);
16690 descdata += addr_size;
16691
16692 printf (" ");
16693 print_vma (start, FULL_HEX);
16694 printf (" ");
16695 print_vma (end, FULL_HEX);
16696 printf (" ");
16697 print_vma (file_ofs, FULL_HEX);
16698 printf ("\n %s\n", filenames);
16699
16700 filenames += 1 + strlen ((char *) filenames);
16701 }
16702
32ec8896 16703 return TRUE;
9ece1fa9
TT
16704}
16705
1118d252
RM
16706static const char *
16707get_gnu_elf_note_type (unsigned e_type)
16708{
1449284b 16709 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
16710 switch (e_type)
16711 {
16712 case NT_GNU_ABI_TAG:
16713 return _("NT_GNU_ABI_TAG (ABI version tag)");
16714 case NT_GNU_HWCAP:
16715 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
16716 case NT_GNU_BUILD_ID:
16717 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
16718 case NT_GNU_GOLD_VERSION:
16719 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
16720 case NT_GNU_PROPERTY_TYPE_0:
16721 return _("NT_GNU_PROPERTY_TYPE_0");
16722 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
16723 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
16724 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
16725 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 16726 default:
1449284b
NC
16727 {
16728 static char buff[64];
1118d252 16729
1449284b
NC
16730 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
16731 return buff;
16732 }
16733 }
1118d252
RM
16734}
16735
9ef920e9 16736static void
1fc87489 16737decode_x86_isa (unsigned int bitmask)
9ef920e9
NC
16738{
16739 while (bitmask)
16740 {
1fc87489 16741 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
16742
16743 bitmask &= ~ bit;
16744 switch (bit)
16745 {
16746 case GNU_PROPERTY_X86_ISA_1_486: printf ("i486"); break;
16747 case GNU_PROPERTY_X86_ISA_1_586: printf ("586"); break;
16748 case GNU_PROPERTY_X86_ISA_1_686: printf ("686"); break;
16749 case GNU_PROPERTY_X86_ISA_1_SSE: printf ("SSE"); break;
16750 case GNU_PROPERTY_X86_ISA_1_SSE2: printf ("SSE2"); break;
16751 case GNU_PROPERTY_X86_ISA_1_SSE3: printf ("SSE3"); break;
16752 case GNU_PROPERTY_X86_ISA_1_SSSE3: printf ("SSSE3"); break;
16753 case GNU_PROPERTY_X86_ISA_1_SSE4_1: printf ("SSE4_1"); break;
16754 case GNU_PROPERTY_X86_ISA_1_SSE4_2: printf ("SSE4_2"); break;
16755 case GNU_PROPERTY_X86_ISA_1_AVX: printf ("AVX"); break;
16756 case GNU_PROPERTY_X86_ISA_1_AVX2: printf ("AVX2"); break;
16757 case GNU_PROPERTY_X86_ISA_1_AVX512F: printf ("AVX512F"); break;
16758 case GNU_PROPERTY_X86_ISA_1_AVX512CD: printf ("AVX512CD"); break;
16759 case GNU_PROPERTY_X86_ISA_1_AVX512ER: printf ("AVX512ER"); break;
16760 case GNU_PROPERTY_X86_ISA_1_AVX512PF: printf ("AVX512PF"); break;
16761 case GNU_PROPERTY_X86_ISA_1_AVX512VL: printf ("AVX512VL"); break;
16762 case GNU_PROPERTY_X86_ISA_1_AVX512DQ: printf ("AVX512DQ"); break;
16763 case GNU_PROPERTY_X86_ISA_1_AVX512BW: printf ("AVX512BW"); break;
1fc87489 16764 default: printf (_("<unknown: %x>"), bit); break;
9ef920e9
NC
16765 }
16766 if (bitmask)
16767 printf (", ");
16768 }
16769}
16770
ee2fdd6f
L
16771static void
16772decode_x86_feature (unsigned int type, unsigned int bitmask)
16773{
16774 while (bitmask)
16775 {
16776 unsigned int bit = bitmask & (- bitmask);
16777
16778 bitmask &= ~ bit;
16779 switch (bit)
16780 {
16781 case GNU_PROPERTY_X86_FEATURE_1_IBT:
16782 switch (type)
16783 {
16784 case GNU_PROPERTY_X86_FEATURE_1_AND:
16785 printf ("IBT");
16786 break;
16787 default:
16788 /* This should never happen. */
16789 abort ();
16790 }
16791 break;
48580982
L
16792 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
16793 switch (type)
16794 {
16795 case GNU_PROPERTY_X86_FEATURE_1_AND:
16796 printf ("SHSTK");
16797 break;
16798 default:
16799 /* This should never happen. */
16800 abort ();
16801 }
16802 break;
ee2fdd6f
L
16803 default:
16804 printf (_("<unknown: %x>"), bit);
16805 break;
16806 }
16807 if (bitmask)
16808 printf (", ");
16809 }
16810}
16811
9ef920e9 16812static void
dda8d76d 16813print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
16814{
16815 unsigned char * ptr = (unsigned char *) pnote->descdata;
16816 unsigned char * ptr_end = ptr + pnote->descsz;
16817 unsigned int size = is_32bit_elf ? 4 : 8;
16818
16819 printf (_(" Properties: "));
16820
1fc87489 16821 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
16822 {
16823 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
16824 return;
16825 }
16826
6ab2c4ed 16827 while (ptr < ptr_end)
9ef920e9 16828 {
1fc87489 16829 unsigned int j;
6ab2c4ed
MC
16830 unsigned int type;
16831 unsigned int datasz;
16832
16833 if ((size_t) (ptr_end - ptr) < 8)
16834 {
16835 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
16836 break;
16837 }
16838
16839 type = byte_get (ptr, 4);
16840 datasz = byte_get (ptr + 4, 4);
9ef920e9 16841
1fc87489 16842 ptr += 8;
9ef920e9 16843
6ab2c4ed 16844 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 16845 {
1fc87489
L
16846 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
16847 type, datasz);
9ef920e9 16848 break;
1fc87489 16849 }
9ef920e9 16850
1fc87489
L
16851 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
16852 {
dda8d76d
NC
16853 if (filedata->file_header.e_machine == EM_X86_64
16854 || filedata->file_header.e_machine == EM_IAMCU
16855 || filedata->file_header.e_machine == EM_386)
1fc87489
L
16856 {
16857 switch (type)
16858 {
16859 case GNU_PROPERTY_X86_ISA_1_USED:
16860 printf ("x86 ISA used: ");
16861 if (datasz != 4)
16862 printf (_("<corrupt length: %#x> "), datasz);
16863 else
16864 decode_x86_isa (byte_get (ptr, 4));
16865 goto next;
9ef920e9 16866
1fc87489
L
16867 case GNU_PROPERTY_X86_ISA_1_NEEDED:
16868 printf ("x86 ISA needed: ");
16869 if (datasz != 4)
16870 printf (_("<corrupt length: %#x> "), datasz);
16871 else
16872 decode_x86_isa (byte_get (ptr, 4));
16873 goto next;
9ef920e9 16874
ee2fdd6f
L
16875 case GNU_PROPERTY_X86_FEATURE_1_AND:
16876 printf ("x86 feature: ");
16877 if (datasz != 4)
16878 printf (_("<corrupt length: %#x> "), datasz);
16879 else
16880 decode_x86_feature (type, byte_get (ptr, 4));
16881 goto next;
16882
1fc87489
L
16883 default:
16884 break;
16885 }
16886 }
16887 }
16888 else
16889 {
16890 switch (type)
9ef920e9 16891 {
1fc87489
L
16892 case GNU_PROPERTY_STACK_SIZE:
16893 printf (_("stack size: "));
16894 if (datasz != size)
16895 printf (_("<corrupt length: %#x> "), datasz);
16896 else
16897 printf ("%#lx", (unsigned long) byte_get (ptr, size));
16898 goto next;
16899
16900 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
16901 printf ("no copy on protected ");
16902 if (datasz)
16903 printf (_("<corrupt length: %#x> "), datasz);
16904 goto next;
16905
16906 default:
9ef920e9
NC
16907 break;
16908 }
9ef920e9
NC
16909 }
16910
1fc87489
L
16911 if (type < GNU_PROPERTY_LOPROC)
16912 printf (_("<unknown type %#x data: "), type);
16913 else if (type < GNU_PROPERTY_LOUSER)
16914 printf (_("<procesor-specific type %#x data: "), type);
16915 else
16916 printf (_("<application-specific type %#x data: "), type);
16917 for (j = 0; j < datasz; ++j)
16918 printf ("%02x ", ptr[j] & 0xff);
16919 printf (">");
16920
16921next:
9ef920e9 16922 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
16923 if (ptr == ptr_end)
16924 break;
1fc87489 16925
6ab2c4ed
MC
16926 if (do_wide)
16927 printf (", ");
16928 else
16929 printf ("\n\t");
9ef920e9
NC
16930 }
16931
16932 printf ("\n");
16933}
16934
32ec8896 16935static bfd_boolean
dda8d76d 16936print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 16937{
1449284b 16938 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
16939 switch (pnote->type)
16940 {
16941 case NT_GNU_BUILD_ID:
16942 {
16943 unsigned long i;
16944
16945 printf (_(" Build ID: "));
16946 for (i = 0; i < pnote->descsz; ++i)
16947 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 16948 printf ("\n");
664f90a3
TT
16949 }
16950 break;
16951
16952 case NT_GNU_ABI_TAG:
16953 {
16954 unsigned long os, major, minor, subminor;
16955 const char *osname;
16956
3102e897
NC
16957 /* PR 17531: file: 030-599401-0.004. */
16958 if (pnote->descsz < 16)
16959 {
16960 printf (_(" <corrupt GNU_ABI_TAG>\n"));
16961 break;
16962 }
16963
664f90a3
TT
16964 os = byte_get ((unsigned char *) pnote->descdata, 4);
16965 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
16966 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
16967 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
16968
16969 switch (os)
16970 {
16971 case GNU_ABI_TAG_LINUX:
16972 osname = "Linux";
16973 break;
16974 case GNU_ABI_TAG_HURD:
16975 osname = "Hurd";
16976 break;
16977 case GNU_ABI_TAG_SOLARIS:
16978 osname = "Solaris";
16979 break;
16980 case GNU_ABI_TAG_FREEBSD:
16981 osname = "FreeBSD";
16982 break;
16983 case GNU_ABI_TAG_NETBSD:
16984 osname = "NetBSD";
16985 break;
14ae95f2
RM
16986 case GNU_ABI_TAG_SYLLABLE:
16987 osname = "Syllable";
16988 break;
16989 case GNU_ABI_TAG_NACL:
16990 osname = "NaCl";
16991 break;
664f90a3
TT
16992 default:
16993 osname = "Unknown";
16994 break;
16995 }
16996
16997 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
16998 major, minor, subminor);
16999 }
17000 break;
926c5385
CC
17001
17002 case NT_GNU_GOLD_VERSION:
17003 {
17004 unsigned long i;
17005
17006 printf (_(" Version: "));
17007 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
17008 printf ("%c", pnote->descdata[i]);
17009 printf ("\n");
17010 }
17011 break;
1449284b
NC
17012
17013 case NT_GNU_HWCAP:
17014 {
17015 unsigned long num_entries, mask;
17016
17017 /* Hardware capabilities information. Word 0 is the number of entries.
17018 Word 1 is a bitmask of enabled entries. The rest of the descriptor
17019 is a series of entries, where each entry is a single byte followed
17020 by a nul terminated string. The byte gives the bit number to test
17021 if enabled in the bitmask. */
17022 printf (_(" Hardware Capabilities: "));
17023 if (pnote->descsz < 8)
17024 {
32ec8896
NC
17025 error (_("<corrupt GNU_HWCAP>\n"));
17026 return FALSE;
1449284b
NC
17027 }
17028 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
17029 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17030 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
17031 /* FIXME: Add code to display the entries... */
17032 }
17033 break;
17034
9ef920e9 17035 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 17036 print_gnu_property_note (filedata, pnote);
9ef920e9
NC
17037 break;
17038
1449284b
NC
17039 default:
17040 /* Handle unrecognised types. An error message should have already been
17041 created by get_gnu_elf_note_type(), so all that we need to do is to
17042 display the data. */
17043 {
17044 unsigned long i;
17045
17046 printf (_(" Description data: "));
17047 for (i = 0; i < pnote->descsz; ++i)
17048 printf ("%02x ", pnote->descdata[i] & 0xff);
17049 printf ("\n");
17050 }
17051 break;
664f90a3
TT
17052 }
17053
32ec8896 17054 return TRUE;
664f90a3
TT
17055}
17056
685080f2
NC
17057static const char *
17058get_v850_elf_note_type (enum v850_notes n_type)
17059{
17060 static char buff[64];
17061
17062 switch (n_type)
17063 {
17064 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
17065 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
17066 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
17067 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
17068 case V850_NOTE_CACHE_INFO: return _("Use of cache");
17069 case V850_NOTE_MMU_INFO: return _("Use of MMU");
17070 default:
17071 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
17072 return buff;
17073 }
17074}
17075
32ec8896 17076static bfd_boolean
685080f2
NC
17077print_v850_note (Elf_Internal_Note * pnote)
17078{
17079 unsigned int val;
17080
17081 if (pnote->descsz != 4)
32ec8896
NC
17082 return FALSE;
17083
685080f2
NC
17084 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
17085
17086 if (val == 0)
17087 {
17088 printf (_("not set\n"));
32ec8896 17089 return TRUE;
685080f2
NC
17090 }
17091
17092 switch (pnote->type)
17093 {
17094 case V850_NOTE_ALIGNMENT:
17095 switch (val)
17096 {
32ec8896
NC
17097 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
17098 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
17099 }
17100 break;
14ae95f2 17101
685080f2
NC
17102 case V850_NOTE_DATA_SIZE:
17103 switch (val)
17104 {
32ec8896
NC
17105 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
17106 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
17107 }
17108 break;
14ae95f2 17109
685080f2
NC
17110 case V850_NOTE_FPU_INFO:
17111 switch (val)
17112 {
32ec8896
NC
17113 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
17114 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
17115 }
17116 break;
14ae95f2 17117
685080f2
NC
17118 case V850_NOTE_MMU_INFO:
17119 case V850_NOTE_CACHE_INFO:
17120 case V850_NOTE_SIMD_INFO:
17121 if (val == EF_RH850_SIMD)
17122 {
17123 printf (_("yes\n"));
32ec8896 17124 return TRUE;
685080f2
NC
17125 }
17126 break;
17127
17128 default:
17129 /* An 'unknown note type' message will already have been displayed. */
17130 break;
17131 }
17132
17133 printf (_("unknown value: %x\n"), val);
32ec8896 17134 return FALSE;
685080f2
NC
17135}
17136
32ec8896 17137static bfd_boolean
c6056a74
SF
17138process_netbsd_elf_note (Elf_Internal_Note * pnote)
17139{
17140 unsigned int version;
17141
17142 switch (pnote->type)
17143 {
17144 case NT_NETBSD_IDENT:
17145 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
17146 if ((version / 10000) % 100)
17147 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
17148 version, version / 100000000, (version / 1000000) % 100,
17149 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 17150 'A' + (version / 10000) % 26);
c6056a74
SF
17151 else
17152 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
17153 version, version / 100000000, (version / 1000000) % 100,
15f205b1 17154 (version / 100) % 100);
32ec8896 17155 return TRUE;
c6056a74
SF
17156
17157 case NT_NETBSD_MARCH:
17158 printf (" NetBSD\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
17159 pnote->descdata);
32ec8896 17160 return TRUE;
c6056a74
SF
17161
17162 default:
32ec8896
NC
17163 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n", pnote->descsz,
17164 pnote->type);
17165 return FALSE;
c6056a74 17166 }
c6056a74
SF
17167}
17168
f4ddf30f 17169static const char *
dda8d76d 17170get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 17171{
f4ddf30f
JB
17172 switch (e_type)
17173 {
17174 case NT_FREEBSD_THRMISC:
17175 return _("NT_THRMISC (thrmisc structure)");
17176 case NT_FREEBSD_PROCSTAT_PROC:
17177 return _("NT_PROCSTAT_PROC (proc data)");
17178 case NT_FREEBSD_PROCSTAT_FILES:
17179 return _("NT_PROCSTAT_FILES (files data)");
17180 case NT_FREEBSD_PROCSTAT_VMMAP:
17181 return _("NT_PROCSTAT_VMMAP (vmmap data)");
17182 case NT_FREEBSD_PROCSTAT_GROUPS:
17183 return _("NT_PROCSTAT_GROUPS (groups data)");
17184 case NT_FREEBSD_PROCSTAT_UMASK:
17185 return _("NT_PROCSTAT_UMASK (umask data)");
17186 case NT_FREEBSD_PROCSTAT_RLIMIT:
17187 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
17188 case NT_FREEBSD_PROCSTAT_OSREL:
17189 return _("NT_PROCSTAT_OSREL (osreldate data)");
17190 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
17191 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
17192 case NT_FREEBSD_PROCSTAT_AUXV:
17193 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
17194 case NT_FREEBSD_PTLWPINFO:
17195 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 17196 }
dda8d76d 17197 return get_note_type (filedata, e_type);
f4ddf30f
JB
17198}
17199
9437c45b 17200static const char *
dda8d76d 17201get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
17202{
17203 static char buff[64];
17204
b4db1224 17205 if (e_type == NT_NETBSDCORE_PROCINFO)
dda8d76d 17206 return _("NetBSD procinfo structure");
9437c45b
JT
17207
17208 /* As of Jan 2002 there are no other machine-independent notes
17209 defined for NetBSD core files. If the note type is less
17210 than the start of the machine-dependent note types, we don't
17211 understand it. */
17212
b4db1224 17213 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 17214 {
e9e44622 17215 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
17216 return buff;
17217 }
17218
dda8d76d 17219 switch (filedata->file_header.e_machine)
9437c45b
JT
17220 {
17221 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
17222 and PT_GETFPREGS == mach+2. */
17223
17224 case EM_OLD_ALPHA:
17225 case EM_ALPHA:
17226 case EM_SPARC:
17227 case EM_SPARC32PLUS:
17228 case EM_SPARCV9:
17229 switch (e_type)
17230 {
2b692964 17231 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 17232 return _("PT_GETREGS (reg structure)");
2b692964 17233 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 17234 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17235 default:
17236 break;
17237 }
17238 break;
17239
17240 /* On all other arch's, PT_GETREGS == mach+1 and
17241 PT_GETFPREGS == mach+3. */
17242 default:
17243 switch (e_type)
17244 {
2b692964 17245 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 17246 return _("PT_GETREGS (reg structure)");
2b692964 17247 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 17248 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17249 default:
17250 break;
17251 }
17252 }
17253
9cf03b7e 17254 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 17255 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
17256 return buff;
17257}
17258
70616151
TT
17259static const char *
17260get_stapsdt_note_type (unsigned e_type)
17261{
17262 static char buff[64];
17263
17264 switch (e_type)
17265 {
17266 case NT_STAPSDT:
17267 return _("NT_STAPSDT (SystemTap probe descriptors)");
17268
17269 default:
17270 break;
17271 }
17272
17273 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17274 return buff;
17275}
17276
32ec8896 17277static bfd_boolean
c6a9fc58
TT
17278print_stapsdt_note (Elf_Internal_Note *pnote)
17279{
17280 int addr_size = is_32bit_elf ? 4 : 8;
17281 char *data = pnote->descdata;
17282 char *data_end = pnote->descdata + pnote->descsz;
17283 bfd_vma pc, base_addr, semaphore;
17284 char *provider, *probe, *arg_fmt;
17285
17286 pc = byte_get ((unsigned char *) data, addr_size);
17287 data += addr_size;
17288 base_addr = byte_get ((unsigned char *) data, addr_size);
17289 data += addr_size;
17290 semaphore = byte_get ((unsigned char *) data, addr_size);
17291 data += addr_size;
17292
17293 provider = data;
17294 data += strlen (data) + 1;
17295 probe = data;
17296 data += strlen (data) + 1;
17297 arg_fmt = data;
17298 data += strlen (data) + 1;
17299
17300 printf (_(" Provider: %s\n"), provider);
17301 printf (_(" Name: %s\n"), probe);
17302 printf (_(" Location: "));
17303 print_vma (pc, FULL_HEX);
17304 printf (_(", Base: "));
17305 print_vma (base_addr, FULL_HEX);
17306 printf (_(", Semaphore: "));
17307 print_vma (semaphore, FULL_HEX);
9cf03b7e 17308 printf ("\n");
c6a9fc58
TT
17309 printf (_(" Arguments: %s\n"), arg_fmt);
17310
17311 return data == data_end;
17312}
17313
00e98fc7
TG
17314static const char *
17315get_ia64_vms_note_type (unsigned e_type)
17316{
17317 static char buff[64];
17318
17319 switch (e_type)
17320 {
17321 case NT_VMS_MHD:
17322 return _("NT_VMS_MHD (module header)");
17323 case NT_VMS_LNM:
17324 return _("NT_VMS_LNM (language name)");
17325 case NT_VMS_SRC:
17326 return _("NT_VMS_SRC (source files)");
17327 case NT_VMS_TITLE:
9cf03b7e 17328 return "NT_VMS_TITLE";
00e98fc7
TG
17329 case NT_VMS_EIDC:
17330 return _("NT_VMS_EIDC (consistency check)");
17331 case NT_VMS_FPMODE:
17332 return _("NT_VMS_FPMODE (FP mode)");
17333 case NT_VMS_LINKTIME:
9cf03b7e 17334 return "NT_VMS_LINKTIME";
00e98fc7
TG
17335 case NT_VMS_IMGNAM:
17336 return _("NT_VMS_IMGNAM (image name)");
17337 case NT_VMS_IMGID:
17338 return _("NT_VMS_IMGID (image id)");
17339 case NT_VMS_LINKID:
17340 return _("NT_VMS_LINKID (link id)");
17341 case NT_VMS_IMGBID:
17342 return _("NT_VMS_IMGBID (build id)");
17343 case NT_VMS_GSTNAM:
17344 return _("NT_VMS_GSTNAM (sym table name)");
17345 case NT_VMS_ORIG_DYN:
9cf03b7e 17346 return "NT_VMS_ORIG_DYN";
00e98fc7 17347 case NT_VMS_PATCHTIME:
9cf03b7e 17348 return "NT_VMS_PATCHTIME";
00e98fc7
TG
17349 default:
17350 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17351 return buff;
17352 }
17353}
17354
32ec8896 17355static bfd_boolean
00e98fc7
TG
17356print_ia64_vms_note (Elf_Internal_Note * pnote)
17357{
17358 switch (pnote->type)
17359 {
17360 case NT_VMS_MHD:
17361 if (pnote->descsz > 36)
17362 {
17363 size_t l = strlen (pnote->descdata + 34);
17364 printf (_(" Creation date : %.17s\n"), pnote->descdata);
17365 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
17366 printf (_(" Module name : %s\n"), pnote->descdata + 34);
17367 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
17368 }
17369 else
17370 printf (_(" Invalid size\n"));
17371 break;
17372 case NT_VMS_LNM:
17373 printf (_(" Language: %s\n"), pnote->descdata);
17374 break;
17375#ifdef BFD64
17376 case NT_VMS_FPMODE:
9cf03b7e 17377 printf (_(" Floating Point mode: "));
4a5cb34f 17378 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 17379 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
17380 break;
17381 case NT_VMS_LINKTIME:
17382 printf (_(" Link time: "));
17383 print_vms_time
17384 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
17385 printf ("\n");
17386 break;
17387 case NT_VMS_PATCHTIME:
17388 printf (_(" Patch time: "));
17389 print_vms_time
17390 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
17391 printf ("\n");
17392 break;
17393 case NT_VMS_ORIG_DYN:
17394 printf (_(" Major id: %u, minor id: %u\n"),
17395 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
17396 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 17397 printf (_(" Last modified : "));
00e98fc7
TG
17398 print_vms_time
17399 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 17400 printf (_("\n Link flags : "));
4a5cb34f 17401 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 17402 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 17403 printf (_(" Header flags: 0x%08x\n"),
948f632f 17404 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
00e98fc7
TG
17405 printf (_(" Image id : %s\n"), pnote->descdata + 32);
17406 break;
17407#endif
17408 case NT_VMS_IMGNAM:
17409 printf (_(" Image name: %s\n"), pnote->descdata);
17410 break;
17411 case NT_VMS_GSTNAM:
17412 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
17413 break;
17414 case NT_VMS_IMGID:
17415 printf (_(" Image id: %s\n"), pnote->descdata);
17416 break;
17417 case NT_VMS_LINKID:
17418 printf (_(" Linker id: %s\n"), pnote->descdata);
17419 break;
17420 default:
32ec8896 17421 return FALSE;
00e98fc7 17422 }
32ec8896 17423 return TRUE;
00e98fc7
TG
17424}
17425
6f156d7a
NC
17426/* Find the symbol associated with a build attribute that is attached
17427 to address OFFSET. If PNAME is non-NULL then store the name of
17428 the symbol (if found) in the provided pointer, Returns NULL if a
17429 symbol could not be found. */
c799a79d 17430
6f156d7a
NC
17431static Elf_Internal_Sym *
17432get_symbol_for_build_attribute (Filedata * filedata,
17433 unsigned long offset,
17434 bfd_boolean is_open_attr,
17435 const char ** pname)
9ef920e9 17436{
dda8d76d 17437 static Filedata * saved_filedata = NULL;
c799a79d
NC
17438 static char * strtab;
17439 static unsigned long strtablen;
17440 static Elf_Internal_Sym * symtab;
17441 static unsigned long nsyms;
7296a62a
NC
17442 Elf_Internal_Sym * saved_sym = NULL;
17443 Elf_Internal_Sym * sym;
9ef920e9 17444
dda8d76d
NC
17445 if (filedata->section_headers != NULL
17446 && (saved_filedata == NULL || filedata != saved_filedata))
9ef920e9 17447 {
c799a79d 17448 Elf_Internal_Shdr * symsec;
9ef920e9 17449
c799a79d 17450 /* Load the symbol and string sections. */
dda8d76d
NC
17451 for (symsec = filedata->section_headers;
17452 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 17453 symsec ++)
9ef920e9 17454 {
c799a79d 17455 if (symsec->sh_type == SHT_SYMTAB)
9ef920e9 17456 {
dda8d76d 17457 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
9ef920e9 17458
dda8d76d 17459 if (symsec->sh_link < filedata->file_header.e_shnum)
c799a79d 17460 {
dda8d76d 17461 Elf_Internal_Shdr * strtab_sec = filedata->section_headers + symsec->sh_link;
c799a79d 17462
dda8d76d 17463 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
c799a79d
NC
17464 1, strtab_sec->sh_size,
17465 _("string table"));
17466 strtablen = strtab != NULL ? strtab_sec->sh_size : 0;
17467 }
9ef920e9
NC
17468 }
17469 }
dda8d76d 17470 saved_filedata = filedata;
9ef920e9
NC
17471 }
17472
c799a79d 17473 if (symtab == NULL || strtab == NULL)
6f156d7a 17474 return NULL;
9ef920e9 17475
c799a79d
NC
17476 /* Find a symbol whose value matches offset. */
17477 for (sym = symtab; sym < symtab + nsyms; sym ++)
17478 if (sym->st_value == offset)
17479 {
17480 if (sym->st_name >= strtablen)
17481 /* Huh ? This should not happen. */
17482 continue;
9ef920e9 17483
c799a79d
NC
17484 if (strtab[sym->st_name] == 0)
17485 continue;
9ef920e9 17486
8fd75781
NC
17487 /* The AArch64 and ARM architectures define mapping symbols
17488 (eg $d, $x, $t) which we want to ignore. */
17489 if (strtab[sym->st_name] == '$'
17490 && strtab[sym->st_name + 1] != 0
17491 && strtab[sym->st_name + 2] == 0)
17492 continue;
17493
c799a79d
NC
17494 if (is_open_attr)
17495 {
17496 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
17497 and FILE or OBJECT symbols over NOTYPE symbols. We skip
17498 FUNC symbols entirely. */
17499 switch (ELF_ST_TYPE (sym->st_info))
17500 {
c799a79d 17501 case STT_OBJECT:
6f156d7a 17502 case STT_FILE:
c799a79d 17503 saved_sym = sym;
6f156d7a
NC
17504 if (sym->st_size)
17505 {
17506 /* If the symbol has a size associated
17507 with it then we can stop searching. */
17508 sym = symtab + nsyms;
17509 }
c799a79d 17510 continue;
9ef920e9 17511
c799a79d
NC
17512 case STT_FUNC:
17513 /* Ignore function symbols. */
17514 continue;
17515
17516 default:
17517 break;
17518 }
17519
17520 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 17521 {
c799a79d
NC
17522 case STB_GLOBAL:
17523 if (saved_sym == NULL
17524 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
17525 saved_sym = sym;
17526 break;
c871dade 17527
c799a79d
NC
17528 case STB_LOCAL:
17529 if (saved_sym == NULL)
17530 saved_sym = sym;
17531 break;
17532
17533 default:
9ef920e9
NC
17534 break;
17535 }
17536 }
c799a79d
NC
17537 else
17538 {
17539 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
17540 continue;
17541
17542 saved_sym = sym;
17543 break;
17544 }
17545 }
17546
6f156d7a
NC
17547 if (saved_sym && pname)
17548 * pname = strtab + saved_sym->st_name;
17549
17550 return saved_sym;
c799a79d
NC
17551}
17552
17553static bfd_boolean
dda8d76d
NC
17554print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
17555 Filedata * filedata)
c799a79d 17556{
6f156d7a
NC
17557 static unsigned long global_offset = 0;
17558 static unsigned long global_end = 0;
17559 static unsigned long func_offset = 0;
17560 static unsigned long func_end = 0;
c871dade 17561
6f156d7a
NC
17562 Elf_Internal_Sym * sym;
17563 const char * name;
17564 unsigned long start;
17565 unsigned long end;
17566 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
17567
17568 switch (pnote->descsz)
c799a79d 17569 {
6f156d7a
NC
17570 case 0:
17571 /* A zero-length description means that the range of
17572 the previous note of the same type should be used. */
c799a79d 17573 if (is_open_attr)
c871dade 17574 {
6f156d7a
NC
17575 if (global_end > global_offset)
17576 printf (_(" Applies to region from %#lx to %#lx\n"),
17577 global_offset, global_end);
17578 else
17579 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
17580 }
17581 else
17582 {
6f156d7a
NC
17583 if (func_end > func_offset)
17584 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
17585 else
17586 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 17587 }
6f156d7a 17588 return TRUE;
9ef920e9 17589
6f156d7a
NC
17590 case 4:
17591 start = byte_get ((unsigned char *) pnote->descdata, 4);
17592 end = 0;
17593 break;
17594
17595 case 8:
17596 if (is_32bit_elf)
17597 {
17598 /* FIXME: We should check that version 3+ notes are being used here... */
17599 start = byte_get ((unsigned char *) pnote->descdata, 4);
17600 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17601 }
17602 else
17603 {
17604 start = byte_get ((unsigned char *) pnote->descdata, 8);
17605 end = 0;
17606 }
17607 break;
17608
17609 case 16:
17610 start = byte_get ((unsigned char *) pnote->descdata, 8);
17611 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
17612 break;
17613
17614 default:
c799a79d
NC
17615 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
17616 printf (_(" <invalid descsz>"));
17617 return FALSE;
17618 }
17619
6f156d7a
NC
17620 name = NULL;
17621 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
17622 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
17623 in order to avoid them being confused with the start address of the
17624 first function in the file... */
17625 if (sym == NULL && is_open_attr)
17626 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
17627 & name);
6f156d7a
NC
17628
17629 if (end == 0 && sym != NULL && sym->st_size > 0)
17630 end = start + sym->st_size;
c799a79d
NC
17631
17632 if (is_open_attr)
17633 {
6f156d7a
NC
17634 /* FIXME: Need to properly allow for section alignment. 16 is just the alignment used on x86_64. */
17635 if (global_end > 0 && start > BFD_ALIGN (global_end, 16))
17636 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
17637 global_end + 1, start - 1);
17638
17639 printf (_(" Applies to region from %#lx"), start);
17640 global_offset = start;
17641
17642 if (end)
17643 {
17644 printf (_(" to %#lx"), end);
17645 global_end = end;
17646 }
c799a79d
NC
17647 }
17648 else
17649 {
6f156d7a
NC
17650 printf (_(" Applies to region from %#lx"), start);
17651 func_offset = start;
17652
17653 if (end)
17654 {
17655 printf (_(" to %#lx"), end);
17656 func_end = end;
17657 }
c799a79d
NC
17658 }
17659
6f156d7a
NC
17660 if (sym && name)
17661 printf (_(" (%s)"), name);
17662
17663 printf ("\n");
17664 return TRUE;
9ef920e9
NC
17665}
17666
17667static bfd_boolean
17668print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
17669{
1d15e434
NC
17670 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
17671 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
17672 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
17673 char name_type;
17674 char name_attribute;
1d15e434 17675 const char * expected_types;
9ef920e9
NC
17676 const char * name = pnote->namedata;
17677 const char * text;
88305e1b 17678 signed int left;
9ef920e9
NC
17679
17680 if (name == NULL || pnote->namesz < 2)
17681 {
17682 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 17683 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
17684 return FALSE;
17685 }
17686
6f156d7a
NC
17687 if (do_wide)
17688 left = 28;
17689 else
17690 left = 20;
88305e1b
NC
17691
17692 /* Version 2 of the spec adds a "GA" prefix to the name field. */
17693 if (name[0] == 'G' && name[1] == 'A')
17694 {
6f156d7a
NC
17695 if (pnote->namesz < 4)
17696 {
17697 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
17698 print_symbol (-20, _(" <corrupt name>"));
17699 return FALSE;
17700 }
17701
88305e1b
NC
17702 printf ("GA");
17703 name += 2;
17704 left -= 2;
17705 }
17706
9ef920e9
NC
17707 switch ((name_type = * name))
17708 {
17709 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
17710 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
17711 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
17712 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
17713 printf ("%c", * name);
88305e1b 17714 left --;
9ef920e9
NC
17715 break;
17716 default:
17717 error (_("unrecognised attribute type in name field: %d\n"), name_type);
17718 print_symbol (-20, _("<unknown name type>"));
17719 return FALSE;
17720 }
17721
9ef920e9
NC
17722 ++ name;
17723 text = NULL;
17724
17725 switch ((name_attribute = * name))
17726 {
17727 case GNU_BUILD_ATTRIBUTE_VERSION:
17728 text = _("<version>");
1d15e434 17729 expected_types = string_expected;
9ef920e9
NC
17730 ++ name;
17731 break;
17732 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
17733 text = _("<stack prot>");
75d7d298 17734 expected_types = "!+*";
9ef920e9
NC
17735 ++ name;
17736 break;
17737 case GNU_BUILD_ATTRIBUTE_RELRO:
17738 text = _("<relro>");
1d15e434 17739 expected_types = bool_expected;
9ef920e9
NC
17740 ++ name;
17741 break;
17742 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
17743 text = _("<stack size>");
1d15e434 17744 expected_types = number_expected;
9ef920e9
NC
17745 ++ name;
17746 break;
17747 case GNU_BUILD_ATTRIBUTE_TOOL:
17748 text = _("<tool>");
1d15e434 17749 expected_types = string_expected;
9ef920e9
NC
17750 ++ name;
17751 break;
17752 case GNU_BUILD_ATTRIBUTE_ABI:
17753 text = _("<ABI>");
17754 expected_types = "$*";
17755 ++ name;
17756 break;
17757 case GNU_BUILD_ATTRIBUTE_PIC:
17758 text = _("<PIC>");
1d15e434 17759 expected_types = number_expected;
9ef920e9
NC
17760 ++ name;
17761 break;
a8be5506
NC
17762 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
17763 text = _("<short enum>");
1d15e434 17764 expected_types = bool_expected;
a8be5506
NC
17765 ++ name;
17766 break;
9ef920e9
NC
17767 default:
17768 if (ISPRINT (* name))
17769 {
17770 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
17771
17772 if (len > left && ! do_wide)
17773 len = left;
75d7d298 17774 printf ("%.*s:", len, name);
9ef920e9 17775 left -= len;
0dd6ae21 17776 name += len;
9ef920e9
NC
17777 }
17778 else
17779 {
3e6b6445 17780 static char tmpbuf [128];
88305e1b 17781
3e6b6445
NC
17782 error (_("unrecognised byte in name field: %d\n"), * name);
17783 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
17784 text = tmpbuf;
17785 name ++;
9ef920e9
NC
17786 }
17787 expected_types = "*$!+";
17788 break;
17789 }
17790
17791 if (text)
88305e1b 17792 left -= printf ("%s", text);
9ef920e9
NC
17793
17794 if (strchr (expected_types, name_type) == NULL)
75d7d298 17795 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
17796
17797 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
17798 {
17799 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
17800 (unsigned long) pnote->namesz,
17801 (long) (name - pnote->namedata));
17802 return FALSE;
17803 }
17804
17805 if (left < 1 && ! do_wide)
17806 return TRUE;
17807
17808 switch (name_type)
17809 {
17810 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
17811 {
b06b2c92 17812 unsigned int bytes;
ddef72cd
NC
17813 unsigned long long val = 0;
17814 unsigned int shift = 0;
17815 char * decoded = NULL;
17816
b06b2c92
NC
17817 bytes = pnote->namesz - (name - pnote->namedata);
17818 if (bytes > 0)
17819 /* The -1 is because the name field is always 0 terminated, and we
17820 want to be able to ensure that the shift in the while loop below
17821 will not overflow. */
17822 -- bytes;
17823
ddef72cd
NC
17824 if (bytes > sizeof (val))
17825 {
3e6b6445
NC
17826 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
17827 bytes);
17828 bytes = sizeof (val);
ddef72cd 17829 }
3e6b6445
NC
17830 /* We do not bother to warn if bytes == 0 as this can
17831 happen with some early versions of the gcc plugin. */
9ef920e9
NC
17832
17833 while (bytes --)
17834 {
79a964dc
NC
17835 unsigned long byte = (* name ++) & 0xff;
17836
17837 val |= byte << shift;
9ef920e9
NC
17838 shift += 8;
17839 }
17840
75d7d298 17841 switch (name_attribute)
9ef920e9 17842 {
75d7d298 17843 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
17844 switch (val)
17845 {
75d7d298
NC
17846 case 0: decoded = "static"; break;
17847 case 1: decoded = "pic"; break;
17848 case 2: decoded = "PIC"; break;
17849 case 3: decoded = "pie"; break;
17850 case 4: decoded = "PIE"; break;
17851 default: break;
9ef920e9 17852 }
75d7d298
NC
17853 break;
17854 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
17855 switch (val)
9ef920e9 17856 {
75d7d298
NC
17857 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
17858 case 0: decoded = "off"; break;
17859 case 1: decoded = "on"; break;
17860 case 2: decoded = "all"; break;
17861 case 3: decoded = "strong"; break;
17862 case 4: decoded = "explicit"; break;
17863 default: break;
9ef920e9 17864 }
75d7d298
NC
17865 break;
17866 default:
17867 break;
9ef920e9
NC
17868 }
17869
75d7d298 17870 if (decoded != NULL)
3e6b6445
NC
17871 {
17872 print_symbol (-left, decoded);
17873 left = 0;
17874 }
17875 else if (val == 0)
17876 {
17877 printf ("0x0");
17878 left -= 3;
17879 }
9ef920e9 17880 else
75d7d298
NC
17881 {
17882 if (do_wide)
ddef72cd 17883 left -= printf ("0x%llx", val);
75d7d298 17884 else
ddef72cd 17885 left -= printf ("0x%-.*llx", left, val);
75d7d298 17886 }
9ef920e9
NC
17887 }
17888 break;
17889 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
17890 left -= print_symbol (- left, name);
17891 break;
17892 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
17893 left -= print_symbol (- left, "true");
17894 break;
17895 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
17896 left -= print_symbol (- left, "false");
17897 break;
17898 }
17899
17900 if (do_wide && left > 0)
17901 printf ("%-*s", left, " ");
17902
17903 return TRUE;
17904}
17905
6d118b09
NC
17906/* Note that by the ELF standard, the name field is already null byte
17907 terminated, and namesz includes the terminating null byte.
17908 I.E. the value of namesz for the name "FSF" is 4.
17909
e3c8793a 17910 If the value of namesz is zero, there is no name present. */
9ef920e9 17911
32ec8896 17912static bfd_boolean
9ef920e9 17913process_note (Elf_Internal_Note * pnote,
dda8d76d 17914 Filedata * filedata)
779fe533 17915{
2cf0635d
NC
17916 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
17917 const char * nt;
9437c45b
JT
17918
17919 if (pnote->namesz == 0)
1ec5cd37
NC
17920 /* If there is no note name, then use the default set of
17921 note type strings. */
dda8d76d 17922 nt = get_note_type (filedata, pnote->type);
1ec5cd37 17923
1118d252
RM
17924 else if (const_strneq (pnote->namedata, "GNU"))
17925 /* GNU-specific object file notes. */
17926 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
17927
17928 else if (const_strneq (pnote->namedata, "FreeBSD"))
17929 /* FreeBSD-specific core file notes. */
dda8d76d 17930 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 17931
0112cd26 17932 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 17933 /* NetBSD-specific core file notes. */
dda8d76d 17934 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 17935
c6056a74
SF
17936 else if (const_strneq (pnote->namedata, "NetBSD"))
17937 /* NetBSD-specific core file notes. */
17938 return process_netbsd_elf_note (pnote);
17939
b15fa79e
AM
17940 else if (strneq (pnote->namedata, "SPU/", 4))
17941 {
17942 /* SPU-specific core file notes. */
17943 nt = pnote->namedata + 4;
17944 name = "SPU";
17945 }
17946
00e98fc7
TG
17947 else if (const_strneq (pnote->namedata, "IPF/VMS"))
17948 /* VMS/ia64-specific file notes. */
17949 nt = get_ia64_vms_note_type (pnote->type);
17950
70616151
TT
17951 else if (const_strneq (pnote->namedata, "stapsdt"))
17952 nt = get_stapsdt_note_type (pnote->type);
17953
9437c45b 17954 else
1ec5cd37
NC
17955 /* Don't recognize this note name; just use the default set of
17956 note type strings. */
dda8d76d 17957 nt = get_note_type (filedata, pnote->type);
9437c45b 17958
1449284b 17959 printf (" ");
9ef920e9 17960
483767a3
AM
17961 if (((const_strneq (pnote->namedata, "GA")
17962 && strchr ("*$!+", pnote->namedata[2]) != NULL)
17963 || strchr ("*$!+", pnote->namedata[0]) != NULL)
17964 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
17965 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
17966 print_gnu_build_attribute_name (pnote);
17967 else
17968 print_symbol (-20, name);
17969
17970 if (do_wide)
17971 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
17972 else
17973 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
17974
17975 if (const_strneq (pnote->namedata, "IPF/VMS"))
17976 return print_ia64_vms_note (pnote);
664f90a3 17977 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 17978 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
17979 else if (const_strneq (pnote->namedata, "stapsdt"))
17980 return print_stapsdt_note (pnote);
9ece1fa9
TT
17981 else if (const_strneq (pnote->namedata, "CORE"))
17982 return print_core_note (pnote);
483767a3
AM
17983 else if (((const_strneq (pnote->namedata, "GA")
17984 && strchr ("*$!+", pnote->namedata[2]) != NULL)
17985 || strchr ("*$!+", pnote->namedata[0]) != NULL)
17986 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
17987 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 17988 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 17989
9ef920e9 17990 if (pnote->descsz)
1449284b
NC
17991 {
17992 unsigned long i;
17993
17994 printf (_(" description data: "));
17995 for (i = 0; i < pnote->descsz; i++)
17996 printf ("%02x ", pnote->descdata[i]);
04ac15ab
AS
17997 if (!do_wide)
17998 printf ("\n");
1449284b
NC
17999 }
18000
9ef920e9
NC
18001 if (do_wide)
18002 printf ("\n");
18003
32ec8896 18004 return TRUE;
1449284b 18005}
6d118b09 18006
32ec8896 18007static bfd_boolean
dda8d76d
NC
18008process_notes_at (Filedata * filedata,
18009 Elf_Internal_Shdr * section,
18010 bfd_vma offset,
82ed9683
L
18011 bfd_vma length,
18012 bfd_vma align)
779fe533 18013{
2cf0635d
NC
18014 Elf_External_Note * pnotes;
18015 Elf_External_Note * external;
4dff97b2
NC
18016 char * end;
18017 bfd_boolean res = TRUE;
103f02d3 18018
779fe533 18019 if (length <= 0)
32ec8896 18020 return FALSE;
103f02d3 18021
1449284b
NC
18022 if (section)
18023 {
dda8d76d 18024 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 18025 if (pnotes)
32ec8896 18026 {
dda8d76d 18027 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
32ec8896
NC
18028 return FALSE;
18029 }
1449284b
NC
18030 }
18031 else
82ed9683 18032 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 18033 _("notes"));
4dff97b2 18034
dd24e3da 18035 if (pnotes == NULL)
32ec8896 18036 return FALSE;
779fe533 18037
103f02d3 18038 external = pnotes;
103f02d3 18039
1449284b 18040 if (section)
dda8d76d 18041 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
18042 else
18043 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
18044 (unsigned long) offset, (unsigned long) length);
18045
82ed9683
L
18046 /* NB: Some note sections may have alignment value of 0 or 1. gABI
18047 specifies that notes should be aligned to 4 bytes in 32-bit
18048 objects and to 8 bytes in 64-bit objects. As a Linux extension,
18049 we also support 4 byte alignment in 64-bit objects. If section
18050 alignment is less than 4, we treate alignment as 4 bytes. */
18051 if (align < 4)
18052 align = 4;
18053 else if (align != 4 && align != 8)
18054 {
18055 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
18056 (long) align);
18057 return FALSE;
18058 }
18059
2aee03ae 18060 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 18061
c8071705
NC
18062 end = (char *) pnotes + length;
18063 while ((char *) external < end)
779fe533 18064 {
b34976b6 18065 Elf_Internal_Note inote;
15b42fb0 18066 size_t min_notesz;
4dff97b2 18067 char * next;
2cf0635d 18068 char * temp = NULL;
c8071705 18069 size_t data_remaining = end - (char *) external;
6d118b09 18070
dda8d76d 18071 if (!is_ia64_vms (filedata))
15b42fb0 18072 {
9dd3a467
NC
18073 /* PR binutils/15191
18074 Make sure that there is enough data to read. */
15b42fb0
AM
18075 min_notesz = offsetof (Elf_External_Note, name);
18076 if (data_remaining < min_notesz)
9dd3a467 18077 {
d3a49aa8
AM
18078 warn (ngettext ("Corrupt note: only %ld byte remains, "
18079 "not enough for a full note\n",
18080 "Corrupt note: only %ld bytes remain, "
18081 "not enough for a full note\n",
18082 data_remaining),
18083 (long) data_remaining);
9dd3a467
NC
18084 break;
18085 }
5396a86e
AM
18086 data_remaining -= min_notesz;
18087
15b42fb0
AM
18088 inote.type = BYTE_GET (external->type);
18089 inote.namesz = BYTE_GET (external->namesz);
18090 inote.namedata = external->name;
18091 inote.descsz = BYTE_GET (external->descsz);
276da9b3 18092 inote.descdata = ((char *) external
4dff97b2 18093 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 18094 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 18095 next = ((char *) external
4dff97b2 18096 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 18097 }
00e98fc7 18098 else
15b42fb0
AM
18099 {
18100 Elf64_External_VMS_Note *vms_external;
00e98fc7 18101
9dd3a467
NC
18102 /* PR binutils/15191
18103 Make sure that there is enough data to read. */
15b42fb0
AM
18104 min_notesz = offsetof (Elf64_External_VMS_Note, name);
18105 if (data_remaining < min_notesz)
9dd3a467 18106 {
d3a49aa8
AM
18107 warn (ngettext ("Corrupt note: only %ld byte remains, "
18108 "not enough for a full note\n",
18109 "Corrupt note: only %ld bytes remain, "
18110 "not enough for a full note\n",
18111 data_remaining),
18112 (long) data_remaining);
9dd3a467
NC
18113 break;
18114 }
5396a86e 18115 data_remaining -= min_notesz;
3e55a963 18116
15b42fb0
AM
18117 vms_external = (Elf64_External_VMS_Note *) external;
18118 inote.type = BYTE_GET (vms_external->type);
18119 inote.namesz = BYTE_GET (vms_external->namesz);
18120 inote.namedata = vms_external->name;
18121 inote.descsz = BYTE_GET (vms_external->descsz);
18122 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
18123 inote.descpos = offset + (inote.descdata - (char *) pnotes);
18124 next = inote.descdata + align_power (inote.descsz, 3);
18125 }
18126
5396a86e
AM
18127 /* PR 17531: file: 3443835e. */
18128 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
18129 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
18130 || (size_t) (inote.descdata - inote.namedata) > data_remaining
18131 || (size_t) (next - inote.descdata) < inote.descsz
18132 || ((size_t) (next - inote.descdata)
18133 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 18134 {
15b42fb0 18135 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 18136 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
18137 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
18138 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
18139 break;
18140 }
18141
15b42fb0 18142 external = (Elf_External_Note *) next;
dd24e3da 18143
6d118b09
NC
18144 /* Verify that name is null terminated. It appears that at least
18145 one version of Linux (RedHat 6.0) generates corefiles that don't
18146 comply with the ELF spec by failing to include the null byte in
18147 namesz. */
8b971f9f 18148 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 18149 {
5396a86e 18150 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 18151 {
5396a86e
AM
18152 temp = (char *) malloc (inote.namesz + 1);
18153 if (temp == NULL)
18154 {
18155 error (_("Out of memory allocating space for inote name\n"));
18156 res = FALSE;
18157 break;
18158 }
76da6bbe 18159
5396a86e
AM
18160 memcpy (temp, inote.namedata, inote.namesz);
18161 inote.namedata = temp;
18162 }
18163 inote.namedata[inote.namesz] = 0;
6d118b09
NC
18164 }
18165
dda8d76d 18166 if (! process_note (& inote, filedata))
6b4bf3bc 18167 res = FALSE;
103f02d3 18168
6d118b09
NC
18169 if (temp != NULL)
18170 {
18171 free (temp);
18172 temp = NULL;
18173 }
779fe533
NC
18174 }
18175
18176 free (pnotes);
103f02d3 18177
779fe533
NC
18178 return res;
18179}
18180
32ec8896 18181static bfd_boolean
dda8d76d 18182process_corefile_note_segments (Filedata * filedata)
779fe533 18183{
2cf0635d 18184 Elf_Internal_Phdr * segment;
b34976b6 18185 unsigned int i;
32ec8896 18186 bfd_boolean res = TRUE;
103f02d3 18187
dda8d76d 18188 if (! get_program_headers (filedata))
6b4bf3bc 18189 return TRUE;
103f02d3 18190
dda8d76d
NC
18191 for (i = 0, segment = filedata->program_headers;
18192 i < filedata->file_header.e_phnum;
b34976b6 18193 i++, segment++)
779fe533
NC
18194 {
18195 if (segment->p_type == PT_NOTE)
dda8d76d 18196 if (! process_notes_at (filedata, NULL,
32ec8896 18197 (bfd_vma) segment->p_offset,
82ed9683
L
18198 (bfd_vma) segment->p_filesz,
18199 (bfd_vma) segment->p_align))
32ec8896 18200 res = FALSE;
779fe533 18201 }
103f02d3 18202
779fe533
NC
18203 return res;
18204}
18205
32ec8896 18206static bfd_boolean
dda8d76d 18207process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
18208{
18209 Elf_External_Note * pnotes;
18210 Elf_External_Note * external;
c8071705 18211 char * end;
32ec8896 18212 bfd_boolean res = TRUE;
685080f2
NC
18213
18214 if (length <= 0)
32ec8896 18215 return FALSE;
685080f2 18216
dda8d76d 18217 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
18218 _("v850 notes"));
18219 if (pnotes == NULL)
32ec8896 18220 return FALSE;
685080f2
NC
18221
18222 external = pnotes;
c8071705 18223 end = (char*) pnotes + length;
685080f2
NC
18224
18225 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
18226 (unsigned long) offset, (unsigned long) length);
18227
c8071705 18228 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
18229 {
18230 Elf_External_Note * next;
18231 Elf_Internal_Note inote;
18232
18233 inote.type = BYTE_GET (external->type);
18234 inote.namesz = BYTE_GET (external->namesz);
18235 inote.namedata = external->name;
18236 inote.descsz = BYTE_GET (external->descsz);
18237 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
18238 inote.descpos = offset + (inote.descdata - (char *) pnotes);
18239
c8071705
NC
18240 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
18241 {
18242 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
18243 inote.descdata = inote.namedata;
18244 inote.namesz = 0;
18245 }
18246
685080f2
NC
18247 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
18248
c8071705 18249 if ( ((char *) next > end)
685080f2
NC
18250 || ((char *) next < (char *) pnotes))
18251 {
18252 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
18253 (unsigned long) ((char *) external - (char *) pnotes));
18254 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
18255 inote.type, inote.namesz, inote.descsz);
18256 break;
18257 }
18258
18259 external = next;
18260
18261 /* Prevent out-of-bounds indexing. */
c8071705 18262 if ( inote.namedata + inote.namesz > end
685080f2
NC
18263 || inote.namedata + inote.namesz < inote.namedata)
18264 {
18265 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
18266 (unsigned long) ((char *) external - (char *) pnotes));
18267 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
18268 inote.type, inote.namesz, inote.descsz);
18269 break;
18270 }
18271
18272 printf (" %s: ", get_v850_elf_note_type (inote.type));
18273
18274 if (! print_v850_note (& inote))
18275 {
32ec8896 18276 res = FALSE;
685080f2
NC
18277 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
18278 inote.namesz, inote.descsz);
18279 }
18280 }
18281
18282 free (pnotes);
18283
18284 return res;
18285}
18286
32ec8896 18287static bfd_boolean
dda8d76d 18288process_note_sections (Filedata * filedata)
1ec5cd37 18289{
2cf0635d 18290 Elf_Internal_Shdr * section;
1ec5cd37 18291 unsigned long i;
32ec8896
NC
18292 unsigned int n = 0;
18293 bfd_boolean res = TRUE;
1ec5cd37 18294
dda8d76d
NC
18295 for (i = 0, section = filedata->section_headers;
18296 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 18297 i++, section++)
685080f2
NC
18298 {
18299 if (section->sh_type == SHT_NOTE)
18300 {
dda8d76d 18301 if (! process_notes_at (filedata, section,
32ec8896 18302 (bfd_vma) section->sh_offset,
82ed9683
L
18303 (bfd_vma) section->sh_size,
18304 (bfd_vma) section->sh_addralign))
32ec8896 18305 res = FALSE;
685080f2
NC
18306 n++;
18307 }
18308
dda8d76d
NC
18309 if (( filedata->file_header.e_machine == EM_V800
18310 || filedata->file_header.e_machine == EM_V850
18311 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
18312 && section->sh_type == SHT_RENESAS_INFO)
18313 {
dda8d76d 18314 if (! process_v850_notes (filedata,
32ec8896
NC
18315 (bfd_vma) section->sh_offset,
18316 (bfd_vma) section->sh_size))
18317 res = FALSE;
685080f2
NC
18318 n++;
18319 }
18320 }
df565f32
NC
18321
18322 if (n == 0)
18323 /* Try processing NOTE segments instead. */
dda8d76d 18324 return process_corefile_note_segments (filedata);
1ec5cd37
NC
18325
18326 return res;
18327}
18328
32ec8896 18329static bfd_boolean
dda8d76d 18330process_notes (Filedata * filedata)
779fe533
NC
18331{
18332 /* If we have not been asked to display the notes then do nothing. */
18333 if (! do_notes)
32ec8896 18334 return TRUE;
103f02d3 18335
dda8d76d
NC
18336 if (filedata->file_header.e_type != ET_CORE)
18337 return process_note_sections (filedata);
103f02d3 18338
779fe533 18339 /* No program headers means no NOTE segment. */
dda8d76d
NC
18340 if (filedata->file_header.e_phnum > 0)
18341 return process_corefile_note_segments (filedata);
779fe533 18342
1ec5cd37 18343 printf (_("No note segments present in the core file.\n"));
32ec8896 18344 return TRUE;
779fe533
NC
18345}
18346
60abdbed
NC
18347static unsigned char *
18348display_public_gnu_attributes (unsigned char * start,
18349 const unsigned char * const end)
18350{
18351 printf (_(" Unknown GNU attribute: %s\n"), start);
18352
18353 start += strnlen ((char *) start, end - start);
18354 display_raw_attribute (start, end);
18355
18356 return (unsigned char *) end;
18357}
18358
18359static unsigned char *
18360display_generic_attribute (unsigned char * start,
18361 unsigned int tag,
18362 const unsigned char * const end)
18363{
18364 if (tag == 0)
18365 return (unsigned char *) end;
18366
18367 return display_tag_value (tag, start, end);
18368}
18369
32ec8896 18370static bfd_boolean
dda8d76d 18371process_arch_specific (Filedata * filedata)
252b5132 18372{
a952a375 18373 if (! do_arch)
32ec8896 18374 return TRUE;
a952a375 18375
dda8d76d 18376 switch (filedata->file_header.e_machine)
252b5132 18377 {
53a346d8
CZ
18378 case EM_ARC:
18379 case EM_ARC_COMPACT:
18380 case EM_ARC_COMPACT2:
dda8d76d 18381 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
18382 display_arc_attribute,
18383 display_generic_attribute);
11c1ff18 18384 case EM_ARM:
dda8d76d 18385 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
18386 display_arm_attribute,
18387 display_generic_attribute);
18388
252b5132 18389 case EM_MIPS:
4fe85591 18390 case EM_MIPS_RS3_LE:
dda8d76d 18391 return process_mips_specific (filedata);
60abdbed
NC
18392
18393 case EM_MSP430:
dda8d76d
NC
18394 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
18395 display_msp430x_attribute,
18396 display_generic_attribute);
60abdbed 18397
35c08157 18398 case EM_NDS32:
dda8d76d 18399 return process_nds32_specific (filedata);
60abdbed 18400
34c8bcba 18401 case EM_PPC:
b82317dd 18402 case EM_PPC64:
dda8d76d 18403 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18404 display_power_gnu_attribute);
18405
643f7afb
AK
18406 case EM_S390:
18407 case EM_S390_OLD:
dda8d76d 18408 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18409 display_s390_gnu_attribute);
18410
9e8c70f9
DM
18411 case EM_SPARC:
18412 case EM_SPARC32PLUS:
18413 case EM_SPARCV9:
dda8d76d 18414 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18415 display_sparc_gnu_attribute);
18416
59e6276b 18417 case EM_TI_C6000:
dda8d76d 18418 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
18419 display_tic6x_attribute,
18420 display_generic_attribute);
18421
252b5132 18422 default:
dda8d76d 18423 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
18424 display_public_gnu_attributes,
18425 display_generic_attribute);
252b5132 18426 }
252b5132
RH
18427}
18428
32ec8896 18429static bfd_boolean
dda8d76d 18430get_file_header (Filedata * filedata)
252b5132 18431{
9ea033b2 18432 /* Read in the identity array. */
dda8d76d 18433 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18434 return FALSE;
252b5132 18435
9ea033b2 18436 /* Determine how to read the rest of the header. */
dda8d76d 18437 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 18438 {
1a0670f3
AM
18439 default:
18440 case ELFDATANONE:
adab8cdc
AO
18441 case ELFDATA2LSB:
18442 byte_get = byte_get_little_endian;
18443 byte_put = byte_put_little_endian;
18444 break;
18445 case ELFDATA2MSB:
18446 byte_get = byte_get_big_endian;
18447 byte_put = byte_put_big_endian;
18448 break;
9ea033b2
NC
18449 }
18450
18451 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 18452 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
18453
18454 /* Read in the rest of the header. */
18455 if (is_32bit_elf)
18456 {
18457 Elf32_External_Ehdr ehdr32;
252b5132 18458
dda8d76d 18459 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18460 return FALSE;
103f02d3 18461
dda8d76d
NC
18462 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
18463 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
18464 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
18465 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
18466 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
18467 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
18468 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
18469 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
18470 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
18471 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
18472 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
18473 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
18474 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 18475 }
252b5132 18476 else
9ea033b2
NC
18477 {
18478 Elf64_External_Ehdr ehdr64;
a952a375
NC
18479
18480 /* If we have been compiled with sizeof (bfd_vma) == 4, then
18481 we will not be able to cope with the 64bit data found in
18482 64 ELF files. Detect this now and abort before we start
50c2245b 18483 overwriting things. */
a952a375
NC
18484 if (sizeof (bfd_vma) < 8)
18485 {
e3c8793a
NC
18486 error (_("This instance of readelf has been built without support for a\n\
1848764 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 18488 return FALSE;
a952a375 18489 }
103f02d3 18490
dda8d76d 18491 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18492 return FALSE;
103f02d3 18493
dda8d76d
NC
18494 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
18495 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
18496 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
18497 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
18498 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
18499 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
18500 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
18501 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
18502 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
18503 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
18504 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
18505 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
18506 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 18507 }
252b5132 18508
dda8d76d 18509 if (filedata->file_header.e_shoff)
7ece0d85
JJ
18510 {
18511 /* There may be some extensions in the first section header. Don't
18512 bomb if we can't read it. */
18513 if (is_32bit_elf)
dda8d76d 18514 get_32bit_section_headers (filedata, TRUE);
7ece0d85 18515 else
dda8d76d 18516 get_64bit_section_headers (filedata, TRUE);
7ece0d85 18517 }
560f3c1c 18518
32ec8896 18519 return TRUE;
252b5132
RH
18520}
18521
dda8d76d
NC
18522static void
18523close_file (Filedata * filedata)
18524{
18525 if (filedata)
18526 {
18527 if (filedata->handle)
18528 fclose (filedata->handle);
18529 free (filedata);
18530 }
18531}
18532
18533void
18534close_debug_file (void * data)
18535{
18536 close_file ((Filedata *) data);
18537}
18538
18539static Filedata *
18540open_file (const char * pathname)
18541{
18542 struct stat statbuf;
18543 Filedata * filedata = NULL;
18544
18545 if (stat (pathname, & statbuf) < 0
18546 || ! S_ISREG (statbuf.st_mode))
18547 goto fail;
18548
18549 filedata = calloc (1, sizeof * filedata);
18550 if (filedata == NULL)
18551 goto fail;
18552
18553 filedata->handle = fopen (pathname, "rb");
18554 if (filedata->handle == NULL)
18555 goto fail;
18556
18557 filedata->file_size = (bfd_size_type) statbuf.st_size;
18558 filedata->file_name = pathname;
18559
18560 if (! get_file_header (filedata))
18561 goto fail;
18562
18563 if (filedata->file_header.e_shoff)
18564 {
18565 bfd_boolean res;
18566
18567 /* Read the section headers again, this time for real. */
18568 if (is_32bit_elf)
18569 res = get_32bit_section_headers (filedata, FALSE);
18570 else
18571 res = get_64bit_section_headers (filedata, FALSE);
18572
18573 if (!res)
18574 goto fail;
18575 }
18576
18577 return filedata;
18578
18579 fail:
18580 if (filedata)
18581 {
18582 if (filedata->handle)
18583 fclose (filedata->handle);
18584 free (filedata);
18585 }
18586 return NULL;
18587}
18588
18589void *
18590open_debug_file (const char * pathname)
18591{
18592 return open_file (pathname);
18593}
18594
fb52b2f4
NC
18595/* Process one ELF object file according to the command line options.
18596 This file may actually be stored in an archive. The file is
32ec8896
NC
18597 positioned at the start of the ELF object. Returns TRUE if no
18598 problems were encountered, FALSE otherwise. */
fb52b2f4 18599
32ec8896 18600static bfd_boolean
dda8d76d 18601process_object (Filedata * filedata)
252b5132 18602{
dda8d76d 18603 Filedata * separates;
252b5132 18604 unsigned int i;
32ec8896 18605 bfd_boolean res = TRUE;
252b5132 18606
dda8d76d 18607 if (! get_file_header (filedata))
252b5132 18608 {
dda8d76d 18609 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 18610 return FALSE;
252b5132
RH
18611 }
18612
18613 /* Initialise per file variables. */
60bca95a 18614 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
18615 version_info[i] = 0;
18616
60bca95a 18617 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 18618 dynamic_info[i] = 0;
5115b233 18619 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
18620
18621 /* Process the file. */
18622 if (show_name)
dda8d76d 18623 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 18624
18bd398b
NC
18625 /* Initialise the dump_sects array from the cmdline_dump_sects array.
18626 Note we do this even if cmdline_dump_sects is empty because we
18627 must make sure that the dump_sets array is zeroed out before each
18628 object file is processed. */
dda8d76d
NC
18629 if (filedata->num_dump_sects > cmdline.num_dump_sects)
18630 memset (filedata->dump_sects, 0, filedata->num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 18631
dda8d76d 18632 if (cmdline.num_dump_sects > 0)
18bd398b 18633 {
dda8d76d 18634 if (filedata->num_dump_sects == 0)
18bd398b 18635 /* A sneaky way of allocating the dump_sects array. */
dda8d76d 18636 request_dump_bynumber (filedata, cmdline.num_dump_sects, 0);
18bd398b 18637
dda8d76d
NC
18638 assert (filedata->num_dump_sects >= cmdline.num_dump_sects);
18639 memcpy (filedata->dump_sects, cmdline.dump_sects,
18640 cmdline.num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 18641 }
d70c5fc7 18642
dda8d76d 18643 if (! process_file_header (filedata))
32ec8896 18644 return FALSE;
252b5132 18645
dda8d76d 18646 if (! process_section_headers (filedata))
2f62977e 18647 {
32ec8896
NC
18648 /* Without loaded section headers we cannot process lots of things. */
18649 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 18650
2f62977e 18651 if (! do_using_dynamic)
32ec8896 18652 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 18653 }
252b5132 18654
dda8d76d 18655 if (! process_section_groups (filedata))
32ec8896
NC
18656 /* Without loaded section groups we cannot process unwind. */
18657 do_unwind = FALSE;
d1f5c6e3 18658
dda8d76d
NC
18659 if (process_program_headers (filedata))
18660 process_dynamic_section (filedata);
32ec8896
NC
18661 else
18662 res = FALSE;
252b5132 18663
dda8d76d 18664 if (! process_relocs (filedata))
32ec8896 18665 res = FALSE;
252b5132 18666
dda8d76d 18667 if (! process_unwind (filedata))
32ec8896 18668 res = FALSE;
4d6ed7c8 18669
dda8d76d 18670 if (! process_symbol_table (filedata))
32ec8896 18671 res = FALSE;
252b5132 18672
dda8d76d 18673 if (! process_syminfo (filedata))
32ec8896 18674 res = FALSE;
252b5132 18675
dda8d76d 18676 if (! process_version_sections (filedata))
32ec8896 18677 res = FALSE;
252b5132 18678
82ed9683
L
18679 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
18680 separates = load_separate_debug_file (filedata, filedata->file_name);
18681 else
18682 separates = NULL;
dda8d76d
NC
18683
18684 if (! process_section_contents (filedata))
32ec8896 18685 res = FALSE;
f5842774 18686
dda8d76d
NC
18687 if (separates)
18688 {
18689 if (! process_section_headers (separates))
18690 res = FALSE;
18691 else if (! process_section_contents (separates))
18692 res = FALSE;
18693 }
18694
18695 if (! process_notes (filedata))
32ec8896 18696 res = FALSE;
103f02d3 18697
dda8d76d 18698 if (! process_gnu_liblist (filedata))
32ec8896 18699 res = FALSE;
047b2264 18700
dda8d76d 18701 if (! process_arch_specific (filedata))
32ec8896 18702 res = FALSE;
252b5132 18703
dda8d76d
NC
18704 free (filedata->program_headers);
18705 filedata->program_headers = NULL;
d93f0186 18706
dda8d76d
NC
18707 free (filedata->section_headers);
18708 filedata->section_headers = NULL;
252b5132 18709
dda8d76d
NC
18710 free (filedata->string_table);
18711 filedata->string_table = NULL;
18712 filedata->string_table_length = 0;
252b5132
RH
18713
18714 if (dynamic_strings)
18715 {
18716 free (dynamic_strings);
18717 dynamic_strings = NULL;
d79b3d50 18718 dynamic_strings_length = 0;
252b5132
RH
18719 }
18720
18721 if (dynamic_symbols)
18722 {
18723 free (dynamic_symbols);
18724 dynamic_symbols = NULL;
19936277 18725 num_dynamic_syms = 0;
252b5132
RH
18726 }
18727
18728 if (dynamic_syminfo)
18729 {
18730 free (dynamic_syminfo);
18731 dynamic_syminfo = NULL;
18732 }
ff78d6d6 18733
293c573e
MR
18734 if (dynamic_section)
18735 {
18736 free (dynamic_section);
18737 dynamic_section = NULL;
18738 }
18739
e4b17d5c
L
18740 if (section_headers_groups)
18741 {
18742 free (section_headers_groups);
18743 section_headers_groups = NULL;
18744 }
18745
18746 if (section_groups)
18747 {
2cf0635d
NC
18748 struct group_list * g;
18749 struct group_list * next;
e4b17d5c
L
18750
18751 for (i = 0; i < group_count; i++)
18752 {
18753 for (g = section_groups [i].root; g != NULL; g = next)
18754 {
18755 next = g->next;
18756 free (g);
18757 }
18758 }
18759
18760 free (section_groups);
18761 section_groups = NULL;
18762 }
18763
19e6b90e 18764 free_debug_memory ();
18bd398b 18765
32ec8896 18766 return res;
252b5132
RH
18767}
18768
2cf0635d 18769/* Process an ELF archive.
32ec8896
NC
18770 On entry the file is positioned just after the ARMAG string.
18771 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 18772
32ec8896 18773static bfd_boolean
dda8d76d 18774process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
18775{
18776 struct archive_info arch;
18777 struct archive_info nested_arch;
18778 size_t got;
32ec8896 18779 bfd_boolean ret = TRUE;
2cf0635d 18780
32ec8896 18781 show_name = TRUE;
2cf0635d
NC
18782
18783 /* The ARCH structure is used to hold information about this archive. */
18784 arch.file_name = NULL;
18785 arch.file = NULL;
18786 arch.index_array = NULL;
18787 arch.sym_table = NULL;
18788 arch.longnames = NULL;
18789
18790 /* The NESTED_ARCH structure is used as a single-item cache of information
18791 about a nested archive (when members of a thin archive reside within
18792 another regular archive file). */
18793 nested_arch.file_name = NULL;
18794 nested_arch.file = NULL;
18795 nested_arch.index_array = NULL;
18796 nested_arch.sym_table = NULL;
18797 nested_arch.longnames = NULL;
18798
dda8d76d
NC
18799 if (setup_archive (&arch, filedata->file_name, filedata->handle,
18800 is_thin_archive, do_archive_index) != 0)
2cf0635d 18801 {
32ec8896 18802 ret = FALSE;
2cf0635d 18803 goto out;
4145f1d5 18804 }
fb52b2f4 18805
4145f1d5
NC
18806 if (do_archive_index)
18807 {
2cf0635d 18808 if (arch.sym_table == NULL)
dda8d76d 18809 error (_("%s: unable to dump the index as none was found\n"), filedata->file_name);
4145f1d5
NC
18810 else
18811 {
591f7597 18812 unsigned long i, l;
4145f1d5
NC
18813 unsigned long current_pos;
18814
591f7597 18815 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
dda8d76d
NC
18816 filedata->file_name, (unsigned long) arch.index_num, arch.sym_size);
18817
18818 current_pos = ftell (filedata->handle);
4145f1d5 18819
2cf0635d 18820 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 18821 {
2cf0635d
NC
18822 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
18823 {
18824 char * member_name;
4145f1d5 18825
2cf0635d
NC
18826 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
18827
18828 if (member_name != NULL)
18829 {
18830 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
18831
18832 if (qualified_name != NULL)
18833 {
c2a7d3f5
NC
18834 printf (_("Contents of binary %s at offset "), qualified_name);
18835 (void) print_vma (arch.index_array[i], PREFIX_HEX);
18836 putchar ('\n');
2cf0635d
NC
18837 free (qualified_name);
18838 }
4145f1d5
NC
18839 }
18840 }
2cf0635d
NC
18841
18842 if (l >= arch.sym_size)
4145f1d5
NC
18843 {
18844 error (_("%s: end of the symbol table reached before the end of the index\n"),
dda8d76d 18845 filedata->file_name);
32ec8896 18846 ret = FALSE;
cb8f3167 18847 break;
4145f1d5 18848 }
591f7597
NC
18849 /* PR 17531: file: 0b6630b2. */
18850 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
18851 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
18852 }
18853
c2a7d3f5
NC
18854 if (arch.uses_64bit_indicies)
18855 l = (l + 7) & ~ 7;
18856 else
18857 l += l & 1;
18858
2cf0635d 18859 if (l < arch.sym_size)
32ec8896 18860 {
d3a49aa8
AM
18861 error (ngettext ("%s: %ld byte remains in the symbol table, "
18862 "but without corresponding entries in "
18863 "the index table\n",
18864 "%s: %ld bytes remain in the symbol table, "
18865 "but without corresponding entries in "
18866 "the index table\n",
18867 arch.sym_size - l),
dda8d76d 18868 filedata->file_name, arch.sym_size - l);
32ec8896
NC
18869 ret = FALSE;
18870 }
4145f1d5 18871
dda8d76d 18872 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 18873 {
dda8d76d
NC
18874 error (_("%s: failed to seek back to start of object files in the archive\n"),
18875 filedata->file_name);
32ec8896 18876 ret = FALSE;
2cf0635d 18877 goto out;
4145f1d5 18878 }
fb52b2f4 18879 }
4145f1d5
NC
18880
18881 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
18882 && !do_segments && !do_header && !do_dump && !do_version
18883 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 18884 && !do_section_groups && !do_dyn_syms)
2cf0635d 18885 {
32ec8896 18886 ret = TRUE; /* Archive index only. */
2cf0635d
NC
18887 goto out;
18888 }
fb52b2f4
NC
18889 }
18890
fb52b2f4
NC
18891 while (1)
18892 {
2cf0635d
NC
18893 char * name;
18894 size_t namelen;
18895 char * qualified_name;
18896
18897 /* Read the next archive header. */
dda8d76d 18898 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
2cf0635d 18899 {
dda8d76d 18900 error (_("%s: failed to seek to next archive header\n"), filedata->file_name);
32ec8896 18901 return FALSE;
2cf0635d 18902 }
dda8d76d 18903 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d
NC
18904 if (got != sizeof arch.arhdr)
18905 {
18906 if (got == 0)
18907 break;
dda8d76d 18908 error (_("%s: failed to read archive header\n"), filedata->file_name);
32ec8896 18909 ret = FALSE;
2cf0635d
NC
18910 break;
18911 }
18912 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
18913 {
18914 error (_("%s: did not find a valid archive header\n"), arch.file_name);
32ec8896 18915 ret = FALSE;
2cf0635d
NC
18916 break;
18917 }
18918
18919 arch.next_arhdr_offset += sizeof arch.arhdr;
18920
18921 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
18922 if (archive_file_size & 01)
18923 ++archive_file_size;
18924
18925 name = get_archive_member_name (&arch, &nested_arch);
18926 if (name == NULL)
fb52b2f4 18927 {
dda8d76d 18928 error (_("%s: bad archive file name\n"), filedata->file_name);
32ec8896 18929 ret = FALSE;
d989285c 18930 break;
fb52b2f4 18931 }
2cf0635d 18932 namelen = strlen (name);
fb52b2f4 18933
2cf0635d
NC
18934 qualified_name = make_qualified_name (&arch, &nested_arch, name);
18935 if (qualified_name == NULL)
fb52b2f4 18936 {
dda8d76d 18937 error (_("%s: bad archive file name\n"), filedata->file_name);
32ec8896 18938 ret = FALSE;
d989285c 18939 break;
fb52b2f4
NC
18940 }
18941
2cf0635d
NC
18942 if (is_thin_archive && arch.nested_member_origin == 0)
18943 {
18944 /* This is a proxy for an external member of a thin archive. */
dda8d76d
NC
18945 Filedata * member_filedata;
18946 char * member_file_name = adjust_relative_path
18947 (filedata->file_name, name, namelen);
32ec8896 18948
2cf0635d
NC
18949 if (member_file_name == NULL)
18950 {
32ec8896 18951 ret = FALSE;
2cf0635d
NC
18952 break;
18953 }
18954
dda8d76d
NC
18955 member_filedata = open_file (member_file_name);
18956 if (member_filedata == NULL)
2cf0635d
NC
18957 {
18958 error (_("Input file '%s' is not readable.\n"), member_file_name);
18959 free (member_file_name);
32ec8896 18960 ret = FALSE;
2cf0635d
NC
18961 break;
18962 }
18963
18964 archive_file_offset = arch.nested_member_origin;
dda8d76d 18965 member_filedata->file_name = qualified_name;
2cf0635d 18966
dda8d76d 18967 if (! process_object (member_filedata))
32ec8896 18968 ret = FALSE;
2cf0635d 18969
dda8d76d 18970 close_file (member_filedata);
2cf0635d
NC
18971 free (member_file_name);
18972 }
18973 else if (is_thin_archive)
18974 {
eb02c04d
PK
18975 Filedata thin_filedata;
18976
18977 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 18978
a043396b
NC
18979 /* PR 15140: Allow for corrupt thin archives. */
18980 if (nested_arch.file == NULL)
18981 {
18982 error (_("%s: contains corrupt thin archive: %s\n"),
dda8d76d 18983 filedata->file_name, name);
32ec8896 18984 ret = FALSE;
a043396b
NC
18985 break;
18986 }
18987
2cf0635d
NC
18988 /* This is a proxy for a member of a nested archive. */
18989 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
18990
18991 /* The nested archive file will have been opened and setup by
18992 get_archive_member_name. */
18993 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
18994 {
18995 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
32ec8896 18996 ret = FALSE;
2cf0635d
NC
18997 break;
18998 }
18999
dda8d76d
NC
19000 thin_filedata.handle = nested_arch.file;
19001 thin_filedata.file_name = qualified_name;
19002
19003 if (! process_object (& thin_filedata))
32ec8896 19004 ret = FALSE;
2cf0635d
NC
19005 }
19006 else
19007 {
19008 archive_file_offset = arch.next_arhdr_offset;
19009 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 19010
6a6196fc 19011 filedata->file_name = qualified_name;
dda8d76d 19012 if (! process_object (filedata))
32ec8896 19013 ret = FALSE;
2cf0635d 19014 }
fb52b2f4 19015
dda8d76d 19016 if (filedata->dump_sects != NULL)
2b52916e 19017 {
dda8d76d
NC
19018 free (filedata->dump_sects);
19019 filedata->dump_sects = NULL;
19020 filedata->num_dump_sects = 0;
2b52916e
L
19021 }
19022
2cf0635d 19023 free (qualified_name);
fb52b2f4
NC
19024 }
19025
4145f1d5 19026 out:
2cf0635d
NC
19027 if (nested_arch.file != NULL)
19028 fclose (nested_arch.file);
19029 release_archive (&nested_arch);
19030 release_archive (&arch);
fb52b2f4 19031
d989285c 19032 return ret;
fb52b2f4
NC
19033}
19034
32ec8896 19035static bfd_boolean
2cf0635d 19036process_file (char * file_name)
fb52b2f4 19037{
dda8d76d 19038 Filedata * filedata = NULL;
fb52b2f4
NC
19039 struct stat statbuf;
19040 char armag[SARMAG];
32ec8896 19041 bfd_boolean ret = TRUE;
fb52b2f4
NC
19042
19043 if (stat (file_name, &statbuf) < 0)
19044 {
f24ddbdd
NC
19045 if (errno == ENOENT)
19046 error (_("'%s': No such file\n"), file_name);
19047 else
19048 error (_("Could not locate '%s'. System error message: %s\n"),
19049 file_name, strerror (errno));
32ec8896 19050 return FALSE;
f24ddbdd
NC
19051 }
19052
19053 if (! S_ISREG (statbuf.st_mode))
19054 {
19055 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 19056 return FALSE;
fb52b2f4
NC
19057 }
19058
dda8d76d
NC
19059 filedata = calloc (1, sizeof * filedata);
19060 if (filedata == NULL)
19061 {
19062 error (_("Out of memory allocating file data structure\n"));
19063 return FALSE;
19064 }
19065
19066 filedata->file_name = file_name;
19067 filedata->handle = fopen (file_name, "rb");
19068 if (filedata->handle == NULL)
fb52b2f4 19069 {
f24ddbdd 19070 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 19071 free (filedata);
32ec8896 19072 return FALSE;
fb52b2f4
NC
19073 }
19074
dda8d76d 19075 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 19076 {
4145f1d5 19077 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
19078 fclose (filedata->handle);
19079 free (filedata);
32ec8896 19080 return FALSE;
fb52b2f4
NC
19081 }
19082
dda8d76d 19083 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 19084
fb52b2f4 19085 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 19086 {
dda8d76d 19087 if (! process_archive (filedata, FALSE))
32ec8896
NC
19088 ret = FALSE;
19089 }
2cf0635d 19090 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 19091 {
dda8d76d 19092 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
19093 ret = FALSE;
19094 }
fb52b2f4
NC
19095 else
19096 {
4145f1d5
NC
19097 if (do_archive_index)
19098 error (_("File %s is not an archive so its index cannot be displayed.\n"),
19099 file_name);
19100
dda8d76d 19101 rewind (filedata->handle);
fb52b2f4 19102 archive_file_size = archive_file_offset = 0;
32ec8896 19103
dda8d76d 19104 if (! process_object (filedata))
32ec8896 19105 ret = FALSE;
fb52b2f4
NC
19106 }
19107
dda8d76d
NC
19108 fclose (filedata->handle);
19109 free (filedata);
32ec8896 19110
fb52b2f4
NC
19111 return ret;
19112}
19113
252b5132
RH
19114#ifdef SUPPORT_DISASSEMBLY
19115/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 19116 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 19117 symbols. */
252b5132
RH
19118
19119void
2cf0635d 19120print_address (unsigned int addr, FILE * outfile)
252b5132
RH
19121{
19122 fprintf (outfile,"0x%8.8x", addr);
19123}
19124
e3c8793a 19125/* Needed by the i386 disassembler. */
dda8d76d 19126
252b5132
RH
19127void
19128db_task_printsym (unsigned int addr)
19129{
19130 print_address (addr, stderr);
19131}
19132#endif
19133
19134int
2cf0635d 19135main (int argc, char ** argv)
252b5132 19136{
ff78d6d6
L
19137 int err;
19138
252b5132
RH
19139#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
19140 setlocale (LC_MESSAGES, "");
3882b010
L
19141#endif
19142#if defined (HAVE_SETLOCALE)
19143 setlocale (LC_CTYPE, "");
252b5132
RH
19144#endif
19145 bindtextdomain (PACKAGE, LOCALEDIR);
19146 textdomain (PACKAGE);
19147
869b9d07
MM
19148 expandargv (&argc, &argv);
19149
dda8d76d
NC
19150 cmdline.file_name = "<cmdline>";
19151 parse_args (& cmdline, argc, argv);
59f14fc0 19152
18bd398b 19153 if (optind < (argc - 1))
32ec8896 19154 show_name = TRUE;
5656ba2c
L
19155 else if (optind >= argc)
19156 {
19157 warn (_("Nothing to do.\n"));
19158 usage (stderr);
19159 }
18bd398b 19160
32ec8896 19161 err = FALSE;
252b5132 19162 while (optind < argc)
32ec8896
NC
19163 if (! process_file (argv[optind++]))
19164 err = TRUE;
252b5132 19165
dda8d76d
NC
19166 if (cmdline.dump_sects != NULL)
19167 free (cmdline.dump_sects);
252b5132 19168
32ec8896 19169 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 19170}
This page took 2.776705 seconds and 4 git commands to generate.