[MIPS] Add Loongson 3A2000/3A3000 proccessor support.
[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"
b8891f8d 101#include "elf/csky.h"
252b5132
RH
102#include "elf/d10v.h"
103#include "elf/d30v.h"
d172d4ba 104#include "elf/dlx.h"
cfb8c092 105#include "elf/epiphany.h"
252b5132 106#include "elf/fr30.h"
5c70f934 107#include "elf/frv.h"
3f8107ab 108#include "elf/ft32.h"
3b16e843
NC
109#include "elf/h8.h"
110#include "elf/hppa.h"
111#include "elf/i386.h"
f954747f
AM
112#include "elf/i370.h"
113#include "elf/i860.h"
114#include "elf/i960.h"
3b16e843 115#include "elf/ia64.h"
1e4cf259 116#include "elf/ip2k.h"
84e94c90 117#include "elf/lm32.h"
1c0d3aa6 118#include "elf/iq2000.h"
49f58d10 119#include "elf/m32c.h"
3b16e843
NC
120#include "elf/m32r.h"
121#include "elf/m68k.h"
75751cd9 122#include "elf/m68hc11.h"
7b4ae824 123#include "elf/s12z.h"
252b5132 124#include "elf/mcore.h"
15ab5209 125#include "elf/mep.h"
a3c62988 126#include "elf/metag.h"
7ba29e2a 127#include "elf/microblaze.h"
3b16e843 128#include "elf/mips.h"
3c3bdf30 129#include "elf/mmix.h"
3b16e843
NC
130#include "elf/mn10200.h"
131#include "elf/mn10300.h"
5506d11a 132#include "elf/moxie.h"
4970f871 133#include "elf/mt.h"
2469cfa2 134#include "elf/msp430.h"
35c08157 135#include "elf/nds32.h"
fe944acf 136#include "elf/nfp.h"
13761a11 137#include "elf/nios2.h"
73589c9d 138#include "elf/or1k.h"
7d466069 139#include "elf/pj.h"
3b16e843 140#include "elf/ppc.h"
c833c019 141#include "elf/ppc64.h"
2b100bb5 142#include "elf/pru.h"
03336641 143#include "elf/riscv.h"
99c513f6 144#include "elf/rl78.h"
c7927a3c 145#include "elf/rx.h"
a85d7ed0 146#include "elf/s390.h"
1c0d3aa6 147#include "elf/score.h"
3b16e843
NC
148#include "elf/sh.h"
149#include "elf/sparc.h"
e9f53129 150#include "elf/spu.h"
40b36596 151#include "elf/tic6x.h"
aa137e4d
NC
152#include "elf/tilegx.h"
153#include "elf/tilepro.h"
3b16e843 154#include "elf/v850.h"
179d3252 155#include "elf/vax.h"
619ed720 156#include "elf/visium.h"
f96bd6c2 157#include "elf/wasm32.h"
3b16e843 158#include "elf/x86-64.h"
c29aca4a 159#include "elf/xc16x.h"
f6c1a2d5 160#include "elf/xgate.h"
93fbbb04 161#include "elf/xstormy16.h"
88da6820 162#include "elf/xtensa.h"
252b5132 163
252b5132 164#include "getopt.h"
566b0d53 165#include "libiberty.h"
09c11c86 166#include "safe-ctype.h"
2cf0635d 167#include "filenames.h"
252b5132 168
15b42fb0
AM
169#ifndef offsetof
170#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
171#endif
172
6a40cf0c
NC
173typedef struct elf_section_list
174{
dda8d76d
NC
175 Elf_Internal_Shdr * hdr;
176 struct elf_section_list * next;
6a40cf0c
NC
177} elf_section_list;
178
dda8d76d
NC
179/* Flag bits indicating particular types of dump. */
180#define HEX_DUMP (1 << 0) /* The -x command line switch. */
181#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
182#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
183#define STRING_DUMP (1 << 3) /* The -p command line switch. */
184#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
185
186typedef unsigned char dump_type;
187
188/* A linked list of the section names for which dumps were requested. */
189struct dump_list_entry
190{
191 char * name;
192 dump_type type;
193 struct dump_list_entry * next;
194};
195
196typedef struct filedata
197{
198 const char * file_name;
199 FILE * handle;
200 bfd_size_type file_size;
201 Elf_Internal_Ehdr file_header;
202 Elf_Internal_Shdr * section_headers;
203 Elf_Internal_Phdr * program_headers;
204 char * string_table;
205 unsigned long string_table_length;
206 /* A dynamic array of flags indicating for which sections a dump of
207 some kind has been requested. It is reset on a per-object file
208 basis and then initialised from the cmdline_dump_sects array,
209 the results of interpreting the -w switch, and the
210 dump_sects_byname list. */
211 dump_type * dump_sects;
212 unsigned int num_dump_sects;
213} Filedata;
214
2cf0635d 215char * program_name = "readelf";
dda8d76d 216
c9c1d674 217static unsigned long archive_file_offset;
85b1c36d
BE
218static unsigned long archive_file_size;
219static unsigned long dynamic_addr;
220static bfd_size_type dynamic_size;
8b73c356 221static size_t dynamic_nent;
2cf0635d 222static char * dynamic_strings;
85b1c36d 223static unsigned long dynamic_strings_length;
85b1c36d 224static unsigned long num_dynamic_syms;
2cf0635d
NC
225static Elf_Internal_Sym * dynamic_symbols;
226static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
227static unsigned long dynamic_syminfo_offset;
228static unsigned int dynamic_syminfo_nent;
f8eae8b2 229static char program_interpreter[PATH_MAX];
bb8a0291 230static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 231static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d 232static bfd_vma version_info[16];
2cf0635d 233static Elf_Internal_Dyn * dynamic_section;
6a40cf0c 234static elf_section_list * symtab_shndx_list;
32ec8896
NC
235static bfd_boolean show_name = FALSE;
236static bfd_boolean do_dynamic = FALSE;
237static bfd_boolean do_syms = FALSE;
238static bfd_boolean do_dyn_syms = FALSE;
239static bfd_boolean do_reloc = FALSE;
240static bfd_boolean do_sections = FALSE;
241static bfd_boolean do_section_groups = FALSE;
242static bfd_boolean do_section_details = FALSE;
243static bfd_boolean do_segments = FALSE;
244static bfd_boolean do_unwind = FALSE;
245static bfd_boolean do_using_dynamic = FALSE;
246static bfd_boolean do_header = FALSE;
247static bfd_boolean do_dump = FALSE;
248static bfd_boolean do_version = FALSE;
249static bfd_boolean do_histogram = FALSE;
250static bfd_boolean do_debugging = FALSE;
251static bfd_boolean do_arch = FALSE;
252static bfd_boolean do_notes = FALSE;
253static bfd_boolean do_archive_index = FALSE;
254static bfd_boolean is_32bit_elf = FALSE;
255static bfd_boolean decompress_dumps = FALSE;
252b5132 256
e4b17d5c
L
257struct group_list
258{
dda8d76d
NC
259 struct group_list * next;
260 unsigned int section_index;
e4b17d5c
L
261};
262
263struct group
264{
dda8d76d
NC
265 struct group_list * root;
266 unsigned int group_index;
e4b17d5c
L
267};
268
dda8d76d
NC
269static size_t group_count;
270static struct group * section_groups;
271static struct group ** section_headers_groups;
aef1f6d0 272
09c11c86
NC
273/* A dynamic array of flags indicating for which sections a dump
274 has been requested via command line switches. */
dda8d76d 275static Filedata cmdline;
252b5132 276
dda8d76d 277static struct dump_list_entry * dump_sects_byname;
252b5132 278
c256ffe7 279/* How to print a vma value. */
843dd992
NC
280typedef enum print_mode
281{
282 HEX,
283 DEC,
284 DEC_5,
285 UNSIGNED,
286 PREFIX_HEX,
287 FULL_HEX,
288 LONG_HEX
289}
290print_mode;
291
bb4d2ac2
L
292/* Versioned symbol info. */
293enum versioned_symbol_info
294{
295 symbol_undefined,
296 symbol_hidden,
297 symbol_public
298};
299
32ec8896 300static const char * get_symbol_version_string
dda8d76d 301 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 302 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 303
9c19a809
NC
304#define UNKNOWN -1
305
2b692964
NC
306#define SECTION_NAME(X) \
307 ((X) == NULL ? _("<none>") \
dda8d76d
NC
308 : filedata->string_table == NULL ? _("<no-strings>") \
309 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
310 : filedata->string_table + (X)->sh_name))
252b5132 311
ee42cf8c 312#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 313
ba5cdace
NC
314#define GET_ELF_SYMBOLS(file, section, sym_count) \
315 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
316 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 317
d79b3d50
NC
318#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
319/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
320 already been called and verified that the string exists. */
321#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 322
61865e30
NC
323#define REMOVE_ARCH_BITS(ADDR) \
324 do \
325 { \
dda8d76d 326 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
327 (ADDR) &= ~1; \
328 } \
329 while (0)
d79b3d50 330\f
66cfc0fd
AM
331/* Print a BFD_VMA to an internal buffer, for use in error messages.
332 BFD_FMA_FMT can't be used in translated strings. */
333
334static const char *
335bfd_vmatoa (char *fmtch, bfd_vma value)
336{
337 /* bfd_vmatoa is used more then once in a printf call for output.
338 Cycle through an array of buffers. */
339 static int buf_pos = 0;
340 static struct bfd_vmatoa_buf
341 {
342 char place[64];
343 } buf[4];
344 char *ret;
345 char fmt[32];
346
347 ret = buf[buf_pos++].place;
348 buf_pos %= ARRAY_SIZE (buf);
349
350 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
351 snprintf (ret, sizeof (buf[0].place), fmt, value);
352 return ret;
353}
354
dda8d76d
NC
355/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
356 OFFSET + the offset of the current archive member, if we are examining an
357 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
358 allocate a buffer using malloc and fill that. In either case return the
359 pointer to the start of the retrieved data or NULL if something went wrong.
360 If something does go wrong and REASON is not NULL then emit an error
361 message using REASON as part of the context. */
59245841 362
c256ffe7 363static void *
dda8d76d
NC
364get_data (void * var,
365 Filedata * filedata,
366 unsigned long offset,
367 bfd_size_type size,
368 bfd_size_type nmemb,
369 const char * reason)
a6e9f9df 370{
2cf0635d 371 void * mvar;
57028622 372 bfd_size_type amt = size * nmemb;
a6e9f9df 373
c256ffe7 374 if (size == 0 || nmemb == 0)
a6e9f9df
AM
375 return NULL;
376
57028622
NC
377 /* If the size_t type is smaller than the bfd_size_type, eg because
378 you are building a 32-bit tool on a 64-bit host, then make sure
379 that when the sizes are cast to (size_t) no information is lost. */
380 if (sizeof (size_t) < sizeof (bfd_size_type)
381 && ( (bfd_size_type) ((size_t) size) != size
382 || (bfd_size_type) ((size_t) nmemb) != nmemb))
383 {
384 if (reason)
66cfc0fd
AM
385 error (_("Size truncation prevents reading %s"
386 " elements of size %s for %s\n"),
387 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
388 return NULL;
389 }
390
391 /* Check for size overflow. */
392 if (amt < nmemb)
393 {
394 if (reason)
66cfc0fd
AM
395 error (_("Size overflow prevents reading %s"
396 " elements of size %s for %s\n"),
397 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
398 return NULL;
399 }
400
c9c1d674
EG
401 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
402 attempting to allocate memory when the read is bound to fail. */
dda8d76d
NC
403 if (amt > filedata->file_size
404 || offset + archive_file_offset + amt > filedata->file_size)
a6e9f9df 405 {
049b0c3a 406 if (reason)
66cfc0fd
AM
407 error (_("Reading %s bytes extends past end of file for %s\n"),
408 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
409 return NULL;
410 }
411
dda8d76d 412 if (fseek (filedata->handle, archive_file_offset + offset, SEEK_SET))
071436c6
NC
413 {
414 if (reason)
c9c1d674 415 error (_("Unable to seek to 0x%lx for %s\n"),
ed754a13 416 archive_file_offset + offset, reason);
071436c6
NC
417 return NULL;
418 }
419
a6e9f9df
AM
420 mvar = var;
421 if (mvar == NULL)
422 {
c256ffe7 423 /* Check for overflow. */
57028622 424 if (nmemb < (~(bfd_size_type) 0 - 1) / size)
c256ffe7 425 /* + 1 so that we can '\0' terminate invalid string table sections. */
57028622 426 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
427
428 if (mvar == NULL)
429 {
049b0c3a 430 if (reason)
66cfc0fd
AM
431 error (_("Out of memory allocating %s bytes for %s\n"),
432 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
433 return NULL;
434 }
c256ffe7 435
c9c1d674 436 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
437 }
438
dda8d76d 439 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 440 {
049b0c3a 441 if (reason)
66cfc0fd
AM
442 error (_("Unable to read in %s bytes of %s\n"),
443 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
444 if (mvar != var)
445 free (mvar);
446 return NULL;
447 }
448
449 return mvar;
450}
451
32ec8896
NC
452/* Print a VMA value in the MODE specified.
453 Returns the number of characters displayed. */
cb8f3167 454
32ec8896 455static unsigned int
14a91970 456print_vma (bfd_vma vma, print_mode mode)
66543521 457{
32ec8896 458 unsigned int nc = 0;
66543521 459
14a91970 460 switch (mode)
66543521 461 {
14a91970
AM
462 case FULL_HEX:
463 nc = printf ("0x");
1a0670f3 464 /* Fall through. */
14a91970 465 case LONG_HEX:
f7a99963 466#ifdef BFD64
14a91970 467 if (is_32bit_elf)
437c2fb7 468 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 469#endif
14a91970
AM
470 printf_vma (vma);
471 return nc + 16;
b19aac67 472
14a91970
AM
473 case DEC_5:
474 if (vma <= 99999)
475 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 476 /* Fall through. */
14a91970
AM
477 case PREFIX_HEX:
478 nc = printf ("0x");
1a0670f3 479 /* Fall through. */
14a91970
AM
480 case HEX:
481 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 482
14a91970
AM
483 case DEC:
484 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 485
14a91970
AM
486 case UNSIGNED:
487 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
488
489 default:
490 /* FIXME: Report unrecognised mode ? */
491 return 0;
f7a99963 492 }
f7a99963
NC
493}
494
7bfd842d 495/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 496 multibye characters (assuming the host environment supports them).
31104126 497
7bfd842d
NC
498 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
499
500 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
501 padding as necessary.
171191ba
NC
502
503 Returns the number of emitted characters. */
504
505static unsigned int
32ec8896 506print_symbol (signed int width, const char *symbol)
31104126 507{
171191ba 508 bfd_boolean extra_padding = FALSE;
32ec8896 509 signed int num_printed = 0;
3bfcb652 510#ifdef HAVE_MBSTATE_T
7bfd842d 511 mbstate_t state;
3bfcb652 512#endif
32ec8896 513 unsigned int width_remaining;
961c521f 514
7bfd842d 515 if (width < 0)
961c521f 516 {
88305e1b 517 /* Keep the width positive. This helps the code below. */
961c521f 518 width = - width;
171191ba 519 extra_padding = TRUE;
0b4362b0 520 }
56d8f8a9
NC
521 else if (width == 0)
522 return 0;
961c521f 523
7bfd842d
NC
524 if (do_wide)
525 /* Set the remaining width to a very large value.
526 This simplifies the code below. */
527 width_remaining = INT_MAX;
528 else
529 width_remaining = width;
cb8f3167 530
3bfcb652 531#ifdef HAVE_MBSTATE_T
7bfd842d
NC
532 /* Initialise the multibyte conversion state. */
533 memset (& state, 0, sizeof (state));
3bfcb652 534#endif
961c521f 535
7bfd842d
NC
536 while (width_remaining)
537 {
538 size_t n;
7bfd842d 539 const char c = *symbol++;
961c521f 540
7bfd842d 541 if (c == 0)
961c521f
NC
542 break;
543
7bfd842d
NC
544 /* Do not print control characters directly as they can affect terminal
545 settings. Such characters usually appear in the names generated
546 by the assembler for local labels. */
547 if (ISCNTRL (c))
961c521f 548 {
7bfd842d 549 if (width_remaining < 2)
961c521f
NC
550 break;
551
7bfd842d
NC
552 printf ("^%c", c + 0x40);
553 width_remaining -= 2;
171191ba 554 num_printed += 2;
961c521f 555 }
7bfd842d
NC
556 else if (ISPRINT (c))
557 {
558 putchar (c);
559 width_remaining --;
560 num_printed ++;
561 }
961c521f
NC
562 else
563 {
3bfcb652
NC
564#ifdef HAVE_MBSTATE_T
565 wchar_t w;
566#endif
7bfd842d
NC
567 /* Let printf do the hard work of displaying multibyte characters. */
568 printf ("%.1s", symbol - 1);
569 width_remaining --;
570 num_printed ++;
571
3bfcb652 572#ifdef HAVE_MBSTATE_T
7bfd842d
NC
573 /* Try to find out how many bytes made up the character that was
574 just printed. Advance the symbol pointer past the bytes that
575 were displayed. */
576 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
577#else
578 n = 1;
579#endif
7bfd842d
NC
580 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
581 symbol += (n - 1);
961c521f 582 }
961c521f 583 }
171191ba 584
7bfd842d 585 if (extra_padding && num_printed < width)
171191ba
NC
586 {
587 /* Fill in the remaining spaces. */
7bfd842d
NC
588 printf ("%-*s", width - num_printed, " ");
589 num_printed = width;
171191ba
NC
590 }
591
592 return num_printed;
31104126
NC
593}
594
1449284b 595/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
596 the given section's name. Like print_symbol, except that it does not try
597 to print multibyte characters, it just interprets them as hex values. */
598
599static const char *
dda8d76d 600printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
601{
602#define MAX_PRINT_SEC_NAME_LEN 128
603 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
604 const char * name = SECTION_NAME (sec);
605 char * buf = sec_name_buf;
606 char c;
607 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
608
609 while ((c = * name ++) != 0)
610 {
611 if (ISCNTRL (c))
612 {
613 if (remaining < 2)
614 break;
948f632f 615
74e1a04b
NC
616 * buf ++ = '^';
617 * buf ++ = c + 0x40;
618 remaining -= 2;
619 }
620 else if (ISPRINT (c))
621 {
622 * buf ++ = c;
623 remaining -= 1;
624 }
625 else
626 {
627 static char hex[17] = "0123456789ABCDEF";
628
629 if (remaining < 4)
630 break;
631 * buf ++ = '<';
632 * buf ++ = hex[(c & 0xf0) >> 4];
633 * buf ++ = hex[c & 0x0f];
634 * buf ++ = '>';
635 remaining -= 4;
636 }
637
638 if (remaining == 0)
639 break;
640 }
641
642 * buf = 0;
643 return sec_name_buf;
644}
645
646static const char *
dda8d76d 647printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 648{
dda8d76d 649 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
650 return _("<corrupt>");
651
dda8d76d 652 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
653}
654
89fac5e3
RS
655/* Return a pointer to section NAME, or NULL if no such section exists. */
656
657static Elf_Internal_Shdr *
dda8d76d 658find_section (Filedata * filedata, const char * name)
89fac5e3
RS
659{
660 unsigned int i;
661
68807c3c
NC
662 if (filedata->section_headers == NULL)
663 return NULL;
dda8d76d
NC
664
665 for (i = 0; i < filedata->file_header.e_shnum; i++)
666 if (streq (SECTION_NAME (filedata->section_headers + i), name))
667 return filedata->section_headers + i;
89fac5e3
RS
668
669 return NULL;
670}
671
0b6ae522
DJ
672/* Return a pointer to a section containing ADDR, or NULL if no such
673 section exists. */
674
675static Elf_Internal_Shdr *
dda8d76d 676find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
677{
678 unsigned int i;
679
68807c3c
NC
680 if (filedata->section_headers == NULL)
681 return NULL;
682
dda8d76d 683 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 684 {
dda8d76d
NC
685 Elf_Internal_Shdr *sec = filedata->section_headers + i;
686
0b6ae522
DJ
687 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
688 return sec;
689 }
690
691 return NULL;
692}
693
071436c6 694static Elf_Internal_Shdr *
dda8d76d 695find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
696{
697 unsigned int i;
698
68807c3c
NC
699 if (filedata->section_headers == NULL)
700 return NULL;
701
dda8d76d 702 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 703 {
dda8d76d
NC
704 Elf_Internal_Shdr *sec = filedata->section_headers + i;
705
071436c6
NC
706 if (sec->sh_type == type)
707 return sec;
708 }
709
710 return NULL;
711}
712
657d0d47
CC
713/* Return a pointer to section NAME, or NULL if no such section exists,
714 restricted to the list of sections given in SET. */
715
716static Elf_Internal_Shdr *
dda8d76d 717find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
718{
719 unsigned int i;
720
68807c3c
NC
721 if (filedata->section_headers == NULL)
722 return NULL;
723
657d0d47
CC
724 if (set != NULL)
725 {
726 while ((i = *set++) > 0)
b814a36d
NC
727 {
728 /* See PR 21156 for a reproducer. */
dda8d76d 729 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
730 continue; /* FIXME: Should we issue an error message ? */
731
dda8d76d
NC
732 if (streq (SECTION_NAME (filedata->section_headers + i), name))
733 return filedata->section_headers + i;
b814a36d 734 }
657d0d47
CC
735 }
736
dda8d76d 737 return find_section (filedata, name);
657d0d47
CC
738}
739
32ec8896
NC
740/* Read an unsigned LEB128 encoded value from DATA.
741 Set *LENGTH_RETURN to the number of bytes read. */
0b6ae522 742
f6f0e17b 743static inline unsigned long
32ec8896
NC
744read_uleb128 (unsigned char * data,
745 unsigned int * length_return,
f6f0e17b 746 const unsigned char * const end)
0b6ae522 747{
f6f0e17b 748 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
749}
750
32ec8896 751/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
752 This OS has so many departures from the ELF standard that we test it at
753 many places. */
754
32ec8896 755static inline bfd_boolean
dda8d76d 756is_ia64_vms (Filedata * filedata)
28f997cf 757{
dda8d76d
NC
758 return filedata->file_header.e_machine == EM_IA_64
759 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
760}
761
bcedfee6 762/* Guess the relocation size commonly used by the specific machines. */
252b5132 763
32ec8896 764static bfd_boolean
2dc4cec1 765guess_is_rela (unsigned int e_machine)
252b5132 766{
9c19a809 767 switch (e_machine)
252b5132
RH
768 {
769 /* Targets that use REL relocations. */
252b5132 770 case EM_386:
22abe556 771 case EM_IAMCU:
f954747f 772 case EM_960:
e9f53129 773 case EM_ARM:
2b0337b0 774 case EM_D10V:
252b5132 775 case EM_CYGNUS_D10V:
e9f53129 776 case EM_DLX:
252b5132 777 case EM_MIPS:
4fe85591 778 case EM_MIPS_RS3_LE:
e9f53129 779 case EM_CYGNUS_M32R:
1c0d3aa6 780 case EM_SCORE:
f6c1a2d5 781 case EM_XGATE:
fe944acf 782 case EM_NFP:
9c19a809 783 return FALSE;
103f02d3 784
252b5132
RH
785 /* Targets that use RELA relocations. */
786 case EM_68K:
f954747f 787 case EM_860:
a06ea964 788 case EM_AARCH64:
cfb8c092 789 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
790 case EM_ALPHA:
791 case EM_ALTERA_NIOS2:
886a2506
NC
792 case EM_ARC:
793 case EM_ARC_COMPACT:
794 case EM_ARC_COMPACT2:
e9f53129
AM
795 case EM_AVR:
796 case EM_AVR_OLD:
797 case EM_BLACKFIN:
60bca95a 798 case EM_CR16:
e9f53129
AM
799 case EM_CRIS:
800 case EM_CRX:
b8891f8d 801 case EM_CSKY:
2b0337b0 802 case EM_D30V:
252b5132 803 case EM_CYGNUS_D30V:
2b0337b0 804 case EM_FR30:
3f8107ab 805 case EM_FT32:
252b5132 806 case EM_CYGNUS_FR30:
5c70f934 807 case EM_CYGNUS_FRV:
e9f53129
AM
808 case EM_H8S:
809 case EM_H8_300:
810 case EM_H8_300H:
800eeca4 811 case EM_IA_64:
1e4cf259
NC
812 case EM_IP2K:
813 case EM_IP2K_OLD:
3b36097d 814 case EM_IQ2000:
84e94c90 815 case EM_LATTICEMICO32:
ff7eeb89 816 case EM_M32C_OLD:
49f58d10 817 case EM_M32C:
e9f53129
AM
818 case EM_M32R:
819 case EM_MCORE:
15ab5209 820 case EM_CYGNUS_MEP:
a3c62988 821 case EM_METAG:
e9f53129
AM
822 case EM_MMIX:
823 case EM_MN10200:
824 case EM_CYGNUS_MN10200:
825 case EM_MN10300:
826 case EM_CYGNUS_MN10300:
5506d11a 827 case EM_MOXIE:
e9f53129
AM
828 case EM_MSP430:
829 case EM_MSP430_OLD:
d031aafb 830 case EM_MT:
35c08157 831 case EM_NDS32:
64fd6348 832 case EM_NIOS32:
73589c9d 833 case EM_OR1K:
e9f53129
AM
834 case EM_PPC64:
835 case EM_PPC:
2b100bb5 836 case EM_TI_PRU:
e23eba97 837 case EM_RISCV:
99c513f6 838 case EM_RL78:
c7927a3c 839 case EM_RX:
e9f53129
AM
840 case EM_S390:
841 case EM_S390_OLD:
842 case EM_SH:
843 case EM_SPARC:
844 case EM_SPARC32PLUS:
845 case EM_SPARCV9:
846 case EM_SPU:
40b36596 847 case EM_TI_C6000:
aa137e4d
NC
848 case EM_TILEGX:
849 case EM_TILEPRO:
708e2187 850 case EM_V800:
e9f53129
AM
851 case EM_V850:
852 case EM_CYGNUS_V850:
853 case EM_VAX:
619ed720 854 case EM_VISIUM:
e9f53129 855 case EM_X86_64:
8a9036a4 856 case EM_L1OM:
7a9068fe 857 case EM_K1OM:
e9f53129
AM
858 case EM_XSTORMY16:
859 case EM_XTENSA:
860 case EM_XTENSA_OLD:
7ba29e2a
NC
861 case EM_MICROBLAZE:
862 case EM_MICROBLAZE_OLD:
f96bd6c2 863 case EM_WEBASSEMBLY:
9c19a809 864 return TRUE;
103f02d3 865
e9f53129
AM
866 case EM_68HC05:
867 case EM_68HC08:
868 case EM_68HC11:
869 case EM_68HC16:
870 case EM_FX66:
871 case EM_ME16:
d1133906 872 case EM_MMA:
d1133906
NC
873 case EM_NCPU:
874 case EM_NDR1:
e9f53129 875 case EM_PCP:
d1133906 876 case EM_ST100:
e9f53129 877 case EM_ST19:
d1133906 878 case EM_ST7:
e9f53129
AM
879 case EM_ST9PLUS:
880 case EM_STARCORE:
d1133906 881 case EM_SVX:
e9f53129 882 case EM_TINYJ:
9c19a809
NC
883 default:
884 warn (_("Don't know about relocations on this machine architecture\n"));
885 return FALSE;
886 }
887}
252b5132 888
dda8d76d 889/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
890 Returns TRUE upon success, FALSE otherwise. If successful then a
891 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
892 and the number of relocs loaded is placed in *NRELASP. It is the caller's
893 responsibility to free the allocated buffer. */
894
895static bfd_boolean
dda8d76d
NC
896slurp_rela_relocs (Filedata * filedata,
897 unsigned long rel_offset,
898 unsigned long rel_size,
899 Elf_Internal_Rela ** relasp,
900 unsigned long * nrelasp)
9c19a809 901{
2cf0635d 902 Elf_Internal_Rela * relas;
8b73c356 903 size_t nrelas;
4d6ed7c8 904 unsigned int i;
252b5132 905
4d6ed7c8
NC
906 if (is_32bit_elf)
907 {
2cf0635d 908 Elf32_External_Rela * erelas;
103f02d3 909
dda8d76d 910 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 911 rel_size, _("32-bit relocation data"));
a6e9f9df 912 if (!erelas)
32ec8896 913 return FALSE;
252b5132 914
4d6ed7c8 915 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 916
3f5e193b
NC
917 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
918 sizeof (Elf_Internal_Rela));
103f02d3 919
4d6ed7c8
NC
920 if (relas == NULL)
921 {
c256ffe7 922 free (erelas);
591a748a 923 error (_("out of memory parsing relocs\n"));
32ec8896 924 return FALSE;
4d6ed7c8 925 }
103f02d3 926
4d6ed7c8
NC
927 for (i = 0; i < nrelas; i++)
928 {
929 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
930 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 931 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 932 }
103f02d3 933
4d6ed7c8
NC
934 free (erelas);
935 }
936 else
937 {
2cf0635d 938 Elf64_External_Rela * erelas;
103f02d3 939
dda8d76d 940 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 941 rel_size, _("64-bit relocation data"));
a6e9f9df 942 if (!erelas)
32ec8896 943 return FALSE;
4d6ed7c8
NC
944
945 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 946
3f5e193b
NC
947 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
948 sizeof (Elf_Internal_Rela));
103f02d3 949
4d6ed7c8
NC
950 if (relas == NULL)
951 {
c256ffe7 952 free (erelas);
591a748a 953 error (_("out of memory parsing relocs\n"));
32ec8896 954 return FALSE;
9c19a809 955 }
4d6ed7c8
NC
956
957 for (i = 0; i < nrelas; i++)
9c19a809 958 {
66543521
AM
959 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
960 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 961 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
962
963 /* The #ifdef BFD64 below is to prevent a compile time
964 warning. We know that if we do not have a 64 bit data
965 type that we will never execute this code anyway. */
966#ifdef BFD64
dda8d76d
NC
967 if (filedata->file_header.e_machine == EM_MIPS
968 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
969 {
970 /* In little-endian objects, r_info isn't really a
971 64-bit little-endian value: it has a 32-bit
972 little-endian symbol index followed by four
973 individual byte fields. Reorder INFO
974 accordingly. */
91d6fa6a
NC
975 bfd_vma inf = relas[i].r_info;
976 inf = (((inf & 0xffffffff) << 32)
977 | ((inf >> 56) & 0xff)
978 | ((inf >> 40) & 0xff00)
979 | ((inf >> 24) & 0xff0000)
980 | ((inf >> 8) & 0xff000000));
981 relas[i].r_info = inf;
861fb55a
DJ
982 }
983#endif /* BFD64 */
4d6ed7c8 984 }
103f02d3 985
4d6ed7c8
NC
986 free (erelas);
987 }
32ec8896 988
4d6ed7c8
NC
989 *relasp = relas;
990 *nrelasp = nrelas;
32ec8896 991 return TRUE;
4d6ed7c8 992}
103f02d3 993
dda8d76d 994/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
995 Returns TRUE upon success, FALSE otherwise. If successful then a
996 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
997 and the number of relocs loaded is placed in *NRELSP. It is the caller's
998 responsibility to free the allocated buffer. */
999
1000static bfd_boolean
dda8d76d
NC
1001slurp_rel_relocs (Filedata * filedata,
1002 unsigned long rel_offset,
1003 unsigned long rel_size,
1004 Elf_Internal_Rela ** relsp,
1005 unsigned long * nrelsp)
4d6ed7c8 1006{
2cf0635d 1007 Elf_Internal_Rela * rels;
8b73c356 1008 size_t nrels;
4d6ed7c8 1009 unsigned int i;
103f02d3 1010
4d6ed7c8
NC
1011 if (is_32bit_elf)
1012 {
2cf0635d 1013 Elf32_External_Rel * erels;
103f02d3 1014
dda8d76d 1015 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1016 rel_size, _("32-bit relocation data"));
a6e9f9df 1017 if (!erels)
32ec8896 1018 return FALSE;
103f02d3 1019
4d6ed7c8 1020 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1021
3f5e193b 1022 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1023
4d6ed7c8
NC
1024 if (rels == NULL)
1025 {
c256ffe7 1026 free (erels);
591a748a 1027 error (_("out of memory parsing relocs\n"));
32ec8896 1028 return FALSE;
4d6ed7c8
NC
1029 }
1030
1031 for (i = 0; i < nrels; i++)
1032 {
1033 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1034 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1035 rels[i].r_addend = 0;
9ea033b2 1036 }
4d6ed7c8
NC
1037
1038 free (erels);
9c19a809
NC
1039 }
1040 else
1041 {
2cf0635d 1042 Elf64_External_Rel * erels;
9ea033b2 1043
dda8d76d 1044 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1045 rel_size, _("64-bit relocation data"));
a6e9f9df 1046 if (!erels)
32ec8896 1047 return FALSE;
103f02d3 1048
4d6ed7c8 1049 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1050
3f5e193b 1051 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1052
4d6ed7c8 1053 if (rels == NULL)
9c19a809 1054 {
c256ffe7 1055 free (erels);
591a748a 1056 error (_("out of memory parsing relocs\n"));
32ec8896 1057 return FALSE;
4d6ed7c8 1058 }
103f02d3 1059
4d6ed7c8
NC
1060 for (i = 0; i < nrels; i++)
1061 {
66543521
AM
1062 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1063 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1064 rels[i].r_addend = 0;
861fb55a
DJ
1065
1066 /* The #ifdef BFD64 below is to prevent a compile time
1067 warning. We know that if we do not have a 64 bit data
1068 type that we will never execute this code anyway. */
1069#ifdef BFD64
dda8d76d
NC
1070 if (filedata->file_header.e_machine == EM_MIPS
1071 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1072 {
1073 /* In little-endian objects, r_info isn't really a
1074 64-bit little-endian value: it has a 32-bit
1075 little-endian symbol index followed by four
1076 individual byte fields. Reorder INFO
1077 accordingly. */
91d6fa6a
NC
1078 bfd_vma inf = rels[i].r_info;
1079 inf = (((inf & 0xffffffff) << 32)
1080 | ((inf >> 56) & 0xff)
1081 | ((inf >> 40) & 0xff00)
1082 | ((inf >> 24) & 0xff0000)
1083 | ((inf >> 8) & 0xff000000));
1084 rels[i].r_info = inf;
861fb55a
DJ
1085 }
1086#endif /* BFD64 */
4d6ed7c8 1087 }
103f02d3 1088
4d6ed7c8
NC
1089 free (erels);
1090 }
32ec8896 1091
4d6ed7c8
NC
1092 *relsp = rels;
1093 *nrelsp = nrels;
32ec8896 1094 return TRUE;
4d6ed7c8 1095}
103f02d3 1096
aca88567
NC
1097/* Returns the reloc type extracted from the reloc info field. */
1098
1099static unsigned int
dda8d76d 1100get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1101{
1102 if (is_32bit_elf)
1103 return ELF32_R_TYPE (reloc_info);
1104
dda8d76d 1105 switch (filedata->file_header.e_machine)
aca88567
NC
1106 {
1107 case EM_MIPS:
1108 /* Note: We assume that reloc_info has already been adjusted for us. */
1109 return ELF64_MIPS_R_TYPE (reloc_info);
1110
1111 case EM_SPARCV9:
1112 return ELF64_R_TYPE_ID (reloc_info);
1113
1114 default:
1115 return ELF64_R_TYPE (reloc_info);
1116 }
1117}
1118
1119/* Return the symbol index extracted from the reloc info field. */
1120
1121static bfd_vma
1122get_reloc_symindex (bfd_vma reloc_info)
1123{
1124 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1125}
1126
13761a11 1127static inline bfd_boolean
dda8d76d 1128uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1129{
1130 return
dda8d76d 1131 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1132 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1133 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1134 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1135 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1136}
1137
d3ba0551
AM
1138/* Display the contents of the relocation data found at the specified
1139 offset. */
ee42cf8c 1140
32ec8896 1141static bfd_boolean
dda8d76d
NC
1142dump_relocations (Filedata * filedata,
1143 unsigned long rel_offset,
1144 unsigned long rel_size,
1145 Elf_Internal_Sym * symtab,
1146 unsigned long nsyms,
1147 char * strtab,
1148 unsigned long strtablen,
1149 int is_rela,
1150 bfd_boolean is_dynsym)
4d6ed7c8 1151{
32ec8896 1152 unsigned long i;
2cf0635d 1153 Elf_Internal_Rela * rels;
32ec8896 1154 bfd_boolean res = TRUE;
103f02d3 1155
4d6ed7c8 1156 if (is_rela == UNKNOWN)
dda8d76d 1157 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1158
4d6ed7c8
NC
1159 if (is_rela)
1160 {
dda8d76d 1161 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1162 return FALSE;
4d6ed7c8
NC
1163 }
1164 else
1165 {
dda8d76d 1166 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1167 return FALSE;
252b5132
RH
1168 }
1169
410f7a12
L
1170 if (is_32bit_elf)
1171 {
1172 if (is_rela)
2c71103e
NC
1173 {
1174 if (do_wide)
1175 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1176 else
1177 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1178 }
410f7a12 1179 else
2c71103e
NC
1180 {
1181 if (do_wide)
1182 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1183 else
1184 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1185 }
410f7a12 1186 }
252b5132 1187 else
410f7a12
L
1188 {
1189 if (is_rela)
2c71103e
NC
1190 {
1191 if (do_wide)
8beeaeb7 1192 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1193 else
1194 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1195 }
410f7a12 1196 else
2c71103e
NC
1197 {
1198 if (do_wide)
8beeaeb7 1199 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1200 else
1201 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1202 }
410f7a12 1203 }
252b5132
RH
1204
1205 for (i = 0; i < rel_size; i++)
1206 {
2cf0635d 1207 const char * rtype;
b34976b6 1208 bfd_vma offset;
91d6fa6a 1209 bfd_vma inf;
b34976b6
AM
1210 bfd_vma symtab_index;
1211 bfd_vma type;
103f02d3 1212
b34976b6 1213 offset = rels[i].r_offset;
91d6fa6a 1214 inf = rels[i].r_info;
103f02d3 1215
dda8d76d 1216 type = get_reloc_type (filedata, inf);
91d6fa6a 1217 symtab_index = get_reloc_symindex (inf);
252b5132 1218
410f7a12
L
1219 if (is_32bit_elf)
1220 {
39dbeff8
AM
1221 printf ("%8.8lx %8.8lx ",
1222 (unsigned long) offset & 0xffffffff,
91d6fa6a 1223 (unsigned long) inf & 0xffffffff);
410f7a12
L
1224 }
1225 else
1226 {
39dbeff8
AM
1227#if BFD_HOST_64BIT_LONG
1228 printf (do_wide
1229 ? "%16.16lx %16.16lx "
1230 : "%12.12lx %12.12lx ",
91d6fa6a 1231 offset, inf);
39dbeff8 1232#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1233#ifndef __MSVCRT__
39dbeff8
AM
1234 printf (do_wide
1235 ? "%16.16llx %16.16llx "
1236 : "%12.12llx %12.12llx ",
91d6fa6a 1237 offset, inf);
6e3d6dc1
NC
1238#else
1239 printf (do_wide
1240 ? "%16.16I64x %16.16I64x "
1241 : "%12.12I64x %12.12I64x ",
91d6fa6a 1242 offset, inf);
6e3d6dc1 1243#endif
39dbeff8 1244#else
2c71103e
NC
1245 printf (do_wide
1246 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1247 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1248 _bfd_int64_high (offset),
1249 _bfd_int64_low (offset),
91d6fa6a
NC
1250 _bfd_int64_high (inf),
1251 _bfd_int64_low (inf));
9ea033b2 1252#endif
410f7a12 1253 }
103f02d3 1254
dda8d76d 1255 switch (filedata->file_header.e_machine)
252b5132
RH
1256 {
1257 default:
1258 rtype = NULL;
1259 break;
1260
a06ea964
NC
1261 case EM_AARCH64:
1262 rtype = elf_aarch64_reloc_type (type);
1263 break;
1264
2b0337b0 1265 case EM_M32R:
252b5132 1266 case EM_CYGNUS_M32R:
9ea033b2 1267 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1268 break;
1269
1270 case EM_386:
22abe556 1271 case EM_IAMCU:
9ea033b2 1272 rtype = elf_i386_reloc_type (type);
252b5132
RH
1273 break;
1274
ba2685cc
AM
1275 case EM_68HC11:
1276 case EM_68HC12:
1277 rtype = elf_m68hc11_reloc_type (type);
1278 break;
75751cd9 1279
7b4ae824
JD
1280 case EM_S12Z:
1281 rtype = elf_s12z_reloc_type (type);
1282 break;
1283
252b5132 1284 case EM_68K:
9ea033b2 1285 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1286 break;
1287
f954747f
AM
1288 case EM_960:
1289 rtype = elf_i960_reloc_type (type);
1290 break;
1291
adde6300 1292 case EM_AVR:
2b0337b0 1293 case EM_AVR_OLD:
adde6300
AM
1294 rtype = elf_avr_reloc_type (type);
1295 break;
1296
9ea033b2
NC
1297 case EM_OLD_SPARCV9:
1298 case EM_SPARC32PLUS:
1299 case EM_SPARCV9:
252b5132 1300 case EM_SPARC:
9ea033b2 1301 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1302 break;
1303
e9f53129
AM
1304 case EM_SPU:
1305 rtype = elf_spu_reloc_type (type);
1306 break;
1307
708e2187
NC
1308 case EM_V800:
1309 rtype = v800_reloc_type (type);
1310 break;
2b0337b0 1311 case EM_V850:
252b5132 1312 case EM_CYGNUS_V850:
9ea033b2 1313 rtype = v850_reloc_type (type);
252b5132
RH
1314 break;
1315
2b0337b0 1316 case EM_D10V:
252b5132 1317 case EM_CYGNUS_D10V:
9ea033b2 1318 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1319 break;
1320
2b0337b0 1321 case EM_D30V:
252b5132 1322 case EM_CYGNUS_D30V:
9ea033b2 1323 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1324 break;
1325
d172d4ba
NC
1326 case EM_DLX:
1327 rtype = elf_dlx_reloc_type (type);
1328 break;
1329
252b5132 1330 case EM_SH:
9ea033b2 1331 rtype = elf_sh_reloc_type (type);
252b5132
RH
1332 break;
1333
2b0337b0 1334 case EM_MN10300:
252b5132 1335 case EM_CYGNUS_MN10300:
9ea033b2 1336 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1337 break;
1338
2b0337b0 1339 case EM_MN10200:
252b5132 1340 case EM_CYGNUS_MN10200:
9ea033b2 1341 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1342 break;
1343
2b0337b0 1344 case EM_FR30:
252b5132 1345 case EM_CYGNUS_FR30:
9ea033b2 1346 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1347 break;
1348
ba2685cc
AM
1349 case EM_CYGNUS_FRV:
1350 rtype = elf_frv_reloc_type (type);
1351 break;
5c70f934 1352
b8891f8d
AJ
1353 case EM_CSKY:
1354 rtype = elf_csky_reloc_type (type);
1355 break;
1356
3f8107ab
AM
1357 case EM_FT32:
1358 rtype = elf_ft32_reloc_type (type);
1359 break;
1360
252b5132 1361 case EM_MCORE:
9ea033b2 1362 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1363 break;
1364
3c3bdf30
NC
1365 case EM_MMIX:
1366 rtype = elf_mmix_reloc_type (type);
1367 break;
1368
5506d11a
AM
1369 case EM_MOXIE:
1370 rtype = elf_moxie_reloc_type (type);
1371 break;
1372
2469cfa2 1373 case EM_MSP430:
dda8d76d 1374 if (uses_msp430x_relocs (filedata))
13761a11
NC
1375 {
1376 rtype = elf_msp430x_reloc_type (type);
1377 break;
1378 }
1a0670f3 1379 /* Fall through. */
2469cfa2
NC
1380 case EM_MSP430_OLD:
1381 rtype = elf_msp430_reloc_type (type);
1382 break;
1383
35c08157
KLC
1384 case EM_NDS32:
1385 rtype = elf_nds32_reloc_type (type);
1386 break;
1387
252b5132 1388 case EM_PPC:
9ea033b2 1389 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1390 break;
1391
c833c019
AM
1392 case EM_PPC64:
1393 rtype = elf_ppc64_reloc_type (type);
1394 break;
1395
252b5132 1396 case EM_MIPS:
4fe85591 1397 case EM_MIPS_RS3_LE:
9ea033b2 1398 rtype = elf_mips_reloc_type (type);
252b5132
RH
1399 break;
1400
e23eba97
NC
1401 case EM_RISCV:
1402 rtype = elf_riscv_reloc_type (type);
1403 break;
1404
252b5132 1405 case EM_ALPHA:
9ea033b2 1406 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1407 break;
1408
1409 case EM_ARM:
9ea033b2 1410 rtype = elf_arm_reloc_type (type);
252b5132
RH
1411 break;
1412
584da044 1413 case EM_ARC:
886a2506
NC
1414 case EM_ARC_COMPACT:
1415 case EM_ARC_COMPACT2:
9ea033b2 1416 rtype = elf_arc_reloc_type (type);
252b5132
RH
1417 break;
1418
1419 case EM_PARISC:
69e617ca 1420 rtype = elf_hppa_reloc_type (type);
252b5132 1421 break;
7d466069 1422
b8720f9d
JL
1423 case EM_H8_300:
1424 case EM_H8_300H:
1425 case EM_H8S:
1426 rtype = elf_h8_reloc_type (type);
1427 break;
1428
73589c9d
CS
1429 case EM_OR1K:
1430 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1431 break;
1432
7d466069 1433 case EM_PJ:
2b0337b0 1434 case EM_PJ_OLD:
7d466069
ILT
1435 rtype = elf_pj_reloc_type (type);
1436 break;
800eeca4
JW
1437 case EM_IA_64:
1438 rtype = elf_ia64_reloc_type (type);
1439 break;
1b61cf92
HPN
1440
1441 case EM_CRIS:
1442 rtype = elf_cris_reloc_type (type);
1443 break;
535c37ff 1444
f954747f
AM
1445 case EM_860:
1446 rtype = elf_i860_reloc_type (type);
1447 break;
1448
bcedfee6 1449 case EM_X86_64:
8a9036a4 1450 case EM_L1OM:
7a9068fe 1451 case EM_K1OM:
bcedfee6
NC
1452 rtype = elf_x86_64_reloc_type (type);
1453 break;
a85d7ed0 1454
f954747f
AM
1455 case EM_S370:
1456 rtype = i370_reloc_type (type);
1457 break;
1458
53c7db4b
KH
1459 case EM_S390_OLD:
1460 case EM_S390:
1461 rtype = elf_s390_reloc_type (type);
1462 break;
93fbbb04 1463
1c0d3aa6
NC
1464 case EM_SCORE:
1465 rtype = elf_score_reloc_type (type);
1466 break;
1467
93fbbb04
GK
1468 case EM_XSTORMY16:
1469 rtype = elf_xstormy16_reloc_type (type);
1470 break;
179d3252 1471
1fe1f39c
NC
1472 case EM_CRX:
1473 rtype = elf_crx_reloc_type (type);
1474 break;
1475
179d3252
JT
1476 case EM_VAX:
1477 rtype = elf_vax_reloc_type (type);
1478 break;
1e4cf259 1479
619ed720
EB
1480 case EM_VISIUM:
1481 rtype = elf_visium_reloc_type (type);
1482 break;
1483
cfb8c092
NC
1484 case EM_ADAPTEVA_EPIPHANY:
1485 rtype = elf_epiphany_reloc_type (type);
1486 break;
1487
1e4cf259
NC
1488 case EM_IP2K:
1489 case EM_IP2K_OLD:
1490 rtype = elf_ip2k_reloc_type (type);
1491 break;
3b36097d
SC
1492
1493 case EM_IQ2000:
1494 rtype = elf_iq2000_reloc_type (type);
1495 break;
88da6820
NC
1496
1497 case EM_XTENSA_OLD:
1498 case EM_XTENSA:
1499 rtype = elf_xtensa_reloc_type (type);
1500 break;
a34e3ecb 1501
84e94c90
NC
1502 case EM_LATTICEMICO32:
1503 rtype = elf_lm32_reloc_type (type);
1504 break;
1505
ff7eeb89 1506 case EM_M32C_OLD:
49f58d10
JB
1507 case EM_M32C:
1508 rtype = elf_m32c_reloc_type (type);
1509 break;
1510
d031aafb
NS
1511 case EM_MT:
1512 rtype = elf_mt_reloc_type (type);
a34e3ecb 1513 break;
1d65ded4
CM
1514
1515 case EM_BLACKFIN:
1516 rtype = elf_bfin_reloc_type (type);
1517 break;
15ab5209
DB
1518
1519 case EM_CYGNUS_MEP:
1520 rtype = elf_mep_reloc_type (type);
1521 break;
60bca95a
NC
1522
1523 case EM_CR16:
1524 rtype = elf_cr16_reloc_type (type);
1525 break;
dd24e3da 1526
7ba29e2a
NC
1527 case EM_MICROBLAZE:
1528 case EM_MICROBLAZE_OLD:
1529 rtype = elf_microblaze_reloc_type (type);
1530 break;
c7927a3c 1531
99c513f6
DD
1532 case EM_RL78:
1533 rtype = elf_rl78_reloc_type (type);
1534 break;
1535
c7927a3c
NC
1536 case EM_RX:
1537 rtype = elf_rx_reloc_type (type);
1538 break;
c29aca4a 1539
a3c62988
NC
1540 case EM_METAG:
1541 rtype = elf_metag_reloc_type (type);
1542 break;
1543
c29aca4a
NC
1544 case EM_XC16X:
1545 case EM_C166:
1546 rtype = elf_xc16x_reloc_type (type);
1547 break;
40b36596
JM
1548
1549 case EM_TI_C6000:
1550 rtype = elf_tic6x_reloc_type (type);
1551 break;
aa137e4d
NC
1552
1553 case EM_TILEGX:
1554 rtype = elf_tilegx_reloc_type (type);
1555 break;
1556
1557 case EM_TILEPRO:
1558 rtype = elf_tilepro_reloc_type (type);
1559 break;
f6c1a2d5 1560
f96bd6c2
PC
1561 case EM_WEBASSEMBLY:
1562 rtype = elf_wasm32_reloc_type (type);
1563 break;
1564
f6c1a2d5
NC
1565 case EM_XGATE:
1566 rtype = elf_xgate_reloc_type (type);
1567 break;
36591ba1
SL
1568
1569 case EM_ALTERA_NIOS2:
1570 rtype = elf_nios2_reloc_type (type);
1571 break;
2b100bb5
DD
1572
1573 case EM_TI_PRU:
1574 rtype = elf_pru_reloc_type (type);
1575 break;
fe944acf
FT
1576
1577 case EM_NFP:
1578 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1579 rtype = elf_nfp3200_reloc_type (type);
1580 else
1581 rtype = elf_nfp_reloc_type (type);
1582 break;
252b5132
RH
1583 }
1584
1585 if (rtype == NULL)
39dbeff8 1586 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1587 else
5c144731 1588 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1589
dda8d76d 1590 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1591 && rtype != NULL
7ace3541
RH
1592 && streq (rtype, "R_ALPHA_LITUSE")
1593 && is_rela)
1594 {
1595 switch (rels[i].r_addend)
1596 {
1597 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1598 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1599 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1600 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1601 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1602 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1603 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1604 default: rtype = NULL;
1605 }
32ec8896 1606
7ace3541
RH
1607 if (rtype)
1608 printf (" (%s)", rtype);
1609 else
1610 {
1611 putchar (' ');
1612 printf (_("<unknown addend: %lx>"),
1613 (unsigned long) rels[i].r_addend);
32ec8896 1614 res = FALSE;
7ace3541
RH
1615 }
1616 }
1617 else if (symtab_index)
252b5132 1618 {
af3fc3bc 1619 if (symtab == NULL || symtab_index >= nsyms)
32ec8896
NC
1620 {
1621 error (_(" bad symbol index: %08lx in reloc"), (unsigned long) symtab_index);
1622 res = FALSE;
1623 }
af3fc3bc 1624 else
19936277 1625 {
2cf0635d 1626 Elf_Internal_Sym * psym;
bb4d2ac2
L
1627 const char * version_string;
1628 enum versioned_symbol_info sym_info;
1629 unsigned short vna_other;
19936277 1630
af3fc3bc 1631 psym = symtab + symtab_index;
103f02d3 1632
bb4d2ac2 1633 version_string
dda8d76d 1634 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1635 strtab, strtablen,
1636 symtab_index,
1637 psym,
1638 &sym_info,
1639 &vna_other);
1640
af3fc3bc 1641 printf (" ");
171191ba 1642
d8045f23
NC
1643 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1644 {
1645 const char * name;
1646 unsigned int len;
1647 unsigned int width = is_32bit_elf ? 8 : 14;
1648
1649 /* Relocations against GNU_IFUNC symbols do not use the value
1650 of the symbol as the address to relocate against. Instead
1651 they invoke the function named by the symbol and use its
1652 result as the address for relocation.
1653
1654 To indicate this to the user, do not display the value of
1655 the symbol in the "Symbols's Value" field. Instead show
1656 its name followed by () as a hint that the symbol is
1657 invoked. */
1658
1659 if (strtab == NULL
1660 || psym->st_name == 0
1661 || psym->st_name >= strtablen)
1662 name = "??";
1663 else
1664 name = strtab + psym->st_name;
1665
1666 len = print_symbol (width, name);
bb4d2ac2
L
1667 if (version_string)
1668 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1669 version_string);
d8045f23
NC
1670 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1671 }
1672 else
1673 {
1674 print_vma (psym->st_value, LONG_HEX);
171191ba 1675
d8045f23
NC
1676 printf (is_32bit_elf ? " " : " ");
1677 }
103f02d3 1678
af3fc3bc 1679 if (psym->st_name == 0)
f1ef08cb 1680 {
2cf0635d 1681 const char * sec_name = "<null>";
f1ef08cb
AM
1682 char name_buf[40];
1683
1684 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1685 {
dda8d76d
NC
1686 if (psym->st_shndx < filedata->file_header.e_shnum)
1687 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1688 else if (psym->st_shndx == SHN_ABS)
1689 sec_name = "ABS";
1690 else if (psym->st_shndx == SHN_COMMON)
1691 sec_name = "COMMON";
dda8d76d 1692 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1693 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1694 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1695 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1696 sec_name = "SCOMMON";
dda8d76d 1697 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1698 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1699 sec_name = "SUNDEF";
dda8d76d
NC
1700 else if ((filedata->file_header.e_machine == EM_X86_64
1701 || filedata->file_header.e_machine == EM_L1OM
1702 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1703 && psym->st_shndx == SHN_X86_64_LCOMMON)
1704 sec_name = "LARGE_COMMON";
dda8d76d
NC
1705 else if (filedata->file_header.e_machine == EM_IA_64
1706 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1707 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1708 sec_name = "ANSI_COM";
dda8d76d 1709 else if (is_ia64_vms (filedata)
148b93f2
NC
1710 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1711 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1712 else
1713 {
1714 sprintf (name_buf, "<section 0x%x>",
1715 (unsigned int) psym->st_shndx);
1716 sec_name = name_buf;
1717 }
1718 }
1719 print_symbol (22, sec_name);
1720 }
af3fc3bc 1721 else if (strtab == NULL)
d79b3d50 1722 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1723 else if (psym->st_name >= strtablen)
32ec8896
NC
1724 {
1725 error (_("<corrupt string table index: %3ld>"), psym->st_name);
1726 res = FALSE;
1727 }
af3fc3bc 1728 else
bb4d2ac2
L
1729 {
1730 print_symbol (22, strtab + psym->st_name);
1731 if (version_string)
1732 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1733 version_string);
1734 }
103f02d3 1735
af3fc3bc 1736 if (is_rela)
171191ba 1737 {
7360e63f 1738 bfd_vma off = rels[i].r_addend;
171191ba 1739
7360e63f 1740 if ((bfd_signed_vma) off < 0)
598aaa76 1741 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1742 else
598aaa76 1743 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1744 }
19936277 1745 }
252b5132 1746 }
1b228002 1747 else if (is_rela)
f7a99963 1748 {
7360e63f 1749 bfd_vma off = rels[i].r_addend;
e04d7088
L
1750
1751 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1752 if ((bfd_signed_vma) off < 0)
e04d7088
L
1753 printf ("-%" BFD_VMA_FMT "x", - off);
1754 else
1755 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1756 }
252b5132 1757
dda8d76d 1758 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1759 && rtype != NULL
1760 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1761 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1762
252b5132 1763 putchar ('\n');
2c71103e 1764
aca88567 1765#ifdef BFD64
dda8d76d 1766 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1767 {
91d6fa6a
NC
1768 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1769 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1770 const char * rtype2 = elf_mips_reloc_type (type2);
1771 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1772
2c71103e
NC
1773 printf (" Type2: ");
1774
1775 if (rtype2 == NULL)
39dbeff8
AM
1776 printf (_("unrecognized: %-7lx"),
1777 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1778 else
1779 printf ("%-17.17s", rtype2);
1780
18bd398b 1781 printf ("\n Type3: ");
2c71103e
NC
1782
1783 if (rtype3 == NULL)
39dbeff8
AM
1784 printf (_("unrecognized: %-7lx"),
1785 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1786 else
1787 printf ("%-17.17s", rtype3);
1788
53c7db4b 1789 putchar ('\n');
2c71103e 1790 }
aca88567 1791#endif /* BFD64 */
252b5132
RH
1792 }
1793
c8286bd1 1794 free (rels);
32ec8896
NC
1795
1796 return res;
252b5132
RH
1797}
1798
1799static const char *
d3ba0551 1800get_mips_dynamic_type (unsigned long type)
252b5132
RH
1801{
1802 switch (type)
1803 {
1804 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1805 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1806 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1807 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1808 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1809 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1810 case DT_MIPS_MSYM: return "MIPS_MSYM";
1811 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1812 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1813 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1814 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1815 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1816 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1817 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1818 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1819 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1820 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1821 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1822 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1823 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1824 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1825 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1826 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1827 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1828 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1829 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1830 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1831 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1832 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1833 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1834 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1835 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1836 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1837 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1838 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1839 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1840 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1841 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1842 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1843 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1844 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1845 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1846 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1847 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1848 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1849 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1850 default:
1851 return NULL;
1852 }
1853}
1854
9a097730 1855static const char *
d3ba0551 1856get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1857{
1858 switch (type)
1859 {
1860 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1861 default:
1862 return NULL;
1863 }
103f02d3
UD
1864}
1865
7490d522
AM
1866static const char *
1867get_ppc_dynamic_type (unsigned long type)
1868{
1869 switch (type)
1870 {
a7f2871e 1871 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1872 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1873 default:
1874 return NULL;
1875 }
1876}
1877
f1cb7e17 1878static const char *
d3ba0551 1879get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1880{
1881 switch (type)
1882 {
a7f2871e
AM
1883 case DT_PPC64_GLINK: return "PPC64_GLINK";
1884 case DT_PPC64_OPD: return "PPC64_OPD";
1885 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1886 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1887 default:
1888 return NULL;
1889 }
1890}
1891
103f02d3 1892static const char *
d3ba0551 1893get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1894{
1895 switch (type)
1896 {
1897 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1898 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1899 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1900 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1901 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1902 case DT_HP_PREINIT: return "HP_PREINIT";
1903 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1904 case DT_HP_NEEDED: return "HP_NEEDED";
1905 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1906 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1907 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1908 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1909 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1910 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1911 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1912 case DT_HP_FILTERED: return "HP_FILTERED";
1913 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1914 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1915 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1916 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1917 case DT_PLT: return "PLT";
1918 case DT_PLT_SIZE: return "PLT_SIZE";
1919 case DT_DLT: return "DLT";
1920 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1921 default:
1922 return NULL;
1923 }
1924}
9a097730 1925
ecc51f48 1926static const char *
d3ba0551 1927get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1928{
1929 switch (type)
1930 {
148b93f2
NC
1931 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1932 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1933 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1934 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1935 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1936 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1937 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1938 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1939 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1940 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1941 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1942 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1943 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1944 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1945 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1946 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1947 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1948 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1949 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1950 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1951 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1952 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1953 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1954 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1955 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1956 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1957 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1958 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1959 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1960 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1961 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1962 default:
1963 return NULL;
1964 }
1965}
1966
fd85a6a1
NC
1967static const char *
1968get_solaris_section_type (unsigned long type)
1969{
1970 switch (type)
1971 {
1972 case 0x6fffffee: return "SUNW_ancillary";
1973 case 0x6fffffef: return "SUNW_capchain";
1974 case 0x6ffffff0: return "SUNW_capinfo";
1975 case 0x6ffffff1: return "SUNW_symsort";
1976 case 0x6ffffff2: return "SUNW_tlssort";
1977 case 0x6ffffff3: return "SUNW_LDYNSYM";
1978 case 0x6ffffff4: return "SUNW_dof";
1979 case 0x6ffffff5: return "SUNW_cap";
1980 case 0x6ffffff6: return "SUNW_SIGNATURE";
1981 case 0x6ffffff7: return "SUNW_ANNOTATE";
1982 case 0x6ffffff8: return "SUNW_DEBUGSTR";
1983 case 0x6ffffff9: return "SUNW_DEBUG";
1984 case 0x6ffffffa: return "SUNW_move";
1985 case 0x6ffffffb: return "SUNW_COMDAT";
1986 case 0x6ffffffc: return "SUNW_syminfo";
1987 case 0x6ffffffd: return "SUNW_verdef";
1988 case 0x6ffffffe: return "SUNW_verneed";
1989 case 0x6fffffff: return "SUNW_versym";
1990 case 0x70000000: return "SPARC_GOTDATA";
1991 default: return NULL;
1992 }
1993}
1994
fabcb361
RH
1995static const char *
1996get_alpha_dynamic_type (unsigned long type)
1997{
1998 switch (type)
1999 {
2000 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2001 default: return NULL;
fabcb361
RH
2002 }
2003}
2004
1c0d3aa6
NC
2005static const char *
2006get_score_dynamic_type (unsigned long type)
2007{
2008 switch (type)
2009 {
2010 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2011 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2012 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2013 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2014 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2015 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2016 default: return NULL;
1c0d3aa6
NC
2017 }
2018}
2019
40b36596
JM
2020static const char *
2021get_tic6x_dynamic_type (unsigned long type)
2022{
2023 switch (type)
2024 {
2025 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2026 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2027 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2028 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2029 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2030 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2031 default: return NULL;
40b36596
JM
2032 }
2033}
1c0d3aa6 2034
36591ba1
SL
2035static const char *
2036get_nios2_dynamic_type (unsigned long type)
2037{
2038 switch (type)
2039 {
2040 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2041 default: return NULL;
36591ba1
SL
2042 }
2043}
2044
fd85a6a1
NC
2045static const char *
2046get_solaris_dynamic_type (unsigned long type)
2047{
2048 switch (type)
2049 {
2050 case 0x6000000d: return "SUNW_AUXILIARY";
2051 case 0x6000000e: return "SUNW_RTLDINF";
2052 case 0x6000000f: return "SUNW_FILTER";
2053 case 0x60000010: return "SUNW_CAP";
2054 case 0x60000011: return "SUNW_SYMTAB";
2055 case 0x60000012: return "SUNW_SYMSZ";
2056 case 0x60000013: return "SUNW_SORTENT";
2057 case 0x60000014: return "SUNW_SYMSORT";
2058 case 0x60000015: return "SUNW_SYMSORTSZ";
2059 case 0x60000016: return "SUNW_TLSSORT";
2060 case 0x60000017: return "SUNW_TLSSORTSZ";
2061 case 0x60000018: return "SUNW_CAPINFO";
2062 case 0x60000019: return "SUNW_STRPAD";
2063 case 0x6000001a: return "SUNW_CAPCHAIN";
2064 case 0x6000001b: return "SUNW_LDMACH";
2065 case 0x6000001d: return "SUNW_CAPCHAINENT";
2066 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2067 case 0x60000021: return "SUNW_PARENT";
2068 case 0x60000023: return "SUNW_ASLR";
2069 case 0x60000025: return "SUNW_RELAX";
2070 case 0x60000029: return "SUNW_NXHEAP";
2071 case 0x6000002b: return "SUNW_NXSTACK";
2072
2073 case 0x70000001: return "SPARC_REGISTER";
2074 case 0x7ffffffd: return "AUXILIARY";
2075 case 0x7ffffffe: return "USED";
2076 case 0x7fffffff: return "FILTER";
2077
15f205b1 2078 default: return NULL;
fd85a6a1
NC
2079 }
2080}
2081
252b5132 2082static const char *
dda8d76d 2083get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2084{
e9e44622 2085 static char buff[64];
252b5132
RH
2086
2087 switch (type)
2088 {
2089 case DT_NULL: return "NULL";
2090 case DT_NEEDED: return "NEEDED";
2091 case DT_PLTRELSZ: return "PLTRELSZ";
2092 case DT_PLTGOT: return "PLTGOT";
2093 case DT_HASH: return "HASH";
2094 case DT_STRTAB: return "STRTAB";
2095 case DT_SYMTAB: return "SYMTAB";
2096 case DT_RELA: return "RELA";
2097 case DT_RELASZ: return "RELASZ";
2098 case DT_RELAENT: return "RELAENT";
2099 case DT_STRSZ: return "STRSZ";
2100 case DT_SYMENT: return "SYMENT";
2101 case DT_INIT: return "INIT";
2102 case DT_FINI: return "FINI";
2103 case DT_SONAME: return "SONAME";
2104 case DT_RPATH: return "RPATH";
2105 case DT_SYMBOLIC: return "SYMBOLIC";
2106 case DT_REL: return "REL";
2107 case DT_RELSZ: return "RELSZ";
2108 case DT_RELENT: return "RELENT";
2109 case DT_PLTREL: return "PLTREL";
2110 case DT_DEBUG: return "DEBUG";
2111 case DT_TEXTREL: return "TEXTREL";
2112 case DT_JMPREL: return "JMPREL";
2113 case DT_BIND_NOW: return "BIND_NOW";
2114 case DT_INIT_ARRAY: return "INIT_ARRAY";
2115 case DT_FINI_ARRAY: return "FINI_ARRAY";
2116 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2117 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2118 case DT_RUNPATH: return "RUNPATH";
2119 case DT_FLAGS: return "FLAGS";
2d0e6f43 2120
d1133906
NC
2121 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2122 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2123 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2124
05107a46 2125 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2126 case DT_PLTPADSZ: return "PLTPADSZ";
2127 case DT_MOVEENT: return "MOVEENT";
2128 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2129 case DT_FEATURE: return "FEATURE";
252b5132
RH
2130 case DT_POSFLAG_1: return "POSFLAG_1";
2131 case DT_SYMINSZ: return "SYMINSZ";
2132 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2133
252b5132 2134 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2135 case DT_CONFIG: return "CONFIG";
2136 case DT_DEPAUDIT: return "DEPAUDIT";
2137 case DT_AUDIT: return "AUDIT";
2138 case DT_PLTPAD: return "PLTPAD";
2139 case DT_MOVETAB: return "MOVETAB";
252b5132 2140 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2141
252b5132 2142 case DT_VERSYM: return "VERSYM";
103f02d3 2143
67a4f2b7
AO
2144 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2145 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2146 case DT_RELACOUNT: return "RELACOUNT";
2147 case DT_RELCOUNT: return "RELCOUNT";
2148 case DT_FLAGS_1: return "FLAGS_1";
2149 case DT_VERDEF: return "VERDEF";
2150 case DT_VERDEFNUM: return "VERDEFNUM";
2151 case DT_VERNEED: return "VERNEED";
2152 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2153
019148e4 2154 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2155 case DT_USED: return "USED";
2156 case DT_FILTER: return "FILTER";
103f02d3 2157
047b2264
JJ
2158 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2159 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2160 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2161 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2162 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2163 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2164
252b5132
RH
2165 default:
2166 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2167 {
2cf0635d 2168 const char * result;
103f02d3 2169
dda8d76d 2170 switch (filedata->file_header.e_machine)
252b5132
RH
2171 {
2172 case EM_MIPS:
4fe85591 2173 case EM_MIPS_RS3_LE:
252b5132
RH
2174 result = get_mips_dynamic_type (type);
2175 break;
9a097730
RH
2176 case EM_SPARCV9:
2177 result = get_sparc64_dynamic_type (type);
2178 break;
7490d522
AM
2179 case EM_PPC:
2180 result = get_ppc_dynamic_type (type);
2181 break;
f1cb7e17
AM
2182 case EM_PPC64:
2183 result = get_ppc64_dynamic_type (type);
2184 break;
ecc51f48
NC
2185 case EM_IA_64:
2186 result = get_ia64_dynamic_type (type);
2187 break;
fabcb361
RH
2188 case EM_ALPHA:
2189 result = get_alpha_dynamic_type (type);
2190 break;
1c0d3aa6
NC
2191 case EM_SCORE:
2192 result = get_score_dynamic_type (type);
2193 break;
40b36596
JM
2194 case EM_TI_C6000:
2195 result = get_tic6x_dynamic_type (type);
2196 break;
36591ba1
SL
2197 case EM_ALTERA_NIOS2:
2198 result = get_nios2_dynamic_type (type);
2199 break;
252b5132 2200 default:
dda8d76d 2201 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2202 result = get_solaris_dynamic_type (type);
2203 else
2204 result = NULL;
252b5132
RH
2205 break;
2206 }
2207
2208 if (result != NULL)
2209 return result;
2210
e9e44622 2211 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2212 }
eec8f817 2213 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2214 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2215 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2216 {
2cf0635d 2217 const char * result;
103f02d3 2218
dda8d76d 2219 switch (filedata->file_header.e_machine)
103f02d3
UD
2220 {
2221 case EM_PARISC:
2222 result = get_parisc_dynamic_type (type);
2223 break;
148b93f2
NC
2224 case EM_IA_64:
2225 result = get_ia64_dynamic_type (type);
2226 break;
103f02d3 2227 default:
dda8d76d 2228 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2229 result = get_solaris_dynamic_type (type);
2230 else
2231 result = NULL;
103f02d3
UD
2232 break;
2233 }
2234
2235 if (result != NULL)
2236 return result;
2237
e9e44622
JJ
2238 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2239 type);
103f02d3 2240 }
252b5132 2241 else
e9e44622 2242 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2243
252b5132
RH
2244 return buff;
2245 }
2246}
2247
2248static char *
d3ba0551 2249get_file_type (unsigned e_type)
252b5132 2250{
b34976b6 2251 static char buff[32];
252b5132
RH
2252
2253 switch (e_type)
2254 {
32ec8896
NC
2255 case ET_NONE: return _("NONE (None)");
2256 case ET_REL: return _("REL (Relocatable file)");
2257 case ET_EXEC: return _("EXEC (Executable file)");
2258 case ET_DYN: return _("DYN (Shared object file)");
2259 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2260
2261 default:
2262 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2263 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2264 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2265 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2266 else
e9e44622 2267 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2268 return buff;
2269 }
2270}
2271
2272static char *
d3ba0551 2273get_machine_name (unsigned e_machine)
252b5132 2274{
b34976b6 2275 static char buff[64]; /* XXX */
252b5132
RH
2276
2277 switch (e_machine)
2278 {
55e22ca8
NC
2279 /* Please keep this switch table sorted by increasing EM_ value. */
2280 /* 0 */
c45021f2
NC
2281 case EM_NONE: return _("None");
2282 case EM_M32: return "WE32100";
2283 case EM_SPARC: return "Sparc";
2284 case EM_386: return "Intel 80386";
2285 case EM_68K: return "MC68000";
2286 case EM_88K: return "MC88000";
22abe556 2287 case EM_IAMCU: return "Intel MCU";
fb70ec17 2288 case EM_860: return "Intel 80860";
c45021f2
NC
2289 case EM_MIPS: return "MIPS R3000";
2290 case EM_S370: return "IBM System/370";
55e22ca8 2291 /* 10 */
7036c0e1 2292 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2293 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2294 case EM_PARISC: return "HPPA";
55e22ca8 2295 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2296 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2297 case EM_960: return "Intel 80960";
c45021f2 2298 case EM_PPC: return "PowerPC";
55e22ca8 2299 /* 20 */
285d1771 2300 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2301 case EM_S390_OLD:
2302 case EM_S390: return "IBM S/390";
2303 case EM_SPU: return "SPU";
2304 /* 30 */
2305 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2306 case EM_FR20: return "Fujitsu FR20";
2307 case EM_RH32: return "TRW RH32";
b34976b6 2308 case EM_MCORE: return "MCORE";
55e22ca8 2309 /* 40 */
7036c0e1
AJ
2310 case EM_ARM: return "ARM";
2311 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2312 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2313 case EM_SPARCV9: return "Sparc v9";
2314 case EM_TRICORE: return "Siemens Tricore";
584da044 2315 case EM_ARC: return "ARC";
c2dcd04e
NC
2316 case EM_H8_300: return "Renesas H8/300";
2317 case EM_H8_300H: return "Renesas H8/300H";
2318 case EM_H8S: return "Renesas H8S";
2319 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2320 /* 50 */
30800947 2321 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2322 case EM_MIPS_X: return "Stanford MIPS-X";
2323 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2324 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2325 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2326 case EM_PCP: return "Siemens PCP";
2327 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2328 case EM_NDR1: return "Denso NDR1 microprocesspr";
2329 case EM_STARCORE: return "Motorola Star*Core processor";
2330 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2331 /* 60 */
7036c0e1
AJ
2332 case EM_ST100: return "STMicroelectronics ST100 processor";
2333 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2334 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2335 case EM_PDSP: return "Sony DSP processor";
2336 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2337 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2338 case EM_FX66: return "Siemens FX66 microcontroller";
2339 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2340 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2341 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2342 /* 70 */
7036c0e1
AJ
2343 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2344 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2345 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2346 case EM_SVX: return "Silicon Graphics SVx";
2347 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2348 case EM_VAX: return "Digital VAX";
1b61cf92 2349 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2350 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2351 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2352 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2353 /* 80 */
b34976b6 2354 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2355 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2356 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2357 case EM_AVR_OLD:
2358 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2359 case EM_CYGNUS_FR30:
2360 case EM_FR30: return "Fujitsu FR30";
2361 case EM_CYGNUS_D10V:
2362 case EM_D10V: return "d10v";
2363 case EM_CYGNUS_D30V:
2364 case EM_D30V: return "d30v";
2365 case EM_CYGNUS_V850:
2366 case EM_V850: return "Renesas V850";
2367 case EM_CYGNUS_M32R:
2368 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2369 case EM_CYGNUS_MN10300:
2370 case EM_MN10300: return "mn10300";
2371 /* 90 */
2372 case EM_CYGNUS_MN10200:
2373 case EM_MN10200: return "mn10200";
2374 case EM_PJ: return "picoJava";
73589c9d 2375 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2376 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2377 case EM_XTENSA_OLD:
2378 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2379 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2380 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2381 case EM_NS32K: return "National Semiconductor 32000 series";
2382 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2383 case EM_SNP1K: return "Trebia SNP 1000 processor";
2384 /* 100 */
2385 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2386 case EM_IP2K_OLD:
2387 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2388 case EM_MAX: return "MAX Processor";
2389 case EM_CR: return "National Semiconductor CompactRISC";
2390 case EM_F2MC16: return "Fujitsu F2MC16";
2391 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2392 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2393 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2394 case EM_SEP: return "Sharp embedded microprocessor";
2395 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2396 /* 110 */
11636f9e
JM
2397 case EM_UNICORE: return "Unicore";
2398 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2399 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2400 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2401 case EM_CRX: return "National Semiconductor CRX microprocessor";
2402 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2403 case EM_C166:
d70c5fc7 2404 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2405 case EM_M16C: return "Renesas M16C series microprocessors";
2406 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2407 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2408 /* 120 */
2409 case EM_M32C: return "Renesas M32c";
2410 /* 130 */
11636f9e
JM
2411 case EM_TSK3000: return "Altium TSK3000 core";
2412 case EM_RS08: return "Freescale RS08 embedded processor";
2413 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2414 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2415 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2416 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2417 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2418 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2419 /* 140 */
11636f9e
JM
2420 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2421 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2422 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2423 case EM_TI_PRU: return "TI PRU I/O processor";
2424 /* 160 */
11636f9e
JM
2425 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2426 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2427 case EM_R32C: return "Renesas R32C series microprocessors";
2428 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2429 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2430 case EM_8051: return "Intel 8051 and variants";
2431 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2432 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2433 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2434 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2435 /* 170 */
11636f9e
JM
2436 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2437 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2438 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2439 case EM_RX: return "Renesas RX";
a3c62988 2440 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2441 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2442 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2443 case EM_CR16:
2444 case EM_MICROBLAZE:
2445 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2446 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2447 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2448 /* 180 */
2449 case EM_L1OM: return "Intel L1OM";
2450 case EM_K1OM: return "Intel K1OM";
2451 case EM_INTEL182: return "Intel (reserved)";
2452 case EM_AARCH64: return "AArch64";
2453 case EM_ARM184: return "ARM (reserved)";
2454 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2455 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2456 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2457 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2458 /* 190 */
11636f9e 2459 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2460 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2461 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2462 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2463 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2464 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2465 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2466 case EM_RL78: return "Renesas RL78";
6d913794 2467 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2468 case EM_78K0R: return "Renesas 78K0R";
2469 /* 200 */
6d913794 2470 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2471 case EM_BA1: return "Beyond BA1 CPU architecture";
2472 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2473 case EM_XCORE: return "XMOS xCORE processor family";
2474 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2475 /* 210 */
6d913794
NC
2476 case EM_KM32: return "KM211 KM32 32-bit processor";
2477 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2478 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2479 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2480 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2481 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2482 case EM_COGE: return "Cognitive Smart Memory Processor";
2483 case EM_COOL: return "Bluechip Systems CoolEngine";
2484 case EM_NORC: return "Nanoradio Optimized RISC";
2485 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2486 /* 220 */
15f205b1 2487 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2488 case EM_VISIUM: return "CDS VISIUMcore processor";
2489 case EM_FT32: return "FTDI Chip FT32";
2490 case EM_MOXIE: return "Moxie";
2491 case EM_AMDGPU: return "AMD GPU";
2492 case EM_RISCV: return "RISC-V";
2493 case EM_LANAI: return "Lanai 32-bit processor";
2494 case EM_BPF: return "Linux BPF";
fe944acf 2495 case EM_NFP: return "Netronome Flow Processor";
55e22ca8
NC
2496
2497 /* Large numbers... */
2498 case EM_MT: return "Morpho Techologies MT processor";
2499 case EM_ALPHA: return "Alpha";
2500 case EM_WEBASSEMBLY: return "Web Assembly";
2501 case EM_DLX: return "OpenDLX";
2502 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2503 case EM_IQ2000: return "Vitesse IQ2000";
2504 case EM_M32C_OLD:
2505 case EM_NIOS32: return "Altera Nios";
2506 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2507 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2508 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2509 case EM_S12Z: return "Freescale S12Z";
b8891f8d 2510 case EM_CSKY: return "C-SKY";
55e22ca8 2511
252b5132 2512 default:
35d9dd2f 2513 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2514 return buff;
2515 }
2516}
2517
a9522a21
AB
2518static void
2519decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2520{
2521 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2522 other compilers don't a specific architecture type in the e_flags, and
2523 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2524 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2525 architectures.
2526
2527 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2528 but also sets a specific architecture type in the e_flags field.
2529
2530 However, when decoding the flags we don't worry if we see an
2531 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2532 ARCEM architecture type. */
2533
2534 switch (e_flags & EF_ARC_MACH_MSK)
2535 {
2536 /* We only expect these to occur for EM_ARC_COMPACT2. */
2537 case EF_ARC_CPU_ARCV2EM:
2538 strcat (buf, ", ARC EM");
2539 break;
2540 case EF_ARC_CPU_ARCV2HS:
2541 strcat (buf, ", ARC HS");
2542 break;
2543
2544 /* We only expect these to occur for EM_ARC_COMPACT. */
2545 case E_ARC_MACH_ARC600:
2546 strcat (buf, ", ARC600");
2547 break;
2548 case E_ARC_MACH_ARC601:
2549 strcat (buf, ", ARC601");
2550 break;
2551 case E_ARC_MACH_ARC700:
2552 strcat (buf, ", ARC700");
2553 break;
2554
2555 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2556 new ELF with new architecture being read by an old version of
2557 readelf, or (c) An ELF built with non-GNU compiler that does not
2558 set the architecture in the e_flags. */
2559 default:
2560 if (e_machine == EM_ARC_COMPACT)
2561 strcat (buf, ", Unknown ARCompact");
2562 else
2563 strcat (buf, ", Unknown ARC");
2564 break;
2565 }
2566
2567 switch (e_flags & EF_ARC_OSABI_MSK)
2568 {
2569 case E_ARC_OSABI_ORIG:
2570 strcat (buf, ", (ABI:legacy)");
2571 break;
2572 case E_ARC_OSABI_V2:
2573 strcat (buf, ", (ABI:v2)");
2574 break;
2575 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2576 case E_ARC_OSABI_V3:
2577 strcat (buf, ", v3 no-legacy-syscalls ABI");
2578 break;
53a346d8
CZ
2579 case E_ARC_OSABI_V4:
2580 strcat (buf, ", v4 ABI");
2581 break;
a9522a21
AB
2582 default:
2583 strcat (buf, ", unrecognised ARC OSABI flag");
2584 break;
2585 }
2586}
2587
f3485b74 2588static void
d3ba0551 2589decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2590{
2591 unsigned eabi;
32ec8896 2592 bfd_boolean unknown = FALSE;
f3485b74
NC
2593
2594 eabi = EF_ARM_EABI_VERSION (e_flags);
2595 e_flags &= ~ EF_ARM_EABIMASK;
2596
2597 /* Handle "generic" ARM flags. */
2598 if (e_flags & EF_ARM_RELEXEC)
2599 {
2600 strcat (buf, ", relocatable executable");
2601 e_flags &= ~ EF_ARM_RELEXEC;
2602 }
76da6bbe 2603
18a20338
CL
2604 if (e_flags & EF_ARM_PIC)
2605 {
2606 strcat (buf, ", position independent");
2607 e_flags &= ~ EF_ARM_PIC;
2608 }
2609
f3485b74
NC
2610 /* Now handle EABI specific flags. */
2611 switch (eabi)
2612 {
2613 default:
2c71103e 2614 strcat (buf, ", <unrecognized EABI>");
f3485b74 2615 if (e_flags)
32ec8896 2616 unknown = TRUE;
f3485b74
NC
2617 break;
2618
2619 case EF_ARM_EABI_VER1:
a5bcd848 2620 strcat (buf, ", Version1 EABI");
f3485b74
NC
2621 while (e_flags)
2622 {
2623 unsigned flag;
76da6bbe 2624
f3485b74
NC
2625 /* Process flags one bit at a time. */
2626 flag = e_flags & - e_flags;
2627 e_flags &= ~ flag;
76da6bbe 2628
f3485b74
NC
2629 switch (flag)
2630 {
a5bcd848 2631 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2632 strcat (buf, ", sorted symbol tables");
2633 break;
76da6bbe 2634
f3485b74 2635 default:
32ec8896 2636 unknown = TRUE;
f3485b74
NC
2637 break;
2638 }
2639 }
2640 break;
76da6bbe 2641
a5bcd848
PB
2642 case EF_ARM_EABI_VER2:
2643 strcat (buf, ", Version2 EABI");
2644 while (e_flags)
2645 {
2646 unsigned flag;
2647
2648 /* Process flags one bit at a time. */
2649 flag = e_flags & - e_flags;
2650 e_flags &= ~ flag;
2651
2652 switch (flag)
2653 {
2654 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2655 strcat (buf, ", sorted symbol tables");
2656 break;
2657
2658 case EF_ARM_DYNSYMSUSESEGIDX:
2659 strcat (buf, ", dynamic symbols use segment index");
2660 break;
2661
2662 case EF_ARM_MAPSYMSFIRST:
2663 strcat (buf, ", mapping symbols precede others");
2664 break;
2665
2666 default:
32ec8896 2667 unknown = TRUE;
a5bcd848
PB
2668 break;
2669 }
2670 }
2671 break;
2672
d507cf36
PB
2673 case EF_ARM_EABI_VER3:
2674 strcat (buf, ", Version3 EABI");
8cb51566
PB
2675 break;
2676
2677 case EF_ARM_EABI_VER4:
2678 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2679 while (e_flags)
2680 {
2681 unsigned flag;
2682
2683 /* Process flags one bit at a time. */
2684 flag = e_flags & - e_flags;
2685 e_flags &= ~ flag;
2686
2687 switch (flag)
2688 {
2689 case EF_ARM_BE8:
2690 strcat (buf, ", BE8");
2691 break;
2692
2693 case EF_ARM_LE8:
2694 strcat (buf, ", LE8");
2695 break;
2696
2697 default:
32ec8896 2698 unknown = TRUE;
3bfcb652
NC
2699 break;
2700 }
3bfcb652
NC
2701 }
2702 break;
3a4a14e9
PB
2703
2704 case EF_ARM_EABI_VER5:
2705 strcat (buf, ", Version5 EABI");
d507cf36
PB
2706 while (e_flags)
2707 {
2708 unsigned flag;
2709
2710 /* Process flags one bit at a time. */
2711 flag = e_flags & - e_flags;
2712 e_flags &= ~ flag;
2713
2714 switch (flag)
2715 {
2716 case EF_ARM_BE8:
2717 strcat (buf, ", BE8");
2718 break;
2719
2720 case EF_ARM_LE8:
2721 strcat (buf, ", LE8");
2722 break;
2723
3bfcb652
NC
2724 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2725 strcat (buf, ", soft-float ABI");
2726 break;
2727
2728 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2729 strcat (buf, ", hard-float ABI");
2730 break;
2731
d507cf36 2732 default:
32ec8896 2733 unknown = TRUE;
d507cf36
PB
2734 break;
2735 }
2736 }
2737 break;
2738
f3485b74 2739 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2740 strcat (buf, ", GNU EABI");
f3485b74
NC
2741 while (e_flags)
2742 {
2743 unsigned flag;
76da6bbe 2744
f3485b74
NC
2745 /* Process flags one bit at a time. */
2746 flag = e_flags & - e_flags;
2747 e_flags &= ~ flag;
76da6bbe 2748
f3485b74
NC
2749 switch (flag)
2750 {
a5bcd848 2751 case EF_ARM_INTERWORK:
f3485b74
NC
2752 strcat (buf, ", interworking enabled");
2753 break;
76da6bbe 2754
a5bcd848 2755 case EF_ARM_APCS_26:
f3485b74
NC
2756 strcat (buf, ", uses APCS/26");
2757 break;
76da6bbe 2758
a5bcd848 2759 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2760 strcat (buf, ", uses APCS/float");
2761 break;
76da6bbe 2762
a5bcd848 2763 case EF_ARM_PIC:
f3485b74
NC
2764 strcat (buf, ", position independent");
2765 break;
76da6bbe 2766
a5bcd848 2767 case EF_ARM_ALIGN8:
f3485b74
NC
2768 strcat (buf, ", 8 bit structure alignment");
2769 break;
76da6bbe 2770
a5bcd848 2771 case EF_ARM_NEW_ABI:
f3485b74
NC
2772 strcat (buf, ", uses new ABI");
2773 break;
76da6bbe 2774
a5bcd848 2775 case EF_ARM_OLD_ABI:
f3485b74
NC
2776 strcat (buf, ", uses old ABI");
2777 break;
76da6bbe 2778
a5bcd848 2779 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2780 strcat (buf, ", software FP");
2781 break;
76da6bbe 2782
90e01f86
ILT
2783 case EF_ARM_VFP_FLOAT:
2784 strcat (buf, ", VFP");
2785 break;
2786
fde78edd
NC
2787 case EF_ARM_MAVERICK_FLOAT:
2788 strcat (buf, ", Maverick FP");
2789 break;
2790
f3485b74 2791 default:
32ec8896 2792 unknown = TRUE;
f3485b74
NC
2793 break;
2794 }
2795 }
2796 }
f3485b74
NC
2797
2798 if (unknown)
2b692964 2799 strcat (buf,_(", <unknown>"));
f3485b74
NC
2800}
2801
343433df
AB
2802static void
2803decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2804{
2805 --size; /* Leave space for null terminator. */
2806
2807 switch (e_flags & EF_AVR_MACH)
2808 {
2809 case E_AVR_MACH_AVR1:
2810 strncat (buf, ", avr:1", size);
2811 break;
2812 case E_AVR_MACH_AVR2:
2813 strncat (buf, ", avr:2", size);
2814 break;
2815 case E_AVR_MACH_AVR25:
2816 strncat (buf, ", avr:25", size);
2817 break;
2818 case E_AVR_MACH_AVR3:
2819 strncat (buf, ", avr:3", size);
2820 break;
2821 case E_AVR_MACH_AVR31:
2822 strncat (buf, ", avr:31", size);
2823 break;
2824 case E_AVR_MACH_AVR35:
2825 strncat (buf, ", avr:35", size);
2826 break;
2827 case E_AVR_MACH_AVR4:
2828 strncat (buf, ", avr:4", size);
2829 break;
2830 case E_AVR_MACH_AVR5:
2831 strncat (buf, ", avr:5", size);
2832 break;
2833 case E_AVR_MACH_AVR51:
2834 strncat (buf, ", avr:51", size);
2835 break;
2836 case E_AVR_MACH_AVR6:
2837 strncat (buf, ", avr:6", size);
2838 break;
2839 case E_AVR_MACH_AVRTINY:
2840 strncat (buf, ", avr:100", size);
2841 break;
2842 case E_AVR_MACH_XMEGA1:
2843 strncat (buf, ", avr:101", size);
2844 break;
2845 case E_AVR_MACH_XMEGA2:
2846 strncat (buf, ", avr:102", size);
2847 break;
2848 case E_AVR_MACH_XMEGA3:
2849 strncat (buf, ", avr:103", size);
2850 break;
2851 case E_AVR_MACH_XMEGA4:
2852 strncat (buf, ", avr:104", size);
2853 break;
2854 case E_AVR_MACH_XMEGA5:
2855 strncat (buf, ", avr:105", size);
2856 break;
2857 case E_AVR_MACH_XMEGA6:
2858 strncat (buf, ", avr:106", size);
2859 break;
2860 case E_AVR_MACH_XMEGA7:
2861 strncat (buf, ", avr:107", size);
2862 break;
2863 default:
2864 strncat (buf, ", avr:<unknown>", size);
2865 break;
2866 }
2867
2868 size -= strlen (buf);
2869 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2870 strncat (buf, ", link-relax", size);
2871}
2872
35c08157
KLC
2873static void
2874decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2875{
2876 unsigned abi;
2877 unsigned arch;
2878 unsigned config;
2879 unsigned version;
32ec8896
NC
2880 bfd_boolean has_fpu = FALSE;
2881 unsigned int r = 0;
35c08157
KLC
2882
2883 static const char *ABI_STRINGS[] =
2884 {
2885 "ABI v0", /* use r5 as return register; only used in N1213HC */
2886 "ABI v1", /* use r0 as return register */
2887 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2888 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2889 "AABI",
2890 "ABI2 FP+"
35c08157
KLC
2891 };
2892 static const char *VER_STRINGS[] =
2893 {
2894 "Andes ELF V1.3 or older",
2895 "Andes ELF V1.3.1",
2896 "Andes ELF V1.4"
2897 };
2898 static const char *ARCH_STRINGS[] =
2899 {
2900 "",
2901 "Andes Star v1.0",
2902 "Andes Star v2.0",
2903 "Andes Star v3.0",
2904 "Andes Star v3.0m"
2905 };
2906
2907 abi = EF_NDS_ABI & e_flags;
2908 arch = EF_NDS_ARCH & e_flags;
2909 config = EF_NDS_INST & e_flags;
2910 version = EF_NDS32_ELF_VERSION & e_flags;
2911
2912 memset (buf, 0, size);
2913
2914 switch (abi)
2915 {
2916 case E_NDS_ABI_V0:
2917 case E_NDS_ABI_V1:
2918 case E_NDS_ABI_V2:
2919 case E_NDS_ABI_V2FP:
2920 case E_NDS_ABI_AABI:
40c7a7cb 2921 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2922 /* In case there are holes in the array. */
2923 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2924 break;
2925
2926 default:
2927 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2928 break;
2929 }
2930
2931 switch (version)
2932 {
2933 case E_NDS32_ELF_VER_1_2:
2934 case E_NDS32_ELF_VER_1_3:
2935 case E_NDS32_ELF_VER_1_4:
2936 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2937 break;
2938
2939 default:
2940 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2941 break;
2942 }
2943
2944 if (E_NDS_ABI_V0 == abi)
2945 {
2946 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2947 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2948 if (arch == E_NDS_ARCH_STAR_V1_0)
2949 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2950 return;
2951 }
2952
2953 switch (arch)
2954 {
2955 case E_NDS_ARCH_STAR_V1_0:
2956 case E_NDS_ARCH_STAR_V2_0:
2957 case E_NDS_ARCH_STAR_V3_0:
2958 case E_NDS_ARCH_STAR_V3_M:
2959 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2960 break;
2961
2962 default:
2963 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2964 /* ARCH version determines how the e_flags are interpreted.
2965 If it is unknown, we cannot proceed. */
2966 return;
2967 }
2968
2969 /* Newer ABI; Now handle architecture specific flags. */
2970 if (arch == E_NDS_ARCH_STAR_V1_0)
2971 {
2972 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2973 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2974
2975 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2976 r += snprintf (buf + r, size -r, ", MAC");
2977
2978 if (config & E_NDS32_HAS_DIV_INST)
2979 r += snprintf (buf + r, size -r, ", DIV");
2980
2981 if (config & E_NDS32_HAS_16BIT_INST)
2982 r += snprintf (buf + r, size -r, ", 16b");
2983 }
2984 else
2985 {
2986 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2987 {
2988 if (version <= E_NDS32_ELF_VER_1_3)
2989 r += snprintf (buf + r, size -r, ", [B8]");
2990 else
2991 r += snprintf (buf + r, size -r, ", EX9");
2992 }
2993
2994 if (config & E_NDS32_HAS_MAC_DX_INST)
2995 r += snprintf (buf + r, size -r, ", MAC_DX");
2996
2997 if (config & E_NDS32_HAS_DIV_DX_INST)
2998 r += snprintf (buf + r, size -r, ", DIV_DX");
2999
3000 if (config & E_NDS32_HAS_16BIT_INST)
3001 {
3002 if (version <= E_NDS32_ELF_VER_1_3)
3003 r += snprintf (buf + r, size -r, ", 16b");
3004 else
3005 r += snprintf (buf + r, size -r, ", IFC");
3006 }
3007 }
3008
3009 if (config & E_NDS32_HAS_EXT_INST)
3010 r += snprintf (buf + r, size -r, ", PERF1");
3011
3012 if (config & E_NDS32_HAS_EXT2_INST)
3013 r += snprintf (buf + r, size -r, ", PERF2");
3014
3015 if (config & E_NDS32_HAS_FPU_INST)
3016 {
32ec8896 3017 has_fpu = TRUE;
35c08157
KLC
3018 r += snprintf (buf + r, size -r, ", FPU_SP");
3019 }
3020
3021 if (config & E_NDS32_HAS_FPU_DP_INST)
3022 {
32ec8896 3023 has_fpu = TRUE;
35c08157
KLC
3024 r += snprintf (buf + r, size -r, ", FPU_DP");
3025 }
3026
3027 if (config & E_NDS32_HAS_FPU_MAC_INST)
3028 {
32ec8896 3029 has_fpu = TRUE;
35c08157
KLC
3030 r += snprintf (buf + r, size -r, ", FPU_MAC");
3031 }
3032
3033 if (has_fpu)
3034 {
3035 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3036 {
3037 case E_NDS32_FPU_REG_8SP_4DP:
3038 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3039 break;
3040 case E_NDS32_FPU_REG_16SP_8DP:
3041 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3042 break;
3043 case E_NDS32_FPU_REG_32SP_16DP:
3044 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3045 break;
3046 case E_NDS32_FPU_REG_32SP_32DP:
3047 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3048 break;
3049 }
3050 }
3051
3052 if (config & E_NDS32_HAS_AUDIO_INST)
3053 r += snprintf (buf + r, size -r, ", AUDIO");
3054
3055 if (config & E_NDS32_HAS_STRING_INST)
3056 r += snprintf (buf + r, size -r, ", STR");
3057
3058 if (config & E_NDS32_HAS_REDUCED_REGS)
3059 r += snprintf (buf + r, size -r, ", 16REG");
3060
3061 if (config & E_NDS32_HAS_VIDEO_INST)
3062 {
3063 if (version <= E_NDS32_ELF_VER_1_3)
3064 r += snprintf (buf + r, size -r, ", VIDEO");
3065 else
3066 r += snprintf (buf + r, size -r, ", SATURATION");
3067 }
3068
3069 if (config & E_NDS32_HAS_ENCRIPT_INST)
3070 r += snprintf (buf + r, size -r, ", ENCRP");
3071
3072 if (config & E_NDS32_HAS_L2C_INST)
3073 r += snprintf (buf + r, size -r, ", L2C");
3074}
3075
252b5132 3076static char *
dda8d76d 3077get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3078{
b34976b6 3079 static char buf[1024];
252b5132
RH
3080
3081 buf[0] = '\0';
76da6bbe 3082
252b5132
RH
3083 if (e_flags)
3084 {
3085 switch (e_machine)
3086 {
3087 default:
3088 break;
3089
886a2506 3090 case EM_ARC_COMPACT2:
886a2506 3091 case EM_ARC_COMPACT:
a9522a21
AB
3092 decode_ARC_machine_flags (e_flags, e_machine, buf);
3093 break;
886a2506 3094
f3485b74
NC
3095 case EM_ARM:
3096 decode_ARM_machine_flags (e_flags, buf);
3097 break;
76da6bbe 3098
343433df
AB
3099 case EM_AVR:
3100 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3101 break;
3102
781303ce
MF
3103 case EM_BLACKFIN:
3104 if (e_flags & EF_BFIN_PIC)
3105 strcat (buf, ", PIC");
3106
3107 if (e_flags & EF_BFIN_FDPIC)
3108 strcat (buf, ", FDPIC");
3109
3110 if (e_flags & EF_BFIN_CODE_IN_L1)
3111 strcat (buf, ", code in L1");
3112
3113 if (e_flags & EF_BFIN_DATA_IN_L1)
3114 strcat (buf, ", data in L1");
3115
3116 break;
3117
ec2dfb42
AO
3118 case EM_CYGNUS_FRV:
3119 switch (e_flags & EF_FRV_CPU_MASK)
3120 {
3121 case EF_FRV_CPU_GENERIC:
3122 break;
3123
3124 default:
3125 strcat (buf, ", fr???");
3126 break;
57346661 3127
ec2dfb42
AO
3128 case EF_FRV_CPU_FR300:
3129 strcat (buf, ", fr300");
3130 break;
3131
3132 case EF_FRV_CPU_FR400:
3133 strcat (buf, ", fr400");
3134 break;
3135 case EF_FRV_CPU_FR405:
3136 strcat (buf, ", fr405");
3137 break;
3138
3139 case EF_FRV_CPU_FR450:
3140 strcat (buf, ", fr450");
3141 break;
3142
3143 case EF_FRV_CPU_FR500:
3144 strcat (buf, ", fr500");
3145 break;
3146 case EF_FRV_CPU_FR550:
3147 strcat (buf, ", fr550");
3148 break;
3149
3150 case EF_FRV_CPU_SIMPLE:
3151 strcat (buf, ", simple");
3152 break;
3153 case EF_FRV_CPU_TOMCAT:
3154 strcat (buf, ", tomcat");
3155 break;
3156 }
1c877e87 3157 break;
ec2dfb42 3158
53c7db4b 3159 case EM_68K:
425c6cb0 3160 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3161 strcat (buf, ", m68000");
425c6cb0 3162 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3163 strcat (buf, ", cpu32");
3164 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3165 strcat (buf, ", fido_a");
425c6cb0 3166 else
266abb8f 3167 {
2cf0635d
NC
3168 char const * isa = _("unknown");
3169 char const * mac = _("unknown mac");
3170 char const * additional = NULL;
0112cd26 3171
c694fd50 3172 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3173 {
c694fd50 3174 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3175 isa = "A";
3176 additional = ", nodiv";
3177 break;
c694fd50 3178 case EF_M68K_CF_ISA_A:
266abb8f
NS
3179 isa = "A";
3180 break;
c694fd50 3181 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3182 isa = "A+";
3183 break;
c694fd50 3184 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3185 isa = "B";
3186 additional = ", nousp";
3187 break;
c694fd50 3188 case EF_M68K_CF_ISA_B:
266abb8f
NS
3189 isa = "B";
3190 break;
f608cd77
NS
3191 case EF_M68K_CF_ISA_C:
3192 isa = "C";
3193 break;
3194 case EF_M68K_CF_ISA_C_NODIV:
3195 isa = "C";
3196 additional = ", nodiv";
3197 break;
266abb8f
NS
3198 }
3199 strcat (buf, ", cf, isa ");
3200 strcat (buf, isa);
0b2e31dc
NS
3201 if (additional)
3202 strcat (buf, additional);
c694fd50 3203 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3204 strcat (buf, ", float");
c694fd50 3205 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3206 {
3207 case 0:
3208 mac = NULL;
3209 break;
c694fd50 3210 case EF_M68K_CF_MAC:
266abb8f
NS
3211 mac = "mac";
3212 break;
c694fd50 3213 case EF_M68K_CF_EMAC:
266abb8f
NS
3214 mac = "emac";
3215 break;
f608cd77
NS
3216 case EF_M68K_CF_EMAC_B:
3217 mac = "emac_b";
3218 break;
266abb8f
NS
3219 }
3220 if (mac)
3221 {
3222 strcat (buf, ", ");
3223 strcat (buf, mac);
3224 }
266abb8f 3225 }
53c7db4b 3226 break;
33c63f9d 3227
153a2776
NC
3228 case EM_CYGNUS_MEP:
3229 switch (e_flags & EF_MEP_CPU_MASK)
3230 {
3231 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3232 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3233 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3234 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3235 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3236 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3237 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3238 }
3239
3240 switch (e_flags & EF_MEP_COP_MASK)
3241 {
3242 case EF_MEP_COP_NONE: break;
3243 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3244 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3245 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3246 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3247 default: strcat (buf, _("<unknown MeP copro type>")); break;
3248 }
3249
3250 if (e_flags & EF_MEP_LIBRARY)
3251 strcat (buf, ", Built for Library");
3252
3253 if (e_flags & EF_MEP_INDEX_MASK)
3254 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3255 e_flags & EF_MEP_INDEX_MASK);
3256
3257 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3258 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3259 e_flags & ~ EF_MEP_ALL_FLAGS);
3260 break;
3261
252b5132
RH
3262 case EM_PPC:
3263 if (e_flags & EF_PPC_EMB)
3264 strcat (buf, ", emb");
3265
3266 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3267 strcat (buf, _(", relocatable"));
252b5132
RH
3268
3269 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3270 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3271 break;
3272
ee67d69a
AM
3273 case EM_PPC64:
3274 if (e_flags & EF_PPC64_ABI)
3275 {
3276 char abi[] = ", abiv0";
3277
3278 abi[6] += e_flags & EF_PPC64_ABI;
3279 strcat (buf, abi);
3280 }
3281 break;
3282
708e2187
NC
3283 case EM_V800:
3284 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3285 strcat (buf, ", RH850 ABI");
0b4362b0 3286
708e2187
NC
3287 if (e_flags & EF_V800_850E3)
3288 strcat (buf, ", V3 architecture");
3289
3290 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3291 strcat (buf, ", FPU not used");
3292
3293 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3294 strcat (buf, ", regmode: COMMON");
3295
3296 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3297 strcat (buf, ", r4 not used");
3298
3299 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3300 strcat (buf, ", r30 not used");
3301
3302 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3303 strcat (buf, ", r5 not used");
3304
3305 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3306 strcat (buf, ", r2 not used");
3307
3308 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3309 {
3310 switch (e_flags & - e_flags)
3311 {
3312 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3313 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3314 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3315 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3316 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3317 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3318 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3319 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3320 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3321 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3322 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3323 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3324 default: break;
3325 }
3326 }
3327 break;
3328
2b0337b0 3329 case EM_V850:
252b5132
RH
3330 case EM_CYGNUS_V850:
3331 switch (e_flags & EF_V850_ARCH)
3332 {
78c8d46c
NC
3333 case E_V850E3V5_ARCH:
3334 strcat (buf, ", v850e3v5");
3335 break;
1cd986c5
NC
3336 case E_V850E2V3_ARCH:
3337 strcat (buf, ", v850e2v3");
3338 break;
3339 case E_V850E2_ARCH:
3340 strcat (buf, ", v850e2");
3341 break;
3342 case E_V850E1_ARCH:
3343 strcat (buf, ", v850e1");
8ad30312 3344 break;
252b5132
RH
3345 case E_V850E_ARCH:
3346 strcat (buf, ", v850e");
3347 break;
252b5132
RH
3348 case E_V850_ARCH:
3349 strcat (buf, ", v850");
3350 break;
3351 default:
2b692964 3352 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3353 break;
3354 }
3355 break;
3356
2b0337b0 3357 case EM_M32R:
252b5132
RH
3358 case EM_CYGNUS_M32R:
3359 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3360 strcat (buf, ", m32r");
252b5132
RH
3361 break;
3362
3363 case EM_MIPS:
4fe85591 3364 case EM_MIPS_RS3_LE:
252b5132
RH
3365 if (e_flags & EF_MIPS_NOREORDER)
3366 strcat (buf, ", noreorder");
3367
3368 if (e_flags & EF_MIPS_PIC)
3369 strcat (buf, ", pic");
3370
3371 if (e_flags & EF_MIPS_CPIC)
3372 strcat (buf, ", cpic");
3373
d1bdd336
TS
3374 if (e_flags & EF_MIPS_UCODE)
3375 strcat (buf, ", ugen_reserved");
3376
252b5132
RH
3377 if (e_flags & EF_MIPS_ABI2)
3378 strcat (buf, ", abi2");
3379
43521d43
TS
3380 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3381 strcat (buf, ", odk first");
3382
a5d22d2a
TS
3383 if (e_flags & EF_MIPS_32BITMODE)
3384 strcat (buf, ", 32bitmode");
3385
ba92f887
MR
3386 if (e_flags & EF_MIPS_NAN2008)
3387 strcat (buf, ", nan2008");
3388
fef1b0b3
SE
3389 if (e_flags & EF_MIPS_FP64)
3390 strcat (buf, ", fp64");
3391
156c2f8b
NC
3392 switch ((e_flags & EF_MIPS_MACH))
3393 {
3394 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3395 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3396 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3397 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3398 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3399 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3400 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3401 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3402 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3403 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3404 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3405 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3406 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3407 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3408 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
05c6f050 3409 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3410 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3411 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3412 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3413 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3414 case 0:
3415 /* We simply ignore the field in this case to avoid confusion:
3416 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3417 extension. */
3418 break;
2b692964 3419 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3420 }
43521d43
TS
3421
3422 switch ((e_flags & EF_MIPS_ABI))
3423 {
3424 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3425 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3426 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3427 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3428 case 0:
3429 /* We simply ignore the field in this case to avoid confusion:
3430 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3431 This means it is likely to be an o32 file, but not for
3432 sure. */
3433 break;
2b692964 3434 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3435 }
3436
3437 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3438 strcat (buf, ", mdmx");
3439
3440 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3441 strcat (buf, ", mips16");
3442
df58fc94
RS
3443 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3444 strcat (buf, ", micromips");
3445
43521d43
TS
3446 switch ((e_flags & EF_MIPS_ARCH))
3447 {
3448 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3449 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3450 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3451 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3452 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3453 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3454 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3455 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3456 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3457 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3458 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3459 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3460 }
252b5132 3461 break;
351b4b40 3462
35c08157
KLC
3463 case EM_NDS32:
3464 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3465 break;
3466
fe944acf
FT
3467 case EM_NFP:
3468 switch (EF_NFP_MACH (e_flags))
3469 {
3470 case E_NFP_MACH_3200:
3471 strcat (buf, ", NFP-32xx");
3472 break;
3473 case E_NFP_MACH_6000:
3474 strcat (buf, ", NFP-6xxx");
3475 break;
3476 }
3477 break;
3478
e23eba97
NC
3479 case EM_RISCV:
3480 if (e_flags & EF_RISCV_RVC)
3481 strcat (buf, ", RVC");
2922d21d 3482
7f999549
JW
3483 if (e_flags & EF_RISCV_RVE)
3484 strcat (buf, ", RVE");
3485
2922d21d
AW
3486 switch (e_flags & EF_RISCV_FLOAT_ABI)
3487 {
3488 case EF_RISCV_FLOAT_ABI_SOFT:
3489 strcat (buf, ", soft-float ABI");
3490 break;
3491
3492 case EF_RISCV_FLOAT_ABI_SINGLE:
3493 strcat (buf, ", single-float ABI");
3494 break;
3495
3496 case EF_RISCV_FLOAT_ABI_DOUBLE:
3497 strcat (buf, ", double-float ABI");
3498 break;
3499
3500 case EF_RISCV_FLOAT_ABI_QUAD:
3501 strcat (buf, ", quad-float ABI");
3502 break;
3503 }
e23eba97
NC
3504 break;
3505
ccde1100
AO
3506 case EM_SH:
3507 switch ((e_flags & EF_SH_MACH_MASK))
3508 {
3509 case EF_SH1: strcat (buf, ", sh1"); break;
3510 case EF_SH2: strcat (buf, ", sh2"); break;
3511 case EF_SH3: strcat (buf, ", sh3"); break;
3512 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3513 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3514 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3515 case EF_SH3E: strcat (buf, ", sh3e"); break;
3516 case EF_SH4: strcat (buf, ", sh4"); break;
3517 case EF_SH5: strcat (buf, ", sh5"); break;
3518 case EF_SH2E: strcat (buf, ", sh2e"); break;
3519 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3520 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3521 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3522 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3523 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3524 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3525 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3526 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3527 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3528 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3529 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3530 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3531 }
3532
cec6a5b8
MR
3533 if (e_flags & EF_SH_PIC)
3534 strcat (buf, ", pic");
3535
3536 if (e_flags & EF_SH_FDPIC)
3537 strcat (buf, ", fdpic");
ccde1100 3538 break;
948f632f 3539
73589c9d
CS
3540 case EM_OR1K:
3541 if (e_flags & EF_OR1K_NODELAY)
3542 strcat (buf, ", no delay");
3543 break;
57346661 3544
351b4b40
RH
3545 case EM_SPARCV9:
3546 if (e_flags & EF_SPARC_32PLUS)
3547 strcat (buf, ", v8+");
3548
3549 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3550 strcat (buf, ", ultrasparcI");
3551
3552 if (e_flags & EF_SPARC_SUN_US3)
3553 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3554
3555 if (e_flags & EF_SPARC_HAL_R1)
3556 strcat (buf, ", halr1");
3557
3558 if (e_flags & EF_SPARC_LEDATA)
3559 strcat (buf, ", ledata");
3560
3561 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3562 strcat (buf, ", tso");
3563
3564 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3565 strcat (buf, ", pso");
3566
3567 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3568 strcat (buf, ", rmo");
3569 break;
7d466069 3570
103f02d3
UD
3571 case EM_PARISC:
3572 switch (e_flags & EF_PARISC_ARCH)
3573 {
3574 case EFA_PARISC_1_0:
3575 strcpy (buf, ", PA-RISC 1.0");
3576 break;
3577 case EFA_PARISC_1_1:
3578 strcpy (buf, ", PA-RISC 1.1");
3579 break;
3580 case EFA_PARISC_2_0:
3581 strcpy (buf, ", PA-RISC 2.0");
3582 break;
3583 default:
3584 break;
3585 }
3586 if (e_flags & EF_PARISC_TRAPNIL)
3587 strcat (buf, ", trapnil");
3588 if (e_flags & EF_PARISC_EXT)
3589 strcat (buf, ", ext");
3590 if (e_flags & EF_PARISC_LSB)
3591 strcat (buf, ", lsb");
3592 if (e_flags & EF_PARISC_WIDE)
3593 strcat (buf, ", wide");
3594 if (e_flags & EF_PARISC_NO_KABP)
3595 strcat (buf, ", no kabp");
3596 if (e_flags & EF_PARISC_LAZYSWAP)
3597 strcat (buf, ", lazyswap");
30800947 3598 break;
76da6bbe 3599
7d466069 3600 case EM_PJ:
2b0337b0 3601 case EM_PJ_OLD:
7d466069
ILT
3602 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3603 strcat (buf, ", new calling convention");
3604
3605 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3606 strcat (buf, ", gnu calling convention");
3607 break;
4d6ed7c8
NC
3608
3609 case EM_IA_64:
3610 if ((e_flags & EF_IA_64_ABI64))
3611 strcat (buf, ", 64-bit");
3612 else
3613 strcat (buf, ", 32-bit");
3614 if ((e_flags & EF_IA_64_REDUCEDFP))
3615 strcat (buf, ", reduced fp model");
3616 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3617 strcat (buf, ", no function descriptors, constant gp");
3618 else if ((e_flags & EF_IA_64_CONS_GP))
3619 strcat (buf, ", constant gp");
3620 if ((e_flags & EF_IA_64_ABSOLUTE))
3621 strcat (buf, ", absolute");
dda8d76d 3622 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3623 {
3624 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3625 strcat (buf, ", vms_linkages");
3626 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3627 {
3628 case EF_IA_64_VMS_COMCOD_SUCCESS:
3629 break;
3630 case EF_IA_64_VMS_COMCOD_WARNING:
3631 strcat (buf, ", warning");
3632 break;
3633 case EF_IA_64_VMS_COMCOD_ERROR:
3634 strcat (buf, ", error");
3635 break;
3636 case EF_IA_64_VMS_COMCOD_ABORT:
3637 strcat (buf, ", abort");
3638 break;
3639 default:
bee0ee85
NC
3640 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3641 e_flags & EF_IA_64_VMS_COMCOD);
3642 strcat (buf, ", <unknown>");
28f997cf
TG
3643 }
3644 }
4d6ed7c8 3645 break;
179d3252
JT
3646
3647 case EM_VAX:
3648 if ((e_flags & EF_VAX_NONPIC))
3649 strcat (buf, ", non-PIC");
3650 if ((e_flags & EF_VAX_DFLOAT))
3651 strcat (buf, ", D-Float");
3652 if ((e_flags & EF_VAX_GFLOAT))
3653 strcat (buf, ", G-Float");
3654 break;
c7927a3c 3655
619ed720
EB
3656 case EM_VISIUM:
3657 if (e_flags & EF_VISIUM_ARCH_MCM)
3658 strcat (buf, ", mcm");
3659 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3660 strcat (buf, ", mcm24");
3661 if (e_flags & EF_VISIUM_ARCH_GR6)
3662 strcat (buf, ", gr6");
3663 break;
3664
4046d87a 3665 case EM_RL78:
1740ba0c
NC
3666 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3667 {
3668 case E_FLAG_RL78_ANY_CPU: break;
3669 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3670 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3671 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3672 }
856ea05c
KP
3673 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3674 strcat (buf, ", 64-bit doubles");
4046d87a 3675 break;
0b4362b0 3676
c7927a3c
NC
3677 case EM_RX:
3678 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3679 strcat (buf, ", 64-bit doubles");
3680 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3681 strcat (buf, ", dsp");
d4cb0ea0 3682 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3683 strcat (buf, ", pid");
708e2187
NC
3684 if (e_flags & E_FLAG_RX_ABI)
3685 strcat (buf, ", RX ABI");
3525236c
NC
3686 if (e_flags & E_FLAG_RX_SINSNS_SET)
3687 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3688 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3689 if (e_flags & E_FLAG_RX_V2)
3690 strcat (buf, ", V2");
d4cb0ea0 3691 break;
55786da2
AK
3692
3693 case EM_S390:
3694 if (e_flags & EF_S390_HIGH_GPRS)
3695 strcat (buf, ", highgprs");
d4cb0ea0 3696 break;
40b36596
JM
3697
3698 case EM_TI_C6000:
3699 if ((e_flags & EF_C6000_REL))
3700 strcat (buf, ", relocatable module");
d4cb0ea0 3701 break;
13761a11
NC
3702
3703 case EM_MSP430:
3704 strcat (buf, _(": architecture variant: "));
3705 switch (e_flags & EF_MSP430_MACH)
3706 {
3707 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3708 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3709 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3710 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3711 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3712 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3713 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3714 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3715 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3716 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3717 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3718 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3719 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3720 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3721 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3722 default:
3723 strcat (buf, _(": unknown")); break;
3724 }
3725
3726 if (e_flags & ~ EF_MSP430_MACH)
3727 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3728 }
3729 }
3730
3731 return buf;
3732}
3733
252b5132 3734static const char *
dda8d76d 3735get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3736{
3737 static char buff[32];
3738
3739 switch (osabi)
3740 {
3741 case ELFOSABI_NONE: return "UNIX - System V";
3742 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3743 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3744 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3745 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3746 case ELFOSABI_AIX: return "UNIX - AIX";
3747 case ELFOSABI_IRIX: return "UNIX - IRIX";
3748 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3749 case ELFOSABI_TRU64: return "UNIX - TRU64";
3750 case ELFOSABI_MODESTO: return "Novell - Modesto";
3751 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3752 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3753 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3754 case ELFOSABI_AROS: return "AROS";
11636f9e 3755 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3756 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3757 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3758 default:
40b36596 3759 if (osabi >= 64)
dda8d76d 3760 switch (filedata->file_header.e_machine)
40b36596
JM
3761 {
3762 case EM_ARM:
3763 switch (osabi)
3764 {
3765 case ELFOSABI_ARM: return "ARM";
18a20338 3766 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3767 default:
3768 break;
3769 }
3770 break;
3771
3772 case EM_MSP430:
3773 case EM_MSP430_OLD:
619ed720 3774 case EM_VISIUM:
40b36596
JM
3775 switch (osabi)
3776 {
3777 case ELFOSABI_STANDALONE: return _("Standalone App");
3778 default:
3779 break;
3780 }
3781 break;
3782
3783 case EM_TI_C6000:
3784 switch (osabi)
3785 {
3786 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3787 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3788 default:
3789 break;
3790 }
3791 break;
3792
3793 default:
3794 break;
3795 }
e9e44622 3796 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3797 return buff;
3798 }
3799}
3800
a06ea964
NC
3801static const char *
3802get_aarch64_segment_type (unsigned long type)
3803{
3804 switch (type)
3805 {
32ec8896
NC
3806 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3807 default: return NULL;
a06ea964 3808 }
a06ea964
NC
3809}
3810
b294bdf8
MM
3811static const char *
3812get_arm_segment_type (unsigned long type)
3813{
3814 switch (type)
3815 {
32ec8896
NC
3816 case PT_ARM_EXIDX: return "EXIDX";
3817 default: return NULL;
b294bdf8 3818 }
b294bdf8
MM
3819}
3820
b4cbbe8f
AK
3821static const char *
3822get_s390_segment_type (unsigned long type)
3823{
3824 switch (type)
3825 {
3826 case PT_S390_PGSTE: return "S390_PGSTE";
3827 default: return NULL;
3828 }
3829}
3830
d3ba0551
AM
3831static const char *
3832get_mips_segment_type (unsigned long type)
252b5132
RH
3833{
3834 switch (type)
3835 {
32ec8896
NC
3836 case PT_MIPS_REGINFO: return "REGINFO";
3837 case PT_MIPS_RTPROC: return "RTPROC";
3838 case PT_MIPS_OPTIONS: return "OPTIONS";
3839 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3840 default: return NULL;
252b5132 3841 }
252b5132
RH
3842}
3843
103f02d3 3844static const char *
d3ba0551 3845get_parisc_segment_type (unsigned long type)
103f02d3
UD
3846{
3847 switch (type)
3848 {
3849 case PT_HP_TLS: return "HP_TLS";
3850 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3851 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3852 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3853 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3854 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3855 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3856 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3857 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3858 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3859 case PT_HP_PARALLEL: return "HP_PARALLEL";
3860 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3861 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3862 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3863 case PT_HP_STACK: return "HP_STACK";
3864 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3865 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3866 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3867 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3868 default: return NULL;
103f02d3 3869 }
103f02d3
UD
3870}
3871
4d6ed7c8 3872static const char *
d3ba0551 3873get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3874{
3875 switch (type)
3876 {
3877 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3878 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3879 case PT_HP_TLS: return "HP_TLS";
3880 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3881 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3882 case PT_IA_64_HP_STACK: return "HP_STACK";
32ec8896 3883 default: return NULL;
4d6ed7c8 3884 }
4d6ed7c8
NC
3885}
3886
40b36596
JM
3887static const char *
3888get_tic6x_segment_type (unsigned long type)
3889{
3890 switch (type)
3891 {
32ec8896
NC
3892 case PT_C6000_PHATTR: return "C6000_PHATTR";
3893 default: return NULL;
40b36596 3894 }
40b36596
JM
3895}
3896
5522f910
NC
3897static const char *
3898get_solaris_segment_type (unsigned long type)
3899{
3900 switch (type)
3901 {
3902 case 0x6464e550: return "PT_SUNW_UNWIND";
3903 case 0x6474e550: return "PT_SUNW_EH_FRAME";
3904 case 0x6ffffff7: return "PT_LOSUNW";
3905 case 0x6ffffffa: return "PT_SUNWBSS";
3906 case 0x6ffffffb: return "PT_SUNWSTACK";
3907 case 0x6ffffffc: return "PT_SUNWDTRACE";
3908 case 0x6ffffffd: return "PT_SUNWCAP";
3909 case 0x6fffffff: return "PT_HISUNW";
32ec8896 3910 default: return NULL;
5522f910
NC
3911 }
3912}
3913
252b5132 3914static const char *
dda8d76d 3915get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 3916{
b34976b6 3917 static char buff[32];
252b5132
RH
3918
3919 switch (p_type)
3920 {
b34976b6
AM
3921 case PT_NULL: return "NULL";
3922 case PT_LOAD: return "LOAD";
252b5132 3923 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3924 case PT_INTERP: return "INTERP";
3925 case PT_NOTE: return "NOTE";
3926 case PT_SHLIB: return "SHLIB";
3927 case PT_PHDR: return "PHDR";
13ae64f3 3928 case PT_TLS: return "TLS";
32ec8896 3929 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 3930 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3931 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3932
252b5132 3933 default:
a91e1603
L
3934 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
3935 {
3936 sprintf (buff, "GNU_MBIND+%#lx",
3937 p_type - PT_GNU_MBIND_LO);
3938 }
3939 else if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 3940 {
2cf0635d 3941 const char * result;
103f02d3 3942
dda8d76d 3943 switch (filedata->file_header.e_machine)
252b5132 3944 {
a06ea964
NC
3945 case EM_AARCH64:
3946 result = get_aarch64_segment_type (p_type);
3947 break;
b294bdf8
MM
3948 case EM_ARM:
3949 result = get_arm_segment_type (p_type);
3950 break;
252b5132 3951 case EM_MIPS:
4fe85591 3952 case EM_MIPS_RS3_LE:
252b5132
RH
3953 result = get_mips_segment_type (p_type);
3954 break;
103f02d3
UD
3955 case EM_PARISC:
3956 result = get_parisc_segment_type (p_type);
3957 break;
4d6ed7c8
NC
3958 case EM_IA_64:
3959 result = get_ia64_segment_type (p_type);
3960 break;
40b36596
JM
3961 case EM_TI_C6000:
3962 result = get_tic6x_segment_type (p_type);
3963 break;
b4cbbe8f
AK
3964 case EM_S390:
3965 case EM_S390_OLD:
3966 result = get_s390_segment_type (p_type);
3967 break;
252b5132
RH
3968 default:
3969 result = NULL;
3970 break;
3971 }
103f02d3 3972
252b5132
RH
3973 if (result != NULL)
3974 return result;
103f02d3 3975
1a9ccd70 3976 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
3977 }
3978 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3979 {
2cf0635d 3980 const char * result;
103f02d3 3981
dda8d76d 3982 switch (filedata->file_header.e_machine)
103f02d3
UD
3983 {
3984 case EM_PARISC:
3985 result = get_parisc_segment_type (p_type);
3986 break;
00428cca
AM
3987 case EM_IA_64:
3988 result = get_ia64_segment_type (p_type);
3989 break;
103f02d3 3990 default:
dda8d76d 3991 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5522f910
NC
3992 result = get_solaris_segment_type (p_type);
3993 else
3994 result = NULL;
103f02d3
UD
3995 break;
3996 }
3997
3998 if (result != NULL)
3999 return result;
4000
1a9ccd70 4001 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4002 }
252b5132 4003 else
e9e44622 4004 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4005
4006 return buff;
4007 }
4008}
4009
53a346d8
CZ
4010static const char *
4011get_arc_section_type_name (unsigned int sh_type)
4012{
4013 switch (sh_type)
4014 {
4015 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4016 default:
4017 break;
4018 }
4019 return NULL;
4020}
4021
252b5132 4022static const char *
d3ba0551 4023get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4024{
4025 switch (sh_type)
4026 {
b34976b6
AM
4027 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4028 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4029 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4030 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4031 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4032 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4033 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4034 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4035 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4036 case SHT_MIPS_RELD: return "MIPS_RELD";
4037 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4038 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4039 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4040 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4041 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4042 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4043 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4044 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4045 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4046 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4047 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4048 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4049 case SHT_MIPS_LINE: return "MIPS_LINE";
4050 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4051 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4052 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4053 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4054 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4055 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4056 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4057 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4058 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4059 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4060 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4061 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4062 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4063 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4064 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4065 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4066 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
4067 default:
4068 break;
4069 }
4070 return NULL;
4071}
4072
103f02d3 4073static const char *
d3ba0551 4074get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4075{
4076 switch (sh_type)
4077 {
4078 case SHT_PARISC_EXT: return "PARISC_EXT";
4079 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4080 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4081 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4082 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4083 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4084 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4085 default: return NULL;
103f02d3 4086 }
103f02d3
UD
4087}
4088
4d6ed7c8 4089static const char *
dda8d76d 4090get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4091{
18bd398b 4092 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4093 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4094 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4095
4d6ed7c8
NC
4096 switch (sh_type)
4097 {
148b93f2
NC
4098 case SHT_IA_64_EXT: return "IA_64_EXT";
4099 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4100 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4101 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4102 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4103 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4104 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4105 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4106 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4107 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4108 default:
4109 break;
4110 }
4111 return NULL;
4112}
4113
d2b2c203
DJ
4114static const char *
4115get_x86_64_section_type_name (unsigned int sh_type)
4116{
4117 switch (sh_type)
4118 {
4119 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4120 default: return NULL;
d2b2c203 4121 }
d2b2c203
DJ
4122}
4123
a06ea964
NC
4124static const char *
4125get_aarch64_section_type_name (unsigned int sh_type)
4126{
4127 switch (sh_type)
4128 {
32ec8896
NC
4129 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4130 default: return NULL;
a06ea964 4131 }
a06ea964
NC
4132}
4133
40a18ebd
NC
4134static const char *
4135get_arm_section_type_name (unsigned int sh_type)
4136{
4137 switch (sh_type)
4138 {
7f6fed87
NC
4139 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4140 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4141 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4142 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4143 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4144 default: return NULL;
40a18ebd 4145 }
40a18ebd
NC
4146}
4147
40b36596
JM
4148static const char *
4149get_tic6x_section_type_name (unsigned int sh_type)
4150{
4151 switch (sh_type)
4152 {
32ec8896
NC
4153 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4154 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4155 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4156 case SHT_TI_ICODE: return "TI_ICODE";
4157 case SHT_TI_XREF: return "TI_XREF";
4158 case SHT_TI_HANDLER: return "TI_HANDLER";
4159 case SHT_TI_INITINFO: return "TI_INITINFO";
4160 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4161 default: return NULL;
40b36596 4162 }
40b36596
JM
4163}
4164
13761a11
NC
4165static const char *
4166get_msp430x_section_type_name (unsigned int sh_type)
4167{
4168 switch (sh_type)
4169 {
32ec8896
NC
4170 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4171 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4172 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4173 default: return NULL;
13761a11
NC
4174 }
4175}
4176
fe944acf
FT
4177static const char *
4178get_nfp_section_type_name (unsigned int sh_type)
4179{
4180 switch (sh_type)
4181 {
4182 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4183 case SHT_NFP_INITREG: return "NFP_INITREG";
4184 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4185 default: return NULL;
4186 }
4187}
4188
685080f2
NC
4189static const char *
4190get_v850_section_type_name (unsigned int sh_type)
4191{
4192 switch (sh_type)
4193 {
32ec8896
NC
4194 case SHT_V850_SCOMMON: return "V850 Small Common";
4195 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4196 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4197 case SHT_RENESAS_IOP: return "RENESAS IOP";
4198 case SHT_RENESAS_INFO: return "RENESAS INFO";
4199 default: return NULL;
685080f2
NC
4200 }
4201}
4202
252b5132 4203static const char *
dda8d76d 4204get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4205{
b34976b6 4206 static char buff[32];
9fb71ee4 4207 const char * result;
252b5132
RH
4208
4209 switch (sh_type)
4210 {
4211 case SHT_NULL: return "NULL";
4212 case SHT_PROGBITS: return "PROGBITS";
4213 case SHT_SYMTAB: return "SYMTAB";
4214 case SHT_STRTAB: return "STRTAB";
4215 case SHT_RELA: return "RELA";
4216 case SHT_HASH: return "HASH";
4217 case SHT_DYNAMIC: return "DYNAMIC";
4218 case SHT_NOTE: return "NOTE";
4219 case SHT_NOBITS: return "NOBITS";
4220 case SHT_REL: return "REL";
4221 case SHT_SHLIB: return "SHLIB";
4222 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4223 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4224 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4225 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4226 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4227 case SHT_GROUP: return "GROUP";
67ce483b 4228 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4229 case SHT_GNU_verdef: return "VERDEF";
4230 case SHT_GNU_verneed: return "VERNEED";
4231 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4232 case 0x6ffffff0: return "VERSYM";
4233 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4234 case 0x7ffffffd: return "AUXILIARY";
4235 case 0x7fffffff: return "FILTER";
047b2264 4236 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4237
4238 default:
4239 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4240 {
dda8d76d 4241 switch (filedata->file_header.e_machine)
252b5132 4242 {
53a346d8
CZ
4243 case EM_ARC:
4244 case EM_ARC_COMPACT:
4245 case EM_ARC_COMPACT2:
4246 result = get_arc_section_type_name (sh_type);
4247 break;
252b5132 4248 case EM_MIPS:
4fe85591 4249 case EM_MIPS_RS3_LE:
252b5132
RH
4250 result = get_mips_section_type_name (sh_type);
4251 break;
103f02d3
UD
4252 case EM_PARISC:
4253 result = get_parisc_section_type_name (sh_type);
4254 break;
4d6ed7c8 4255 case EM_IA_64:
dda8d76d 4256 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4257 break;
d2b2c203 4258 case EM_X86_64:
8a9036a4 4259 case EM_L1OM:
7a9068fe 4260 case EM_K1OM:
d2b2c203
DJ
4261 result = get_x86_64_section_type_name (sh_type);
4262 break;
a06ea964
NC
4263 case EM_AARCH64:
4264 result = get_aarch64_section_type_name (sh_type);
4265 break;
40a18ebd
NC
4266 case EM_ARM:
4267 result = get_arm_section_type_name (sh_type);
4268 break;
40b36596
JM
4269 case EM_TI_C6000:
4270 result = get_tic6x_section_type_name (sh_type);
4271 break;
13761a11
NC
4272 case EM_MSP430:
4273 result = get_msp430x_section_type_name (sh_type);
4274 break;
fe944acf
FT
4275 case EM_NFP:
4276 result = get_nfp_section_type_name (sh_type);
4277 break;
685080f2
NC
4278 case EM_V800:
4279 case EM_V850:
4280 case EM_CYGNUS_V850:
4281 result = get_v850_section_type_name (sh_type);
4282 break;
252b5132
RH
4283 default:
4284 result = NULL;
4285 break;
4286 }
4287
4288 if (result != NULL)
4289 return result;
4290
9fb71ee4 4291 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4292 }
4293 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4294 {
dda8d76d 4295 switch (filedata->file_header.e_machine)
148b93f2
NC
4296 {
4297 case EM_IA_64:
dda8d76d 4298 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4299 break;
4300 default:
dda8d76d 4301 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4302 result = get_solaris_section_type (sh_type);
4303 else
1b4b80bf
NC
4304 {
4305 switch (sh_type)
4306 {
4307 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4308 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4309 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4310 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4311 default:
4312 result = NULL;
4313 break;
4314 }
4315 }
148b93f2
NC
4316 break;
4317 }
4318
4319 if (result != NULL)
4320 return result;
4321
9fb71ee4 4322 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4323 }
252b5132 4324 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4325 {
dda8d76d 4326 switch (filedata->file_header.e_machine)
685080f2
NC
4327 {
4328 case EM_V800:
4329 case EM_V850:
4330 case EM_CYGNUS_V850:
9fb71ee4 4331 result = get_v850_section_type_name (sh_type);
a9fb83be 4332 break;
685080f2 4333 default:
9fb71ee4 4334 result = NULL;
685080f2
NC
4335 break;
4336 }
4337
9fb71ee4
NC
4338 if (result != NULL)
4339 return result;
4340
4341 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4342 }
252b5132 4343 else
a7dbfd1c
NC
4344 /* This message is probably going to be displayed in a 15
4345 character wide field, so put the hex value first. */
4346 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4347
252b5132
RH
4348 return buff;
4349 }
4350}
4351
2979dc34 4352#define OPTION_DEBUG_DUMP 512
2c610e4b 4353#define OPTION_DYN_SYMS 513
fd2f0033
TT
4354#define OPTION_DWARF_DEPTH 514
4355#define OPTION_DWARF_START 515
4723351a 4356#define OPTION_DWARF_CHECK 516
2979dc34 4357
85b1c36d 4358static struct option options[] =
252b5132 4359{
b34976b6 4360 {"all", no_argument, 0, 'a'},
252b5132
RH
4361 {"file-header", no_argument, 0, 'h'},
4362 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4363 {"headers", no_argument, 0, 'e'},
4364 {"histogram", no_argument, 0, 'I'},
4365 {"segments", no_argument, 0, 'l'},
4366 {"sections", no_argument, 0, 'S'},
252b5132 4367 {"section-headers", no_argument, 0, 'S'},
f5842774 4368 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4369 {"section-details", no_argument, 0, 't'},
595cf52e 4370 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4371 {"symbols", no_argument, 0, 's'},
4372 {"syms", no_argument, 0, 's'},
2c610e4b 4373 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4374 {"relocs", no_argument, 0, 'r'},
4375 {"notes", no_argument, 0, 'n'},
4376 {"dynamic", no_argument, 0, 'd'},
a952a375 4377 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4378 {"version-info", no_argument, 0, 'V'},
4379 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4380 {"unwind", no_argument, 0, 'u'},
4145f1d5 4381 {"archive-index", no_argument, 0, 'c'},
b34976b6 4382 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4383 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4384 {"string-dump", required_argument, 0, 'p'},
0e602686 4385 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4386#ifdef SUPPORT_DISASSEMBLY
4387 {"instruction-dump", required_argument, 0, 'i'},
4388#endif
cf13d699 4389 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4390
fd2f0033
TT
4391 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4392 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4393 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4394
b34976b6
AM
4395 {"version", no_argument, 0, 'v'},
4396 {"wide", no_argument, 0, 'W'},
4397 {"help", no_argument, 0, 'H'},
4398 {0, no_argument, 0, 0}
252b5132
RH
4399};
4400
4401static void
2cf0635d 4402usage (FILE * stream)
252b5132 4403{
92f01d61
JM
4404 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4405 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4406 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4407 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4408 -h --file-header Display the ELF file header\n\
4409 -l --program-headers Display the program headers\n\
4410 --segments An alias for --program-headers\n\
4411 -S --section-headers Display the sections' header\n\
4412 --sections An alias for --section-headers\n\
f5842774 4413 -g --section-groups Display the section groups\n\
5477e8a0 4414 -t --section-details Display the section details\n\
8b53311e
NC
4415 -e --headers Equivalent to: -h -l -S\n\
4416 -s --syms Display the symbol table\n\
3f08eb35 4417 --symbols An alias for --syms\n\
2c610e4b 4418 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4419 -n --notes Display the core notes (if present)\n\
4420 -r --relocs Display the relocations (if present)\n\
4421 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4422 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4423 -V --version-info Display the version sections (if present)\n\
1b31d05e 4424 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4425 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4426 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
4427 -x --hex-dump=<number|name>\n\
4428 Dump the contents of section <number|name> as bytes\n\
4429 -p --string-dump=<number|name>\n\
4430 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4431 -R --relocated-dump=<number|name>\n\
4432 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4433 -z --decompress Decompress section before dumping it\n\
dda8d76d 4434 -w[lLiaprmfFsoRtUuTgAckK] or\n\
1ed06042 4435 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4436 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47 4437 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4438 =addr,=cu_index,=links,=follow-links]\n\
4439 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4440 fprintf (stream, _("\
4441 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4442 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4443 or deeper\n"));
252b5132 4444#ifdef SUPPORT_DISASSEMBLY
92f01d61 4445 fprintf (stream, _("\
09c11c86
NC
4446 -i --instruction-dump=<number|name>\n\
4447 Disassemble the contents of section <number|name>\n"));
252b5132 4448#endif
92f01d61 4449 fprintf (stream, _("\
8b53311e
NC
4450 -I --histogram Display histogram of bucket list lengths\n\
4451 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4452 @<file> Read options from <file>\n\
8b53311e
NC
4453 -H --help Display this information\n\
4454 -v --version Display the version number of readelf\n"));
1118d252 4455
92f01d61
JM
4456 if (REPORT_BUGS_TO[0] && stream == stdout)
4457 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4458
92f01d61 4459 exit (stream == stdout ? 0 : 1);
252b5132
RH
4460}
4461
18bd398b
NC
4462/* Record the fact that the user wants the contents of section number
4463 SECTION to be displayed using the method(s) encoded as flags bits
4464 in TYPE. Note, TYPE can be zero if we are creating the array for
4465 the first time. */
4466
252b5132 4467static void
dda8d76d 4468request_dump_bynumber (Filedata * filedata, unsigned int section, dump_type type)
252b5132 4469{
dda8d76d 4470 if (section >= filedata->num_dump_sects)
252b5132 4471 {
2cf0635d 4472 dump_type * new_dump_sects;
252b5132 4473
3f5e193b 4474 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4475 sizeof (* new_dump_sects));
252b5132
RH
4476
4477 if (new_dump_sects == NULL)
591a748a 4478 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4479 else
4480 {
dda8d76d 4481 if (filedata->dump_sects)
21b65bac
NC
4482 {
4483 /* Copy current flag settings. */
dda8d76d
NC
4484 memcpy (new_dump_sects, filedata->dump_sects,
4485 filedata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4486
dda8d76d 4487 free (filedata->dump_sects);
21b65bac 4488 }
252b5132 4489
dda8d76d
NC
4490 filedata->dump_sects = new_dump_sects;
4491 filedata->num_dump_sects = section + 1;
252b5132
RH
4492 }
4493 }
4494
dda8d76d
NC
4495 if (filedata->dump_sects)
4496 filedata->dump_sects[section] |= type;
252b5132
RH
4497}
4498
aef1f6d0
DJ
4499/* Request a dump by section name. */
4500
4501static void
2cf0635d 4502request_dump_byname (const char * section, dump_type type)
aef1f6d0 4503{
2cf0635d 4504 struct dump_list_entry * new_request;
aef1f6d0 4505
3f5e193b
NC
4506 new_request = (struct dump_list_entry *)
4507 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4508 if (!new_request)
591a748a 4509 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4510
4511 new_request->name = strdup (section);
4512 if (!new_request->name)
591a748a 4513 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4514
4515 new_request->type = type;
4516
4517 new_request->next = dump_sects_byname;
4518 dump_sects_byname = new_request;
4519}
4520
cf13d699 4521static inline void
dda8d76d 4522request_dump (Filedata * filedata, dump_type type)
cf13d699
NC
4523{
4524 int section;
4525 char * cp;
4526
4527 do_dump++;
4528 section = strtoul (optarg, & cp, 0);
4529
4530 if (! *cp && section >= 0)
dda8d76d 4531 request_dump_bynumber (filedata, section, type);
cf13d699
NC
4532 else
4533 request_dump_byname (optarg, type);
4534}
4535
252b5132 4536static void
dda8d76d 4537parse_args (Filedata * filedata, int argc, char ** argv)
252b5132
RH
4538{
4539 int c;
4540
4541 if (argc < 2)
92f01d61 4542 usage (stderr);
252b5132
RH
4543
4544 while ((c = getopt_long
0e602686 4545 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4546 {
252b5132
RH
4547 switch (c)
4548 {
4549 case 0:
4550 /* Long options. */
4551 break;
4552 case 'H':
92f01d61 4553 usage (stdout);
252b5132
RH
4554 break;
4555
4556 case 'a':
32ec8896
NC
4557 do_syms = TRUE;
4558 do_reloc = TRUE;
4559 do_unwind = TRUE;
4560 do_dynamic = TRUE;
4561 do_header = TRUE;
4562 do_sections = TRUE;
4563 do_section_groups = TRUE;
4564 do_segments = TRUE;
4565 do_version = TRUE;
4566 do_histogram = TRUE;
4567 do_arch = TRUE;
4568 do_notes = TRUE;
252b5132 4569 break;
f5842774 4570 case 'g':
32ec8896 4571 do_section_groups = TRUE;
f5842774 4572 break;
5477e8a0 4573 case 't':
595cf52e 4574 case 'N':
32ec8896
NC
4575 do_sections = TRUE;
4576 do_section_details = TRUE;
595cf52e 4577 break;
252b5132 4578 case 'e':
32ec8896
NC
4579 do_header = TRUE;
4580 do_sections = TRUE;
4581 do_segments = TRUE;
252b5132 4582 break;
a952a375 4583 case 'A':
32ec8896 4584 do_arch = TRUE;
a952a375 4585 break;
252b5132 4586 case 'D':
32ec8896 4587 do_using_dynamic = TRUE;
252b5132
RH
4588 break;
4589 case 'r':
32ec8896 4590 do_reloc = TRUE;
252b5132 4591 break;
4d6ed7c8 4592 case 'u':
32ec8896 4593 do_unwind = TRUE;
4d6ed7c8 4594 break;
252b5132 4595 case 'h':
32ec8896 4596 do_header = TRUE;
252b5132
RH
4597 break;
4598 case 'l':
32ec8896 4599 do_segments = TRUE;
252b5132
RH
4600 break;
4601 case 's':
32ec8896 4602 do_syms = TRUE;
252b5132
RH
4603 break;
4604 case 'S':
32ec8896 4605 do_sections = TRUE;
252b5132
RH
4606 break;
4607 case 'd':
32ec8896 4608 do_dynamic = TRUE;
252b5132 4609 break;
a952a375 4610 case 'I':
32ec8896 4611 do_histogram = TRUE;
a952a375 4612 break;
779fe533 4613 case 'n':
32ec8896 4614 do_notes = TRUE;
779fe533 4615 break;
4145f1d5 4616 case 'c':
32ec8896 4617 do_archive_index = TRUE;
4145f1d5 4618 break;
252b5132 4619 case 'x':
dda8d76d 4620 request_dump (filedata, HEX_DUMP);
aef1f6d0 4621 break;
09c11c86 4622 case 'p':
dda8d76d 4623 request_dump (filedata, STRING_DUMP);
cf13d699
NC
4624 break;
4625 case 'R':
dda8d76d 4626 request_dump (filedata, RELOC_DUMP);
09c11c86 4627 break;
0e602686 4628 case 'z':
32ec8896 4629 decompress_dumps = TRUE;
0e602686 4630 break;
252b5132 4631 case 'w':
32ec8896 4632 do_dump = TRUE;
252b5132 4633 if (optarg == 0)
613ff48b 4634 {
32ec8896 4635 do_debugging = TRUE;
613ff48b
CC
4636 dwarf_select_sections_all ();
4637 }
252b5132
RH
4638 else
4639 {
32ec8896 4640 do_debugging = FALSE;
4cb93e3b 4641 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4642 }
4643 break;
2979dc34 4644 case OPTION_DEBUG_DUMP:
32ec8896 4645 do_dump = TRUE;
2979dc34 4646 if (optarg == 0)
32ec8896 4647 do_debugging = TRUE;
2979dc34
JJ
4648 else
4649 {
32ec8896 4650 do_debugging = FALSE;
4cb93e3b 4651 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4652 }
4653 break;
fd2f0033
TT
4654 case OPTION_DWARF_DEPTH:
4655 {
4656 char *cp;
4657
4658 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4659 }
4660 break;
4661 case OPTION_DWARF_START:
4662 {
4663 char *cp;
4664
4665 dwarf_start_die = strtoul (optarg, & cp, 0);
4666 }
4667 break;
4723351a 4668 case OPTION_DWARF_CHECK:
32ec8896 4669 dwarf_check = TRUE;
4723351a 4670 break;
2c610e4b 4671 case OPTION_DYN_SYMS:
32ec8896 4672 do_dyn_syms = TRUE;
2c610e4b 4673 break;
252b5132
RH
4674#ifdef SUPPORT_DISASSEMBLY
4675 case 'i':
dda8d76d 4676 request_dump (filedata, DISASS_DUMP);
cf13d699 4677 break;
252b5132
RH
4678#endif
4679 case 'v':
4680 print_version (program_name);
4681 break;
4682 case 'V':
32ec8896 4683 do_version = TRUE;
252b5132 4684 break;
d974e256 4685 case 'W':
32ec8896 4686 do_wide = TRUE;
d974e256 4687 break;
252b5132 4688 default:
252b5132
RH
4689 /* xgettext:c-format */
4690 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4691 /* Fall through. */
252b5132 4692 case '?':
92f01d61 4693 usage (stderr);
252b5132
RH
4694 }
4695 }
4696
4d6ed7c8 4697 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4698 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4699 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4700 && !do_section_groups && !do_archive_index
4701 && !do_dyn_syms)
92f01d61 4702 usage (stderr);
252b5132
RH
4703}
4704
4705static const char *
d3ba0551 4706get_elf_class (unsigned int elf_class)
252b5132 4707{
b34976b6 4708 static char buff[32];
103f02d3 4709
252b5132
RH
4710 switch (elf_class)
4711 {
4712 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4713 case ELFCLASS32: return "ELF32";
4714 case ELFCLASS64: return "ELF64";
ab5e7794 4715 default:
e9e44622 4716 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4717 return buff;
252b5132
RH
4718 }
4719}
4720
4721static const char *
d3ba0551 4722get_data_encoding (unsigned int encoding)
252b5132 4723{
b34976b6 4724 static char buff[32];
103f02d3 4725
252b5132
RH
4726 switch (encoding)
4727 {
4728 case ELFDATANONE: return _("none");
33c63f9d
CM
4729 case ELFDATA2LSB: return _("2's complement, little endian");
4730 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4731 default:
e9e44622 4732 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4733 return buff;
252b5132
RH
4734 }
4735}
4736
dda8d76d 4737/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4738
32ec8896 4739static bfd_boolean
dda8d76d 4740process_file_header (Filedata * filedata)
252b5132 4741{
dda8d76d
NC
4742 Elf_Internal_Ehdr * header = & filedata->file_header;
4743
4744 if ( header->e_ident[EI_MAG0] != ELFMAG0
4745 || header->e_ident[EI_MAG1] != ELFMAG1
4746 || header->e_ident[EI_MAG2] != ELFMAG2
4747 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4748 {
4749 error
4750 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4751 return FALSE;
252b5132
RH
4752 }
4753
dda8d76d 4754 init_dwarf_regnames (header->e_machine);
2dc4cec1 4755
252b5132
RH
4756 if (do_header)
4757 {
32ec8896 4758 unsigned i;
252b5132
RH
4759
4760 printf (_("ELF Header:\n"));
4761 printf (_(" Magic: "));
b34976b6 4762 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4763 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4764 printf ("\n");
4765 printf (_(" Class: %s\n"),
dda8d76d 4766 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4767 printf (_(" Data: %s\n"),
dda8d76d 4768 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 4769 printf (_(" Version: %d%s\n"),
dda8d76d
NC
4770 header->e_ident[EI_VERSION],
4771 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 4772 ? _(" (current)")
dda8d76d 4773 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 4774 ? _(" <unknown>")
789be9f7 4775 : "")));
252b5132 4776 printf (_(" OS/ABI: %s\n"),
dda8d76d 4777 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 4778 printf (_(" ABI Version: %d\n"),
dda8d76d 4779 header->e_ident[EI_ABIVERSION]);
252b5132 4780 printf (_(" Type: %s\n"),
dda8d76d 4781 get_file_type (header->e_type));
252b5132 4782 printf (_(" Machine: %s\n"),
dda8d76d 4783 get_machine_name (header->e_machine));
252b5132 4784 printf (_(" Version: 0x%lx\n"),
e8a64888 4785 header->e_version);
76da6bbe 4786
f7a99963 4787 printf (_(" Entry point address: "));
e8a64888 4788 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 4789 printf (_("\n Start of program headers: "));
e8a64888 4790 print_vma (header->e_phoff, DEC);
f7a99963 4791 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 4792 print_vma (header->e_shoff, DEC);
f7a99963 4793 printf (_(" (bytes into file)\n"));
76da6bbe 4794
252b5132 4795 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 4796 header->e_flags,
dda8d76d 4797 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
4798 printf (_(" Size of this header: %u (bytes)\n"),
4799 header->e_ehsize);
4800 printf (_(" Size of program headers: %u (bytes)\n"),
4801 header->e_phentsize);
4802 printf (_(" Number of program headers: %u"),
4803 header->e_phnum);
dda8d76d
NC
4804 if (filedata->section_headers != NULL
4805 && header->e_phnum == PN_XNUM
4806 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
4807 {
4808 header->e_phnum = filedata->section_headers[0].sh_info;
4809 printf (" (%u)", header->e_phnum);
4810 }
2046a35d 4811 putc ('\n', stdout);
e8a64888
AM
4812 printf (_(" Size of section headers: %u (bytes)\n"),
4813 header->e_shentsize);
4814 printf (_(" Number of section headers: %u"),
4815 header->e_shnum);
dda8d76d 4816 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
4817 {
4818 header->e_shnum = filedata->section_headers[0].sh_size;
4819 printf (" (%u)", header->e_shnum);
4820 }
560f3c1c 4821 putc ('\n', stdout);
e8a64888
AM
4822 printf (_(" Section header string table index: %u"),
4823 header->e_shstrndx);
dda8d76d
NC
4824 if (filedata->section_headers != NULL
4825 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
4826 {
4827 header->e_shstrndx = filedata->section_headers[0].sh_link;
4828 printf (" (%u)", header->e_shstrndx);
4829 }
4830 if (header->e_shstrndx != SHN_UNDEF
4831 && header->e_shstrndx >= header->e_shnum)
4832 {
4833 header->e_shstrndx = SHN_UNDEF;
4834 printf (_(" <corrupt: out of range>"));
4835 }
560f3c1c
AM
4836 putc ('\n', stdout);
4837 }
4838
dda8d76d 4839 if (filedata->section_headers != NULL)
560f3c1c 4840 {
dda8d76d
NC
4841 if (header->e_phnum == PN_XNUM
4842 && filedata->section_headers[0].sh_info != 0)
4843 header->e_phnum = filedata->section_headers[0].sh_info;
4844 if (header->e_shnum == SHN_UNDEF)
4845 header->e_shnum = filedata->section_headers[0].sh_size;
4846 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
4847 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 4848 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
4849 header->e_shstrndx = SHN_UNDEF;
4850 free (filedata->section_headers);
4851 filedata->section_headers = NULL;
252b5132 4852 }
103f02d3 4853
32ec8896 4854 return TRUE;
9ea033b2
NC
4855}
4856
dda8d76d
NC
4857/* Read in the program headers from FILEDATA and store them in PHEADERS.
4858 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
4859
e0a31db1 4860static bfd_boolean
dda8d76d 4861get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4862{
2cf0635d
NC
4863 Elf32_External_Phdr * phdrs;
4864 Elf32_External_Phdr * external;
4865 Elf_Internal_Phdr * internal;
b34976b6 4866 unsigned int i;
dda8d76d
NC
4867 unsigned int size = filedata->file_header.e_phentsize;
4868 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4869
4870 /* PR binutils/17531: Cope with unexpected section header sizes. */
4871 if (size == 0 || num == 0)
4872 return FALSE;
4873 if (size < sizeof * phdrs)
4874 {
4875 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4876 return FALSE;
4877 }
4878 if (size > sizeof * phdrs)
4879 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4880
dda8d76d 4881 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
4882 size, num, _("program headers"));
4883 if (phdrs == NULL)
4884 return FALSE;
9ea033b2 4885
91d6fa6a 4886 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4887 i < filedata->file_header.e_phnum;
b34976b6 4888 i++, internal++, external++)
252b5132 4889 {
9ea033b2
NC
4890 internal->p_type = BYTE_GET (external->p_type);
4891 internal->p_offset = BYTE_GET (external->p_offset);
4892 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4893 internal->p_paddr = BYTE_GET (external->p_paddr);
4894 internal->p_filesz = BYTE_GET (external->p_filesz);
4895 internal->p_memsz = BYTE_GET (external->p_memsz);
4896 internal->p_flags = BYTE_GET (external->p_flags);
4897 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4898 }
4899
9ea033b2 4900 free (phdrs);
e0a31db1 4901 return TRUE;
252b5132
RH
4902}
4903
dda8d76d
NC
4904/* Read in the program headers from FILEDATA and store them in PHEADERS.
4905 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
4906
e0a31db1 4907static bfd_boolean
dda8d76d 4908get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4909{
2cf0635d
NC
4910 Elf64_External_Phdr * phdrs;
4911 Elf64_External_Phdr * external;
4912 Elf_Internal_Phdr * internal;
b34976b6 4913 unsigned int i;
dda8d76d
NC
4914 unsigned int size = filedata->file_header.e_phentsize;
4915 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4916
4917 /* PR binutils/17531: Cope with unexpected section header sizes. */
4918 if (size == 0 || num == 0)
4919 return FALSE;
4920 if (size < sizeof * phdrs)
4921 {
4922 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4923 return FALSE;
4924 }
4925 if (size > sizeof * phdrs)
4926 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4927
dda8d76d 4928 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 4929 size, num, _("program headers"));
a6e9f9df 4930 if (!phdrs)
e0a31db1 4931 return FALSE;
9ea033b2 4932
91d6fa6a 4933 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4934 i < filedata->file_header.e_phnum;
b34976b6 4935 i++, internal++, external++)
9ea033b2
NC
4936 {
4937 internal->p_type = BYTE_GET (external->p_type);
4938 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4939 internal->p_offset = BYTE_GET (external->p_offset);
4940 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4941 internal->p_paddr = BYTE_GET (external->p_paddr);
4942 internal->p_filesz = BYTE_GET (external->p_filesz);
4943 internal->p_memsz = BYTE_GET (external->p_memsz);
4944 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4945 }
4946
4947 free (phdrs);
e0a31db1 4948 return TRUE;
9ea033b2 4949}
252b5132 4950
32ec8896 4951/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 4952
32ec8896 4953static bfd_boolean
dda8d76d 4954get_program_headers (Filedata * filedata)
d93f0186 4955{
2cf0635d 4956 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4957
4958 /* Check cache of prior read. */
dda8d76d 4959 if (filedata->program_headers != NULL)
32ec8896 4960 return TRUE;
d93f0186 4961
82156ab7
NC
4962 /* Be kind to memory checkers by looking for
4963 e_phnum values which we know must be invalid. */
dda8d76d 4964 if (filedata->file_header.e_phnum
82156ab7 4965 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 4966 >= filedata->file_size)
82156ab7
NC
4967 {
4968 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 4969 filedata->file_header.e_phnum);
82156ab7
NC
4970 return FALSE;
4971 }
d93f0186 4972
dda8d76d 4973 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 4974 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4975 if (phdrs == NULL)
4976 {
8b73c356 4977 error (_("Out of memory reading %u program headers\n"),
dda8d76d 4978 filedata->file_header.e_phnum);
32ec8896 4979 return FALSE;
d93f0186
NC
4980 }
4981
4982 if (is_32bit_elf
dda8d76d
NC
4983 ? get_32bit_program_headers (filedata, phdrs)
4984 : get_64bit_program_headers (filedata, phdrs))
d93f0186 4985 {
dda8d76d 4986 filedata->program_headers = phdrs;
32ec8896 4987 return TRUE;
d93f0186
NC
4988 }
4989
4990 free (phdrs);
32ec8896 4991 return FALSE;
d93f0186
NC
4992}
4993
32ec8896 4994/* Returns TRUE if the program headers were loaded. */
2f62977e 4995
32ec8896 4996static bfd_boolean
dda8d76d 4997process_program_headers (Filedata * filedata)
252b5132 4998{
2cf0635d 4999 Elf_Internal_Phdr * segment;
b34976b6 5000 unsigned int i;
1a9ccd70 5001 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5002
dda8d76d 5003 if (filedata->file_header.e_phnum == 0)
252b5132 5004 {
82f2dbf7 5005 /* PR binutils/12467. */
dda8d76d 5006 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5007 {
5008 warn (_("possibly corrupt ELF header - it has a non-zero program"
5009 " header offset, but no program headers\n"));
5010 return FALSE;
5011 }
82f2dbf7 5012 else if (do_segments)
252b5132 5013 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5014 return TRUE;
252b5132
RH
5015 }
5016
5017 if (do_segments && !do_header)
5018 {
dda8d76d
NC
5019 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5020 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5021 printf (ngettext ("There is %d program header, starting at offset %s\n",
5022 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5023 filedata->file_header.e_phnum),
5024 filedata->file_header.e_phnum,
5025 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5026 }
5027
dda8d76d 5028 if (! get_program_headers (filedata))
6b4bf3bc 5029 return TRUE;
103f02d3 5030
252b5132
RH
5031 if (do_segments)
5032 {
dda8d76d 5033 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5034 printf (_("\nProgram Headers:\n"));
5035 else
5036 printf (_("\nProgram Headers:\n"));
76da6bbe 5037
f7a99963
NC
5038 if (is_32bit_elf)
5039 printf
5040 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5041 else if (do_wide)
5042 printf
5043 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5044 else
5045 {
5046 printf
5047 (_(" Type Offset VirtAddr PhysAddr\n"));
5048 printf
5049 (_(" FileSiz MemSiz Flags Align\n"));
5050 }
252b5132
RH
5051 }
5052
252b5132 5053 dynamic_addr = 0;
1b228002 5054 dynamic_size = 0;
252b5132 5055
dda8d76d
NC
5056 for (i = 0, segment = filedata->program_headers;
5057 i < filedata->file_header.e_phnum;
b34976b6 5058 i++, segment++)
252b5132
RH
5059 {
5060 if (do_segments)
5061 {
dda8d76d 5062 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5063
5064 if (is_32bit_elf)
5065 {
5066 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5067 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5068 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5069 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5070 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5071 printf ("%c%c%c ",
5072 (segment->p_flags & PF_R ? 'R' : ' '),
5073 (segment->p_flags & PF_W ? 'W' : ' '),
5074 (segment->p_flags & PF_X ? 'E' : ' '));
5075 printf ("%#lx", (unsigned long) segment->p_align);
5076 }
d974e256
JJ
5077 else if (do_wide)
5078 {
5079 if ((unsigned long) segment->p_offset == segment->p_offset)
5080 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5081 else
5082 {
5083 print_vma (segment->p_offset, FULL_HEX);
5084 putchar (' ');
5085 }
5086
5087 print_vma (segment->p_vaddr, FULL_HEX);
5088 putchar (' ');
5089 print_vma (segment->p_paddr, FULL_HEX);
5090 putchar (' ');
5091
5092 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5093 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5094 else
5095 {
5096 print_vma (segment->p_filesz, FULL_HEX);
5097 putchar (' ');
5098 }
5099
5100 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5101 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5102 else
5103 {
f48e6c45 5104 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5105 }
5106
5107 printf (" %c%c%c ",
5108 (segment->p_flags & PF_R ? 'R' : ' '),
5109 (segment->p_flags & PF_W ? 'W' : ' '),
5110 (segment->p_flags & PF_X ? 'E' : ' '));
5111
5112 if ((unsigned long) segment->p_align == segment->p_align)
5113 printf ("%#lx", (unsigned long) segment->p_align);
5114 else
5115 {
5116 print_vma (segment->p_align, PREFIX_HEX);
5117 }
5118 }
f7a99963
NC
5119 else
5120 {
5121 print_vma (segment->p_offset, FULL_HEX);
5122 putchar (' ');
5123 print_vma (segment->p_vaddr, FULL_HEX);
5124 putchar (' ');
5125 print_vma (segment->p_paddr, FULL_HEX);
5126 printf ("\n ");
5127 print_vma (segment->p_filesz, FULL_HEX);
5128 putchar (' ');
5129 print_vma (segment->p_memsz, FULL_HEX);
5130 printf (" %c%c%c ",
5131 (segment->p_flags & PF_R ? 'R' : ' '),
5132 (segment->p_flags & PF_W ? 'W' : ' '),
5133 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5134 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5135 }
252b5132 5136
1a9ccd70
NC
5137 putc ('\n', stdout);
5138 }
f54498b4 5139
252b5132
RH
5140 switch (segment->p_type)
5141 {
1a9ccd70 5142 case PT_LOAD:
502d895c
NC
5143#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5144 required by the ELF standard, several programs, including the Linux
5145 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5146 if (previous_load
5147 && previous_load->p_vaddr > segment->p_vaddr)
5148 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5149#endif
1a9ccd70
NC
5150 if (segment->p_memsz < segment->p_filesz)
5151 error (_("the segment's file size is larger than its memory size\n"));
5152 previous_load = segment;
5153 break;
5154
5155 case PT_PHDR:
5156 /* PR 20815 - Verify that the program header is loaded into memory. */
5157 if (i > 0 && previous_load != NULL)
5158 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5159 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5160 {
5161 unsigned int j;
5162
dda8d76d
NC
5163 for (j = 1; j < filedata->file_header.e_phnum; j++)
5164 if (filedata->program_headers[j].p_vaddr <= segment->p_vaddr
5165 && (filedata->program_headers[j].p_vaddr
5166 + filedata->program_headers[j].p_memsz)
1a9ccd70
NC
5167 >= (segment->p_vaddr + segment->p_filesz))
5168 break;
dda8d76d 5169 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5170 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5171 }
5172 break;
5173
252b5132
RH
5174 case PT_DYNAMIC:
5175 if (dynamic_addr)
5176 error (_("more than one dynamic segment\n"));
5177
20737c13
AM
5178 /* By default, assume that the .dynamic section is the first
5179 section in the DYNAMIC segment. */
5180 dynamic_addr = segment->p_offset;
5181 dynamic_size = segment->p_filesz;
5182
b2d38a17
NC
5183 /* Try to locate the .dynamic section. If there is
5184 a section header table, we can easily locate it. */
dda8d76d 5185 if (filedata->section_headers != NULL)
b2d38a17 5186 {
2cf0635d 5187 Elf_Internal_Shdr * sec;
b2d38a17 5188
dda8d76d 5189 sec = find_section (filedata, ".dynamic");
89fac5e3 5190 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5191 {
28f997cf
TG
5192 /* A corresponding .dynamic section is expected, but on
5193 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5194 if (!is_ia64_vms (filedata))
28f997cf 5195 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5196 break;
5197 }
5198
42bb2e33 5199 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
5200 {
5201 dynamic_size = 0;
5202 break;
5203 }
42bb2e33 5204
b2d38a17
NC
5205 dynamic_addr = sec->sh_offset;
5206 dynamic_size = sec->sh_size;
5207
5208 if (dynamic_addr < segment->p_offset
5209 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
5210 warn (_("the .dynamic section is not contained"
5211 " within the dynamic segment\n"));
b2d38a17 5212 else if (dynamic_addr > segment->p_offset)
20737c13
AM
5213 warn (_("the .dynamic section is not the first section"
5214 " in the dynamic segment.\n"));
b2d38a17 5215 }
39e224f6
MW
5216
5217 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5218 segment. Check this after matching against the section headers
5219 so we don't warn on debuginfo file (which have NOBITS .dynamic
5220 sections). */
dda8d76d 5221 if (dynamic_addr + dynamic_size >= filedata->file_size)
39e224f6
MW
5222 {
5223 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
5224 dynamic_addr = dynamic_size = 0;
5225 }
252b5132
RH
5226 break;
5227
5228 case PT_INTERP:
dda8d76d 5229 if (fseek (filedata->handle, archive_file_offset + (long) segment->p_offset,
fb52b2f4 5230 SEEK_SET))
252b5132
RH
5231 error (_("Unable to find program interpreter name\n"));
5232 else
5233 {
f8eae8b2 5234 char fmt [32];
9495b2e6 5235 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5236
5237 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5238 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5239
252b5132 5240 program_interpreter[0] = 0;
dda8d76d 5241 if (fscanf (filedata->handle, fmt, program_interpreter) <= 0)
7bd7b3ef 5242 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5243
5244 if (do_segments)
f54498b4 5245 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
5246 program_interpreter);
5247 }
5248 break;
5249 }
252b5132
RH
5250 }
5251
dda8d76d
NC
5252 if (do_segments
5253 && filedata->section_headers != NULL
5254 && filedata->string_table != NULL)
252b5132
RH
5255 {
5256 printf (_("\n Section to Segment mapping:\n"));
5257 printf (_(" Segment Sections...\n"));
5258
dda8d76d 5259 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5260 {
9ad5cbcf 5261 unsigned int j;
2cf0635d 5262 Elf_Internal_Shdr * section;
252b5132 5263
dda8d76d
NC
5264 segment = filedata->program_headers + i;
5265 section = filedata->section_headers + 1;
252b5132
RH
5266
5267 printf (" %2.2d ", i);
5268
dda8d76d 5269 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5270 {
f4638467
AM
5271 if (!ELF_TBSS_SPECIAL (section, segment)
5272 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5273 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5274 }
5275
5276 putc ('\n',stdout);
5277 }
5278 }
5279
32ec8896 5280 return TRUE;
252b5132
RH
5281}
5282
5283
d93f0186
NC
5284/* Find the file offset corresponding to VMA by using the program headers. */
5285
5286static long
dda8d76d 5287offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5288{
2cf0635d 5289 Elf_Internal_Phdr * seg;
d93f0186 5290
dda8d76d 5291 if (! get_program_headers (filedata))
d93f0186
NC
5292 {
5293 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5294 return (long) vma;
5295 }
5296
dda8d76d
NC
5297 for (seg = filedata->program_headers;
5298 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5299 ++seg)
5300 {
5301 if (seg->p_type != PT_LOAD)
5302 continue;
5303
5304 if (vma >= (seg->p_vaddr & -seg->p_align)
5305 && vma + size <= seg->p_vaddr + seg->p_filesz)
5306 return vma - seg->p_vaddr + seg->p_offset;
5307 }
5308
5309 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5310 (unsigned long) vma);
d93f0186
NC
5311 return (long) vma;
5312}
5313
5314
dda8d76d
NC
5315/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5316 If PROBE is true, this is just a probe and we do not generate any error
5317 messages if the load fails. */
049b0c3a
NC
5318
5319static bfd_boolean
dda8d76d 5320get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5321{
2cf0635d
NC
5322 Elf32_External_Shdr * shdrs;
5323 Elf_Internal_Shdr * internal;
dda8d76d
NC
5324 unsigned int i;
5325 unsigned int size = filedata->file_header.e_shentsize;
5326 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5327
5328 /* PR binutils/17531: Cope with unexpected section header sizes. */
5329 if (size == 0 || num == 0)
5330 return FALSE;
5331 if (size < sizeof * shdrs)
5332 {
5333 if (! probe)
5334 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5335 return FALSE;
5336 }
5337 if (!probe && size > sizeof * shdrs)
5338 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5339
dda8d76d 5340 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5341 size, num,
5342 probe ? NULL : _("section headers"));
5343 if (shdrs == NULL)
5344 return FALSE;
252b5132 5345
dda8d76d
NC
5346 free (filedata->section_headers);
5347 filedata->section_headers = (Elf_Internal_Shdr *)
5348 cmalloc (num, sizeof (Elf_Internal_Shdr));
5349 if (filedata->section_headers == NULL)
252b5132 5350 {
049b0c3a 5351 if (!probe)
8b73c356 5352 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5353 free (shdrs);
049b0c3a 5354 return FALSE;
252b5132
RH
5355 }
5356
dda8d76d 5357 for (i = 0, internal = filedata->section_headers;
560f3c1c 5358 i < num;
b34976b6 5359 i++, internal++)
252b5132
RH
5360 {
5361 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5362 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5363 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5364 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5365 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5366 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5367 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5368 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5369 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5370 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5371 if (!probe && internal->sh_link > num)
5372 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5373 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5374 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5375 }
5376
5377 free (shdrs);
049b0c3a 5378 return TRUE;
252b5132
RH
5379}
5380
dda8d76d
NC
5381/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5382
049b0c3a 5383static bfd_boolean
dda8d76d 5384get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5385{
dda8d76d
NC
5386 Elf64_External_Shdr * shdrs;
5387 Elf_Internal_Shdr * internal;
5388 unsigned int i;
5389 unsigned int size = filedata->file_header.e_shentsize;
5390 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5391
5392 /* PR binutils/17531: Cope with unexpected section header sizes. */
5393 if (size == 0 || num == 0)
5394 return FALSE;
dda8d76d 5395
049b0c3a
NC
5396 if (size < sizeof * shdrs)
5397 {
5398 if (! probe)
5399 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5400 return FALSE;
5401 }
dda8d76d 5402
049b0c3a
NC
5403 if (! probe && size > sizeof * shdrs)
5404 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5405
dda8d76d
NC
5406 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5407 filedata->file_header.e_shoff,
049b0c3a
NC
5408 size, num,
5409 probe ? NULL : _("section headers"));
5410 if (shdrs == NULL)
5411 return FALSE;
9ea033b2 5412
dda8d76d
NC
5413 free (filedata->section_headers);
5414 filedata->section_headers = (Elf_Internal_Shdr *)
5415 cmalloc (num, sizeof (Elf_Internal_Shdr));
5416 if (filedata->section_headers == NULL)
9ea033b2 5417 {
049b0c3a 5418 if (! probe)
8b73c356 5419 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5420 free (shdrs);
049b0c3a 5421 return FALSE;
9ea033b2
NC
5422 }
5423
dda8d76d 5424 for (i = 0, internal = filedata->section_headers;
560f3c1c 5425 i < num;
b34976b6 5426 i++, internal++)
9ea033b2
NC
5427 {
5428 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5429 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5430 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5431 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5432 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5433 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5434 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5435 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5436 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5437 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5438 if (!probe && internal->sh_link > num)
5439 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5440 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5441 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5442 }
5443
5444 free (shdrs);
049b0c3a 5445 return TRUE;
9ea033b2
NC
5446}
5447
252b5132 5448static Elf_Internal_Sym *
dda8d76d
NC
5449get_32bit_elf_symbols (Filedata * filedata,
5450 Elf_Internal_Shdr * section,
5451 unsigned long * num_syms_return)
252b5132 5452{
ba5cdace 5453 unsigned long number = 0;
dd24e3da 5454 Elf32_External_Sym * esyms = NULL;
ba5cdace 5455 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5456 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5457 Elf_Internal_Sym * psym;
b34976b6 5458 unsigned int j;
e3d39609 5459 elf_section_list * entry;
252b5132 5460
c9c1d674
EG
5461 if (section->sh_size == 0)
5462 {
5463 if (num_syms_return != NULL)
5464 * num_syms_return = 0;
5465 return NULL;
5466 }
5467
dd24e3da 5468 /* Run some sanity checks first. */
c9c1d674 5469 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5470 {
c9c1d674 5471 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5472 printable_section_name (filedata, section),
5473 (unsigned long) section->sh_entsize);
ba5cdace 5474 goto exit_point;
dd24e3da
NC
5475 }
5476
dda8d76d 5477 if (section->sh_size > filedata->file_size)
f54498b4
NC
5478 {
5479 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5480 printable_section_name (filedata, section),
5481 (unsigned long) section->sh_size);
f54498b4
NC
5482 goto exit_point;
5483 }
5484
dd24e3da
NC
5485 number = section->sh_size / section->sh_entsize;
5486
5487 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5488 {
c9c1d674 5489 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5490 (unsigned long) section->sh_size,
dda8d76d 5491 printable_section_name (filedata, section),
8066deb1 5492 (unsigned long) section->sh_entsize);
ba5cdace 5493 goto exit_point;
dd24e3da
NC
5494 }
5495
dda8d76d 5496 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5497 section->sh_size, _("symbols"));
dd24e3da 5498 if (esyms == NULL)
ba5cdace 5499 goto exit_point;
252b5132 5500
e3d39609
NC
5501 shndx = NULL;
5502 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5503 {
5504 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5505 continue;
5506
5507 if (shndx != NULL)
5508 {
5509 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5510 free (shndx);
5511 }
5512
5513 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5514 entry->hdr->sh_offset,
5515 1, entry->hdr->sh_size,
5516 _("symbol table section indices"));
5517 if (shndx == NULL)
5518 goto exit_point;
5519
5520 /* PR17531: file: heap-buffer-overflow */
5521 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5522 {
5523 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5524 printable_section_name (filedata, entry->hdr),
5525 (unsigned long) entry->hdr->sh_size,
5526 (unsigned long) section->sh_size);
5527 goto exit_point;
c9c1d674 5528 }
e3d39609 5529 }
9ad5cbcf 5530
3f5e193b 5531 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5532
5533 if (isyms == NULL)
5534 {
8b73c356
NC
5535 error (_("Out of memory reading %lu symbols\n"),
5536 (unsigned long) number);
dd24e3da 5537 goto exit_point;
252b5132
RH
5538 }
5539
dd24e3da 5540 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5541 {
5542 psym->st_name = BYTE_GET (esyms[j].st_name);
5543 psym->st_value = BYTE_GET (esyms[j].st_value);
5544 psym->st_size = BYTE_GET (esyms[j].st_size);
5545 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5546 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5547 psym->st_shndx
5548 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5549 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5550 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5551 psym->st_info = BYTE_GET (esyms[j].st_info);
5552 psym->st_other = BYTE_GET (esyms[j].st_other);
5553 }
5554
dd24e3da 5555 exit_point:
e3d39609
NC
5556 free (shndx);
5557 free (esyms);
252b5132 5558
ba5cdace
NC
5559 if (num_syms_return != NULL)
5560 * num_syms_return = isyms == NULL ? 0 : number;
5561
252b5132
RH
5562 return isyms;
5563}
5564
9ea033b2 5565static Elf_Internal_Sym *
dda8d76d
NC
5566get_64bit_elf_symbols (Filedata * filedata,
5567 Elf_Internal_Shdr * section,
5568 unsigned long * num_syms_return)
9ea033b2 5569{
ba5cdace
NC
5570 unsigned long number = 0;
5571 Elf64_External_Sym * esyms = NULL;
5572 Elf_External_Sym_Shndx * shndx = NULL;
5573 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5574 Elf_Internal_Sym * psym;
b34976b6 5575 unsigned int j;
e3d39609 5576 elf_section_list * entry;
9ea033b2 5577
c9c1d674
EG
5578 if (section->sh_size == 0)
5579 {
5580 if (num_syms_return != NULL)
5581 * num_syms_return = 0;
5582 return NULL;
5583 }
5584
dd24e3da 5585 /* Run some sanity checks first. */
c9c1d674 5586 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5587 {
c9c1d674 5588 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5589 printable_section_name (filedata, section),
8066deb1 5590 (unsigned long) section->sh_entsize);
ba5cdace 5591 goto exit_point;
dd24e3da
NC
5592 }
5593
dda8d76d 5594 if (section->sh_size > filedata->file_size)
f54498b4
NC
5595 {
5596 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5597 printable_section_name (filedata, section),
8066deb1 5598 (unsigned long) section->sh_size);
f54498b4
NC
5599 goto exit_point;
5600 }
5601
dd24e3da
NC
5602 number = section->sh_size / section->sh_entsize;
5603
5604 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5605 {
c9c1d674 5606 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5607 (unsigned long) section->sh_size,
dda8d76d 5608 printable_section_name (filedata, section),
8066deb1 5609 (unsigned long) section->sh_entsize);
ba5cdace 5610 goto exit_point;
dd24e3da
NC
5611 }
5612
dda8d76d 5613 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5614 section->sh_size, _("symbols"));
a6e9f9df 5615 if (!esyms)
ba5cdace 5616 goto exit_point;
9ea033b2 5617
e3d39609
NC
5618 shndx = NULL;
5619 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5620 {
5621 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5622 continue;
5623
5624 if (shndx != NULL)
5625 {
5626 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5627 free (shndx);
c9c1d674 5628 }
e3d39609
NC
5629
5630 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5631 entry->hdr->sh_offset,
5632 1, entry->hdr->sh_size,
5633 _("symbol table section indices"));
5634 if (shndx == NULL)
5635 goto exit_point;
5636
5637 /* PR17531: file: heap-buffer-overflow */
5638 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5639 {
5640 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5641 printable_section_name (filedata, entry->hdr),
5642 (unsigned long) entry->hdr->sh_size,
5643 (unsigned long) section->sh_size);
5644 goto exit_point;
5645 }
5646 }
9ad5cbcf 5647
3f5e193b 5648 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5649
5650 if (isyms == NULL)
5651 {
8b73c356
NC
5652 error (_("Out of memory reading %lu symbols\n"),
5653 (unsigned long) number);
ba5cdace 5654 goto exit_point;
9ea033b2
NC
5655 }
5656
ba5cdace 5657 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5658 {
5659 psym->st_name = BYTE_GET (esyms[j].st_name);
5660 psym->st_info = BYTE_GET (esyms[j].st_info);
5661 psym->st_other = BYTE_GET (esyms[j].st_other);
5662 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5663
4fbb74a6 5664 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5665 psym->st_shndx
5666 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5667 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5668 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5669
66543521
AM
5670 psym->st_value = BYTE_GET (esyms[j].st_value);
5671 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5672 }
5673
ba5cdace 5674 exit_point:
e3d39609
NC
5675 free (shndx);
5676 free (esyms);
ba5cdace
NC
5677
5678 if (num_syms_return != NULL)
5679 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5680
5681 return isyms;
5682}
5683
d1133906 5684static const char *
dda8d76d 5685get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5686{
5477e8a0 5687 static char buff[1024];
2cf0635d 5688 char * p = buff;
32ec8896
NC
5689 unsigned int field_size = is_32bit_elf ? 8 : 16;
5690 signed int sindex;
5691 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5692 bfd_vma os_flags = 0;
5693 bfd_vma proc_flags = 0;
5694 bfd_vma unknown_flags = 0;
148b93f2 5695 static const struct
5477e8a0 5696 {
2cf0635d 5697 const char * str;
32ec8896 5698 unsigned int len;
5477e8a0
L
5699 }
5700 flags [] =
5701 {
cfcac11d
NC
5702 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5703 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5704 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5705 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5706 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5707 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5708 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5709 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5710 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5711 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5712 /* IA-64 specific. */
5713 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5714 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5715 /* IA-64 OpenVMS specific. */
5716 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5717 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5718 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5719 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5720 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5721 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5722 /* Generic. */
cfcac11d 5723 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5724 /* SPARC specific. */
77115a4a 5725 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5726 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5727 /* ARM specific. */
5728 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5729 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5730 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5731 /* GNU specific. */
5732 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5733 /* VLE specific. */
5734 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5735 };
5736
5737 if (do_section_details)
5738 {
8d5ff12c
L
5739 sprintf (buff, "[%*.*lx]: ",
5740 field_size, field_size, (unsigned long) sh_flags);
5741 p += field_size + 4;
5477e8a0 5742 }
76da6bbe 5743
d1133906
NC
5744 while (sh_flags)
5745 {
5746 bfd_vma flag;
5747
5748 flag = sh_flags & - sh_flags;
5749 sh_flags &= ~ flag;
76da6bbe 5750
5477e8a0 5751 if (do_section_details)
d1133906 5752 {
5477e8a0
L
5753 switch (flag)
5754 {
91d6fa6a
NC
5755 case SHF_WRITE: sindex = 0; break;
5756 case SHF_ALLOC: sindex = 1; break;
5757 case SHF_EXECINSTR: sindex = 2; break;
5758 case SHF_MERGE: sindex = 3; break;
5759 case SHF_STRINGS: sindex = 4; break;
5760 case SHF_INFO_LINK: sindex = 5; break;
5761 case SHF_LINK_ORDER: sindex = 6; break;
5762 case SHF_OS_NONCONFORMING: sindex = 7; break;
5763 case SHF_GROUP: sindex = 8; break;
5764 case SHF_TLS: sindex = 9; break;
18ae9cc1 5765 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5766 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5767 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 5768
5477e8a0 5769 default:
91d6fa6a 5770 sindex = -1;
dda8d76d 5771 switch (filedata->file_header.e_machine)
148b93f2 5772 {
cfcac11d 5773 case EM_IA_64:
148b93f2 5774 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5775 sindex = 10;
148b93f2 5776 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5777 sindex = 11;
148b93f2 5778#ifdef BFD64
dda8d76d 5779 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
5780 switch (flag)
5781 {
91d6fa6a
NC
5782 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5783 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5784 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5785 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5786 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5787 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5788 default: break;
5789 }
5790#endif
cfcac11d
NC
5791 break;
5792
caa83f8b 5793 case EM_386:
22abe556 5794 case EM_IAMCU:
caa83f8b 5795 case EM_X86_64:
7f502d6c 5796 case EM_L1OM:
7a9068fe 5797 case EM_K1OM:
cfcac11d
NC
5798 case EM_OLD_SPARCV9:
5799 case EM_SPARC32PLUS:
5800 case EM_SPARCV9:
5801 case EM_SPARC:
18ae9cc1 5802 if (flag == SHF_ORDERED)
91d6fa6a 5803 sindex = 19;
cfcac11d 5804 break;
ac4c9b04
MG
5805
5806 case EM_ARM:
5807 switch (flag)
5808 {
5809 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5810 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5811 case SHF_COMDEF: sindex = 23; break;
5812 default: break;
5813 }
5814 break;
83eef883
AFB
5815 case EM_PPC:
5816 if (flag == SHF_PPC_VLE)
5817 sindex = 25;
5818 break;
ac4c9b04 5819
cfcac11d
NC
5820 default:
5821 break;
148b93f2 5822 }
5477e8a0
L
5823 }
5824
91d6fa6a 5825 if (sindex != -1)
5477e8a0 5826 {
8d5ff12c
L
5827 if (p != buff + field_size + 4)
5828 {
5829 if (size < (10 + 2))
bee0ee85
NC
5830 {
5831 warn (_("Internal error: not enough buffer room for section flag info"));
5832 return _("<unknown>");
5833 }
8d5ff12c
L
5834 size -= 2;
5835 *p++ = ',';
5836 *p++ = ' ';
5837 }
5838
91d6fa6a
NC
5839 size -= flags [sindex].len;
5840 p = stpcpy (p, flags [sindex].str);
5477e8a0 5841 }
3b22753a 5842 else if (flag & SHF_MASKOS)
8d5ff12c 5843 os_flags |= flag;
d1133906 5844 else if (flag & SHF_MASKPROC)
8d5ff12c 5845 proc_flags |= flag;
d1133906 5846 else
8d5ff12c 5847 unknown_flags |= flag;
5477e8a0
L
5848 }
5849 else
5850 {
5851 switch (flag)
5852 {
5853 case SHF_WRITE: *p = 'W'; break;
5854 case SHF_ALLOC: *p = 'A'; break;
5855 case SHF_EXECINSTR: *p = 'X'; break;
5856 case SHF_MERGE: *p = 'M'; break;
5857 case SHF_STRINGS: *p = 'S'; break;
5858 case SHF_INFO_LINK: *p = 'I'; break;
5859 case SHF_LINK_ORDER: *p = 'L'; break;
5860 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5861 case SHF_GROUP: *p = 'G'; break;
5862 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5863 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 5864 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 5865 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
5866
5867 default:
dda8d76d
NC
5868 if ((filedata->file_header.e_machine == EM_X86_64
5869 || filedata->file_header.e_machine == EM_L1OM
5870 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
5871 && flag == SHF_X86_64_LARGE)
5872 *p = 'l';
dda8d76d 5873 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 5874 && flag == SHF_ARM_PURECODE)
91f68a68 5875 *p = 'y';
dda8d76d 5876 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
5877 && flag == SHF_PPC_VLE)
5878 *p = 'v';
5477e8a0
L
5879 else if (flag & SHF_MASKOS)
5880 {
5881 *p = 'o';
5882 sh_flags &= ~ SHF_MASKOS;
5883 }
5884 else if (flag & SHF_MASKPROC)
5885 {
5886 *p = 'p';
5887 sh_flags &= ~ SHF_MASKPROC;
5888 }
5889 else
5890 *p = 'x';
5891 break;
5892 }
5893 p++;
d1133906
NC
5894 }
5895 }
76da6bbe 5896
8d5ff12c
L
5897 if (do_section_details)
5898 {
5899 if (os_flags)
5900 {
5901 size -= 5 + field_size;
5902 if (p != buff + field_size + 4)
5903 {
5904 if (size < (2 + 1))
bee0ee85
NC
5905 {
5906 warn (_("Internal error: not enough buffer room for section flag info"));
5907 return _("<unknown>");
5908 }
8d5ff12c
L
5909 size -= 2;
5910 *p++ = ',';
5911 *p++ = ' ';
5912 }
5913 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5914 (unsigned long) os_flags);
5915 p += 5 + field_size;
5916 }
5917 if (proc_flags)
5918 {
5919 size -= 7 + field_size;
5920 if (p != buff + field_size + 4)
5921 {
5922 if (size < (2 + 1))
bee0ee85
NC
5923 {
5924 warn (_("Internal error: not enough buffer room for section flag info"));
5925 return _("<unknown>");
5926 }
8d5ff12c
L
5927 size -= 2;
5928 *p++ = ',';
5929 *p++ = ' ';
5930 }
5931 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5932 (unsigned long) proc_flags);
5933 p += 7 + field_size;
5934 }
5935 if (unknown_flags)
5936 {
5937 size -= 10 + field_size;
5938 if (p != buff + field_size + 4)
5939 {
5940 if (size < (2 + 1))
bee0ee85
NC
5941 {
5942 warn (_("Internal error: not enough buffer room for section flag info"));
5943 return _("<unknown>");
5944 }
8d5ff12c
L
5945 size -= 2;
5946 *p++ = ',';
5947 *p++ = ' ';
5948 }
2b692964 5949 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5950 (unsigned long) unknown_flags);
5951 p += 10 + field_size;
5952 }
5953 }
5954
e9e44622 5955 *p = '\0';
d1133906
NC
5956 return buff;
5957}
5958
77115a4a 5959static unsigned int
ebdf1ebf 5960get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
5961{
5962 if (is_32bit_elf)
5963 {
5964 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 5965
ebdf1ebf
NC
5966 if (size < sizeof (* echdr))
5967 {
5968 error (_("Compressed section is too small even for a compression header\n"));
5969 return 0;
5970 }
5971
77115a4a
L
5972 chdr->ch_type = BYTE_GET (echdr->ch_type);
5973 chdr->ch_size = BYTE_GET (echdr->ch_size);
5974 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5975 return sizeof (*echdr);
5976 }
5977 else
5978 {
5979 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 5980
ebdf1ebf
NC
5981 if (size < sizeof (* echdr))
5982 {
5983 error (_("Compressed section is too small even for a compression header\n"));
5984 return 0;
5985 }
5986
77115a4a
L
5987 chdr->ch_type = BYTE_GET (echdr->ch_type);
5988 chdr->ch_size = BYTE_GET (echdr->ch_size);
5989 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5990 return sizeof (*echdr);
5991 }
5992}
5993
32ec8896 5994static bfd_boolean
dda8d76d 5995process_section_headers (Filedata * filedata)
252b5132 5996{
2cf0635d 5997 Elf_Internal_Shdr * section;
b34976b6 5998 unsigned int i;
252b5132 5999
dda8d76d 6000 filedata->section_headers = NULL;
252b5132 6001
dda8d76d 6002 if (filedata->file_header.e_shnum == 0)
252b5132 6003 {
82f2dbf7 6004 /* PR binutils/12467. */
dda8d76d 6005 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6006 {
6007 warn (_("possibly corrupt ELF file header - it has a non-zero"
6008 " section header offset, but no section headers\n"));
6009 return FALSE;
6010 }
82f2dbf7 6011 else if (do_sections)
252b5132
RH
6012 printf (_("\nThere are no sections in this file.\n"));
6013
32ec8896 6014 return TRUE;
252b5132
RH
6015 }
6016
6017 if (do_sections && !do_header)
d3a49aa8
AM
6018 printf (ngettext ("There is %d section header, "
6019 "starting at offset 0x%lx:\n",
6020 "There are %d section headers, "
6021 "starting at offset 0x%lx:\n",
dda8d76d
NC
6022 filedata->file_header.e_shnum),
6023 filedata->file_header.e_shnum,
6024 (unsigned long) filedata->file_header.e_shoff);
252b5132 6025
9ea033b2
NC
6026 if (is_32bit_elf)
6027 {
dda8d76d 6028 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6029 return FALSE;
6030 }
6031 else
6032 {
dda8d76d 6033 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6034 return FALSE;
9ea033b2 6035 }
252b5132
RH
6036
6037 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6038 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6039 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6040 {
dda8d76d 6041 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6042
c256ffe7
JJ
6043 if (section->sh_size != 0)
6044 {
dda8d76d
NC
6045 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6046 1, section->sh_size,
6047 _("string table"));
0de14b54 6048
dda8d76d 6049 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6050 }
252b5132
RH
6051 }
6052
6053 /* Scan the sections for the dynamic symbol table
e3c8793a 6054 and dynamic string table and debug sections. */
252b5132
RH
6055 dynamic_symbols = NULL;
6056 dynamic_strings = NULL;
6057 dynamic_syminfo = NULL;
6a40cf0c 6058 symtab_shndx_list = NULL;
103f02d3 6059
89fac5e3 6060 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6061 switch (filedata->file_header.e_machine)
89fac5e3
RS
6062 {
6063 case EM_MIPS:
6064 case EM_MIPS_RS3_LE:
6065 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6066 FDE addresses. However, the ABI also has a semi-official ILP32
6067 variant for which the normal FDE address size rules apply.
6068
6069 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6070 section, where XX is the size of longs in bits. Unfortunately,
6071 earlier compilers provided no way of distinguishing ILP32 objects
6072 from LP64 objects, so if there's any doubt, we should assume that
6073 the official LP64 form is being used. */
dda8d76d
NC
6074 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6075 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6076 eh_addr_size = 8;
6077 break;
0f56a26a
DD
6078
6079 case EM_H8_300:
6080 case EM_H8_300H:
dda8d76d 6081 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6082 {
6083 case E_H8_MACH_H8300:
6084 case E_H8_MACH_H8300HN:
6085 case E_H8_MACH_H8300SN:
6086 case E_H8_MACH_H8300SXN:
6087 eh_addr_size = 2;
6088 break;
6089 case E_H8_MACH_H8300H:
6090 case E_H8_MACH_H8300S:
6091 case E_H8_MACH_H8300SX:
6092 eh_addr_size = 4;
6093 break;
6094 }
f4236fe4
DD
6095 break;
6096
ff7eeb89 6097 case EM_M32C_OLD:
f4236fe4 6098 case EM_M32C:
dda8d76d 6099 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6100 {
6101 case EF_M32C_CPU_M16C:
6102 eh_addr_size = 2;
6103 break;
6104 }
6105 break;
89fac5e3
RS
6106 }
6107
76ca31c0
NC
6108#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6109 do \
6110 { \
6111 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6112 if (section->sh_entsize != expected_entsize) \
9dd3a467 6113 { \
76ca31c0
NC
6114 char buf[40]; \
6115 sprintf_vma (buf, section->sh_entsize); \
6116 /* Note: coded this way so that there is a single string for \
6117 translation. */ \
6118 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6119 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6120 (unsigned) expected_entsize); \
9dd3a467 6121 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6122 } \
6123 } \
08d8fa11 6124 while (0)
9dd3a467
NC
6125
6126#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
6127 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
6128 sizeof (Elf64_External_##type))
6129
dda8d76d
NC
6130 for (i = 0, section = filedata->section_headers;
6131 i < filedata->file_header.e_shnum;
b34976b6 6132 i++, section++)
252b5132 6133 {
2cf0635d 6134 char * name = SECTION_NAME (section);
252b5132
RH
6135
6136 if (section->sh_type == SHT_DYNSYM)
6137 {
6138 if (dynamic_symbols != NULL)
6139 {
6140 error (_("File contains multiple dynamic symbol tables\n"));
6141 continue;
6142 }
6143
08d8fa11 6144 CHECK_ENTSIZE (section, i, Sym);
dda8d76d 6145 dynamic_symbols = GET_ELF_SYMBOLS (filedata, section, & num_dynamic_syms);
252b5132
RH
6146 }
6147 else if (section->sh_type == SHT_STRTAB
18bd398b 6148 && streq (name, ".dynstr"))
252b5132
RH
6149 {
6150 if (dynamic_strings != NULL)
6151 {
6152 error (_("File contains multiple dynamic string tables\n"));
6153 continue;
6154 }
6155
dda8d76d 6156 dynamic_strings = (char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6157 1, section->sh_size,
6158 _("dynamic strings"));
59245841 6159 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 6160 }
9ad5cbcf
AM
6161 else if (section->sh_type == SHT_SYMTAB_SHNDX)
6162 {
6a40cf0c 6163 elf_section_list * entry = xmalloc (sizeof * entry);
dda8d76d 6164
6a40cf0c
NC
6165 entry->hdr = section;
6166 entry->next = symtab_shndx_list;
6167 symtab_shndx_list = entry;
9ad5cbcf 6168 }
08d8fa11
JJ
6169 else if (section->sh_type == SHT_SYMTAB)
6170 CHECK_ENTSIZE (section, i, Sym);
6171 else if (section->sh_type == SHT_GROUP)
6172 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6173 else if (section->sh_type == SHT_REL)
6174 CHECK_ENTSIZE (section, i, Rel);
6175 else if (section->sh_type == SHT_RELA)
6176 CHECK_ENTSIZE (section, i, Rela);
252b5132 6177 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 6178 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 6179 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47 6180 || do_debug_str || do_debug_loc || do_debug_ranges
d85bf2ba 6181 || do_debug_addr || do_debug_cu_index || do_debug_links)
1b315056
CS
6182 && (const_strneq (name, ".debug_")
6183 || const_strneq (name, ".zdebug_")))
252b5132 6184 {
1b315056
CS
6185 if (name[1] == 'z')
6186 name += sizeof (".zdebug_") - 1;
6187 else
6188 name += sizeof (".debug_") - 1;
252b5132
RH
6189
6190 if (do_debugging
4723351a
CC
6191 || (do_debug_info && const_strneq (name, "info"))
6192 || (do_debug_info && const_strneq (name, "types"))
6193 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6194 || (do_debug_lines && strcmp (name, "line") == 0)
6195 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6196 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6197 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6198 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6199 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6200 || (do_debug_aranges && const_strneq (name, "aranges"))
6201 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6202 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6203 || (do_debug_frames && const_strneq (name, "frame"))
6204 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6205 || (do_debug_macinfo && const_strneq (name, "macro"))
6206 || (do_debug_str && const_strneq (name, "str"))
6207 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6208 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6209 || (do_debug_addr && const_strneq (name, "addr"))
6210 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6211 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6212 )
dda8d76d 6213 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132 6214 }
a262ae96 6215 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6216 else if ((do_debugging || do_debug_info)
0112cd26 6217 && const_strneq (name, ".gnu.linkonce.wi."))
dda8d76d 6218 request_dump_bynumber (filedata, i, DEBUG_DUMP);
18bd398b 6219 else if (do_debug_frames && streq (name, ".eh_frame"))
dda8d76d 6220 request_dump_bynumber (filedata, i, DEBUG_DUMP);
61364358
JK
6221 else if (do_gdb_index && (streq (name, ".gdb_index")
6222 || streq (name, ".debug_names")))
dda8d76d 6223 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884
TG
6224 /* Trace sections for Itanium VMS. */
6225 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6226 || do_trace_aranges)
6227 && const_strneq (name, ".trace_"))
6228 {
6229 name += sizeof (".trace_") - 1;
6230
6231 if (do_debugging
6232 || (do_trace_info && streq (name, "info"))
6233 || (do_trace_abbrevs && streq (name, "abbrev"))
6234 || (do_trace_aranges && streq (name, "aranges"))
6235 )
dda8d76d 6236 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884 6237 }
dda8d76d
NC
6238 else if ((do_debugging || do_debug_links)
6239 && (const_strneq (name, ".gnu_debuglink")
6240 || const_strneq (name, ".gnu_debugaltlink")))
6241 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132
RH
6242 }
6243
6244 if (! do_sections)
32ec8896 6245 return TRUE;
252b5132 6246
dda8d76d 6247 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6248 printf (_("\nSection Headers:\n"));
6249 else
6250 printf (_("\nSection Header:\n"));
76da6bbe 6251
f7a99963 6252 if (is_32bit_elf)
595cf52e 6253 {
5477e8a0 6254 if (do_section_details)
595cf52e
L
6255 {
6256 printf (_(" [Nr] Name\n"));
5477e8a0 6257 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6258 }
6259 else
6260 printf
6261 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6262 }
d974e256 6263 else if (do_wide)
595cf52e 6264 {
5477e8a0 6265 if (do_section_details)
595cf52e
L
6266 {
6267 printf (_(" [Nr] Name\n"));
5477e8a0 6268 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6269 }
6270 else
6271 printf
6272 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6273 }
f7a99963
NC
6274 else
6275 {
5477e8a0 6276 if (do_section_details)
595cf52e
L
6277 {
6278 printf (_(" [Nr] Name\n"));
5477e8a0
L
6279 printf (_(" Type Address Offset Link\n"));
6280 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6281 }
6282 else
6283 {
6284 printf (_(" [Nr] Name Type Address Offset\n"));
6285 printf (_(" Size EntSize Flags Link Info Align\n"));
6286 }
f7a99963 6287 }
252b5132 6288
5477e8a0
L
6289 if (do_section_details)
6290 printf (_(" Flags\n"));
6291
dda8d76d
NC
6292 for (i = 0, section = filedata->section_headers;
6293 i < filedata->file_header.e_shnum;
b34976b6 6294 i++, section++)
252b5132 6295 {
dd905818
NC
6296 /* Run some sanity checks on the section header. */
6297
6298 /* Check the sh_link field. */
6299 switch (section->sh_type)
6300 {
6301 case SHT_SYMTAB_SHNDX:
6302 case SHT_GROUP:
6303 case SHT_HASH:
6304 case SHT_GNU_HASH:
6305 case SHT_GNU_versym:
6306 case SHT_REL:
6307 case SHT_RELA:
6308 if (section->sh_link < 1
dda8d76d
NC
6309 || section->sh_link >= filedata->file_header.e_shnum
6310 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6311 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6312 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6313 i, section->sh_link);
6314 break;
6315
6316 case SHT_DYNAMIC:
6317 case SHT_SYMTAB:
6318 case SHT_DYNSYM:
6319 case SHT_GNU_verneed:
6320 case SHT_GNU_verdef:
6321 case SHT_GNU_LIBLIST:
6322 if (section->sh_link < 1
dda8d76d
NC
6323 || section->sh_link >= filedata->file_header.e_shnum
6324 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6325 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6326 i, section->sh_link);
6327 break;
6328
6329 case SHT_INIT_ARRAY:
6330 case SHT_FINI_ARRAY:
6331 case SHT_PREINIT_ARRAY:
6332 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6333 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6334 i, section->sh_link);
6335 break;
6336
6337 default:
6338 /* FIXME: Add support for target specific section types. */
6339#if 0 /* Currently we do not check other section types as there are too
6340 many special cases. Stab sections for example have a type
6341 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6342 section. */
6343 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6344 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6345 i, section->sh_link);
6346#endif
6347 break;
6348 }
6349
6350 /* Check the sh_info field. */
6351 switch (section->sh_type)
6352 {
6353 case SHT_REL:
6354 case SHT_RELA:
6355 if (section->sh_info < 1
dda8d76d
NC
6356 || section->sh_info >= filedata->file_header.e_shnum
6357 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6358 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6359 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6360 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
dd905818 6361 /* FIXME: Are other section types valid ? */
dda8d76d 6362 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
dd905818
NC
6363 {
6364 if (section->sh_info == 0
bef7475f
NC
6365 && (filedata->file_header.e_type == ET_EXEC
6366 || filedata->file_header.e_type == ET_DYN
6367 /* These next two tests may be redundant, but
6368 they have been left in for paranoia's sake. */
6369 || streq (SECTION_NAME (section), ".rel.dyn")
dd905818 6370 || streq (SECTION_NAME (section), ".rela.dyn")))
bef7475f
NC
6371 /* Dynamic relocations apply to segments, not sections, so
6372 they do not need an sh_info value. */
6373 ;
dd905818
NC
6374 else
6375 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6376 i, section->sh_info);
6377 }
6378 break;
6379
6380 case SHT_DYNAMIC:
6381 case SHT_HASH:
6382 case SHT_SYMTAB_SHNDX:
6383 case SHT_INIT_ARRAY:
6384 case SHT_FINI_ARRAY:
6385 case SHT_PREINIT_ARRAY:
6386 if (section->sh_info != 0)
6387 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6388 i, section->sh_info);
6389 break;
6390
6391 case SHT_GROUP:
6392 case SHT_SYMTAB:
6393 case SHT_DYNSYM:
6394 /* A symbol index - we assume that it is valid. */
6395 break;
6396
6397 default:
6398 /* FIXME: Add support for target specific section types. */
6399 if (section->sh_type == SHT_NOBITS)
6400 /* NOBITS section headers with non-zero sh_info fields can be
6401 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6402 information. The stripped sections have their headers
6403 preserved but their types set to SHT_NOBITS. So do not check
6404 this type of section. */
dd905818
NC
6405 ;
6406 else if (section->sh_flags & SHF_INFO_LINK)
6407 {
dda8d76d 6408 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6409 warn (_("[%2u]: Expected link to another section in info field"), i);
6410 }
a91e1603
L
6411 else if (section->sh_type < SHT_LOOS
6412 && (section->sh_flags & SHF_GNU_MBIND) == 0
6413 && section->sh_info != 0)
dd905818
NC
6414 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6415 i, section->sh_info);
6416 break;
6417 }
6418
3e6b6445 6419 /* Check the sh_size field. */
dda8d76d 6420 if (section->sh_size > filedata->file_size
3e6b6445
NC
6421 && section->sh_type != SHT_NOBITS
6422 && section->sh_type != SHT_NULL
6423 && section->sh_type < SHT_LOOS)
6424 warn (_("Size of section %u is larger than the entire file!\n"), i);
6425
7bfd842d 6426 printf (" [%2u] ", i);
5477e8a0 6427 if (do_section_details)
dda8d76d 6428 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6429 else
74e1a04b 6430 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6431
ea52a088 6432 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6433 get_section_type_name (filedata, section->sh_type));
0b4362b0 6434
f7a99963
NC
6435 if (is_32bit_elf)
6436 {
cfcac11d
NC
6437 const char * link_too_big = NULL;
6438
f7a99963 6439 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6440
f7a99963
NC
6441 printf ( " %6.6lx %6.6lx %2.2lx",
6442 (unsigned long) section->sh_offset,
6443 (unsigned long) section->sh_size,
6444 (unsigned long) section->sh_entsize);
d1133906 6445
5477e8a0
L
6446 if (do_section_details)
6447 fputs (" ", stdout);
6448 else
dda8d76d 6449 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6450
dda8d76d 6451 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6452 {
6453 link_too_big = "";
6454 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6455 an error but it can have special values in Solaris binaries. */
dda8d76d 6456 switch (filedata->file_header.e_machine)
cfcac11d 6457 {
caa83f8b 6458 case EM_386:
22abe556 6459 case EM_IAMCU:
caa83f8b 6460 case EM_X86_64:
7f502d6c 6461 case EM_L1OM:
7a9068fe 6462 case EM_K1OM:
cfcac11d
NC
6463 case EM_OLD_SPARCV9:
6464 case EM_SPARC32PLUS:
6465 case EM_SPARCV9:
6466 case EM_SPARC:
6467 if (section->sh_link == (SHN_BEFORE & 0xffff))
6468 link_too_big = "BEFORE";
6469 else if (section->sh_link == (SHN_AFTER & 0xffff))
6470 link_too_big = "AFTER";
6471 break;
6472 default:
6473 break;
6474 }
6475 }
6476
6477 if (do_section_details)
6478 {
6479 if (link_too_big != NULL && * link_too_big)
6480 printf ("<%s> ", link_too_big);
6481 else
6482 printf ("%2u ", section->sh_link);
6483 printf ("%3u %2lu\n", section->sh_info,
6484 (unsigned long) section->sh_addralign);
6485 }
6486 else
6487 printf ("%2u %3u %2lu\n",
6488 section->sh_link,
6489 section->sh_info,
6490 (unsigned long) section->sh_addralign);
6491
6492 if (link_too_big && ! * link_too_big)
6493 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6494 i, section->sh_link);
f7a99963 6495 }
d974e256
JJ
6496 else if (do_wide)
6497 {
6498 print_vma (section->sh_addr, LONG_HEX);
6499
6500 if ((long) section->sh_offset == section->sh_offset)
6501 printf (" %6.6lx", (unsigned long) section->sh_offset);
6502 else
6503 {
6504 putchar (' ');
6505 print_vma (section->sh_offset, LONG_HEX);
6506 }
6507
6508 if ((unsigned long) section->sh_size == section->sh_size)
6509 printf (" %6.6lx", (unsigned long) section->sh_size);
6510 else
6511 {
6512 putchar (' ');
6513 print_vma (section->sh_size, LONG_HEX);
6514 }
6515
6516 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6517 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6518 else
6519 {
6520 putchar (' ');
6521 print_vma (section->sh_entsize, LONG_HEX);
6522 }
6523
5477e8a0
L
6524 if (do_section_details)
6525 fputs (" ", stdout);
6526 else
dda8d76d 6527 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6528
72de5009 6529 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6530
6531 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6532 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6533 else
6534 {
6535 print_vma (section->sh_addralign, DEC);
6536 putchar ('\n');
6537 }
6538 }
5477e8a0 6539 else if (do_section_details)
595cf52e 6540 {
55cc53e9 6541 putchar (' ');
595cf52e
L
6542 print_vma (section->sh_addr, LONG_HEX);
6543 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6544 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6545 else
6546 {
6547 printf (" ");
6548 print_vma (section->sh_offset, LONG_HEX);
6549 }
72de5009 6550 printf (" %u\n ", section->sh_link);
595cf52e 6551 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6552 putchar (' ');
595cf52e
L
6553 print_vma (section->sh_entsize, LONG_HEX);
6554
72de5009
AM
6555 printf (" %-16u %lu\n",
6556 section->sh_info,
595cf52e
L
6557 (unsigned long) section->sh_addralign);
6558 }
f7a99963
NC
6559 else
6560 {
6561 putchar (' ');
6562 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6563 if ((long) section->sh_offset == section->sh_offset)
6564 printf (" %8.8lx", (unsigned long) section->sh_offset);
6565 else
6566 {
6567 printf (" ");
6568 print_vma (section->sh_offset, LONG_HEX);
6569 }
f7a99963
NC
6570 printf ("\n ");
6571 print_vma (section->sh_size, LONG_HEX);
6572 printf (" ");
6573 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6574
dda8d76d 6575 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6576
72de5009
AM
6577 printf (" %2u %3u %lu\n",
6578 section->sh_link,
6579 section->sh_info,
f7a99963
NC
6580 (unsigned long) section->sh_addralign);
6581 }
5477e8a0
L
6582
6583 if (do_section_details)
77115a4a 6584 {
dda8d76d 6585 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6586 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6587 {
6588 /* Minimum section size is 12 bytes for 32-bit compression
6589 header + 12 bytes for compressed data header. */
6590 unsigned char buf[24];
d8024a91 6591
77115a4a 6592 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6593 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6594 sizeof (buf), _("compression header")))
6595 {
6596 Elf_Internal_Chdr chdr;
d8024a91 6597
ebdf1ebf 6598 (void) get_compression_header (&chdr, buf, sizeof (buf));
d8024a91 6599
77115a4a
L
6600 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6601 printf (" ZLIB, ");
6602 else
6603 printf (_(" [<unknown>: 0x%x], "),
6604 chdr.ch_type);
6605 print_vma (chdr.ch_size, LONG_HEX);
6606 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6607 }
6608 }
6609 }
252b5132
RH
6610 }
6611
5477e8a0 6612 if (!do_section_details)
3dbcc61d 6613 {
9fb71ee4
NC
6614 /* The ordering of the letters shown here matches the ordering of the
6615 corresponding SHF_xxx values, and hence the order in which these
6616 letters will be displayed to the user. */
6617 printf (_("Key to Flags:\n\
6618 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6619 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6620 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6621 if (filedata->file_header.e_machine == EM_X86_64
6622 || filedata->file_header.e_machine == EM_L1OM
6623 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6624 printf (_("l (large), "));
dda8d76d 6625 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6626 printf (_("y (purecode), "));
dda8d76d 6627 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6628 printf (_("v (VLE), "));
9fb71ee4 6629 printf ("p (processor specific)\n");
0b4362b0 6630 }
d1133906 6631
32ec8896 6632 return TRUE;
252b5132
RH
6633}
6634
f5842774
L
6635static const char *
6636get_group_flags (unsigned int flags)
6637{
1449284b 6638 static char buff[128];
220453ec 6639
6d913794
NC
6640 if (flags == 0)
6641 return "";
6642 else if (flags == GRP_COMDAT)
6643 return "COMDAT ";
f5842774 6644
6d913794
NC
6645 snprintf (buff, 14, _("[0x%x: "), flags);
6646
6647 flags &= ~ GRP_COMDAT;
6648 if (flags & GRP_MASKOS)
6649 {
6650 strcat (buff, "<OS specific>");
6651 flags &= ~ GRP_MASKOS;
f5842774 6652 }
6d913794
NC
6653
6654 if (flags & GRP_MASKPROC)
6655 {
6656 strcat (buff, "<PROC specific>");
6657 flags &= ~ GRP_MASKPROC;
6658 }
6659
6660 if (flags)
6661 strcat (buff, "<unknown>");
6662
6663 strcat (buff, "]");
f5842774
L
6664 return buff;
6665}
6666
32ec8896 6667static bfd_boolean
dda8d76d 6668process_section_groups (Filedata * filedata)
f5842774 6669{
2cf0635d 6670 Elf_Internal_Shdr * section;
f5842774 6671 unsigned int i;
2cf0635d
NC
6672 struct group * group;
6673 Elf_Internal_Shdr * symtab_sec;
6674 Elf_Internal_Shdr * strtab_sec;
6675 Elf_Internal_Sym * symtab;
ba5cdace 6676 unsigned long num_syms;
2cf0635d 6677 char * strtab;
c256ffe7 6678 size_t strtab_size;
d1f5c6e3
L
6679
6680 /* Don't process section groups unless needed. */
6681 if (!do_unwind && !do_section_groups)
32ec8896 6682 return TRUE;
f5842774 6683
dda8d76d 6684 if (filedata->file_header.e_shnum == 0)
f5842774
L
6685 {
6686 if (do_section_groups)
82f2dbf7 6687 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 6688
32ec8896 6689 return TRUE;
f5842774
L
6690 }
6691
dda8d76d 6692 if (filedata->section_headers == NULL)
f5842774
L
6693 {
6694 error (_("Section headers are not available!\n"));
fa1908fd 6695 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 6696 return FALSE;
f5842774
L
6697 }
6698
dda8d76d 6699 section_headers_groups = (struct group **) calloc (filedata->file_header.e_shnum,
3f5e193b 6700 sizeof (struct group *));
e4b17d5c
L
6701
6702 if (section_headers_groups == NULL)
6703 {
8b73c356 6704 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 6705 filedata->file_header.e_shnum);
32ec8896 6706 return FALSE;
e4b17d5c
L
6707 }
6708
f5842774 6709 /* Scan the sections for the group section. */
d1f5c6e3 6710 group_count = 0;
dda8d76d
NC
6711 for (i = 0, section = filedata->section_headers;
6712 i < filedata->file_header.e_shnum;
f5842774 6713 i++, section++)
e4b17d5c
L
6714 if (section->sh_type == SHT_GROUP)
6715 group_count++;
6716
d1f5c6e3
L
6717 if (group_count == 0)
6718 {
6719 if (do_section_groups)
6720 printf (_("\nThere are no section groups in this file.\n"));
6721
32ec8896 6722 return TRUE;
d1f5c6e3
L
6723 }
6724
3f5e193b 6725 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
6726
6727 if (section_groups == NULL)
6728 {
8b73c356
NC
6729 error (_("Out of memory reading %lu groups\n"),
6730 (unsigned long) group_count);
32ec8896 6731 return FALSE;
e4b17d5c
L
6732 }
6733
d1f5c6e3
L
6734 symtab_sec = NULL;
6735 strtab_sec = NULL;
6736 symtab = NULL;
ba5cdace 6737 num_syms = 0;
d1f5c6e3 6738 strtab = NULL;
c256ffe7 6739 strtab_size = 0;
dda8d76d
NC
6740 for (i = 0, section = filedata->section_headers, group = section_groups;
6741 i < filedata->file_header.e_shnum;
e4b17d5c 6742 i++, section++)
f5842774
L
6743 {
6744 if (section->sh_type == SHT_GROUP)
6745 {
dda8d76d 6746 const char * name = printable_section_name (filedata, section);
74e1a04b 6747 const char * group_name;
2cf0635d
NC
6748 unsigned char * start;
6749 unsigned char * indices;
f5842774 6750 unsigned int entry, j, size;
2cf0635d
NC
6751 Elf_Internal_Shdr * sec;
6752 Elf_Internal_Sym * sym;
f5842774
L
6753
6754 /* Get the symbol table. */
dda8d76d
NC
6755 if (section->sh_link >= filedata->file_header.e_shnum
6756 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 6757 != SHT_SYMTAB))
f5842774
L
6758 {
6759 error (_("Bad sh_link in group section `%s'\n"), name);
6760 continue;
6761 }
d1f5c6e3
L
6762
6763 if (symtab_sec != sec)
6764 {
6765 symtab_sec = sec;
6766 if (symtab)
6767 free (symtab);
dda8d76d 6768 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 6769 }
f5842774 6770
dd24e3da
NC
6771 if (symtab == NULL)
6772 {
6773 error (_("Corrupt header in group section `%s'\n"), name);
6774 continue;
6775 }
6776
ba5cdace
NC
6777 if (section->sh_info >= num_syms)
6778 {
6779 error (_("Bad sh_info in group section `%s'\n"), name);
6780 continue;
6781 }
6782
f5842774
L
6783 sym = symtab + section->sh_info;
6784
6785 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6786 {
4fbb74a6 6787 if (sym->st_shndx == 0
dda8d76d 6788 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
6789 {
6790 error (_("Bad sh_info in group section `%s'\n"), name);
6791 continue;
6792 }
ba2685cc 6793
dda8d76d 6794 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7
JJ
6795 strtab_sec = NULL;
6796 if (strtab)
6797 free (strtab);
f5842774 6798 strtab = NULL;
c256ffe7 6799 strtab_size = 0;
f5842774
L
6800 }
6801 else
6802 {
6803 /* Get the string table. */
dda8d76d 6804 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
6805 {
6806 strtab_sec = NULL;
6807 if (strtab)
6808 free (strtab);
6809 strtab = NULL;
6810 strtab_size = 0;
6811 }
6812 else if (strtab_sec
dda8d76d 6813 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
6814 {
6815 strtab_sec = sec;
6816 if (strtab)
6817 free (strtab);
071436c6 6818
dda8d76d 6819 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
6820 1, strtab_sec->sh_size,
6821 _("string table"));
c256ffe7 6822 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 6823 }
c256ffe7 6824 group_name = sym->st_name < strtab_size
2b692964 6825 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
6826 }
6827
c9c1d674
EG
6828 /* PR 17531: file: loop. */
6829 if (section->sh_entsize > section->sh_size)
6830 {
6831 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 6832 printable_section_name (filedata, section),
8066deb1
AM
6833 (unsigned long) section->sh_entsize,
6834 (unsigned long) section->sh_size);
c9c1d674
EG
6835 break;
6836 }
6837
dda8d76d 6838 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6839 1, section->sh_size,
6840 _("section data"));
59245841
NC
6841 if (start == NULL)
6842 continue;
f5842774
L
6843
6844 indices = start;
6845 size = (section->sh_size / section->sh_entsize) - 1;
6846 entry = byte_get (indices, 4);
6847 indices += 4;
e4b17d5c
L
6848
6849 if (do_section_groups)
6850 {
2b692964 6851 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6852 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6853
e4b17d5c
L
6854 printf (_(" [Index] Name\n"));
6855 }
6856
6857 group->group_index = i;
6858
f5842774
L
6859 for (j = 0; j < size; j++)
6860 {
2cf0635d 6861 struct group_list * g;
e4b17d5c 6862
f5842774
L
6863 entry = byte_get (indices, 4);
6864 indices += 4;
6865
dda8d76d 6866 if (entry >= filedata->file_header.e_shnum)
391cb864 6867 {
57028622
NC
6868 static unsigned num_group_errors = 0;
6869
6870 if (num_group_errors ++ < 10)
6871 {
6872 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 6873 entry, i, filedata->file_header.e_shnum - 1);
57028622 6874 if (num_group_errors == 10)
67ce483b 6875 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 6876 }
391cb864
L
6877 continue;
6878 }
391cb864 6879
4fbb74a6 6880 if (section_headers_groups [entry] != NULL)
e4b17d5c 6881 {
d1f5c6e3
L
6882 if (entry)
6883 {
57028622
NC
6884 static unsigned num_errs = 0;
6885
6886 if (num_errs ++ < 10)
6887 {
6888 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6889 entry, i,
6890 section_headers_groups [entry]->group_index);
6891 if (num_errs == 10)
6892 warn (_("Further error messages about already contained group sections suppressed\n"));
6893 }
d1f5c6e3
L
6894 continue;
6895 }
6896 else
6897 {
6898 /* Intel C/C++ compiler may put section 0 in a
32ec8896 6899 section group. We just warn it the first time
d1f5c6e3 6900 and ignore it afterwards. */
32ec8896 6901 static bfd_boolean warned = FALSE;
d1f5c6e3
L
6902 if (!warned)
6903 {
6904 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6905 section_headers_groups [entry]->group_index);
32ec8896 6906 warned = TRUE;
d1f5c6e3
L
6907 }
6908 }
e4b17d5c
L
6909 }
6910
4fbb74a6 6911 section_headers_groups [entry] = group;
e4b17d5c
L
6912
6913 if (do_section_groups)
6914 {
dda8d76d
NC
6915 sec = filedata->section_headers + entry;
6916 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
6917 }
6918
3f5e193b 6919 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6920 g->section_index = entry;
6921 g->next = group->root;
6922 group->root = g;
f5842774
L
6923 }
6924
f5842774
L
6925 if (start)
6926 free (start);
e4b17d5c
L
6927
6928 group++;
f5842774
L
6929 }
6930 }
6931
d1f5c6e3
L
6932 if (symtab)
6933 free (symtab);
6934 if (strtab)
6935 free (strtab);
32ec8896 6936 return TRUE;
f5842774
L
6937}
6938
28f997cf
TG
6939/* Data used to display dynamic fixups. */
6940
6941struct ia64_vms_dynfixup
6942{
6943 bfd_vma needed_ident; /* Library ident number. */
6944 bfd_vma needed; /* Index in the dstrtab of the library name. */
6945 bfd_vma fixup_needed; /* Index of the library. */
6946 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6947 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6948};
6949
6950/* Data used to display dynamic relocations. */
6951
6952struct ia64_vms_dynimgrela
6953{
6954 bfd_vma img_rela_cnt; /* Number of relocations. */
6955 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6956};
6957
6958/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6959 library). */
6960
32ec8896 6961static bfd_boolean
dda8d76d
NC
6962dump_ia64_vms_dynamic_fixups (Filedata * filedata,
6963 struct ia64_vms_dynfixup * fixup,
6964 const char * strtab,
6965 unsigned int strtab_sz)
28f997cf 6966{
32ec8896 6967 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 6968 long i;
32ec8896 6969 const char * lib_name;
28f997cf 6970
dda8d76d 6971 imfs = get_data (NULL, filedata, dynamic_addr + fixup->fixup_rela_off,
28f997cf
TG
6972 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6973 _("dynamic section image fixups"));
6974 if (!imfs)
32ec8896 6975 return FALSE;
28f997cf
TG
6976
6977 if (fixup->needed < strtab_sz)
6978 lib_name = strtab + fixup->needed;
6979 else
6980 {
32ec8896 6981 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 6982 (unsigned long) fixup->needed);
28f997cf
TG
6983 lib_name = "???";
6984 }
6985 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6986 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6987 printf
6988 (_("Seg Offset Type SymVec DataType\n"));
6989
6990 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6991 {
6992 unsigned int type;
6993 const char *rtype;
6994
6995 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6996 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6997 type = BYTE_GET (imfs [i].type);
6998 rtype = elf_ia64_reloc_type (type);
6999 if (rtype == NULL)
7000 printf (" 0x%08x ", type);
7001 else
7002 printf (" %-32s ", rtype);
7003 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7004 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7005 }
7006
7007 free (imfs);
32ec8896 7008 return TRUE;
28f997cf
TG
7009}
7010
7011/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7012
32ec8896 7013static bfd_boolean
dda8d76d 7014dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7015{
7016 Elf64_External_VMS_IMAGE_RELA *imrs;
7017 long i;
7018
dda8d76d 7019 imrs = get_data (NULL, filedata, dynamic_addr + imgrela->img_rela_off,
28f997cf 7020 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 7021 _("dynamic section image relocations"));
28f997cf 7022 if (!imrs)
32ec8896 7023 return FALSE;
28f997cf
TG
7024
7025 printf (_("\nImage relocs\n"));
7026 printf
7027 (_("Seg Offset Type Addend Seg Sym Off\n"));
7028
7029 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7030 {
7031 unsigned int type;
7032 const char *rtype;
7033
7034 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7035 printf ("%08" BFD_VMA_FMT "x ",
7036 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7037 type = BYTE_GET (imrs [i].type);
7038 rtype = elf_ia64_reloc_type (type);
7039 if (rtype == NULL)
7040 printf ("0x%08x ", type);
7041 else
7042 printf ("%-31s ", rtype);
7043 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7044 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7045 printf ("%08" BFD_VMA_FMT "x\n",
7046 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7047 }
7048
7049 free (imrs);
32ec8896 7050 return TRUE;
28f997cf
TG
7051}
7052
7053/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7054
32ec8896 7055static bfd_boolean
dda8d76d 7056process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7057{
7058 struct ia64_vms_dynfixup fixup;
7059 struct ia64_vms_dynimgrela imgrela;
7060 Elf_Internal_Dyn *entry;
28f997cf
TG
7061 bfd_vma strtab_off = 0;
7062 bfd_vma strtab_sz = 0;
7063 char *strtab = NULL;
32ec8896 7064 bfd_boolean res = TRUE;
28f997cf
TG
7065
7066 memset (&fixup, 0, sizeof (fixup));
7067 memset (&imgrela, 0, sizeof (imgrela));
7068
7069 /* Note: the order of the entries is specified by the OpenVMS specs. */
7070 for (entry = dynamic_section;
7071 entry < dynamic_section + dynamic_nent;
7072 entry++)
7073 {
7074 switch (entry->d_tag)
7075 {
7076 case DT_IA_64_VMS_STRTAB_OFFSET:
7077 strtab_off = entry->d_un.d_val;
7078 break;
7079 case DT_STRSZ:
7080 strtab_sz = entry->d_un.d_val;
7081 if (strtab == NULL)
dda8d76d 7082 strtab = get_data (NULL, filedata, dynamic_addr + strtab_off,
28f997cf
TG
7083 1, strtab_sz, _("dynamic string section"));
7084 break;
7085
7086 case DT_IA_64_VMS_NEEDED_IDENT:
7087 fixup.needed_ident = entry->d_un.d_val;
7088 break;
7089 case DT_NEEDED:
7090 fixup.needed = entry->d_un.d_val;
7091 break;
7092 case DT_IA_64_VMS_FIXUP_NEEDED:
7093 fixup.fixup_needed = entry->d_un.d_val;
7094 break;
7095 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7096 fixup.fixup_rela_cnt = entry->d_un.d_val;
7097 break;
7098 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7099 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7100 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7101 res = FALSE;
28f997cf 7102 break;
28f997cf
TG
7103 case DT_IA_64_VMS_IMG_RELA_CNT:
7104 imgrela.img_rela_cnt = entry->d_un.d_val;
7105 break;
7106 case DT_IA_64_VMS_IMG_RELA_OFF:
7107 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7108 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7109 res = FALSE;
28f997cf
TG
7110 break;
7111
7112 default:
7113 break;
7114 }
7115 }
7116
7117 if (strtab != NULL)
7118 free (strtab);
7119
7120 return res;
7121}
7122
85b1c36d 7123static struct
566b0d53 7124{
2cf0635d 7125 const char * name;
566b0d53
L
7126 int reloc;
7127 int size;
7128 int rela;
32ec8896
NC
7129}
7130 dynamic_relocations [] =
566b0d53 7131{
32ec8896
NC
7132 { "REL", DT_REL, DT_RELSZ, FALSE },
7133 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7134 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7135};
7136
252b5132 7137/* Process the reloc section. */
18bd398b 7138
32ec8896 7139static bfd_boolean
dda8d76d 7140process_relocs (Filedata * filedata)
252b5132 7141{
b34976b6
AM
7142 unsigned long rel_size;
7143 unsigned long rel_offset;
252b5132 7144
252b5132 7145 if (!do_reloc)
32ec8896 7146 return TRUE;
252b5132
RH
7147
7148 if (do_using_dynamic)
7149 {
32ec8896 7150 int is_rela;
2cf0635d 7151 const char * name;
32ec8896 7152 bfd_boolean has_dynamic_reloc;
566b0d53 7153 unsigned int i;
0de14b54 7154
32ec8896 7155 has_dynamic_reloc = FALSE;
252b5132 7156
566b0d53 7157 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7158 {
566b0d53
L
7159 is_rela = dynamic_relocations [i].rela;
7160 name = dynamic_relocations [i].name;
7161 rel_size = dynamic_info [dynamic_relocations [i].size];
7162 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 7163
32ec8896
NC
7164 if (rel_size)
7165 has_dynamic_reloc = TRUE;
566b0d53
L
7166
7167 if (is_rela == UNKNOWN)
aa903cfb 7168 {
566b0d53
L
7169 if (dynamic_relocations [i].reloc == DT_JMPREL)
7170 switch (dynamic_info[DT_PLTREL])
7171 {
7172 case DT_REL:
7173 is_rela = FALSE;
7174 break;
7175 case DT_RELA:
7176 is_rela = TRUE;
7177 break;
7178 }
aa903cfb 7179 }
252b5132 7180
566b0d53
L
7181 if (rel_size)
7182 {
7183 printf
7184 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7185 name, rel_offset, rel_size);
252b5132 7186
dda8d76d
NC
7187 dump_relocations (filedata,
7188 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7189 rel_size,
566b0d53 7190 dynamic_symbols, num_dynamic_syms,
bb4d2ac2 7191 dynamic_strings, dynamic_strings_length,
32ec8896 7192 is_rela, TRUE /* is_dynamic */);
566b0d53 7193 }
252b5132 7194 }
566b0d53 7195
dda8d76d
NC
7196 if (is_ia64_vms (filedata))
7197 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7198 has_dynamic_reloc = TRUE;
28f997cf 7199
566b0d53 7200 if (! has_dynamic_reloc)
252b5132
RH
7201 printf (_("\nThere are no dynamic relocations in this file.\n"));
7202 }
7203 else
7204 {
2cf0635d 7205 Elf_Internal_Shdr * section;
b34976b6 7206 unsigned long i;
32ec8896 7207 bfd_boolean found = FALSE;
252b5132 7208
dda8d76d
NC
7209 for (i = 0, section = filedata->section_headers;
7210 i < filedata->file_header.e_shnum;
b34976b6 7211 i++, section++)
252b5132
RH
7212 {
7213 if ( section->sh_type != SHT_RELA
7214 && section->sh_type != SHT_REL)
7215 continue;
7216
7217 rel_offset = section->sh_offset;
7218 rel_size = section->sh_size;
7219
7220 if (rel_size)
7221 {
2cf0635d 7222 Elf_Internal_Shdr * strsec;
b34976b6 7223 int is_rela;
d3a49aa8 7224 unsigned long num_rela;
103f02d3 7225
252b5132
RH
7226 printf (_("\nRelocation section "));
7227
dda8d76d 7228 if (filedata->string_table == NULL)
19936277 7229 printf ("%d", section->sh_name);
252b5132 7230 else
dda8d76d 7231 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7232
d3a49aa8
AM
7233 num_rela = rel_size / section->sh_entsize;
7234 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7235 " at offset 0x%lx contains %lu entries:\n",
7236 num_rela),
7237 rel_offset, num_rela);
252b5132 7238
d79b3d50
NC
7239 is_rela = section->sh_type == SHT_RELA;
7240
4fbb74a6 7241 if (section->sh_link != 0
dda8d76d 7242 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7243 {
2cf0635d
NC
7244 Elf_Internal_Shdr * symsec;
7245 Elf_Internal_Sym * symtab;
d79b3d50 7246 unsigned long nsyms;
c256ffe7 7247 unsigned long strtablen = 0;
2cf0635d 7248 char * strtab = NULL;
57346661 7249
dda8d76d 7250 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7251 if (symsec->sh_type != SHT_SYMTAB
7252 && symsec->sh_type != SHT_DYNSYM)
7253 continue;
7254
dda8d76d 7255 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
252b5132 7256
af3fc3bc
AM
7257 if (symtab == NULL)
7258 continue;
252b5132 7259
4fbb74a6 7260 if (symsec->sh_link != 0
dda8d76d 7261 && symsec->sh_link < filedata->file_header.e_shnum)
c256ffe7 7262 {
dda8d76d 7263 strsec = filedata->section_headers + symsec->sh_link;
103f02d3 7264
dda8d76d 7265 strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
071436c6
NC
7266 1, strsec->sh_size,
7267 _("string table"));
c256ffe7
JJ
7268 strtablen = strtab == NULL ? 0 : strsec->sh_size;
7269 }
252b5132 7270
dda8d76d 7271 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7272 symtab, nsyms, strtab, strtablen,
7273 is_rela,
7274 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
7275 if (strtab)
7276 free (strtab);
7277 free (symtab);
7278 }
7279 else
dda8d76d 7280 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7281 NULL, 0, NULL, 0, is_rela,
7282 FALSE /* is_dynamic */);
252b5132 7283
32ec8896 7284 found = TRUE;
252b5132
RH
7285 }
7286 }
7287
7288 if (! found)
45ac8f4f
NC
7289 {
7290 /* Users sometimes forget the -D option, so try to be helpful. */
7291 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7292 {
7293 if (dynamic_info [dynamic_relocations [i].size])
7294 {
7295 printf (_("\nThere are no static relocations in this file."));
7296 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7297
7298 break;
7299 }
7300 }
7301 if (i == ARRAY_SIZE (dynamic_relocations))
7302 printf (_("\nThere are no relocations in this file.\n"));
7303 }
252b5132
RH
7304 }
7305
32ec8896 7306 return TRUE;
252b5132
RH
7307}
7308
4d6ed7c8
NC
7309/* An absolute address consists of a section and an offset. If the
7310 section is NULL, the offset itself is the address, otherwise, the
7311 address equals to LOAD_ADDRESS(section) + offset. */
7312
7313struct absaddr
948f632f
DA
7314{
7315 unsigned short section;
7316 bfd_vma offset;
7317};
4d6ed7c8 7318
1949de15
L
7319#define ABSADDR(a) \
7320 ((a).section \
dda8d76d 7321 ? filedata->section_headers [(a).section].sh_addr + (a).offset \
1949de15
L
7322 : (a).offset)
7323
948f632f
DA
7324/* Find the nearest symbol at or below ADDR. Returns the symbol
7325 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7326
4d6ed7c8 7327static void
dda8d76d
NC
7328find_symbol_for_address (Filedata * filedata,
7329 Elf_Internal_Sym * symtab,
7330 unsigned long nsyms,
7331 const char * strtab,
7332 unsigned long strtab_size,
7333 struct absaddr addr,
7334 const char ** symname,
7335 bfd_vma * offset)
4d6ed7c8 7336{
d3ba0551 7337 bfd_vma dist = 0x100000;
2cf0635d 7338 Elf_Internal_Sym * sym;
948f632f
DA
7339 Elf_Internal_Sym * beg;
7340 Elf_Internal_Sym * end;
2cf0635d 7341 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7342
0b6ae522 7343 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7344 beg = symtab;
7345 end = symtab + nsyms;
0b6ae522 7346
948f632f 7347 while (beg < end)
4d6ed7c8 7348 {
948f632f
DA
7349 bfd_vma value;
7350
7351 sym = beg + (end - beg) / 2;
0b6ae522 7352
948f632f 7353 value = sym->st_value;
0b6ae522
DJ
7354 REMOVE_ARCH_BITS (value);
7355
948f632f 7356 if (sym->st_name != 0
4d6ed7c8 7357 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7358 && addr.offset >= value
7359 && addr.offset - value < dist)
4d6ed7c8
NC
7360 {
7361 best = sym;
0b6ae522 7362 dist = addr.offset - value;
4d6ed7c8
NC
7363 if (!dist)
7364 break;
7365 }
948f632f
DA
7366
7367 if (addr.offset < value)
7368 end = sym;
7369 else
7370 beg = sym + 1;
4d6ed7c8 7371 }
1b31d05e 7372
4d6ed7c8
NC
7373 if (best)
7374 {
57346661 7375 *symname = (best->st_name >= strtab_size
2b692964 7376 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7377 *offset = dist;
7378 return;
7379 }
1b31d05e 7380
4d6ed7c8
NC
7381 *symname = NULL;
7382 *offset = addr.offset;
7383}
7384
32ec8896 7385static /* signed */ int
948f632f
DA
7386symcmp (const void *p, const void *q)
7387{
7388 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7389 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7390
7391 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7392}
7393
7394/* Process the unwind section. */
7395
7396#include "unwind-ia64.h"
7397
7398struct ia64_unw_table_entry
7399{
7400 struct absaddr start;
7401 struct absaddr end;
7402 struct absaddr info;
7403};
7404
7405struct ia64_unw_aux_info
7406{
32ec8896
NC
7407 struct ia64_unw_table_entry * table; /* Unwind table. */
7408 unsigned long table_len; /* Length of unwind table. */
7409 unsigned char * info; /* Unwind info. */
7410 unsigned long info_size; /* Size of unwind info. */
7411 bfd_vma info_addr; /* Starting address of unwind info. */
7412 bfd_vma seg_base; /* Starting address of segment. */
7413 Elf_Internal_Sym * symtab; /* The symbol table. */
7414 unsigned long nsyms; /* Number of symbols. */
7415 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7416 unsigned long nfuns; /* Number of entries in funtab. */
7417 char * strtab; /* The string table. */
7418 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7419};
7420
32ec8896 7421static bfd_boolean
dda8d76d 7422dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7423{
2cf0635d 7424 struct ia64_unw_table_entry * tp;
948f632f 7425 unsigned long j, nfuns;
4d6ed7c8 7426 int in_body;
32ec8896 7427 bfd_boolean res = TRUE;
7036c0e1 7428
948f632f
DA
7429 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7430 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7431 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7432 aux->funtab[nfuns++] = aux->symtab[j];
7433 aux->nfuns = nfuns;
7434 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7435
4d6ed7c8
NC
7436 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7437 {
7438 bfd_vma stamp;
7439 bfd_vma offset;
2cf0635d
NC
7440 const unsigned char * dp;
7441 const unsigned char * head;
53774b7e 7442 const unsigned char * end;
2cf0635d 7443 const char * procname;
4d6ed7c8 7444
dda8d76d 7445 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7446 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7447
7448 fputs ("\n<", stdout);
7449
7450 if (procname)
7451 {
7452 fputs (procname, stdout);
7453
7454 if (offset)
7455 printf ("+%lx", (unsigned long) offset);
7456 }
7457
7458 fputs (">: [", stdout);
7459 print_vma (tp->start.offset, PREFIX_HEX);
7460 fputc ('-', stdout);
7461 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7462 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7463 (unsigned long) (tp->info.offset - aux->seg_base));
7464
53774b7e
NC
7465 /* PR 17531: file: 86232b32. */
7466 if (aux->info == NULL)
7467 continue;
7468
7469 /* PR 17531: file: 0997b4d1. */
7470 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
7471 {
7472 warn (_("Invalid offset %lx in table entry %ld\n"),
7473 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7474 res = FALSE;
53774b7e
NC
7475 continue;
7476 }
7477
1949de15 7478 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 7479 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7480
86f55779 7481 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7482 (unsigned) UNW_VER (stamp),
7483 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7484 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7485 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7486 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7487
7488 if (UNW_VER (stamp) != 1)
7489 {
2b692964 7490 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7491 continue;
7492 }
7493
7494 in_body = 0;
53774b7e
NC
7495 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7496 /* PR 17531: file: 16ceda89. */
7497 if (end > aux->info + aux->info_size)
7498 end = aux->info + aux->info_size;
7499 for (dp = head + 8; dp < end;)
b4477bc8 7500 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7501 }
948f632f
DA
7502
7503 free (aux->funtab);
32ec8896
NC
7504
7505 return res;
4d6ed7c8
NC
7506}
7507
53774b7e 7508static bfd_boolean
dda8d76d
NC
7509slurp_ia64_unwind_table (Filedata * filedata,
7510 struct ia64_unw_aux_info * aux,
7511 Elf_Internal_Shdr * sec)
4d6ed7c8 7512{
89fac5e3 7513 unsigned long size, nrelas, i;
2cf0635d
NC
7514 Elf_Internal_Phdr * seg;
7515 struct ia64_unw_table_entry * tep;
7516 Elf_Internal_Shdr * relsec;
7517 Elf_Internal_Rela * rela;
7518 Elf_Internal_Rela * rp;
7519 unsigned char * table;
7520 unsigned char * tp;
7521 Elf_Internal_Sym * sym;
7522 const char * relname;
4d6ed7c8 7523
53774b7e
NC
7524 aux->table_len = 0;
7525
4d6ed7c8
NC
7526 /* First, find the starting address of the segment that includes
7527 this section: */
7528
dda8d76d 7529 if (filedata->file_header.e_phnum)
4d6ed7c8 7530 {
dda8d76d 7531 if (! get_program_headers (filedata))
53774b7e 7532 return FALSE;
4d6ed7c8 7533
dda8d76d
NC
7534 for (seg = filedata->program_headers;
7535 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7536 ++seg)
4d6ed7c8
NC
7537 {
7538 if (seg->p_type != PT_LOAD)
7539 continue;
7540
7541 if (sec->sh_addr >= seg->p_vaddr
7542 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7543 {
7544 aux->seg_base = seg->p_vaddr;
7545 break;
7546 }
7547 }
4d6ed7c8
NC
7548 }
7549
7550 /* Second, build the unwind table from the contents of the unwind section: */
7551 size = sec->sh_size;
dda8d76d 7552 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7553 _("unwind table"));
a6e9f9df 7554 if (!table)
53774b7e 7555 return FALSE;
4d6ed7c8 7556
53774b7e 7557 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7558 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7559 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7560 tep = aux->table;
53774b7e
NC
7561
7562 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7563 {
7564 tep->start.section = SHN_UNDEF;
7565 tep->end.section = SHN_UNDEF;
7566 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7567 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7568 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7569 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7570 tep->start.offset += aux->seg_base;
7571 tep->end.offset += aux->seg_base;
7572 tep->info.offset += aux->seg_base;
7573 }
7574 free (table);
7575
41e92641 7576 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7577 for (relsec = filedata->section_headers;
7578 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7579 ++relsec)
7580 {
7581 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7582 || relsec->sh_info >= filedata->file_header.e_shnum
7583 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7584 continue;
7585
dda8d76d 7586 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7587 & rela, & nrelas))
53774b7e
NC
7588 {
7589 free (aux->table);
7590 aux->table = NULL;
7591 aux->table_len = 0;
7592 return FALSE;
7593 }
4d6ed7c8
NC
7594
7595 for (rp = rela; rp < rela + nrelas; ++rp)
7596 {
dda8d76d 7597 relname = elf_ia64_reloc_type (get_reloc_type (filedata, rp->r_info));
aca88567 7598 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 7599
82b1b41b
NC
7600 /* PR 17531: file: 9fa67536. */
7601 if (relname == NULL)
7602 {
dda8d76d
NC
7603 warn (_("Skipping unknown relocation type: %u\n"),
7604 get_reloc_type (filedata, rp->r_info));
82b1b41b
NC
7605 continue;
7606 }
948f632f 7607
0112cd26 7608 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7609 {
82b1b41b 7610 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7611 continue;
7612 }
7613
89fac5e3 7614 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7615
53774b7e
NC
7616 /* PR 17531: file: 5bc8d9bf. */
7617 if (i >= aux->table_len)
7618 {
7619 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7620 continue;
7621 }
7622
7623 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7624 {
7625 case 0:
7626 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7627 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7628 break;
7629 case 1:
7630 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7631 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7632 break;
7633 case 2:
7634 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7635 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7636 break;
7637 default:
7638 break;
7639 }
7640 }
7641
7642 free (rela);
7643 }
7644
53774b7e 7645 return TRUE;
4d6ed7c8
NC
7646}
7647
32ec8896 7648static bfd_boolean
dda8d76d 7649ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7650{
2cf0635d
NC
7651 Elf_Internal_Shdr * sec;
7652 Elf_Internal_Shdr * unwsec = NULL;
7653 Elf_Internal_Shdr * strsec;
89fac5e3 7654 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7655 struct ia64_unw_aux_info aux;
32ec8896 7656 bfd_boolean res = TRUE;
f1467e33 7657
4d6ed7c8
NC
7658 memset (& aux, 0, sizeof (aux));
7659
dda8d76d 7660 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7661 {
c256ffe7 7662 if (sec->sh_type == SHT_SYMTAB
dda8d76d 7663 && sec->sh_link < filedata->file_header.e_shnum)
4d6ed7c8 7664 {
dda8d76d 7665 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
4d6ed7c8 7666
dda8d76d 7667 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
7668 if (aux.strtab != NULL)
7669 {
7670 error (_("Multiple auxillary string tables encountered\n"));
7671 free (aux.strtab);
32ec8896 7672 res = FALSE;
4082ef84 7673 }
dda8d76d 7674 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
7675 1, strsec->sh_size,
7676 _("string table"));
c256ffe7 7677 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
7678 }
7679 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7680 unwcount++;
7681 }
7682
7683 if (!unwcount)
7684 printf (_("\nThere are no unwind sections in this file.\n"));
7685
7686 while (unwcount-- > 0)
7687 {
2cf0635d 7688 char * suffix;
579f31ac
JJ
7689 size_t len, len2;
7690
dda8d76d
NC
7691 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
7692 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
7693 if (sec->sh_type == SHT_IA_64_UNWIND)
7694 {
7695 unwsec = sec;
7696 break;
7697 }
4082ef84
NC
7698 /* We have already counted the number of SHT_IA64_UNWIND
7699 sections so the loop above should never fail. */
7700 assert (unwsec != NULL);
579f31ac
JJ
7701
7702 unwstart = i + 1;
7703 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7704
e4b17d5c
L
7705 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7706 {
7707 /* We need to find which section group it is in. */
4082ef84 7708 struct group_list * g;
e4b17d5c 7709
4082ef84
NC
7710 if (section_headers_groups == NULL
7711 || section_headers_groups [i] == NULL)
dda8d76d 7712 i = filedata->file_header.e_shnum;
4082ef84 7713 else
e4b17d5c 7714 {
4082ef84 7715 g = section_headers_groups [i]->root;
18bd398b 7716
4082ef84
NC
7717 for (; g != NULL; g = g->next)
7718 {
dda8d76d 7719 sec = filedata->section_headers + g->section_index;
e4b17d5c 7720
4082ef84
NC
7721 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7722 break;
7723 }
7724
7725 if (g == NULL)
dda8d76d 7726 i = filedata->file_header.e_shnum;
4082ef84 7727 }
e4b17d5c 7728 }
18bd398b 7729 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7730 {
18bd398b 7731 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7732 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7733 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7734 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7735 ++i, ++sec)
18bd398b
NC
7736 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7737 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7738 break;
7739 }
7740 else
7741 {
7742 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7743 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7744 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7745 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7746 suffix = "";
18bd398b 7747 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 7748 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7749 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7750 ++i, ++sec)
18bd398b
NC
7751 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
7752 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7753 break;
7754 }
7755
dda8d76d 7756 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
7757 {
7758 printf (_("\nCould not find unwind info section for "));
7759
dda8d76d 7760 if (filedata->string_table == NULL)
579f31ac
JJ
7761 printf ("%d", unwsec->sh_name);
7762 else
dda8d76d 7763 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
7764 }
7765 else
4d6ed7c8 7766 {
4d6ed7c8 7767 aux.info_addr = sec->sh_addr;
dda8d76d 7768 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
7769 sec->sh_size,
7770 _("unwind info"));
59245841 7771 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 7772
579f31ac 7773 printf (_("\nUnwind section "));
4d6ed7c8 7774
dda8d76d 7775 if (filedata->string_table == NULL)
579f31ac
JJ
7776 printf ("%d", unwsec->sh_name);
7777 else
dda8d76d 7778 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 7779
579f31ac 7780 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 7781 (unsigned long) unwsec->sh_offset,
89fac5e3 7782 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 7783
dda8d76d 7784 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 7785 && aux.table_len > 0)
dda8d76d 7786 dump_ia64_unwind (filedata, & aux);
579f31ac
JJ
7787
7788 if (aux.table)
7789 free ((char *) aux.table);
7790 if (aux.info)
7791 free ((char *) aux.info);
7792 aux.table = NULL;
7793 aux.info = NULL;
7794 }
4d6ed7c8 7795 }
4d6ed7c8 7796
4d6ed7c8
NC
7797 if (aux.symtab)
7798 free (aux.symtab);
7799 if (aux.strtab)
7800 free ((char *) aux.strtab);
32ec8896
NC
7801
7802 return res;
4d6ed7c8
NC
7803}
7804
3f5e193b 7805struct hppa_unw_table_entry
32ec8896
NC
7806{
7807 struct absaddr start;
7808 struct absaddr end;
7809 unsigned int Cannot_unwind:1; /* 0 */
7810 unsigned int Millicode:1; /* 1 */
7811 unsigned int Millicode_save_sr0:1; /* 2 */
7812 unsigned int Region_description:2; /* 3..4 */
7813 unsigned int reserved1:1; /* 5 */
7814 unsigned int Entry_SR:1; /* 6 */
7815 unsigned int Entry_FR:4; /* Number saved 7..10 */
7816 unsigned int Entry_GR:5; /* Number saved 11..15 */
7817 unsigned int Args_stored:1; /* 16 */
7818 unsigned int Variable_Frame:1; /* 17 */
7819 unsigned int Separate_Package_Body:1; /* 18 */
7820 unsigned int Frame_Extension_Millicode:1; /* 19 */
7821 unsigned int Stack_Overflow_Check:1; /* 20 */
7822 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
7823 unsigned int Ada_Region:1; /* 22 */
7824 unsigned int cxx_info:1; /* 23 */
7825 unsigned int cxx_try_catch:1; /* 24 */
7826 unsigned int sched_entry_seq:1; /* 25 */
7827 unsigned int reserved2:1; /* 26 */
7828 unsigned int Save_SP:1; /* 27 */
7829 unsigned int Save_RP:1; /* 28 */
7830 unsigned int Save_MRP_in_frame:1; /* 29 */
7831 unsigned int extn_ptr_defined:1; /* 30 */
7832 unsigned int Cleanup_defined:1; /* 31 */
7833
7834 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
7835 unsigned int HP_UX_interrupt_marker:1; /* 1 */
7836 unsigned int Large_frame:1; /* 2 */
7837 unsigned int Pseudo_SP_Set:1; /* 3 */
7838 unsigned int reserved4:1; /* 4 */
7839 unsigned int Total_frame_size:27; /* 5..31 */
7840};
3f5e193b 7841
57346661 7842struct hppa_unw_aux_info
948f632f 7843{
32ec8896
NC
7844 struct hppa_unw_table_entry * table; /* Unwind table. */
7845 unsigned long table_len; /* Length of unwind table. */
7846 bfd_vma seg_base; /* Starting address of segment. */
7847 Elf_Internal_Sym * symtab; /* The symbol table. */
7848 unsigned long nsyms; /* Number of symbols. */
7849 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7850 unsigned long nfuns; /* Number of entries in funtab. */
7851 char * strtab; /* The string table. */
7852 unsigned long strtab_size; /* Size of string table. */
948f632f 7853};
57346661 7854
32ec8896 7855static bfd_boolean
dda8d76d 7856dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 7857{
2cf0635d 7858 struct hppa_unw_table_entry * tp;
948f632f 7859 unsigned long j, nfuns;
32ec8896 7860 bfd_boolean res = TRUE;
948f632f
DA
7861
7862 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7863 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7864 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7865 aux->funtab[nfuns++] = aux->symtab[j];
7866 aux->nfuns = nfuns;
7867 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 7868
57346661
AM
7869 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7870 {
7871 bfd_vma offset;
2cf0635d 7872 const char * procname;
57346661 7873
dda8d76d 7874 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
7875 aux->strtab_size, tp->start, &procname,
7876 &offset);
7877
7878 fputs ("\n<", stdout);
7879
7880 if (procname)
7881 {
7882 fputs (procname, stdout);
7883
7884 if (offset)
7885 printf ("+%lx", (unsigned long) offset);
7886 }
7887
7888 fputs (">: [", stdout);
7889 print_vma (tp->start.offset, PREFIX_HEX);
7890 fputc ('-', stdout);
7891 print_vma (tp->end.offset, PREFIX_HEX);
7892 printf ("]\n\t");
7893
18bd398b
NC
7894#define PF(_m) if (tp->_m) printf (#_m " ");
7895#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
7896 PF(Cannot_unwind);
7897 PF(Millicode);
7898 PF(Millicode_save_sr0);
18bd398b 7899 /* PV(Region_description); */
57346661
AM
7900 PF(Entry_SR);
7901 PV(Entry_FR);
7902 PV(Entry_GR);
7903 PF(Args_stored);
7904 PF(Variable_Frame);
7905 PF(Separate_Package_Body);
7906 PF(Frame_Extension_Millicode);
7907 PF(Stack_Overflow_Check);
7908 PF(Two_Instruction_SP_Increment);
7909 PF(Ada_Region);
7910 PF(cxx_info);
7911 PF(cxx_try_catch);
7912 PF(sched_entry_seq);
7913 PF(Save_SP);
7914 PF(Save_RP);
7915 PF(Save_MRP_in_frame);
7916 PF(extn_ptr_defined);
7917 PF(Cleanup_defined);
7918 PF(MPE_XL_interrupt_marker);
7919 PF(HP_UX_interrupt_marker);
7920 PF(Large_frame);
7921 PF(Pseudo_SP_Set);
7922 PV(Total_frame_size);
7923#undef PF
7924#undef PV
7925 }
7926
18bd398b 7927 printf ("\n");
948f632f
DA
7928
7929 free (aux->funtab);
32ec8896
NC
7930
7931 return res;
57346661
AM
7932}
7933
32ec8896 7934static bfd_boolean
dda8d76d
NC
7935slurp_hppa_unwind_table (Filedata * filedata,
7936 struct hppa_unw_aux_info * aux,
7937 Elf_Internal_Shdr * sec)
57346661 7938{
1c0751b2 7939 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7940 Elf_Internal_Phdr * seg;
7941 struct hppa_unw_table_entry * tep;
7942 Elf_Internal_Shdr * relsec;
7943 Elf_Internal_Rela * rela;
7944 Elf_Internal_Rela * rp;
7945 unsigned char * table;
7946 unsigned char * tp;
7947 Elf_Internal_Sym * sym;
7948 const char * relname;
57346661 7949
57346661
AM
7950 /* First, find the starting address of the segment that includes
7951 this section. */
dda8d76d 7952 if (filedata->file_header.e_phnum)
57346661 7953 {
dda8d76d 7954 if (! get_program_headers (filedata))
32ec8896 7955 return FALSE;
57346661 7956
dda8d76d
NC
7957 for (seg = filedata->program_headers;
7958 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
7959 ++seg)
7960 {
7961 if (seg->p_type != PT_LOAD)
7962 continue;
7963
7964 if (sec->sh_addr >= seg->p_vaddr
7965 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7966 {
7967 aux->seg_base = seg->p_vaddr;
7968 break;
7969 }
7970 }
7971 }
7972
7973 /* Second, build the unwind table from the contents of the unwind
7974 section. */
7975 size = sec->sh_size;
dda8d76d 7976 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7977 _("unwind table"));
57346661 7978 if (!table)
32ec8896 7979 return FALSE;
57346661 7980
1c0751b2
DA
7981 unw_ent_size = 16;
7982 nentries = size / unw_ent_size;
7983 size = unw_ent_size * nentries;
57346661 7984
3f5e193b
NC
7985 tep = aux->table = (struct hppa_unw_table_entry *)
7986 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7987
1c0751b2 7988 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7989 {
7990 unsigned int tmp1, tmp2;
7991
7992 tep->start.section = SHN_UNDEF;
7993 tep->end.section = SHN_UNDEF;
7994
1c0751b2
DA
7995 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7996 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7997 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7998 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7999
8000 tep->start.offset += aux->seg_base;
8001 tep->end.offset += aux->seg_base;
57346661
AM
8002
8003 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8004 tep->Millicode = (tmp1 >> 30) & 0x1;
8005 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8006 tep->Region_description = (tmp1 >> 27) & 0x3;
8007 tep->reserved1 = (tmp1 >> 26) & 0x1;
8008 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8009 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8010 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8011 tep->Args_stored = (tmp1 >> 15) & 0x1;
8012 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8013 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8014 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8015 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8016 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8017 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8018 tep->cxx_info = (tmp1 >> 8) & 0x1;
8019 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8020 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8021 tep->reserved2 = (tmp1 >> 5) & 0x1;
8022 tep->Save_SP = (tmp1 >> 4) & 0x1;
8023 tep->Save_RP = (tmp1 >> 3) & 0x1;
8024 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8025 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8026 tep->Cleanup_defined = tmp1 & 0x1;
8027
8028 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8029 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8030 tep->Large_frame = (tmp2 >> 29) & 0x1;
8031 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8032 tep->reserved4 = (tmp2 >> 27) & 0x1;
8033 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8034 }
8035 free (table);
8036
8037 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8038 for (relsec = filedata->section_headers;
8039 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8040 ++relsec)
8041 {
8042 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8043 || relsec->sh_info >= filedata->file_header.e_shnum
8044 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8045 continue;
8046
dda8d76d 8047 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8048 & rela, & nrelas))
32ec8896 8049 return FALSE;
57346661
AM
8050
8051 for (rp = rela; rp < rela + nrelas; ++rp)
8052 {
dda8d76d 8053 relname = elf_hppa_reloc_type (get_reloc_type (filedata, rp->r_info));
aca88567 8054 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
8055
8056 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8057 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
8058 {
8059 warn (_("Skipping unexpected relocation type %s\n"), relname);
8060 continue;
8061 }
8062
8063 i = rp->r_offset / unw_ent_size;
8064
89fac5e3 8065 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
8066 {
8067 case 0:
8068 aux->table[i].start.section = sym->st_shndx;
1e456d54 8069 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8070 break;
8071 case 1:
8072 aux->table[i].end.section = sym->st_shndx;
1e456d54 8073 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8074 break;
8075 default:
8076 break;
8077 }
8078 }
8079
8080 free (rela);
8081 }
8082
1c0751b2 8083 aux->table_len = nentries;
57346661 8084
32ec8896 8085 return TRUE;
57346661
AM
8086}
8087
32ec8896 8088static bfd_boolean
dda8d76d 8089hppa_process_unwind (Filedata * filedata)
57346661 8090{
57346661 8091 struct hppa_unw_aux_info aux;
2cf0635d
NC
8092 Elf_Internal_Shdr * unwsec = NULL;
8093 Elf_Internal_Shdr * strsec;
8094 Elf_Internal_Shdr * sec;
18bd398b 8095 unsigned long i;
32ec8896 8096 bfd_boolean res = TRUE;
57346661 8097
dda8d76d 8098 if (filedata->string_table == NULL)
32ec8896 8099 return FALSE;
1b31d05e
NC
8100
8101 memset (& aux, 0, sizeof (aux));
57346661 8102
dda8d76d 8103 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8104 {
c256ffe7 8105 if (sec->sh_type == SHT_SYMTAB
dda8d76d 8106 && sec->sh_link < filedata->file_header.e_shnum)
57346661 8107 {
dda8d76d 8108 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
57346661 8109
dda8d76d 8110 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
8111 if (aux.strtab != NULL)
8112 {
8113 error (_("Multiple auxillary string tables encountered\n"));
8114 free (aux.strtab);
32ec8896 8115 res = FALSE;
4082ef84 8116 }
dda8d76d 8117 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
8118 1, strsec->sh_size,
8119 _("string table"));
c256ffe7 8120 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 8121 }
18bd398b 8122 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8123 unwsec = sec;
8124 }
8125
8126 if (!unwsec)
8127 printf (_("\nThere are no unwind sections in this file.\n"));
8128
dda8d76d 8129 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8130 {
18bd398b 8131 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8132 {
d3a49aa8 8133 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size + 8);
dda8d76d 8134
d3a49aa8
AM
8135 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8136 "contains %lu entry:\n",
8137 "\nUnwind section '%s' at offset 0x%lx "
8138 "contains %lu entries:\n",
8139 num_unwind),
dda8d76d 8140 printable_section_name (filedata, sec),
57346661 8141 (unsigned long) sec->sh_offset,
d3a49aa8 8142 num_unwind);
57346661 8143
dda8d76d 8144 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8145 res = FALSE;
66b09c7e
S
8146
8147 if (res && aux.table_len > 0)
32ec8896 8148 {
dda8d76d 8149 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8150 res = FALSE;
8151 }
57346661
AM
8152
8153 if (aux.table)
8154 free ((char *) aux.table);
8155 aux.table = NULL;
8156 }
8157 }
8158
8159 if (aux.symtab)
8160 free (aux.symtab);
8161 if (aux.strtab)
8162 free ((char *) aux.strtab);
32ec8896
NC
8163
8164 return res;
57346661
AM
8165}
8166
0b6ae522
DJ
8167struct arm_section
8168{
a734115a
NC
8169 unsigned char * data; /* The unwind data. */
8170 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8171 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8172 unsigned long nrelas; /* The number of relocations. */
8173 unsigned int rel_type; /* REL or RELA ? */
8174 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8175};
8176
8177struct arm_unw_aux_info
8178{
dda8d76d 8179 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8180 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8181 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8182 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8183 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8184 char * strtab; /* The file's string table. */
8185 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8186};
8187
8188static const char *
dda8d76d
NC
8189arm_print_vma_and_name (Filedata * filedata,
8190 struct arm_unw_aux_info * aux,
8191 bfd_vma fn,
8192 struct absaddr addr)
0b6ae522
DJ
8193{
8194 const char *procname;
8195 bfd_vma sym_offset;
8196
8197 if (addr.section == SHN_UNDEF)
8198 addr.offset = fn;
8199
dda8d76d 8200 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8201 aux->strtab_size, addr, &procname,
8202 &sym_offset);
8203
8204 print_vma (fn, PREFIX_HEX);
8205
8206 if (procname)
8207 {
8208 fputs (" <", stdout);
8209 fputs (procname, stdout);
8210
8211 if (sym_offset)
8212 printf ("+0x%lx", (unsigned long) sym_offset);
8213 fputc ('>', stdout);
8214 }
8215
8216 return procname;
8217}
8218
8219static void
8220arm_free_section (struct arm_section *arm_sec)
8221{
8222 if (arm_sec->data != NULL)
8223 free (arm_sec->data);
8224
8225 if (arm_sec->rela != NULL)
8226 free (arm_sec->rela);
8227}
8228
a734115a
NC
8229/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8230 cached section and install SEC instead.
8231 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8232 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8233 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8234 relocation's offset in ADDR.
1b31d05e
NC
8235 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8236 into the string table of the symbol associated with the reloc. If no
8237 reloc was applied store -1 there.
8238 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8239
8240static bfd_boolean
dda8d76d
NC
8241get_unwind_section_word (Filedata * filedata,
8242 struct arm_unw_aux_info * aux,
1b31d05e
NC
8243 struct arm_section * arm_sec,
8244 Elf_Internal_Shdr * sec,
8245 bfd_vma word_offset,
8246 unsigned int * wordp,
8247 struct absaddr * addr,
8248 bfd_vma * sym_name)
0b6ae522
DJ
8249{
8250 Elf_Internal_Rela *rp;
8251 Elf_Internal_Sym *sym;
8252 const char * relname;
8253 unsigned int word;
8254 bfd_boolean wrapped;
8255
e0a31db1
NC
8256 if (sec == NULL || arm_sec == NULL)
8257 return FALSE;
8258
0b6ae522
DJ
8259 addr->section = SHN_UNDEF;
8260 addr->offset = 0;
8261
1b31d05e
NC
8262 if (sym_name != NULL)
8263 *sym_name = (bfd_vma) -1;
8264
a734115a 8265 /* If necessary, update the section cache. */
0b6ae522
DJ
8266 if (sec != arm_sec->sec)
8267 {
8268 Elf_Internal_Shdr *relsec;
8269
8270 arm_free_section (arm_sec);
8271
8272 arm_sec->sec = sec;
dda8d76d 8273 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8274 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8275 arm_sec->rela = NULL;
8276 arm_sec->nrelas = 0;
8277
dda8d76d
NC
8278 for (relsec = filedata->section_headers;
8279 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8280 ++relsec)
8281 {
dda8d76d
NC
8282 if (relsec->sh_info >= filedata->file_header.e_shnum
8283 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8284 /* PR 15745: Check the section type as well. */
8285 || (relsec->sh_type != SHT_REL
8286 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8287 continue;
8288
a734115a 8289 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8290 if (relsec->sh_type == SHT_REL)
8291 {
dda8d76d 8292 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8293 relsec->sh_size,
8294 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8295 return FALSE;
0b6ae522 8296 }
1ae40aa4 8297 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8298 {
dda8d76d 8299 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8300 relsec->sh_size,
8301 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8302 return FALSE;
0b6ae522 8303 }
1ae40aa4 8304 break;
0b6ae522
DJ
8305 }
8306
8307 arm_sec->next_rela = arm_sec->rela;
8308 }
8309
a734115a 8310 /* If there is no unwind data we can do nothing. */
0b6ae522 8311 if (arm_sec->data == NULL)
a734115a 8312 return FALSE;
0b6ae522 8313
e0a31db1 8314 /* If the offset is invalid then fail. */
f32ba729
NC
8315 if (/* PR 21343 *//* PR 18879 */
8316 sec->sh_size < 4
8317 || word_offset > (sec->sh_size - 4)
1a915552 8318 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8319 return FALSE;
8320
a734115a 8321 /* Get the word at the required offset. */
0b6ae522
DJ
8322 word = byte_get (arm_sec->data + word_offset, 4);
8323
0eff7165
NC
8324 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8325 if (arm_sec->rela == NULL)
8326 {
8327 * wordp = word;
8328 return TRUE;
8329 }
8330
a734115a 8331 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8332 wrapped = FALSE;
8333 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8334 {
8335 bfd_vma prelval, offset;
8336
8337 if (rp->r_offset > word_offset && !wrapped)
8338 {
8339 rp = arm_sec->rela;
8340 wrapped = TRUE;
8341 }
8342 if (rp->r_offset > word_offset)
8343 break;
8344
8345 if (rp->r_offset & 3)
8346 {
8347 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8348 (unsigned long) rp->r_offset);
8349 continue;
8350 }
8351
8352 if (rp->r_offset < word_offset)
8353 continue;
8354
74e1a04b
NC
8355 /* PR 17531: file: 027-161405-0.004 */
8356 if (aux->symtab == NULL)
8357 continue;
8358
0b6ae522
DJ
8359 if (arm_sec->rel_type == SHT_REL)
8360 {
8361 offset = word & 0x7fffffff;
8362 if (offset & 0x40000000)
8363 offset |= ~ (bfd_vma) 0x7fffffff;
8364 }
a734115a 8365 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8366 offset = rp->r_addend;
a734115a 8367 else
74e1a04b
NC
8368 {
8369 error (_("Unknown section relocation type %d encountered\n"),
8370 arm_sec->rel_type);
8371 break;
8372 }
0b6ae522 8373
071436c6
NC
8374 /* PR 17531 file: 027-1241568-0.004. */
8375 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8376 {
8377 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8378 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8379 break;
8380 }
8381
8382 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8383 offset += sym->st_value;
8384 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8385
a734115a 8386 /* Check that we are processing the expected reloc type. */
dda8d76d 8387 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8388 {
8389 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8390 if (relname == NULL)
8391 {
8392 warn (_("Skipping unknown ARM relocation type: %d\n"),
8393 (int) ELF32_R_TYPE (rp->r_info));
8394 continue;
8395 }
a734115a
NC
8396
8397 if (streq (relname, "R_ARM_NONE"))
8398 continue;
0b4362b0 8399
a734115a
NC
8400 if (! streq (relname, "R_ARM_PREL31"))
8401 {
071436c6 8402 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8403 continue;
8404 }
8405 }
dda8d76d 8406 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8407 {
8408 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8409 if (relname == NULL)
8410 {
8411 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8412 (int) ELF32_R_TYPE (rp->r_info));
8413 continue;
8414 }
0b4362b0 8415
a734115a
NC
8416 if (streq (relname, "R_C6000_NONE"))
8417 continue;
8418
8419 if (! streq (relname, "R_C6000_PREL31"))
8420 {
071436c6 8421 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8422 continue;
8423 }
8424
8425 prelval >>= 1;
8426 }
8427 else
74e1a04b
NC
8428 {
8429 /* This function currently only supports ARM and TI unwinders. */
8430 warn (_("Only TI and ARM unwinders are currently supported\n"));
8431 break;
8432 }
fa197c1c 8433
0b6ae522
DJ
8434 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8435 addr->section = sym->st_shndx;
8436 addr->offset = offset;
74e1a04b 8437
1b31d05e
NC
8438 if (sym_name)
8439 * sym_name = sym->st_name;
0b6ae522
DJ
8440 break;
8441 }
8442
8443 *wordp = word;
8444 arm_sec->next_rela = rp;
8445
a734115a 8446 return TRUE;
0b6ae522
DJ
8447}
8448
a734115a
NC
8449static const char *tic6x_unwind_regnames[16] =
8450{
0b4362b0
RM
8451 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8452 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8453 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8454};
fa197c1c 8455
0b6ae522 8456static void
fa197c1c 8457decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8458{
fa197c1c
PB
8459 int i;
8460
8461 for (i = 12; mask; mask >>= 1, i--)
8462 {
8463 if (mask & 1)
8464 {
8465 fputs (tic6x_unwind_regnames[i], stdout);
8466 if (mask > 1)
8467 fputs (", ", stdout);
8468 }
8469 }
8470}
0b6ae522
DJ
8471
8472#define ADVANCE \
8473 if (remaining == 0 && more_words) \
8474 { \
8475 data_offset += 4; \
dda8d76d 8476 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8477 data_offset, & word, & addr, NULL)) \
32ec8896 8478 return FALSE; \
0b6ae522
DJ
8479 remaining = 4; \
8480 more_words--; \
8481 } \
8482
8483#define GET_OP(OP) \
8484 ADVANCE; \
8485 if (remaining) \
8486 { \
8487 remaining--; \
8488 (OP) = word >> 24; \
8489 word <<= 8; \
8490 } \
8491 else \
8492 { \
2b692964 8493 printf (_("[Truncated opcode]\n")); \
32ec8896 8494 return FALSE; \
0b6ae522 8495 } \
cc5914eb 8496 printf ("0x%02x ", OP)
0b6ae522 8497
32ec8896 8498static bfd_boolean
dda8d76d
NC
8499decode_arm_unwind_bytecode (Filedata * filedata,
8500 struct arm_unw_aux_info * aux,
948f632f
DA
8501 unsigned int word,
8502 unsigned int remaining,
8503 unsigned int more_words,
8504 bfd_vma data_offset,
8505 Elf_Internal_Shdr * data_sec,
8506 struct arm_section * data_arm_sec)
fa197c1c
PB
8507{
8508 struct absaddr addr;
32ec8896 8509 bfd_boolean res = TRUE;
0b6ae522
DJ
8510
8511 /* Decode the unwinding instructions. */
8512 while (1)
8513 {
8514 unsigned int op, op2;
8515
8516 ADVANCE;
8517 if (remaining == 0)
8518 break;
8519 remaining--;
8520 op = word >> 24;
8521 word <<= 8;
8522
cc5914eb 8523 printf (" 0x%02x ", op);
0b6ae522
DJ
8524
8525 if ((op & 0xc0) == 0x00)
8526 {
8527 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8528
cc5914eb 8529 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8530 }
8531 else if ((op & 0xc0) == 0x40)
8532 {
8533 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8534
cc5914eb 8535 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8536 }
8537 else if ((op & 0xf0) == 0x80)
8538 {
8539 GET_OP (op2);
8540 if (op == 0x80 && op2 == 0)
8541 printf (_("Refuse to unwind"));
8542 else
8543 {
8544 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8545 bfd_boolean first = TRUE;
0b6ae522 8546 int i;
2b692964 8547
0b6ae522
DJ
8548 printf ("pop {");
8549 for (i = 0; i < 12; i++)
8550 if (mask & (1 << i))
8551 {
8552 if (first)
32ec8896 8553 first = FALSE;
0b6ae522
DJ
8554 else
8555 printf (", ");
8556 printf ("r%d", 4 + i);
8557 }
8558 printf ("}");
8559 }
8560 }
8561 else if ((op & 0xf0) == 0x90)
8562 {
8563 if (op == 0x9d || op == 0x9f)
8564 printf (_(" [Reserved]"));
8565 else
cc5914eb 8566 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8567 }
8568 else if ((op & 0xf0) == 0xa0)
8569 {
8570 int end = 4 + (op & 0x07);
32ec8896 8571 bfd_boolean first = TRUE;
0b6ae522 8572 int i;
61865e30 8573
0b6ae522
DJ
8574 printf (" pop {");
8575 for (i = 4; i <= end; i++)
8576 {
8577 if (first)
32ec8896 8578 first = FALSE;
0b6ae522
DJ
8579 else
8580 printf (", ");
8581 printf ("r%d", i);
8582 }
8583 if (op & 0x08)
8584 {
1b31d05e 8585 if (!first)
0b6ae522
DJ
8586 printf (", ");
8587 printf ("r14");
8588 }
8589 printf ("}");
8590 }
8591 else if (op == 0xb0)
8592 printf (_(" finish"));
8593 else if (op == 0xb1)
8594 {
8595 GET_OP (op2);
8596 if (op2 == 0 || (op2 & 0xf0) != 0)
8597 printf (_("[Spare]"));
8598 else
8599 {
8600 unsigned int mask = op2 & 0x0f;
32ec8896 8601 bfd_boolean first = TRUE;
0b6ae522 8602 int i;
61865e30 8603
0b6ae522
DJ
8604 printf ("pop {");
8605 for (i = 0; i < 12; i++)
8606 if (mask & (1 << i))
8607 {
8608 if (first)
32ec8896 8609 first = FALSE;
0b6ae522
DJ
8610 else
8611 printf (", ");
8612 printf ("r%d", i);
8613 }
8614 printf ("}");
8615 }
8616 }
8617 else if (op == 0xb2)
8618 {
b115cf96 8619 unsigned char buf[9];
0b6ae522
DJ
8620 unsigned int i, len;
8621 unsigned long offset;
61865e30 8622
b115cf96 8623 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8624 {
8625 GET_OP (buf[i]);
8626 if ((buf[i] & 0x80) == 0)
8627 break;
8628 }
4082ef84 8629 if (i == sizeof (buf))
32ec8896
NC
8630 {
8631 error (_("corrupt change to vsp"));
8632 res = FALSE;
8633 }
4082ef84
NC
8634 else
8635 {
8636 offset = read_uleb128 (buf, &len, buf + i + 1);
8637 assert (len == i + 1);
8638 offset = offset * 4 + 0x204;
8639 printf ("vsp = vsp + %ld", offset);
8640 }
0b6ae522 8641 }
61865e30 8642 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8643 {
61865e30
NC
8644 unsigned int first, last;
8645
8646 GET_OP (op2);
8647 first = op2 >> 4;
8648 last = op2 & 0x0f;
8649 if (op == 0xc8)
8650 first = first + 16;
8651 printf ("pop {D%d", first);
8652 if (last)
8653 printf ("-D%d", first + last);
8654 printf ("}");
8655 }
8656 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8657 {
8658 unsigned int count = op & 0x07;
8659
8660 printf ("pop {D8");
8661 if (count)
8662 printf ("-D%d", 8 + count);
8663 printf ("}");
8664 }
8665 else if (op >= 0xc0 && op <= 0xc5)
8666 {
8667 unsigned int count = op & 0x07;
8668
8669 printf (" pop {wR10");
8670 if (count)
8671 printf ("-wR%d", 10 + count);
8672 printf ("}");
8673 }
8674 else if (op == 0xc6)
8675 {
8676 unsigned int first, last;
8677
8678 GET_OP (op2);
8679 first = op2 >> 4;
8680 last = op2 & 0x0f;
8681 printf ("pop {wR%d", first);
8682 if (last)
8683 printf ("-wR%d", first + last);
8684 printf ("}");
8685 }
8686 else if (op == 0xc7)
8687 {
8688 GET_OP (op2);
8689 if (op2 == 0 || (op2 & 0xf0) != 0)
8690 printf (_("[Spare]"));
0b6ae522
DJ
8691 else
8692 {
61865e30 8693 unsigned int mask = op2 & 0x0f;
32ec8896 8694 bfd_boolean first = TRUE;
61865e30
NC
8695 int i;
8696
8697 printf ("pop {");
8698 for (i = 0; i < 4; i++)
8699 if (mask & (1 << i))
8700 {
8701 if (first)
32ec8896 8702 first = FALSE;
61865e30
NC
8703 else
8704 printf (", ");
8705 printf ("wCGR%d", i);
8706 }
8707 printf ("}");
0b6ae522
DJ
8708 }
8709 }
61865e30 8710 else
32ec8896
NC
8711 {
8712 printf (_(" [unsupported opcode]"));
8713 res = FALSE;
8714 }
8715
0b6ae522
DJ
8716 printf ("\n");
8717 }
32ec8896
NC
8718
8719 return res;
fa197c1c
PB
8720}
8721
32ec8896 8722static bfd_boolean
dda8d76d
NC
8723decode_tic6x_unwind_bytecode (Filedata * filedata,
8724 struct arm_unw_aux_info * aux,
948f632f
DA
8725 unsigned int word,
8726 unsigned int remaining,
8727 unsigned int more_words,
8728 bfd_vma data_offset,
8729 Elf_Internal_Shdr * data_sec,
8730 struct arm_section * data_arm_sec)
fa197c1c
PB
8731{
8732 struct absaddr addr;
8733
8734 /* Decode the unwinding instructions. */
8735 while (1)
8736 {
8737 unsigned int op, op2;
8738
8739 ADVANCE;
8740 if (remaining == 0)
8741 break;
8742 remaining--;
8743 op = word >> 24;
8744 word <<= 8;
8745
9cf03b7e 8746 printf (" 0x%02x ", op);
fa197c1c
PB
8747
8748 if ((op & 0xc0) == 0x00)
8749 {
8750 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 8751 printf (" sp = sp + %d", offset);
fa197c1c
PB
8752 }
8753 else if ((op & 0xc0) == 0x80)
8754 {
8755 GET_OP (op2);
8756 if (op == 0x80 && op2 == 0)
8757 printf (_("Refuse to unwind"));
8758 else
8759 {
8760 unsigned int mask = ((op & 0x1f) << 8) | op2;
8761 if (op & 0x20)
8762 printf ("pop compact {");
8763 else
8764 printf ("pop {");
8765
8766 decode_tic6x_unwind_regmask (mask);
8767 printf("}");
8768 }
8769 }
8770 else if ((op & 0xf0) == 0xc0)
8771 {
8772 unsigned int reg;
8773 unsigned int nregs;
8774 unsigned int i;
8775 const char *name;
a734115a
NC
8776 struct
8777 {
32ec8896
NC
8778 unsigned int offset;
8779 unsigned int reg;
fa197c1c
PB
8780 } regpos[16];
8781
8782 /* Scan entire instruction first so that GET_OP output is not
8783 interleaved with disassembly. */
8784 nregs = 0;
8785 for (i = 0; nregs < (op & 0xf); i++)
8786 {
8787 GET_OP (op2);
8788 reg = op2 >> 4;
8789 if (reg != 0xf)
8790 {
8791 regpos[nregs].offset = i * 2;
8792 regpos[nregs].reg = reg;
8793 nregs++;
8794 }
8795
8796 reg = op2 & 0xf;
8797 if (reg != 0xf)
8798 {
8799 regpos[nregs].offset = i * 2 + 1;
8800 regpos[nregs].reg = reg;
8801 nregs++;
8802 }
8803 }
8804
8805 printf (_("pop frame {"));
8806 reg = nregs - 1;
8807 for (i = i * 2; i > 0; i--)
8808 {
8809 if (regpos[reg].offset == i - 1)
8810 {
8811 name = tic6x_unwind_regnames[regpos[reg].reg];
8812 if (reg > 0)
8813 reg--;
8814 }
8815 else
8816 name = _("[pad]");
8817
8818 fputs (name, stdout);
8819 if (i > 1)
8820 printf (", ");
8821 }
8822
8823 printf ("}");
8824 }
8825 else if (op == 0xd0)
8826 printf (" MOV FP, SP");
8827 else if (op == 0xd1)
8828 printf (" __c6xabi_pop_rts");
8829 else if (op == 0xd2)
8830 {
8831 unsigned char buf[9];
8832 unsigned int i, len;
8833 unsigned long offset;
a734115a 8834
fa197c1c
PB
8835 for (i = 0; i < sizeof (buf); i++)
8836 {
8837 GET_OP (buf[i]);
8838 if ((buf[i] & 0x80) == 0)
8839 break;
8840 }
0eff7165
NC
8841 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
8842 if (i == sizeof (buf))
8843 {
0eff7165 8844 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 8845 return FALSE;
0eff7165 8846 }
948f632f 8847
f6f0e17b 8848 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
8849 assert (len == i + 1);
8850 offset = offset * 8 + 0x408;
8851 printf (_("sp = sp + %ld"), offset);
8852 }
8853 else if ((op & 0xf0) == 0xe0)
8854 {
8855 if ((op & 0x0f) == 7)
8856 printf (" RETURN");
8857 else
8858 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
8859 }
8860 else
8861 {
8862 printf (_(" [unsupported opcode]"));
8863 }
8864 putchar ('\n');
8865 }
32ec8896
NC
8866
8867 return TRUE;
fa197c1c
PB
8868}
8869
8870static bfd_vma
dda8d76d 8871arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
8872{
8873 bfd_vma offset;
8874
8875 offset = word & 0x7fffffff;
8876 if (offset & 0x40000000)
8877 offset |= ~ (bfd_vma) 0x7fffffff;
8878
dda8d76d 8879 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
8880 offset <<= 1;
8881
8882 return offset + where;
8883}
8884
32ec8896 8885static bfd_boolean
dda8d76d
NC
8886decode_arm_unwind (Filedata * filedata,
8887 struct arm_unw_aux_info * aux,
1b31d05e
NC
8888 unsigned int word,
8889 unsigned int remaining,
8890 bfd_vma data_offset,
8891 Elf_Internal_Shdr * data_sec,
8892 struct arm_section * data_arm_sec)
fa197c1c
PB
8893{
8894 int per_index;
8895 unsigned int more_words = 0;
37e14bc3 8896 struct absaddr addr;
1b31d05e 8897 bfd_vma sym_name = (bfd_vma) -1;
97953bab 8898 bfd_boolean res = TRUE;
fa197c1c
PB
8899
8900 if (remaining == 0)
8901 {
1b31d05e
NC
8902 /* Fetch the first word.
8903 Note - when decoding an object file the address extracted
8904 here will always be 0. So we also pass in the sym_name
8905 parameter so that we can find the symbol associated with
8906 the personality routine. */
dda8d76d 8907 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 8908 & word, & addr, & sym_name))
32ec8896 8909 return FALSE;
1b31d05e 8910
fa197c1c
PB
8911 remaining = 4;
8912 }
8913
8914 if ((word & 0x80000000) == 0)
8915 {
8916 /* Expand prel31 for personality routine. */
8917 bfd_vma fn;
8918 const char *procname;
8919
dda8d76d 8920 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 8921 printf (_(" Personality routine: "));
1b31d05e
NC
8922 if (fn == 0
8923 && addr.section == SHN_UNDEF && addr.offset == 0
8924 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
8925 {
8926 procname = aux->strtab + sym_name;
8927 print_vma (fn, PREFIX_HEX);
8928 if (procname)
8929 {
8930 fputs (" <", stdout);
8931 fputs (procname, stdout);
8932 fputc ('>', stdout);
8933 }
8934 }
8935 else
dda8d76d 8936 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
8937 fputc ('\n', stdout);
8938
8939 /* The GCC personality routines use the standard compact
8940 encoding, starting with one byte giving the number of
8941 words. */
8942 if (procname != NULL
8943 && (const_strneq (procname, "__gcc_personality_v0")
8944 || const_strneq (procname, "__gxx_personality_v0")
8945 || const_strneq (procname, "__gcj_personality_v0")
8946 || const_strneq (procname, "__gnu_objc_personality_v0")))
8947 {
8948 remaining = 0;
8949 more_words = 1;
8950 ADVANCE;
8951 if (!remaining)
8952 {
8953 printf (_(" [Truncated data]\n"));
32ec8896 8954 return FALSE;
fa197c1c
PB
8955 }
8956 more_words = word >> 24;
8957 word <<= 8;
8958 remaining--;
8959 per_index = -1;
8960 }
8961 else
32ec8896 8962 return TRUE;
fa197c1c
PB
8963 }
8964 else
8965 {
1b31d05e 8966 /* ARM EHABI Section 6.3:
0b4362b0 8967
1b31d05e 8968 An exception-handling table entry for the compact model looks like:
0b4362b0 8969
1b31d05e
NC
8970 31 30-28 27-24 23-0
8971 -- ----- ----- ----
8972 1 0 index Data for personalityRoutine[index] */
8973
dda8d76d 8974 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 8975 && (word & 0x70000000))
32ec8896
NC
8976 {
8977 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
8978 res = FALSE;
8979 }
1b31d05e 8980
fa197c1c 8981 per_index = (word >> 24) & 0x7f;
1b31d05e 8982 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
8983 if (per_index == 0)
8984 {
8985 more_words = 0;
8986 word <<= 8;
8987 remaining--;
8988 }
8989 else if (per_index < 3)
8990 {
8991 more_words = (word >> 16) & 0xff;
8992 word <<= 16;
8993 remaining -= 2;
8994 }
8995 }
8996
dda8d76d 8997 switch (filedata->file_header.e_machine)
fa197c1c
PB
8998 {
8999 case EM_ARM:
9000 if (per_index < 3)
9001 {
dda8d76d 9002 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9003 data_offset, data_sec, data_arm_sec))
9004 res = FALSE;
fa197c1c
PB
9005 }
9006 else
1b31d05e
NC
9007 {
9008 warn (_("Unknown ARM compact model index encountered\n"));
9009 printf (_(" [reserved]\n"));
32ec8896 9010 res = FALSE;
1b31d05e 9011 }
fa197c1c
PB
9012 break;
9013
9014 case EM_TI_C6000:
9015 if (per_index < 3)
9016 {
dda8d76d 9017 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9018 data_offset, data_sec, data_arm_sec))
9019 res = FALSE;
fa197c1c
PB
9020 }
9021 else if (per_index < 5)
9022 {
9023 if (((word >> 17) & 0x7f) == 0x7f)
9024 printf (_(" Restore stack from frame pointer\n"));
9025 else
9026 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9027 printf (_(" Registers restored: "));
9028 if (per_index == 4)
9029 printf (" (compact) ");
9030 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9031 putchar ('\n');
9032 printf (_(" Return register: %s\n"),
9033 tic6x_unwind_regnames[word & 0xf]);
9034 }
9035 else
1b31d05e 9036 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9037 break;
9038
9039 default:
74e1a04b 9040 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9041 filedata->file_header.e_machine);
32ec8896 9042 res = FALSE;
fa197c1c 9043 }
0b6ae522
DJ
9044
9045 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9046
9047 return res;
0b6ae522
DJ
9048}
9049
32ec8896 9050static bfd_boolean
dda8d76d
NC
9051dump_arm_unwind (Filedata * filedata,
9052 struct arm_unw_aux_info * aux,
9053 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9054{
9055 struct arm_section exidx_arm_sec, extab_arm_sec;
9056 unsigned int i, exidx_len;
948f632f 9057 unsigned long j, nfuns;
32ec8896 9058 bfd_boolean res = TRUE;
0b6ae522
DJ
9059
9060 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9061 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9062 exidx_len = exidx_sec->sh_size / 8;
9063
948f632f
DA
9064 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9065 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9066 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9067 aux->funtab[nfuns++] = aux->symtab[j];
9068 aux->nfuns = nfuns;
9069 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9070
0b6ae522
DJ
9071 for (i = 0; i < exidx_len; i++)
9072 {
9073 unsigned int exidx_fn, exidx_entry;
9074 struct absaddr fn_addr, entry_addr;
9075 bfd_vma fn;
9076
9077 fputc ('\n', stdout);
9078
dda8d76d 9079 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9080 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9081 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9082 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9083 {
948f632f 9084 free (aux->funtab);
1b31d05e
NC
9085 arm_free_section (& exidx_arm_sec);
9086 arm_free_section (& extab_arm_sec);
32ec8896 9087 return FALSE;
0b6ae522
DJ
9088 }
9089
83c257ca
NC
9090 /* ARM EHABI, Section 5:
9091 An index table entry consists of 2 words.
9092 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9093 if (exidx_fn & 0x80000000)
32ec8896
NC
9094 {
9095 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9096 res = FALSE;
9097 }
83c257ca 9098
dda8d76d 9099 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9100
dda8d76d 9101 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9102 fputs (": ", stdout);
9103
9104 if (exidx_entry == 1)
9105 {
9106 print_vma (exidx_entry, PREFIX_HEX);
9107 fputs (" [cantunwind]\n", stdout);
9108 }
9109 else if (exidx_entry & 0x80000000)
9110 {
9111 print_vma (exidx_entry, PREFIX_HEX);
9112 fputc ('\n', stdout);
dda8d76d 9113 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9114 }
9115 else
9116 {
8f73510c 9117 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9118 Elf_Internal_Shdr *table_sec;
9119
9120 fputs ("@", stdout);
dda8d76d 9121 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9122 print_vma (table, PREFIX_HEX);
9123 printf ("\n");
9124
9125 /* Locate the matching .ARM.extab. */
9126 if (entry_addr.section != SHN_UNDEF
dda8d76d 9127 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9128 {
dda8d76d 9129 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9130 table_offset = entry_addr.offset;
1a915552
NC
9131 /* PR 18879 */
9132 if (table_offset > table_sec->sh_size
9133 || ((bfd_signed_vma) table_offset) < 0)
9134 {
9135 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9136 (unsigned long) table_offset,
dda8d76d 9137 printable_section_name (filedata, table_sec));
32ec8896 9138 res = FALSE;
1a915552
NC
9139 continue;
9140 }
0b6ae522
DJ
9141 }
9142 else
9143 {
dda8d76d 9144 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9145 if (table_sec != NULL)
9146 table_offset = table - table_sec->sh_addr;
9147 }
32ec8896 9148
0b6ae522
DJ
9149 if (table_sec == NULL)
9150 {
9151 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9152 (unsigned long) table);
32ec8896 9153 res = FALSE;
0b6ae522
DJ
9154 continue;
9155 }
32ec8896 9156
dda8d76d 9157 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9158 &extab_arm_sec))
9159 res = FALSE;
0b6ae522
DJ
9160 }
9161 }
9162
9163 printf ("\n");
9164
948f632f 9165 free (aux->funtab);
0b6ae522
DJ
9166 arm_free_section (&exidx_arm_sec);
9167 arm_free_section (&extab_arm_sec);
32ec8896
NC
9168
9169 return res;
0b6ae522
DJ
9170}
9171
fa197c1c 9172/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9173
32ec8896 9174static bfd_boolean
dda8d76d 9175arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9176{
9177 struct arm_unw_aux_info aux;
9178 Elf_Internal_Shdr *unwsec = NULL;
9179 Elf_Internal_Shdr *strsec;
9180 Elf_Internal_Shdr *sec;
9181 unsigned long i;
fa197c1c 9182 unsigned int sec_type;
32ec8896 9183 bfd_boolean res = TRUE;
0b6ae522 9184
dda8d76d 9185 switch (filedata->file_header.e_machine)
fa197c1c
PB
9186 {
9187 case EM_ARM:
9188 sec_type = SHT_ARM_EXIDX;
9189 break;
9190
9191 case EM_TI_C6000:
9192 sec_type = SHT_C6000_UNWIND;
9193 break;
9194
0b4362b0 9195 default:
74e1a04b 9196 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9197 filedata->file_header.e_machine);
32ec8896 9198 return FALSE;
fa197c1c
PB
9199 }
9200
dda8d76d 9201 if (filedata->string_table == NULL)
32ec8896 9202 return FALSE;
1b31d05e
NC
9203
9204 memset (& aux, 0, sizeof (aux));
dda8d76d 9205 aux.filedata = filedata;
0b6ae522 9206
dda8d76d 9207 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9208 {
dda8d76d 9209 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < filedata->file_header.e_shnum)
0b6ae522 9210 {
dda8d76d 9211 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
0b6ae522 9212
dda8d76d 9213 strsec = filedata->section_headers + sec->sh_link;
74e1a04b
NC
9214
9215 /* PR binutils/17531 file: 011-12666-0.004. */
9216 if (aux.strtab != NULL)
9217 {
4082ef84 9218 error (_("Multiple string tables found in file.\n"));
74e1a04b 9219 free (aux.strtab);
32ec8896 9220 res = FALSE;
74e1a04b 9221 }
dda8d76d 9222 aux.strtab = get_data (NULL, filedata, strsec->sh_offset,
0b6ae522
DJ
9223 1, strsec->sh_size, _("string table"));
9224 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
9225 }
fa197c1c 9226 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9227 unwsec = sec;
9228 }
9229
1b31d05e 9230 if (unwsec == NULL)
0b6ae522 9231 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9232 else
dda8d76d 9233 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9234 {
9235 if (sec->sh_type == sec_type)
9236 {
d3a49aa8
AM
9237 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9238 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9239 "contains %lu entry:\n",
9240 "\nUnwind section '%s' at offset 0x%lx "
9241 "contains %lu entries:\n",
9242 num_unwind),
dda8d76d 9243 printable_section_name (filedata, sec),
1b31d05e 9244 (unsigned long) sec->sh_offset,
d3a49aa8 9245 num_unwind);
0b6ae522 9246
dda8d76d 9247 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9248 res = FALSE;
1b31d05e
NC
9249 }
9250 }
0b6ae522
DJ
9251
9252 if (aux.symtab)
9253 free (aux.symtab);
9254 if (aux.strtab)
9255 free ((char *) aux.strtab);
32ec8896
NC
9256
9257 return res;
0b6ae522
DJ
9258}
9259
32ec8896 9260static bfd_boolean
dda8d76d 9261process_unwind (Filedata * filedata)
57346661 9262{
2cf0635d
NC
9263 struct unwind_handler
9264 {
32ec8896 9265 unsigned int machtype;
dda8d76d 9266 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9267 } handlers[] =
9268 {
0b6ae522 9269 { EM_ARM, arm_process_unwind },
57346661
AM
9270 { EM_IA_64, ia64_process_unwind },
9271 { EM_PARISC, hppa_process_unwind },
fa197c1c 9272 { EM_TI_C6000, arm_process_unwind },
32ec8896 9273 { 0, NULL }
57346661
AM
9274 };
9275 int i;
9276
9277 if (!do_unwind)
32ec8896 9278 return TRUE;
57346661
AM
9279
9280 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9281 if (filedata->file_header.e_machine == handlers[i].machtype)
9282 return handlers[i].handler (filedata);
57346661 9283
1b31d05e 9284 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9285 get_machine_name (filedata->file_header.e_machine));
32ec8896 9286 return TRUE;
57346661
AM
9287}
9288
252b5132 9289static void
2cf0635d 9290dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
9291{
9292 switch (entry->d_tag)
9293 {
9294 case DT_MIPS_FLAGS:
9295 if (entry->d_un.d_val == 0)
4b68bca3 9296 printf (_("NONE"));
252b5132
RH
9297 else
9298 {
9299 static const char * opts[] =
9300 {
9301 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9302 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9303 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9304 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9305 "RLD_ORDER_SAFE"
9306 };
9307 unsigned int cnt;
32ec8896 9308 bfd_boolean first = TRUE;
2b692964 9309
60bca95a 9310 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9311 if (entry->d_un.d_val & (1 << cnt))
9312 {
9313 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9314 first = FALSE;
252b5132 9315 }
252b5132
RH
9316 }
9317 break;
103f02d3 9318
252b5132 9319 case DT_MIPS_IVERSION:
d79b3d50 9320 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 9321 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9322 else
76ca31c0
NC
9323 {
9324 char buf[40];
9325 sprintf_vma (buf, entry->d_un.d_ptr);
9326 /* Note: coded this way so that there is a single string for translation. */
9327 printf (_("<corrupt: %s>"), buf);
9328 }
252b5132 9329 break;
103f02d3 9330
252b5132
RH
9331 case DT_MIPS_TIME_STAMP:
9332 {
d5b07ef4 9333 char timebuf[128];
2cf0635d 9334 struct tm * tmp;
91d6fa6a 9335 time_t atime = entry->d_un.d_val;
82b1b41b 9336
91d6fa6a 9337 tmp = gmtime (&atime);
82b1b41b
NC
9338 /* PR 17531: file: 6accc532. */
9339 if (tmp == NULL)
9340 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9341 else
9342 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9343 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9344 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9345 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9346 }
9347 break;
103f02d3 9348
252b5132
RH
9349 case DT_MIPS_RLD_VERSION:
9350 case DT_MIPS_LOCAL_GOTNO:
9351 case DT_MIPS_CONFLICTNO:
9352 case DT_MIPS_LIBLISTNO:
9353 case DT_MIPS_SYMTABNO:
9354 case DT_MIPS_UNREFEXTNO:
9355 case DT_MIPS_HIPAGENO:
9356 case DT_MIPS_DELTA_CLASS_NO:
9357 case DT_MIPS_DELTA_INSTANCE_NO:
9358 case DT_MIPS_DELTA_RELOC_NO:
9359 case DT_MIPS_DELTA_SYM_NO:
9360 case DT_MIPS_DELTA_CLASSSYM_NO:
9361 case DT_MIPS_COMPACT_SIZE:
c69075ac 9362 print_vma (entry->d_un.d_val, DEC);
252b5132 9363 break;
103f02d3
UD
9364
9365 default:
4b68bca3 9366 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9367 }
4b68bca3 9368 putchar ('\n');
103f02d3
UD
9369}
9370
103f02d3 9371static void
2cf0635d 9372dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9373{
9374 switch (entry->d_tag)
9375 {
9376 case DT_HP_DLD_FLAGS:
9377 {
9378 static struct
9379 {
9380 long int bit;
2cf0635d 9381 const char * str;
5e220199
NC
9382 }
9383 flags[] =
9384 {
9385 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9386 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9387 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9388 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9389 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9390 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9391 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9392 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9393 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9394 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9395 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9396 { DT_HP_GST, "HP_GST" },
9397 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9398 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9399 { DT_HP_NODELETE, "HP_NODELETE" },
9400 { DT_HP_GROUP, "HP_GROUP" },
9401 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9402 };
32ec8896 9403 bfd_boolean first = TRUE;
5e220199 9404 size_t cnt;
f7a99963 9405 bfd_vma val = entry->d_un.d_val;
103f02d3 9406
60bca95a 9407 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9408 if (val & flags[cnt].bit)
30800947
NC
9409 {
9410 if (! first)
9411 putchar (' ');
9412 fputs (flags[cnt].str, stdout);
32ec8896 9413 first = FALSE;
30800947
NC
9414 val ^= flags[cnt].bit;
9415 }
76da6bbe 9416
103f02d3 9417 if (val != 0 || first)
f7a99963
NC
9418 {
9419 if (! first)
9420 putchar (' ');
9421 print_vma (val, HEX);
9422 }
103f02d3
UD
9423 }
9424 break;
76da6bbe 9425
252b5132 9426 default:
f7a99963
NC
9427 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9428 break;
252b5132 9429 }
35b1837e 9430 putchar ('\n');
252b5132
RH
9431}
9432
28f997cf
TG
9433#ifdef BFD64
9434
9435/* VMS vs Unix time offset and factor. */
9436
9437#define VMS_EPOCH_OFFSET 35067168000000000LL
9438#define VMS_GRANULARITY_FACTOR 10000000
9439
9440/* Display a VMS time in a human readable format. */
9441
9442static void
9443print_vms_time (bfd_int64_t vmstime)
9444{
9445 struct tm *tm;
9446 time_t unxtime;
9447
9448 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9449 tm = gmtime (&unxtime);
9450 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9451 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9452 tm->tm_hour, tm->tm_min, tm->tm_sec);
9453}
9454#endif /* BFD64 */
9455
ecc51f48 9456static void
2cf0635d 9457dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9458{
9459 switch (entry->d_tag)
9460 {
0de14b54 9461 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9462 /* First 3 slots reserved. */
ecc51f48
NC
9463 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9464 printf (" -- ");
9465 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9466 break;
9467
28f997cf
TG
9468 case DT_IA_64_VMS_LINKTIME:
9469#ifdef BFD64
9470 print_vms_time (entry->d_un.d_val);
9471#endif
9472 break;
9473
9474 case DT_IA_64_VMS_LNKFLAGS:
9475 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9476 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9477 printf (" CALL_DEBUG");
9478 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9479 printf (" NOP0BUFS");
9480 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9481 printf (" P0IMAGE");
9482 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9483 printf (" MKTHREADS");
9484 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9485 printf (" UPCALLS");
9486 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9487 printf (" IMGSTA");
9488 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9489 printf (" INITIALIZE");
9490 if (entry->d_un.d_val & VMS_LF_MAIN)
9491 printf (" MAIN");
9492 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9493 printf (" EXE_INIT");
9494 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9495 printf (" TBK_IN_IMG");
9496 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9497 printf (" DBG_IN_IMG");
9498 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9499 printf (" TBK_IN_DSF");
9500 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9501 printf (" DBG_IN_DSF");
9502 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9503 printf (" SIGNATURES");
9504 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9505 printf (" REL_SEG_OFF");
9506 break;
9507
bdf4d63a
JJ
9508 default:
9509 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9510 break;
ecc51f48 9511 }
bdf4d63a 9512 putchar ('\n');
ecc51f48
NC
9513}
9514
32ec8896 9515static bfd_boolean
dda8d76d 9516get_32bit_dynamic_section (Filedata * filedata)
252b5132 9517{
2cf0635d
NC
9518 Elf32_External_Dyn * edyn;
9519 Elf32_External_Dyn * ext;
9520 Elf_Internal_Dyn * entry;
103f02d3 9521
dda8d76d 9522 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9523 dynamic_size, _("dynamic section"));
a6e9f9df 9524 if (!edyn)
32ec8896 9525 return FALSE;
103f02d3 9526
071436c6
NC
9527 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9528 might not have the luxury of section headers. Look for the DT_NULL
9529 terminator to determine the number of entries. */
ba2685cc 9530 for (ext = edyn, dynamic_nent = 0;
53c3012c 9531 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9532 ext++)
9533 {
9534 dynamic_nent++;
9535 if (BYTE_GET (ext->d_tag) == DT_NULL)
9536 break;
9537 }
252b5132 9538
3f5e193b
NC
9539 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9540 sizeof (* entry));
b2d38a17 9541 if (dynamic_section == NULL)
252b5132 9542 {
8b73c356
NC
9543 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9544 (unsigned long) dynamic_nent);
9ea033b2 9545 free (edyn);
32ec8896 9546 return FALSE;
9ea033b2 9547 }
252b5132 9548
fb514b26 9549 for (ext = edyn, entry = dynamic_section;
ba2685cc 9550 entry < dynamic_section + dynamic_nent;
fb514b26 9551 ext++, entry++)
9ea033b2 9552 {
fb514b26
AM
9553 entry->d_tag = BYTE_GET (ext->d_tag);
9554 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9555 }
9556
9ea033b2
NC
9557 free (edyn);
9558
32ec8896 9559 return TRUE;
9ea033b2
NC
9560}
9561
32ec8896 9562static bfd_boolean
dda8d76d 9563get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9564{
2cf0635d
NC
9565 Elf64_External_Dyn * edyn;
9566 Elf64_External_Dyn * ext;
9567 Elf_Internal_Dyn * entry;
103f02d3 9568
071436c6 9569 /* Read in the data. */
dda8d76d 9570 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9571 dynamic_size, _("dynamic section"));
a6e9f9df 9572 if (!edyn)
32ec8896 9573 return FALSE;
103f02d3 9574
071436c6
NC
9575 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9576 might not have the luxury of section headers. Look for the DT_NULL
9577 terminator to determine the number of entries. */
ba2685cc 9578 for (ext = edyn, dynamic_nent = 0;
53c3012c
AM
9579 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
9580 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9581 ext++)
9582 {
9583 dynamic_nent++;
66543521 9584 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9585 break;
9586 }
252b5132 9587
3f5e193b
NC
9588 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9589 sizeof (* entry));
b2d38a17 9590 if (dynamic_section == NULL)
252b5132 9591 {
8b73c356
NC
9592 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9593 (unsigned long) dynamic_nent);
252b5132 9594 free (edyn);
32ec8896 9595 return FALSE;
252b5132
RH
9596 }
9597
071436c6 9598 /* Convert from external to internal formats. */
fb514b26 9599 for (ext = edyn, entry = dynamic_section;
ba2685cc 9600 entry < dynamic_section + dynamic_nent;
fb514b26 9601 ext++, entry++)
252b5132 9602 {
66543521
AM
9603 entry->d_tag = BYTE_GET (ext->d_tag);
9604 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9605 }
9606
9607 free (edyn);
9608
32ec8896 9609 return TRUE;
9ea033b2
NC
9610}
9611
e9e44622
JJ
9612static void
9613print_dynamic_flags (bfd_vma flags)
d1133906 9614{
32ec8896 9615 bfd_boolean first = TRUE;
13ae64f3 9616
d1133906
NC
9617 while (flags)
9618 {
9619 bfd_vma flag;
9620
9621 flag = flags & - flags;
9622 flags &= ~ flag;
9623
e9e44622 9624 if (first)
32ec8896 9625 first = FALSE;
e9e44622
JJ
9626 else
9627 putc (' ', stdout);
13ae64f3 9628
d1133906
NC
9629 switch (flag)
9630 {
e9e44622
JJ
9631 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9632 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9633 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9634 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9635 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9636 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9637 }
9638 }
e9e44622 9639 puts ("");
d1133906
NC
9640}
9641
b2d38a17
NC
9642/* Parse and display the contents of the dynamic section. */
9643
32ec8896 9644static bfd_boolean
dda8d76d 9645process_dynamic_section (Filedata * filedata)
9ea033b2 9646{
2cf0635d 9647 Elf_Internal_Dyn * entry;
9ea033b2
NC
9648
9649 if (dynamic_size == 0)
9650 {
9651 if (do_dynamic)
b2d38a17 9652 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 9653
32ec8896 9654 return TRUE;
9ea033b2
NC
9655 }
9656
9657 if (is_32bit_elf)
9658 {
dda8d76d 9659 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
9660 return FALSE;
9661 }
9662 else
9663 {
dda8d76d 9664 if (! get_64bit_dynamic_section (filedata))
32ec8896 9665 return FALSE;
9ea033b2 9666 }
9ea033b2 9667
252b5132
RH
9668 /* Find the appropriate symbol table. */
9669 if (dynamic_symbols == NULL)
9670 {
86dba8ee
AM
9671 for (entry = dynamic_section;
9672 entry < dynamic_section + dynamic_nent;
9673 ++entry)
252b5132 9674 {
c8286bd1 9675 Elf_Internal_Shdr section;
252b5132
RH
9676
9677 if (entry->d_tag != DT_SYMTAB)
9678 continue;
9679
9680 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
9681
9682 /* Since we do not know how big the symbol table is,
9683 we default to reading in the entire file (!) and
9684 processing that. This is overkill, I know, but it
e3c8793a 9685 should work. */
dda8d76d
NC
9686 section.sh_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
9687 if ((bfd_size_type) section.sh_offset > filedata->file_size)
7296a62a
NC
9688 {
9689 /* See PR 21379 for a reproducer. */
9690 error (_("Invalid DT_SYMTAB entry: %lx"), (long) section.sh_offset);
9691 return FALSE;
9692 }
252b5132 9693
fb52b2f4
NC
9694 if (archive_file_offset != 0)
9695 section.sh_size = archive_file_size - section.sh_offset;
9696 else
dda8d76d 9697 section.sh_size = filedata->file_size - section.sh_offset;
252b5132 9698
9ea033b2 9699 if (is_32bit_elf)
9ad5cbcf 9700 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 9701 else
9ad5cbcf 9702 section.sh_entsize = sizeof (Elf64_External_Sym);
dda8d76d 9703 section.sh_name = filedata->string_table_length;
252b5132 9704
e3d39609
NC
9705 if (dynamic_symbols != NULL)
9706 {
9707 error (_("Multiple dynamic symbol table sections found\n"));
9708 free (dynamic_symbols);
9709 }
dda8d76d 9710 dynamic_symbols = GET_ELF_SYMBOLS (filedata, &section, & num_dynamic_syms);
19936277 9711 if (num_dynamic_syms < 1)
252b5132
RH
9712 {
9713 error (_("Unable to determine the number of symbols to load\n"));
9714 continue;
9715 }
252b5132
RH
9716 }
9717 }
9718
9719 /* Similarly find a string table. */
9720 if (dynamic_strings == NULL)
9721 {
86dba8ee
AM
9722 for (entry = dynamic_section;
9723 entry < dynamic_section + dynamic_nent;
9724 ++entry)
252b5132
RH
9725 {
9726 unsigned long offset;
b34976b6 9727 long str_tab_len;
252b5132
RH
9728
9729 if (entry->d_tag != DT_STRTAB)
9730 continue;
9731
9732 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
9733
9734 /* Since we do not know how big the string table is,
9735 we default to reading in the entire file (!) and
9736 processing that. This is overkill, I know, but it
e3c8793a 9737 should work. */
252b5132 9738
dda8d76d 9739 offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
fb52b2f4
NC
9740
9741 if (archive_file_offset != 0)
9742 str_tab_len = archive_file_size - offset;
9743 else
86c6c6df 9744 str_tab_len = filedata->file_size - offset;
252b5132
RH
9745
9746 if (str_tab_len < 1)
9747 {
9748 error
9749 (_("Unable to determine the length of the dynamic string table\n"));
9750 continue;
9751 }
9752
e3d39609
NC
9753 if (dynamic_strings != NULL)
9754 {
9755 error (_("Multiple dynamic string tables found\n"));
9756 free (dynamic_strings);
9757 }
9758
dda8d76d 9759 dynamic_strings = (char *) get_data (NULL, filedata, offset, 1,
3f5e193b
NC
9760 str_tab_len,
9761 _("dynamic string table"));
59245841 9762 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
9763 }
9764 }
9765
9766 /* And find the syminfo section if available. */
9767 if (dynamic_syminfo == NULL)
9768 {
3e8bba36 9769 unsigned long syminsz = 0;
252b5132 9770
86dba8ee
AM
9771 for (entry = dynamic_section;
9772 entry < dynamic_section + dynamic_nent;
9773 ++entry)
252b5132
RH
9774 {
9775 if (entry->d_tag == DT_SYMINENT)
9776 {
9777 /* Note: these braces are necessary to avoid a syntax
9778 error from the SunOS4 C compiler. */
049b0c3a
NC
9779 /* PR binutils/17531: A corrupt file can trigger this test.
9780 So do not use an assert, instead generate an error message. */
9781 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 9782 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 9783 (int) entry->d_un.d_val);
252b5132
RH
9784 }
9785 else if (entry->d_tag == DT_SYMINSZ)
9786 syminsz = entry->d_un.d_val;
9787 else if (entry->d_tag == DT_SYMINFO)
dda8d76d 9788 dynamic_syminfo_offset = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 9789 syminsz);
252b5132
RH
9790 }
9791
9792 if (dynamic_syminfo_offset != 0 && syminsz != 0)
9793 {
2cf0635d
NC
9794 Elf_External_Syminfo * extsyminfo;
9795 Elf_External_Syminfo * extsym;
9796 Elf_Internal_Syminfo * syminfo;
252b5132
RH
9797
9798 /* There is a syminfo section. Read the data. */
3f5e193b 9799 extsyminfo = (Elf_External_Syminfo *)
dda8d76d 9800 get_data (NULL, filedata, dynamic_syminfo_offset, 1, syminsz,
3f5e193b 9801 _("symbol information"));
a6e9f9df 9802 if (!extsyminfo)
32ec8896 9803 return FALSE;
252b5132 9804
e3d39609
NC
9805 if (dynamic_syminfo != NULL)
9806 {
9807 error (_("Multiple dynamic symbol information sections found\n"));
9808 free (dynamic_syminfo);
9809 }
3f5e193b 9810 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
9811 if (dynamic_syminfo == NULL)
9812 {
8b73c356
NC
9813 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
9814 (unsigned long) syminsz);
32ec8896 9815 return FALSE;
252b5132
RH
9816 }
9817
9818 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
9819 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
9820 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
9821 ++syminfo, ++extsym)
252b5132 9822 {
86dba8ee
AM
9823 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
9824 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
9825 }
9826
9827 free (extsyminfo);
9828 }
9829 }
9830
9831 if (do_dynamic && dynamic_addr)
d3a49aa8
AM
9832 printf (ngettext ("\nDynamic section at offset 0x%lx "
9833 "contains %lu entry:\n",
9834 "\nDynamic section at offset 0x%lx "
9835 "contains %lu entries:\n",
9836 dynamic_nent),
8b73c356 9837 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
9838 if (do_dynamic)
9839 printf (_(" Tag Type Name/Value\n"));
9840
86dba8ee
AM
9841 for (entry = dynamic_section;
9842 entry < dynamic_section + dynamic_nent;
9843 entry++)
252b5132
RH
9844 {
9845 if (do_dynamic)
f7a99963 9846 {
2cf0635d 9847 const char * dtype;
e699b9ff 9848
f7a99963
NC
9849 putchar (' ');
9850 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 9851 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 9852 printf (" (%s)%*s", dtype,
32ec8896 9853 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 9854 }
252b5132
RH
9855
9856 switch (entry->d_tag)
9857 {
d1133906
NC
9858 case DT_FLAGS:
9859 if (do_dynamic)
e9e44622 9860 print_dynamic_flags (entry->d_un.d_val);
d1133906 9861 break;
76da6bbe 9862
252b5132
RH
9863 case DT_AUXILIARY:
9864 case DT_FILTER:
019148e4
L
9865 case DT_CONFIG:
9866 case DT_DEPAUDIT:
9867 case DT_AUDIT:
252b5132
RH
9868 if (do_dynamic)
9869 {
019148e4 9870 switch (entry->d_tag)
b34976b6 9871 {
019148e4
L
9872 case DT_AUXILIARY:
9873 printf (_("Auxiliary library"));
9874 break;
9875
9876 case DT_FILTER:
9877 printf (_("Filter library"));
9878 break;
9879
b34976b6 9880 case DT_CONFIG:
019148e4
L
9881 printf (_("Configuration file"));
9882 break;
9883
9884 case DT_DEPAUDIT:
9885 printf (_("Dependency audit library"));
9886 break;
9887
9888 case DT_AUDIT:
9889 printf (_("Audit library"));
9890 break;
9891 }
252b5132 9892
d79b3d50
NC
9893 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9894 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9895 else
f7a99963
NC
9896 {
9897 printf (": ");
9898 print_vma (entry->d_un.d_val, PREFIX_HEX);
9899 putchar ('\n');
9900 }
252b5132
RH
9901 }
9902 break;
9903
dcefbbbd 9904 case DT_FEATURE:
252b5132
RH
9905 if (do_dynamic)
9906 {
9907 printf (_("Flags:"));
86f55779 9908
252b5132
RH
9909 if (entry->d_un.d_val == 0)
9910 printf (_(" None\n"));
9911 else
9912 {
9913 unsigned long int val = entry->d_un.d_val;
86f55779 9914
252b5132
RH
9915 if (val & DTF_1_PARINIT)
9916 {
9917 printf (" PARINIT");
9918 val ^= DTF_1_PARINIT;
9919 }
dcefbbbd
L
9920 if (val & DTF_1_CONFEXP)
9921 {
9922 printf (" CONFEXP");
9923 val ^= DTF_1_CONFEXP;
9924 }
252b5132
RH
9925 if (val != 0)
9926 printf (" %lx", val);
9927 puts ("");
9928 }
9929 }
9930 break;
9931
9932 case DT_POSFLAG_1:
9933 if (do_dynamic)
9934 {
9935 printf (_("Flags:"));
86f55779 9936
252b5132
RH
9937 if (entry->d_un.d_val == 0)
9938 printf (_(" None\n"));
9939 else
9940 {
9941 unsigned long int val = entry->d_un.d_val;
86f55779 9942
252b5132
RH
9943 if (val & DF_P1_LAZYLOAD)
9944 {
9945 printf (" LAZYLOAD");
9946 val ^= DF_P1_LAZYLOAD;
9947 }
9948 if (val & DF_P1_GROUPPERM)
9949 {
9950 printf (" GROUPPERM");
9951 val ^= DF_P1_GROUPPERM;
9952 }
9953 if (val != 0)
9954 printf (" %lx", val);
9955 puts ("");
9956 }
9957 }
9958 break;
9959
9960 case DT_FLAGS_1:
9961 if (do_dynamic)
9962 {
9963 printf (_("Flags:"));
9964 if (entry->d_un.d_val == 0)
9965 printf (_(" None\n"));
9966 else
9967 {
9968 unsigned long int val = entry->d_un.d_val;
86f55779 9969
252b5132
RH
9970 if (val & DF_1_NOW)
9971 {
9972 printf (" NOW");
9973 val ^= DF_1_NOW;
9974 }
9975 if (val & DF_1_GLOBAL)
9976 {
9977 printf (" GLOBAL");
9978 val ^= DF_1_GLOBAL;
9979 }
9980 if (val & DF_1_GROUP)
9981 {
9982 printf (" GROUP");
9983 val ^= DF_1_GROUP;
9984 }
9985 if (val & DF_1_NODELETE)
9986 {
9987 printf (" NODELETE");
9988 val ^= DF_1_NODELETE;
9989 }
9990 if (val & DF_1_LOADFLTR)
9991 {
9992 printf (" LOADFLTR");
9993 val ^= DF_1_LOADFLTR;
9994 }
9995 if (val & DF_1_INITFIRST)
9996 {
9997 printf (" INITFIRST");
9998 val ^= DF_1_INITFIRST;
9999 }
10000 if (val & DF_1_NOOPEN)
10001 {
10002 printf (" NOOPEN");
10003 val ^= DF_1_NOOPEN;
10004 }
10005 if (val & DF_1_ORIGIN)
10006 {
10007 printf (" ORIGIN");
10008 val ^= DF_1_ORIGIN;
10009 }
10010 if (val & DF_1_DIRECT)
10011 {
10012 printf (" DIRECT");
10013 val ^= DF_1_DIRECT;
10014 }
10015 if (val & DF_1_TRANS)
10016 {
10017 printf (" TRANS");
10018 val ^= DF_1_TRANS;
10019 }
10020 if (val & DF_1_INTERPOSE)
10021 {
10022 printf (" INTERPOSE");
10023 val ^= DF_1_INTERPOSE;
10024 }
f7db6139 10025 if (val & DF_1_NODEFLIB)
dcefbbbd 10026 {
f7db6139
L
10027 printf (" NODEFLIB");
10028 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10029 }
10030 if (val & DF_1_NODUMP)
10031 {
10032 printf (" NODUMP");
10033 val ^= DF_1_NODUMP;
10034 }
34b60028 10035 if (val & DF_1_CONFALT)
dcefbbbd 10036 {
34b60028
L
10037 printf (" CONFALT");
10038 val ^= DF_1_CONFALT;
10039 }
10040 if (val & DF_1_ENDFILTEE)
10041 {
10042 printf (" ENDFILTEE");
10043 val ^= DF_1_ENDFILTEE;
10044 }
10045 if (val & DF_1_DISPRELDNE)
10046 {
10047 printf (" DISPRELDNE");
10048 val ^= DF_1_DISPRELDNE;
10049 }
10050 if (val & DF_1_DISPRELPND)
10051 {
10052 printf (" DISPRELPND");
10053 val ^= DF_1_DISPRELPND;
10054 }
10055 if (val & DF_1_NODIRECT)
10056 {
10057 printf (" NODIRECT");
10058 val ^= DF_1_NODIRECT;
10059 }
10060 if (val & DF_1_IGNMULDEF)
10061 {
10062 printf (" IGNMULDEF");
10063 val ^= DF_1_IGNMULDEF;
10064 }
10065 if (val & DF_1_NOKSYMS)
10066 {
10067 printf (" NOKSYMS");
10068 val ^= DF_1_NOKSYMS;
10069 }
10070 if (val & DF_1_NOHDR)
10071 {
10072 printf (" NOHDR");
10073 val ^= DF_1_NOHDR;
10074 }
10075 if (val & DF_1_EDITED)
10076 {
10077 printf (" EDITED");
10078 val ^= DF_1_EDITED;
10079 }
10080 if (val & DF_1_NORELOC)
10081 {
10082 printf (" NORELOC");
10083 val ^= DF_1_NORELOC;
10084 }
10085 if (val & DF_1_SYMINTPOSE)
10086 {
10087 printf (" SYMINTPOSE");
10088 val ^= DF_1_SYMINTPOSE;
10089 }
10090 if (val & DF_1_GLOBAUDIT)
10091 {
10092 printf (" GLOBAUDIT");
10093 val ^= DF_1_GLOBAUDIT;
10094 }
10095 if (val & DF_1_SINGLETON)
10096 {
10097 printf (" SINGLETON");
10098 val ^= DF_1_SINGLETON;
dcefbbbd 10099 }
5c383f02
RO
10100 if (val & DF_1_STUB)
10101 {
10102 printf (" STUB");
10103 val ^= DF_1_STUB;
10104 }
10105 if (val & DF_1_PIE)
10106 {
10107 printf (" PIE");
10108 val ^= DF_1_PIE;
10109 }
b1202ffa
L
10110 if (val & DF_1_KMOD)
10111 {
10112 printf (" KMOD");
10113 val ^= DF_1_KMOD;
10114 }
10115 if (val & DF_1_WEAKFILTER)
10116 {
10117 printf (" WEAKFILTER");
10118 val ^= DF_1_WEAKFILTER;
10119 }
10120 if (val & DF_1_NOCOMMON)
10121 {
10122 printf (" NOCOMMON");
10123 val ^= DF_1_NOCOMMON;
10124 }
252b5132
RH
10125 if (val != 0)
10126 printf (" %lx", val);
10127 puts ("");
10128 }
10129 }
10130 break;
10131
10132 case DT_PLTREL:
566b0d53 10133 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10134 if (do_dynamic)
dda8d76d 10135 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10136 break;
10137
10138 case DT_NULL :
10139 case DT_NEEDED :
10140 case DT_PLTGOT :
10141 case DT_HASH :
10142 case DT_STRTAB :
10143 case DT_SYMTAB :
10144 case DT_RELA :
10145 case DT_INIT :
10146 case DT_FINI :
10147 case DT_SONAME :
10148 case DT_RPATH :
10149 case DT_SYMBOLIC:
10150 case DT_REL :
10151 case DT_DEBUG :
10152 case DT_TEXTREL :
10153 case DT_JMPREL :
019148e4 10154 case DT_RUNPATH :
252b5132
RH
10155 dynamic_info[entry->d_tag] = entry->d_un.d_val;
10156
10157 if (do_dynamic)
10158 {
2cf0635d 10159 char * name;
252b5132 10160
d79b3d50
NC
10161 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
10162 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10163 else
d79b3d50 10164 name = NULL;
252b5132
RH
10165
10166 if (name)
10167 {
10168 switch (entry->d_tag)
10169 {
10170 case DT_NEEDED:
10171 printf (_("Shared library: [%s]"), name);
10172
18bd398b 10173 if (streq (name, program_interpreter))
f7a99963 10174 printf (_(" program interpreter"));
252b5132
RH
10175 break;
10176
10177 case DT_SONAME:
f7a99963 10178 printf (_("Library soname: [%s]"), name);
252b5132
RH
10179 break;
10180
10181 case DT_RPATH:
f7a99963 10182 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10183 break;
10184
019148e4
L
10185 case DT_RUNPATH:
10186 printf (_("Library runpath: [%s]"), name);
10187 break;
10188
252b5132 10189 default:
f7a99963
NC
10190 print_vma (entry->d_un.d_val, PREFIX_HEX);
10191 break;
252b5132
RH
10192 }
10193 }
10194 else
f7a99963
NC
10195 print_vma (entry->d_un.d_val, PREFIX_HEX);
10196
10197 putchar ('\n');
252b5132
RH
10198 }
10199 break;
10200
10201 case DT_PLTRELSZ:
10202 case DT_RELASZ :
10203 case DT_STRSZ :
10204 case DT_RELSZ :
10205 case DT_RELAENT :
10206 case DT_SYMENT :
10207 case DT_RELENT :
566b0d53 10208 dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10209 /* Fall through. */
252b5132
RH
10210 case DT_PLTPADSZ:
10211 case DT_MOVEENT :
10212 case DT_MOVESZ :
10213 case DT_INIT_ARRAYSZ:
10214 case DT_FINI_ARRAYSZ:
047b2264
JJ
10215 case DT_GNU_CONFLICTSZ:
10216 case DT_GNU_LIBLISTSZ:
252b5132 10217 if (do_dynamic)
f7a99963
NC
10218 {
10219 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10220 printf (_(" (bytes)\n"));
f7a99963 10221 }
252b5132
RH
10222 break;
10223
10224 case DT_VERDEFNUM:
10225 case DT_VERNEEDNUM:
10226 case DT_RELACOUNT:
10227 case DT_RELCOUNT:
10228 if (do_dynamic)
f7a99963
NC
10229 {
10230 print_vma (entry->d_un.d_val, UNSIGNED);
10231 putchar ('\n');
10232 }
252b5132
RH
10233 break;
10234
10235 case DT_SYMINSZ:
10236 case DT_SYMINENT:
10237 case DT_SYMINFO:
10238 case DT_USED:
10239 case DT_INIT_ARRAY:
10240 case DT_FINI_ARRAY:
10241 if (do_dynamic)
10242 {
d79b3d50
NC
10243 if (entry->d_tag == DT_USED
10244 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 10245 {
2cf0635d 10246 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10247
b34976b6 10248 if (*name)
252b5132
RH
10249 {
10250 printf (_("Not needed object: [%s]\n"), name);
10251 break;
10252 }
10253 }
103f02d3 10254
f7a99963
NC
10255 print_vma (entry->d_un.d_val, PREFIX_HEX);
10256 putchar ('\n');
252b5132
RH
10257 }
10258 break;
10259
10260 case DT_BIND_NOW:
10261 /* The value of this entry is ignored. */
35b1837e
AM
10262 if (do_dynamic)
10263 putchar ('\n');
252b5132 10264 break;
103f02d3 10265
047b2264
JJ
10266 case DT_GNU_PRELINKED:
10267 if (do_dynamic)
10268 {
2cf0635d 10269 struct tm * tmp;
91d6fa6a 10270 time_t atime = entry->d_un.d_val;
047b2264 10271
91d6fa6a 10272 tmp = gmtime (&atime);
071436c6
NC
10273 /* PR 17533 file: 041-1244816-0.004. */
10274 if (tmp == NULL)
5a2cbcf4
L
10275 printf (_("<corrupt time val: %lx"),
10276 (unsigned long) atime);
071436c6
NC
10277 else
10278 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10279 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10280 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10281
10282 }
10283 break;
10284
fdc90cb4
JJ
10285 case DT_GNU_HASH:
10286 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10287 if (do_dynamic)
10288 {
10289 print_vma (entry->d_un.d_val, PREFIX_HEX);
10290 putchar ('\n');
10291 }
10292 break;
10293
252b5132
RH
10294 default:
10295 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 10296 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
10297 entry->d_un.d_val;
10298
10299 if (do_dynamic)
10300 {
dda8d76d 10301 switch (filedata->file_header.e_machine)
252b5132
RH
10302 {
10303 case EM_MIPS:
4fe85591 10304 case EM_MIPS_RS3_LE:
b2d38a17 10305 dynamic_section_mips_val (entry);
252b5132 10306 break;
103f02d3 10307 case EM_PARISC:
b2d38a17 10308 dynamic_section_parisc_val (entry);
103f02d3 10309 break;
ecc51f48 10310 case EM_IA_64:
b2d38a17 10311 dynamic_section_ia64_val (entry);
ecc51f48 10312 break;
252b5132 10313 default:
f7a99963
NC
10314 print_vma (entry->d_un.d_val, PREFIX_HEX);
10315 putchar ('\n');
252b5132
RH
10316 }
10317 }
10318 break;
10319 }
10320 }
10321
32ec8896 10322 return TRUE;
252b5132
RH
10323}
10324
10325static char *
d3ba0551 10326get_ver_flags (unsigned int flags)
252b5132 10327{
6d4f21f6 10328 static char buff[128];
252b5132
RH
10329
10330 buff[0] = 0;
10331
10332 if (flags == 0)
10333 return _("none");
10334
10335 if (flags & VER_FLG_BASE)
7bb1ad17 10336 strcat (buff, "BASE");
252b5132
RH
10337
10338 if (flags & VER_FLG_WEAK)
10339 {
10340 if (flags & VER_FLG_BASE)
7bb1ad17 10341 strcat (buff, " | ");
252b5132 10342
7bb1ad17 10343 strcat (buff, "WEAK");
252b5132
RH
10344 }
10345
44ec90b9
RO
10346 if (flags & VER_FLG_INFO)
10347 {
10348 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 10349 strcat (buff, " | ");
44ec90b9 10350
7bb1ad17 10351 strcat (buff, "INFO");
44ec90b9
RO
10352 }
10353
10354 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
10355 {
10356 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
10357 strcat (buff, " | ");
10358
10359 strcat (buff, _("<unknown>"));
10360 }
252b5132
RH
10361
10362 return buff;
10363}
10364
10365/* Display the contents of the version sections. */
98fb390a 10366
32ec8896 10367static bfd_boolean
dda8d76d 10368process_version_sections (Filedata * filedata)
252b5132 10369{
2cf0635d 10370 Elf_Internal_Shdr * section;
b34976b6 10371 unsigned i;
32ec8896 10372 bfd_boolean found = FALSE;
252b5132
RH
10373
10374 if (! do_version)
32ec8896 10375 return TRUE;
252b5132 10376
dda8d76d
NC
10377 for (i = 0, section = filedata->section_headers;
10378 i < filedata->file_header.e_shnum;
b34976b6 10379 i++, section++)
252b5132
RH
10380 {
10381 switch (section->sh_type)
10382 {
10383 case SHT_GNU_verdef:
10384 {
2cf0635d 10385 Elf_External_Verdef * edefs;
452bf675
AM
10386 unsigned long idx;
10387 unsigned long cnt;
2cf0635d 10388 char * endbuf;
252b5132 10389
32ec8896 10390 found = TRUE;
252b5132 10391
d3a49aa8
AM
10392 printf (ngettext ("\nVersion definition section '%s' "
10393 "contains %u entry:\n",
10394 "\nVersion definition section '%s' "
10395 "contains %u entries:\n",
10396 section->sh_info),
dda8d76d 10397 printable_section_name (filedata, section),
74e1a04b 10398 section->sh_info);
252b5132
RH
10399
10400 printf (_(" Addr: 0x"));
10401 printf_vma (section->sh_addr);
233f82cf 10402 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10403 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10404 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10405
3f5e193b 10406 edefs = (Elf_External_Verdef *)
dda8d76d 10407 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 10408 _("version definition section"));
a6e9f9df
AM
10409 if (!edefs)
10410 break;
59245841 10411 endbuf = (char *) edefs + section->sh_size;
252b5132 10412
1445030f 10413 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 10414 {
2cf0635d
NC
10415 char * vstart;
10416 Elf_External_Verdef * edef;
b34976b6 10417 Elf_Internal_Verdef ent;
2cf0635d 10418 Elf_External_Verdaux * eaux;
b34976b6 10419 Elf_Internal_Verdaux aux;
452bf675 10420 unsigned long isum;
b34976b6 10421 int j;
103f02d3 10422
252b5132 10423 vstart = ((char *) edefs) + idx;
54806181
AM
10424 if (vstart + sizeof (*edef) > endbuf)
10425 break;
252b5132
RH
10426
10427 edef = (Elf_External_Verdef *) vstart;
10428
10429 ent.vd_version = BYTE_GET (edef->vd_version);
10430 ent.vd_flags = BYTE_GET (edef->vd_flags);
10431 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
10432 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
10433 ent.vd_hash = BYTE_GET (edef->vd_hash);
10434 ent.vd_aux = BYTE_GET (edef->vd_aux);
10435 ent.vd_next = BYTE_GET (edef->vd_next);
10436
452bf675 10437 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
10438 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
10439
10440 printf (_(" Index: %d Cnt: %d "),
10441 ent.vd_ndx, ent.vd_cnt);
10442
452bf675 10443 /* Check for overflow. */
1445030f 10444 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
10445 break;
10446
252b5132
RH
10447 vstart += ent.vd_aux;
10448
1445030f
AM
10449 if (vstart + sizeof (*eaux) > endbuf)
10450 break;
252b5132
RH
10451 eaux = (Elf_External_Verdaux *) vstart;
10452
10453 aux.vda_name = BYTE_GET (eaux->vda_name);
10454 aux.vda_next = BYTE_GET (eaux->vda_next);
10455
d79b3d50
NC
10456 if (VALID_DYNAMIC_NAME (aux.vda_name))
10457 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
10458 else
10459 printf (_("Name index: %ld\n"), aux.vda_name);
10460
10461 isum = idx + ent.vd_aux;
10462
b34976b6 10463 for (j = 1; j < ent.vd_cnt; j++)
252b5132 10464 {
1445030f
AM
10465 if (aux.vda_next < sizeof (*eaux)
10466 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
10467 {
10468 warn (_("Invalid vda_next field of %lx\n"),
10469 aux.vda_next);
10470 j = ent.vd_cnt;
10471 break;
10472 }
dd24e3da 10473 /* Check for overflow. */
7e26601c 10474 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
10475 break;
10476
252b5132
RH
10477 isum += aux.vda_next;
10478 vstart += aux.vda_next;
10479
54806181
AM
10480 if (vstart + sizeof (*eaux) > endbuf)
10481 break;
1445030f 10482 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
10483
10484 aux.vda_name = BYTE_GET (eaux->vda_name);
10485 aux.vda_next = BYTE_GET (eaux->vda_next);
10486
d79b3d50 10487 if (VALID_DYNAMIC_NAME (aux.vda_name))
452bf675 10488 printf (_(" %#06lx: Parent %d: %s\n"),
d79b3d50 10489 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132 10490 else
452bf675 10491 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
10492 isum, j, aux.vda_name);
10493 }
dd24e3da 10494
54806181
AM
10495 if (j < ent.vd_cnt)
10496 printf (_(" Version def aux past end of section\n"));
252b5132 10497
c9f02c3e
MR
10498 /* PR 17531:
10499 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
10500 if (ent.vd_next < sizeof (*edef)
10501 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
10502 {
10503 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
10504 cnt = section->sh_info;
10505 break;
10506 }
452bf675 10507 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
10508 break;
10509
252b5132
RH
10510 idx += ent.vd_next;
10511 }
dd24e3da 10512
54806181
AM
10513 if (cnt < section->sh_info)
10514 printf (_(" Version definition past end of section\n"));
252b5132
RH
10515
10516 free (edefs);
10517 }
10518 break;
103f02d3 10519
252b5132
RH
10520 case SHT_GNU_verneed:
10521 {
2cf0635d 10522 Elf_External_Verneed * eneed;
452bf675
AM
10523 unsigned long idx;
10524 unsigned long cnt;
2cf0635d 10525 char * endbuf;
252b5132 10526
32ec8896 10527 found = TRUE;
252b5132 10528
d3a49aa8
AM
10529 printf (ngettext ("\nVersion needs section '%s' "
10530 "contains %u entry:\n",
10531 "\nVersion needs section '%s' "
10532 "contains %u entries:\n",
10533 section->sh_info),
dda8d76d 10534 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
10535
10536 printf (_(" Addr: 0x"));
10537 printf_vma (section->sh_addr);
72de5009 10538 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10539 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10540 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10541
dda8d76d 10542 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
10543 section->sh_offset, 1,
10544 section->sh_size,
9cf03b7e 10545 _("Version Needs section"));
a6e9f9df
AM
10546 if (!eneed)
10547 break;
59245841 10548 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
10549
10550 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
10551 {
2cf0635d 10552 Elf_External_Verneed * entry;
b34976b6 10553 Elf_Internal_Verneed ent;
452bf675 10554 unsigned long isum;
b34976b6 10555 int j;
2cf0635d 10556 char * vstart;
252b5132
RH
10557
10558 vstart = ((char *) eneed) + idx;
54806181
AM
10559 if (vstart + sizeof (*entry) > endbuf)
10560 break;
252b5132
RH
10561
10562 entry = (Elf_External_Verneed *) vstart;
10563
10564 ent.vn_version = BYTE_GET (entry->vn_version);
10565 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
10566 ent.vn_file = BYTE_GET (entry->vn_file);
10567 ent.vn_aux = BYTE_GET (entry->vn_aux);
10568 ent.vn_next = BYTE_GET (entry->vn_next);
10569
452bf675 10570 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 10571
d79b3d50
NC
10572 if (VALID_DYNAMIC_NAME (ent.vn_file))
10573 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
10574 else
10575 printf (_(" File: %lx"), ent.vn_file);
10576
10577 printf (_(" Cnt: %d\n"), ent.vn_cnt);
10578
dd24e3da 10579 /* Check for overflow. */
7e26601c 10580 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 10581 break;
252b5132
RH
10582 vstart += ent.vn_aux;
10583
10584 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
10585 {
2cf0635d 10586 Elf_External_Vernaux * eaux;
b34976b6 10587 Elf_Internal_Vernaux aux;
252b5132 10588
54806181
AM
10589 if (vstart + sizeof (*eaux) > endbuf)
10590 break;
252b5132
RH
10591 eaux = (Elf_External_Vernaux *) vstart;
10592
10593 aux.vna_hash = BYTE_GET (eaux->vna_hash);
10594 aux.vna_flags = BYTE_GET (eaux->vna_flags);
10595 aux.vna_other = BYTE_GET (eaux->vna_other);
10596 aux.vna_name = BYTE_GET (eaux->vna_name);
10597 aux.vna_next = BYTE_GET (eaux->vna_next);
10598
d79b3d50 10599 if (VALID_DYNAMIC_NAME (aux.vna_name))
452bf675 10600 printf (_(" %#06lx: Name: %s"),
d79b3d50 10601 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 10602 else
452bf675 10603 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
10604 isum, aux.vna_name);
10605
10606 printf (_(" Flags: %s Version: %d\n"),
10607 get_ver_flags (aux.vna_flags), aux.vna_other);
10608
1445030f
AM
10609 if (aux.vna_next < sizeof (*eaux)
10610 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
10611 {
10612 warn (_("Invalid vna_next field of %lx\n"),
10613 aux.vna_next);
10614 j = ent.vn_cnt;
10615 break;
10616 }
1445030f
AM
10617 /* Check for overflow. */
10618 if (aux.vna_next > (size_t) (endbuf - vstart))
10619 break;
252b5132
RH
10620 isum += aux.vna_next;
10621 vstart += aux.vna_next;
10622 }
9cf03b7e 10623
54806181 10624 if (j < ent.vn_cnt)
9cf03b7e 10625 warn (_("Missing Version Needs auxillary information\n"));
252b5132 10626
1445030f
AM
10627 if (ent.vn_next < sizeof (*entry)
10628 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 10629 {
452bf675 10630 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
10631 cnt = section->sh_info;
10632 break;
10633 }
1445030f
AM
10634 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
10635 break;
252b5132
RH
10636 idx += ent.vn_next;
10637 }
9cf03b7e 10638
54806181 10639 if (cnt < section->sh_info)
9cf03b7e 10640 warn (_("Missing Version Needs information\n"));
103f02d3 10641
252b5132
RH
10642 free (eneed);
10643 }
10644 break;
10645
10646 case SHT_GNU_versym:
10647 {
2cf0635d 10648 Elf_Internal_Shdr * link_section;
8b73c356
NC
10649 size_t total;
10650 unsigned int cnt;
2cf0635d
NC
10651 unsigned char * edata;
10652 unsigned short * data;
10653 char * strtab;
10654 Elf_Internal_Sym * symbols;
10655 Elf_Internal_Shdr * string_sec;
ba5cdace 10656 unsigned long num_syms;
d3ba0551 10657 long off;
252b5132 10658
dda8d76d 10659 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10660 break;
10661
dda8d76d 10662 link_section = filedata->section_headers + section->sh_link;
08d8fa11 10663 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 10664
dda8d76d 10665 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10666 break;
10667
32ec8896 10668 found = TRUE;
252b5132 10669
dda8d76d 10670 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
10671 if (symbols == NULL)
10672 break;
252b5132 10673
dda8d76d 10674 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 10675
dda8d76d 10676 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
10677 string_sec->sh_size,
10678 _("version string table"));
a6e9f9df 10679 if (!strtab)
0429c154
MS
10680 {
10681 free (symbols);
10682 break;
10683 }
252b5132 10684
d3a49aa8
AM
10685 printf (ngettext ("\nVersion symbols section '%s' "
10686 "contains %lu entry:\n",
10687 "\nVersion symbols section '%s' "
10688 "contains %lu entries:\n",
10689 total),
dda8d76d 10690 printable_section_name (filedata, section), (unsigned long) total);
252b5132
RH
10691
10692 printf (_(" Addr: "));
10693 printf_vma (section->sh_addr);
72de5009 10694 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10695 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10696 printable_section_name (filedata, link_section));
252b5132 10697
dda8d76d 10698 off = offset_from_vma (filedata,
d3ba0551
AM
10699 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10700 total * sizeof (short));
dda8d76d 10701 edata = (unsigned char *) get_data (NULL, filedata, off, total,
3f5e193b
NC
10702 sizeof (short),
10703 _("version symbol data"));
a6e9f9df
AM
10704 if (!edata)
10705 {
10706 free (strtab);
0429c154 10707 free (symbols);
a6e9f9df
AM
10708 break;
10709 }
252b5132 10710
3f5e193b 10711 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
10712
10713 for (cnt = total; cnt --;)
b34976b6
AM
10714 data[cnt] = byte_get (edata + cnt * sizeof (short),
10715 sizeof (short));
252b5132
RH
10716
10717 free (edata);
10718
10719 for (cnt = 0; cnt < total; cnt += 4)
10720 {
10721 int j, nn;
ab273396
AM
10722 char *name;
10723 char *invalid = _("*invalid*");
252b5132
RH
10724
10725 printf (" %03x:", cnt);
10726
10727 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 10728 switch (data[cnt + j])
252b5132
RH
10729 {
10730 case 0:
10731 fputs (_(" 0 (*local*) "), stdout);
10732 break;
10733
10734 case 1:
10735 fputs (_(" 1 (*global*) "), stdout);
10736 break;
10737
10738 default:
c244d050
NC
10739 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
10740 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 10741
dd24e3da 10742 /* If this index value is greater than the size of the symbols
ba5cdace
NC
10743 array, break to avoid an out-of-bounds read. */
10744 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
10745 {
10746 warn (_("invalid index into symbol array\n"));
10747 break;
10748 }
10749
ab273396
AM
10750 name = NULL;
10751 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 10752 {
b34976b6
AM
10753 Elf_Internal_Verneed ivn;
10754 unsigned long offset;
252b5132 10755
d93f0186 10756 offset = offset_from_vma
dda8d76d 10757 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 10758 sizeof (Elf_External_Verneed));
252b5132 10759
b34976b6 10760 do
252b5132 10761 {
b34976b6
AM
10762 Elf_Internal_Vernaux ivna;
10763 Elf_External_Verneed evn;
10764 Elf_External_Vernaux evna;
10765 unsigned long a_off;
252b5132 10766
dda8d76d 10767 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
10768 _("version need")) == NULL)
10769 break;
0b4362b0 10770
252b5132
RH
10771 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10772 ivn.vn_next = BYTE_GET (evn.vn_next);
10773
10774 a_off = offset + ivn.vn_aux;
10775
10776 do
10777 {
dda8d76d 10778 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
10779 1, _("version need aux (2)")) == NULL)
10780 {
10781 ivna.vna_next = 0;
10782 ivna.vna_other = 0;
10783 }
10784 else
10785 {
10786 ivna.vna_next = BYTE_GET (evna.vna_next);
10787 ivna.vna_other = BYTE_GET (evna.vna_other);
10788 }
252b5132
RH
10789
10790 a_off += ivna.vna_next;
10791 }
b34976b6 10792 while (ivna.vna_other != data[cnt + j]
252b5132
RH
10793 && ivna.vna_next != 0);
10794
b34976b6 10795 if (ivna.vna_other == data[cnt + j])
252b5132
RH
10796 {
10797 ivna.vna_name = BYTE_GET (evna.vna_name);
10798
54806181 10799 if (ivna.vna_name >= string_sec->sh_size)
ab273396 10800 name = invalid;
54806181
AM
10801 else
10802 name = strtab + ivna.vna_name;
252b5132
RH
10803 break;
10804 }
10805
10806 offset += ivn.vn_next;
10807 }
10808 while (ivn.vn_next);
10809 }
00d93f34 10810
ab273396 10811 if (data[cnt + j] != 0x8001
b34976b6 10812 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10813 {
b34976b6
AM
10814 Elf_Internal_Verdef ivd;
10815 Elf_External_Verdef evd;
10816 unsigned long offset;
252b5132 10817
d93f0186 10818 offset = offset_from_vma
dda8d76d 10819 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 10820 sizeof evd);
252b5132
RH
10821
10822 do
10823 {
dda8d76d 10824 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
10825 _("version def")) == NULL)
10826 {
10827 ivd.vd_next = 0;
948f632f 10828 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
10829 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
10830 break;
59245841
NC
10831 }
10832 else
10833 {
10834 ivd.vd_next = BYTE_GET (evd.vd_next);
10835 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10836 }
252b5132
RH
10837
10838 offset += ivd.vd_next;
10839 }
c244d050 10840 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
10841 && ivd.vd_next != 0);
10842
c244d050 10843 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 10844 {
b34976b6
AM
10845 Elf_External_Verdaux evda;
10846 Elf_Internal_Verdaux ivda;
252b5132
RH
10847
10848 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10849
dda8d76d 10850 if (get_data (&evda, filedata,
59245841
NC
10851 offset - ivd.vd_next + ivd.vd_aux,
10852 sizeof (evda), 1,
10853 _("version def aux")) == NULL)
10854 break;
252b5132
RH
10855
10856 ivda.vda_name = BYTE_GET (evda.vda_name);
10857
54806181 10858 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
10859 name = invalid;
10860 else if (name != NULL && name != invalid)
10861 name = _("*both*");
54806181
AM
10862 else
10863 name = strtab + ivda.vda_name;
252b5132
RH
10864 }
10865 }
ab273396
AM
10866 if (name != NULL)
10867 nn += printf ("(%s%-*s",
10868 name,
10869 12 - (int) strlen (name),
10870 ")");
252b5132
RH
10871
10872 if (nn < 18)
10873 printf ("%*c", 18 - nn, ' ');
10874 }
10875
10876 putchar ('\n');
10877 }
10878
10879 free (data);
10880 free (strtab);
10881 free (symbols);
10882 }
10883 break;
103f02d3 10884
252b5132
RH
10885 default:
10886 break;
10887 }
10888 }
10889
10890 if (! found)
10891 printf (_("\nNo version information found in this file.\n"));
10892
32ec8896 10893 return TRUE;
252b5132
RH
10894}
10895
d1133906 10896static const char *
dda8d76d 10897get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 10898{
b34976b6 10899 static char buff[32];
252b5132
RH
10900
10901 switch (binding)
10902 {
b34976b6
AM
10903 case STB_LOCAL: return "LOCAL";
10904 case STB_GLOBAL: return "GLOBAL";
10905 case STB_WEAK: return "WEAK";
252b5132
RH
10906 default:
10907 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
10908 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
10909 binding);
252b5132 10910 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
10911 {
10912 if (binding == STB_GNU_UNIQUE
dda8d76d 10913 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9c55345c 10914 /* GNU is still using the default value 0. */
dda8d76d 10915 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
3e7a7d11
NC
10916 return "UNIQUE";
10917 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
10918 }
252b5132 10919 else
e9e44622 10920 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
10921 return buff;
10922 }
10923}
10924
d1133906 10925static const char *
dda8d76d 10926get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 10927{
b34976b6 10928 static char buff[32];
252b5132
RH
10929
10930 switch (type)
10931 {
b34976b6
AM
10932 case STT_NOTYPE: return "NOTYPE";
10933 case STT_OBJECT: return "OBJECT";
10934 case STT_FUNC: return "FUNC";
10935 case STT_SECTION: return "SECTION";
10936 case STT_FILE: return "FILE";
10937 case STT_COMMON: return "COMMON";
10938 case STT_TLS: return "TLS";
15ab5209
DB
10939 case STT_RELC: return "RELC";
10940 case STT_SRELC: return "SRELC";
252b5132
RH
10941 default:
10942 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 10943 {
dda8d76d 10944 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 10945 return "THUMB_FUNC";
103f02d3 10946
dda8d76d 10947 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
10948 return "REGISTER";
10949
dda8d76d 10950 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
10951 return "PARISC_MILLI";
10952
e9e44622 10953 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 10954 }
252b5132 10955 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 10956 {
dda8d76d 10957 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
10958 {
10959 if (type == STT_HP_OPAQUE)
10960 return "HP_OPAQUE";
10961 if (type == STT_HP_STUB)
10962 return "HP_STUB";
10963 }
10964
d8045f23 10965 if (type == STT_GNU_IFUNC
dda8d76d
NC
10966 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
10967 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 10968 /* GNU is still using the default value 0. */
dda8d76d 10969 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
d8045f23
NC
10970 return "IFUNC";
10971
e9e44622 10972 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 10973 }
252b5132 10974 else
e9e44622 10975 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
10976 return buff;
10977 }
10978}
10979
d1133906 10980static const char *
d3ba0551 10981get_symbol_visibility (unsigned int visibility)
d1133906
NC
10982{
10983 switch (visibility)
10984 {
b34976b6
AM
10985 case STV_DEFAULT: return "DEFAULT";
10986 case STV_INTERNAL: return "INTERNAL";
10987 case STV_HIDDEN: return "HIDDEN";
d1133906 10988 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
10989 default:
10990 error (_("Unrecognized visibility value: %u"), visibility);
10991 return _("<unknown>");
d1133906
NC
10992 }
10993}
10994
fd85a6a1
NC
10995static const char *
10996get_solaris_symbol_visibility (unsigned int visibility)
10997{
10998 switch (visibility)
10999 {
11000 case 4: return "EXPORTED";
11001 case 5: return "SINGLETON";
11002 case 6: return "ELIMINATE";
11003 default: return get_symbol_visibility (visibility);
11004 }
11005}
11006
5e2b0d47
NC
11007static const char *
11008get_mips_symbol_other (unsigned int other)
11009{
11010 switch (other)
11011 {
32ec8896
NC
11012 case STO_OPTIONAL: return "OPTIONAL";
11013 case STO_MIPS_PLT: return "MIPS PLT";
11014 case STO_MIPS_PIC: return "MIPS PIC";
11015 case STO_MICROMIPS: return "MICROMIPS";
11016 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11017 case STO_MIPS16: return "MIPS16";
11018 default: return NULL;
5e2b0d47
NC
11019 }
11020}
11021
28f997cf 11022static const char *
dda8d76d 11023get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11024{
dda8d76d 11025 if (is_ia64_vms (filedata))
28f997cf
TG
11026 {
11027 static char res[32];
11028
11029 res[0] = 0;
11030
11031 /* Function types is for images and .STB files only. */
dda8d76d 11032 switch (filedata->file_header.e_type)
28f997cf
TG
11033 {
11034 case ET_DYN:
11035 case ET_EXEC:
11036 switch (VMS_ST_FUNC_TYPE (other))
11037 {
11038 case VMS_SFT_CODE_ADDR:
11039 strcat (res, " CA");
11040 break;
11041 case VMS_SFT_SYMV_IDX:
11042 strcat (res, " VEC");
11043 break;
11044 case VMS_SFT_FD:
11045 strcat (res, " FD");
11046 break;
11047 case VMS_SFT_RESERVE:
11048 strcat (res, " RSV");
11049 break;
11050 default:
bee0ee85
NC
11051 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11052 VMS_ST_FUNC_TYPE (other));
11053 strcat (res, " <unknown>");
11054 break;
28f997cf
TG
11055 }
11056 break;
11057 default:
11058 break;
11059 }
11060 switch (VMS_ST_LINKAGE (other))
11061 {
11062 case VMS_STL_IGNORE:
11063 strcat (res, " IGN");
11064 break;
11065 case VMS_STL_RESERVE:
11066 strcat (res, " RSV");
11067 break;
11068 case VMS_STL_STD:
11069 strcat (res, " STD");
11070 break;
11071 case VMS_STL_LNK:
11072 strcat (res, " LNK");
11073 break;
11074 default:
bee0ee85
NC
11075 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11076 VMS_ST_LINKAGE (other));
11077 strcat (res, " <unknown>");
11078 break;
28f997cf
TG
11079 }
11080
11081 if (res[0] != 0)
11082 return res + 1;
11083 else
11084 return res;
11085 }
11086 return NULL;
11087}
11088
6911b7dc
AM
11089static const char *
11090get_ppc64_symbol_other (unsigned int other)
11091{
14732552
AM
11092 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11093 return NULL;
11094
11095 other >>= STO_PPC64_LOCAL_BIT;
11096 if (other <= 6)
6911b7dc
AM
11097 {
11098 static char buf[32];
14732552
AM
11099 if (other >= 2)
11100 other = ppc64_decode_local_entry (other);
11101 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11102 return buf;
11103 }
11104 return NULL;
11105}
11106
5e2b0d47 11107static const char *
dda8d76d 11108get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11109{
11110 const char * result = NULL;
11111 static char buff [32];
11112
11113 if (other == 0)
11114 return "";
11115
dda8d76d 11116 switch (filedata->file_header.e_machine)
5e2b0d47
NC
11117 {
11118 case EM_MIPS:
11119 result = get_mips_symbol_other (other);
28f997cf
TG
11120 break;
11121 case EM_IA_64:
dda8d76d 11122 result = get_ia64_symbol_other (filedata, other);
28f997cf 11123 break;
6911b7dc
AM
11124 case EM_PPC64:
11125 result = get_ppc64_symbol_other (other);
11126 break;
5e2b0d47 11127 default:
fd85a6a1 11128 result = NULL;
5e2b0d47
NC
11129 break;
11130 }
11131
11132 if (result)
11133 return result;
11134
11135 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11136 return buff;
11137}
11138
d1133906 11139static const char *
dda8d76d 11140get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11141{
b34976b6 11142 static char buff[32];
5cf1065c 11143
252b5132
RH
11144 switch (type)
11145 {
b34976b6
AM
11146 case SHN_UNDEF: return "UND";
11147 case SHN_ABS: return "ABS";
11148 case SHN_COMMON: return "COM";
252b5132 11149 default:
9ce701e2 11150 if (type == SHN_IA_64_ANSI_COMMON
dda8d76d
NC
11151 && filedata->file_header.e_machine == EM_IA_64
11152 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9ce701e2 11153 return "ANSI_COM";
dda8d76d
NC
11154 else if ((filedata->file_header.e_machine == EM_X86_64
11155 || filedata->file_header.e_machine == EM_L1OM
11156 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
11157 && type == SHN_X86_64_LCOMMON)
11158 return "LARGE_COM";
ac145307 11159 else if ((type == SHN_MIPS_SCOMMON
dda8d76d 11160 && filedata->file_header.e_machine == EM_MIPS)
ac145307 11161 || (type == SHN_TIC6X_SCOMMON
dda8d76d 11162 && filedata->file_header.e_machine == EM_TI_C6000))
172553c7
TS
11163 return "SCOM";
11164 else if (type == SHN_MIPS_SUNDEFINED
dda8d76d 11165 && filedata->file_header.e_machine == EM_MIPS)
172553c7 11166 return "SUND";
9ce701e2 11167 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 11168 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 11169 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
11170 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11171 else if (type >= SHN_LORESERVE)
11172 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
dda8d76d 11173 else if (type >= filedata->file_header.e_shnum)
e0a31db1 11174 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 11175 else
232e7cb8 11176 sprintf (buff, "%3d", type);
5cf1065c 11177 break;
252b5132 11178 }
5cf1065c
NC
11179
11180 return buff;
252b5132
RH
11181}
11182
66543521 11183static bfd_vma *
dda8d76d 11184get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
252b5132 11185{
2cf0635d
NC
11186 unsigned char * e_data;
11187 bfd_vma * i_data;
252b5132 11188
57028622
NC
11189 /* If the size_t type is smaller than the bfd_size_type, eg because
11190 you are building a 32-bit tool on a 64-bit host, then make sure
11191 that when (number) is cast to (size_t) no information is lost. */
11192 if (sizeof (size_t) < sizeof (bfd_size_type)
11193 && (bfd_size_type) ((size_t) number) != number)
11194 {
66cfc0fd
AM
11195 error (_("Size truncation prevents reading %s elements of size %u\n"),
11196 bfd_vmatoa ("u", number), ent_size);
57028622
NC
11197 return NULL;
11198 }
948f632f 11199
3102e897
NC
11200 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
11201 attempting to allocate memory when the read is bound to fail. */
dda8d76d 11202 if (ent_size * number > filedata->file_size)
3102e897 11203 {
66cfc0fd
AM
11204 error (_("Invalid number of dynamic entries: %s\n"),
11205 bfd_vmatoa ("u", number));
3102e897
NC
11206 return NULL;
11207 }
11208
57028622 11209 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
11210 if (e_data == NULL)
11211 {
66cfc0fd
AM
11212 error (_("Out of memory reading %s dynamic entries\n"),
11213 bfd_vmatoa ("u", number));
252b5132
RH
11214 return NULL;
11215 }
11216
dda8d76d 11217 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
252b5132 11218 {
66cfc0fd
AM
11219 error (_("Unable to read in %s bytes of dynamic data\n"),
11220 bfd_vmatoa ("u", number * ent_size));
3102e897 11221 free (e_data);
252b5132
RH
11222 return NULL;
11223 }
11224
57028622 11225 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
11226 if (i_data == NULL)
11227 {
66cfc0fd
AM
11228 error (_("Out of memory allocating space for %s dynamic entries\n"),
11229 bfd_vmatoa ("u", number));
252b5132
RH
11230 free (e_data);
11231 return NULL;
11232 }
11233
11234 while (number--)
66543521 11235 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
11236
11237 free (e_data);
11238
11239 return i_data;
11240}
11241
6bd1a22c 11242static void
dda8d76d 11243print_dynamic_symbol (Filedata * filedata, bfd_vma si, unsigned long hn)
6bd1a22c 11244{
2cf0635d 11245 Elf_Internal_Sym * psym;
6bd1a22c
L
11246 int n;
11247
6bd1a22c
L
11248 n = print_vma (si, DEC_5);
11249 if (n < 5)
0b4362b0 11250 fputs (&" "[n], stdout);
6bd1a22c 11251 printf (" %3lu: ", hn);
e0a31db1
NC
11252
11253 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
11254 {
3102e897
NC
11255 printf (_("<No info available for dynamic symbol number %lu>\n"),
11256 (unsigned long) si);
e0a31db1
NC
11257 return;
11258 }
11259
11260 psym = dynamic_symbols + si;
6bd1a22c
L
11261 print_vma (psym->st_value, LONG_HEX);
11262 putchar (' ');
11263 print_vma (psym->st_size, DEC_5);
11264
dda8d76d
NC
11265 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11266 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
fd85a6a1 11267
dda8d76d 11268 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11269 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11270 else
11271 {
11272 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11273
11274 printf (" %-7s", get_symbol_visibility (vis));
11275 /* Check to see if any other bits in the st_other field are set.
11276 Note - displaying this information disrupts the layout of the
11277 table being generated, but for the moment this case is very
11278 rare. */
11279 if (psym->st_other ^ vis)
dda8d76d 11280 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1
NC
11281 }
11282
dda8d76d 11283 printf (" %3.3s ", get_symbol_index_type (filedata, psym->st_shndx));
6bd1a22c
L
11284 if (VALID_DYNAMIC_NAME (psym->st_name))
11285 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11286 else
2b692964 11287 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
11288 putchar ('\n');
11289}
11290
bb4d2ac2 11291static const char *
dda8d76d 11292get_symbol_version_string (Filedata * filedata,
1449284b
NC
11293 bfd_boolean is_dynsym,
11294 const char * strtab,
11295 unsigned long int strtab_size,
11296 unsigned int si,
11297 Elf_Internal_Sym * psym,
11298 enum versioned_symbol_info * sym_info,
11299 unsigned short * vna_other)
bb4d2ac2 11300{
ab273396
AM
11301 unsigned char data[2];
11302 unsigned short vers_data;
11303 unsigned long offset;
7a815dd5 11304 unsigned short max_vd_ndx;
bb4d2ac2 11305
ab273396
AM
11306 if (!is_dynsym
11307 || version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
11308 return NULL;
bb4d2ac2 11309
dda8d76d 11310 offset = offset_from_vma (filedata, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11311 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11312
dda8d76d 11313 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11314 sizeof (data), 1, _("version data")) == NULL)
11315 return NULL;
11316
11317 vers_data = byte_get (data, 2);
bb4d2ac2 11318
1f6f5dba 11319 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11320 return NULL;
bb4d2ac2 11321
7a815dd5
L
11322 max_vd_ndx = 0;
11323
ab273396
AM
11324 /* Usually we'd only see verdef for defined symbols, and verneed for
11325 undefined symbols. However, symbols defined by the linker in
11326 .dynbss for variables copied from a shared library in order to
11327 avoid text relocations are defined yet have verneed. We could
11328 use a heuristic to detect the special case, for example, check
11329 for verneed first on symbols defined in SHT_NOBITS sections, but
11330 it is simpler and more reliable to just look for both verdef and
11331 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11332
ab273396
AM
11333 if (psym->st_shndx != SHN_UNDEF
11334 && vers_data != 0x8001
11335 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
11336 {
11337 Elf_Internal_Verdef ivd;
11338 Elf_Internal_Verdaux ivda;
11339 Elf_External_Verdaux evda;
11340 unsigned long off;
bb4d2ac2 11341
dda8d76d 11342 off = offset_from_vma (filedata,
ab273396
AM
11343 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
11344 sizeof (Elf_External_Verdef));
11345
11346 do
bb4d2ac2 11347 {
ab273396
AM
11348 Elf_External_Verdef evd;
11349
dda8d76d 11350 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11351 _("version def")) == NULL)
11352 {
11353 ivd.vd_ndx = 0;
11354 ivd.vd_aux = 0;
11355 ivd.vd_next = 0;
1f6f5dba 11356 ivd.vd_flags = 0;
ab273396
AM
11357 }
11358 else
bb4d2ac2 11359 {
ab273396
AM
11360 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11361 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11362 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 11363 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 11364 }
bb4d2ac2 11365
7a815dd5
L
11366 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
11367 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
11368
ab273396
AM
11369 off += ivd.vd_next;
11370 }
11371 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11372
ab273396
AM
11373 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11374 {
1f6f5dba
L
11375 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
11376 return NULL;
11377
ab273396
AM
11378 off -= ivd.vd_next;
11379 off += ivd.vd_aux;
bb4d2ac2 11380
dda8d76d 11381 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
11382 _("version def aux")) != NULL)
11383 {
11384 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 11385
ab273396
AM
11386 if (psym->st_name != ivda.vda_name)
11387 {
11388 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
11389 ? symbol_hidden : symbol_public);
11390 return (ivda.vda_name < strtab_size
11391 ? strtab + ivda.vda_name : _("<corrupt>"));
11392 }
11393 }
11394 }
11395 }
bb4d2ac2 11396
ab273396
AM
11397 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
11398 {
11399 Elf_External_Verneed evn;
11400 Elf_Internal_Verneed ivn;
11401 Elf_Internal_Vernaux ivna;
bb4d2ac2 11402
dda8d76d 11403 offset = offset_from_vma (filedata,
ab273396
AM
11404 version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
11405 sizeof evn);
11406 do
11407 {
11408 unsigned long vna_off;
bb4d2ac2 11409
dda8d76d 11410 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
11411 _("version need")) == NULL)
11412 {
11413 ivna.vna_next = 0;
11414 ivna.vna_other = 0;
11415 ivna.vna_name = 0;
11416 break;
11417 }
bb4d2ac2 11418
ab273396
AM
11419 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11420 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 11421
ab273396 11422 vna_off = offset + ivn.vn_aux;
bb4d2ac2 11423
ab273396
AM
11424 do
11425 {
11426 Elf_External_Vernaux evna;
bb4d2ac2 11427
dda8d76d 11428 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 11429 _("version need aux (3)")) == NULL)
bb4d2ac2 11430 {
ab273396
AM
11431 ivna.vna_next = 0;
11432 ivna.vna_other = 0;
11433 ivna.vna_name = 0;
bb4d2ac2 11434 }
bb4d2ac2 11435 else
bb4d2ac2 11436 {
ab273396
AM
11437 ivna.vna_other = BYTE_GET (evna.vna_other);
11438 ivna.vna_next = BYTE_GET (evna.vna_next);
11439 ivna.vna_name = BYTE_GET (evna.vna_name);
11440 }
bb4d2ac2 11441
ab273396
AM
11442 vna_off += ivna.vna_next;
11443 }
11444 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 11445
ab273396
AM
11446 if (ivna.vna_other == vers_data)
11447 break;
bb4d2ac2 11448
ab273396
AM
11449 offset += ivn.vn_next;
11450 }
11451 while (ivn.vn_next != 0);
bb4d2ac2 11452
ab273396
AM
11453 if (ivna.vna_other == vers_data)
11454 {
11455 *sym_info = symbol_undefined;
11456 *vna_other = ivna.vna_other;
11457 return (ivna.vna_name < strtab_size
11458 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 11459 }
7a815dd5
L
11460 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
11461 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
11462 return _("<corrupt>");
bb4d2ac2 11463 }
ab273396 11464 return NULL;
bb4d2ac2
L
11465}
11466
e3c8793a 11467/* Dump the symbol table. */
32ec8896 11468static bfd_boolean
dda8d76d 11469process_symbol_table (Filedata * filedata)
252b5132 11470{
2cf0635d 11471 Elf_Internal_Shdr * section;
8b73c356
NC
11472 bfd_size_type nbuckets = 0;
11473 bfd_size_type nchains = 0;
2cf0635d
NC
11474 bfd_vma * buckets = NULL;
11475 bfd_vma * chains = NULL;
fdc90cb4 11476 bfd_vma ngnubuckets = 0;
2cf0635d
NC
11477 bfd_vma * gnubuckets = NULL;
11478 bfd_vma * gnuchains = NULL;
6bd1a22c 11479 bfd_vma gnusymidx = 0;
071436c6 11480 bfd_size_type ngnuchains = 0;
252b5132 11481
2c610e4b 11482 if (!do_syms && !do_dyn_syms && !do_histogram)
32ec8896 11483 return TRUE;
252b5132 11484
6bd1a22c
L
11485 if (dynamic_info[DT_HASH]
11486 && (do_histogram
2c610e4b
L
11487 || (do_using_dynamic
11488 && !do_dyn_syms
11489 && dynamic_strings != NULL)))
252b5132 11490 {
66543521
AM
11491 unsigned char nb[8];
11492 unsigned char nc[8];
8b73c356 11493 unsigned int hash_ent_size = 4;
66543521 11494
dda8d76d
NC
11495 if ((filedata->file_header.e_machine == EM_ALPHA
11496 || filedata->file_header.e_machine == EM_S390
11497 || filedata->file_header.e_machine == EM_S390_OLD)
11498 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
66543521
AM
11499 hash_ent_size = 8;
11500
dda8d76d 11501 if (fseek (filedata->handle,
fb52b2f4 11502 (archive_file_offset
dda8d76d 11503 + offset_from_vma (filedata, dynamic_info[DT_HASH],
fb52b2f4 11504 sizeof nb + sizeof nc)),
d93f0186 11505 SEEK_SET))
252b5132 11506 {
591a748a 11507 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11508 goto no_hash;
252b5132
RH
11509 }
11510
dda8d76d 11511 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11512 {
11513 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11514 goto no_hash;
252b5132
RH
11515 }
11516
dda8d76d 11517 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11518 {
11519 error (_("Failed to read in number of chains\n"));
d3a44ec6 11520 goto no_hash;
252b5132
RH
11521 }
11522
66543521
AM
11523 nbuckets = byte_get (nb, hash_ent_size);
11524 nchains = byte_get (nc, hash_ent_size);
252b5132 11525
dda8d76d
NC
11526 buckets = get_dynamic_data (filedata, nbuckets, hash_ent_size);
11527 chains = get_dynamic_data (filedata, nchains, hash_ent_size);
252b5132 11528
d3a44ec6 11529 no_hash:
252b5132 11530 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
11531 {
11532 if (do_using_dynamic)
32ec8896 11533 return FALSE;
d3a44ec6
JJ
11534 free (buckets);
11535 free (chains);
11536 buckets = NULL;
11537 chains = NULL;
11538 nbuckets = 0;
11539 nchains = 0;
11540 }
252b5132
RH
11541 }
11542
6bd1a22c
L
11543 if (dynamic_info_DT_GNU_HASH
11544 && (do_histogram
2c610e4b
L
11545 || (do_using_dynamic
11546 && !do_dyn_syms
11547 && dynamic_strings != NULL)))
252b5132 11548 {
6bd1a22c
L
11549 unsigned char nb[16];
11550 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11551 bfd_vma buckets_vma;
11552
dda8d76d 11553 if (fseek (filedata->handle,
6bd1a22c 11554 (archive_file_offset
dda8d76d 11555 + offset_from_vma (filedata, dynamic_info_DT_GNU_HASH,
6bd1a22c
L
11556 sizeof nb)),
11557 SEEK_SET))
11558 {
11559 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11560 goto no_gnu_hash;
6bd1a22c 11561 }
252b5132 11562
dda8d76d 11563 if (fread (nb, 16, 1, filedata->handle) != 1)
6bd1a22c
L
11564 {
11565 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11566 goto no_gnu_hash;
6bd1a22c
L
11567 }
11568
11569 ngnubuckets = byte_get (nb, 4);
11570 gnusymidx = byte_get (nb + 4, 4);
11571 bitmaskwords = byte_get (nb + 8, 4);
11572 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 11573 if (is_32bit_elf)
6bd1a22c 11574 buckets_vma += bitmaskwords * 4;
f7a99963 11575 else
6bd1a22c 11576 buckets_vma += bitmaskwords * 8;
252b5132 11577
dda8d76d 11578 if (fseek (filedata->handle,
6bd1a22c 11579 (archive_file_offset
dda8d76d 11580 + offset_from_vma (filedata, buckets_vma, 4)),
6bd1a22c 11581 SEEK_SET))
252b5132 11582 {
6bd1a22c 11583 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11584 goto no_gnu_hash;
6bd1a22c
L
11585 }
11586
dda8d76d 11587 gnubuckets = get_dynamic_data (filedata, ngnubuckets, 4);
252b5132 11588
6bd1a22c 11589 if (gnubuckets == NULL)
d3a44ec6 11590 goto no_gnu_hash;
6bd1a22c
L
11591
11592 for (i = 0; i < ngnubuckets; i++)
11593 if (gnubuckets[i] != 0)
11594 {
11595 if (gnubuckets[i] < gnusymidx)
32ec8896 11596 return FALSE;
6bd1a22c
L
11597
11598 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
11599 maxchain = gnubuckets[i];
11600 }
11601
11602 if (maxchain == 0xffffffff)
d3a44ec6 11603 goto no_gnu_hash;
6bd1a22c
L
11604
11605 maxchain -= gnusymidx;
11606
dda8d76d 11607 if (fseek (filedata->handle,
6bd1a22c 11608 (archive_file_offset
dda8d76d 11609 + offset_from_vma (filedata, buckets_vma
6bd1a22c
L
11610 + 4 * (ngnubuckets + maxchain), 4)),
11611 SEEK_SET))
11612 {
11613 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11614 goto no_gnu_hash;
6bd1a22c
L
11615 }
11616
11617 do
11618 {
dda8d76d 11619 if (fread (nb, 4, 1, filedata->handle) != 1)
252b5132 11620 {
6bd1a22c 11621 error (_("Failed to determine last chain length\n"));
d3a44ec6 11622 goto no_gnu_hash;
6bd1a22c 11623 }
252b5132 11624
6bd1a22c 11625 if (maxchain + 1 == 0)
d3a44ec6 11626 goto no_gnu_hash;
252b5132 11627
6bd1a22c
L
11628 ++maxchain;
11629 }
11630 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 11631
dda8d76d 11632 if (fseek (filedata->handle,
6bd1a22c 11633 (archive_file_offset
dda8d76d 11634 + offset_from_vma (filedata, buckets_vma + 4 * ngnubuckets, 4)),
6bd1a22c
L
11635 SEEK_SET))
11636 {
11637 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11638 goto no_gnu_hash;
6bd1a22c
L
11639 }
11640
dda8d76d 11641 gnuchains = get_dynamic_data (filedata, maxchain, 4);
071436c6 11642 ngnuchains = maxchain;
6bd1a22c 11643
d3a44ec6 11644 no_gnu_hash:
6bd1a22c 11645 if (gnuchains == NULL)
d3a44ec6
JJ
11646 {
11647 free (gnubuckets);
d3a44ec6
JJ
11648 gnubuckets = NULL;
11649 ngnubuckets = 0;
f64fddf1 11650 if (do_using_dynamic)
32ec8896 11651 return FALSE;
d3a44ec6 11652 }
6bd1a22c
L
11653 }
11654
11655 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
11656 && do_syms
11657 && do_using_dynamic
3102e897
NC
11658 && dynamic_strings != NULL
11659 && dynamic_symbols != NULL)
6bd1a22c
L
11660 {
11661 unsigned long hn;
11662
11663 if (dynamic_info[DT_HASH])
11664 {
11665 bfd_vma si;
6bd6a03d 11666 char *visited;
6bd1a22c
L
11667
11668 printf (_("\nSymbol table for image:\n"));
11669 if (is_32bit_elf)
11670 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11671 else
11672 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11673
6bd6a03d
AM
11674 visited = xcmalloc (nchains, 1);
11675 memset (visited, 0, nchains);
6bd1a22c
L
11676 for (hn = 0; hn < nbuckets; hn++)
11677 {
6bd6a03d
AM
11678 for (si = buckets[hn]; si > 0; si = chains[si])
11679 {
dda8d76d 11680 print_dynamic_symbol (filedata, si, hn);
6bd6a03d
AM
11681 if (si >= nchains || visited[si])
11682 {
11683 error (_("histogram chain is corrupt\n"));
11684 break;
11685 }
11686 visited[si] = 1;
11687 }
252b5132 11688 }
6bd6a03d 11689 free (visited);
252b5132 11690 }
6bd1a22c
L
11691
11692 if (dynamic_info_DT_GNU_HASH)
11693 {
11694 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
11695 if (is_32bit_elf)
11696 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11697 else
11698 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11699
11700 for (hn = 0; hn < ngnubuckets; ++hn)
11701 if (gnubuckets[hn] != 0)
11702 {
11703 bfd_vma si = gnubuckets[hn];
11704 bfd_vma off = si - gnusymidx;
11705
11706 do
11707 {
dda8d76d 11708 print_dynamic_symbol (filedata, si, hn);
6bd1a22c
L
11709 si++;
11710 }
071436c6 11711 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
11712 }
11713 }
252b5132 11714 }
8b73c356 11715 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 11716 && filedata->section_headers != NULL)
252b5132 11717 {
b34976b6 11718 unsigned int i;
252b5132 11719
dda8d76d
NC
11720 for (i = 0, section = filedata->section_headers;
11721 i < filedata->file_header.e_shnum;
252b5132
RH
11722 i++, section++)
11723 {
b34976b6 11724 unsigned int si;
2cf0635d 11725 char * strtab = NULL;
c256ffe7 11726 unsigned long int strtab_size = 0;
2cf0635d
NC
11727 Elf_Internal_Sym * symtab;
11728 Elf_Internal_Sym * psym;
ba5cdace 11729 unsigned long num_syms;
252b5132 11730
2c610e4b
L
11731 if ((section->sh_type != SHT_SYMTAB
11732 && section->sh_type != SHT_DYNSYM)
11733 || (!do_syms
11734 && section->sh_type == SHT_SYMTAB))
252b5132
RH
11735 continue;
11736
dd24e3da
NC
11737 if (section->sh_entsize == 0)
11738 {
11739 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 11740 printable_section_name (filedata, section));
dd24e3da
NC
11741 continue;
11742 }
11743
d3a49aa8
AM
11744 num_syms = section->sh_size / section->sh_entsize;
11745 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
11746 "\nSymbol table '%s' contains %lu entries:\n",
11747 num_syms),
dda8d76d 11748 printable_section_name (filedata, section),
d3a49aa8 11749 num_syms);
dd24e3da 11750
f7a99963 11751 if (is_32bit_elf)
ca47b30c 11752 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 11753 else
ca47b30c 11754 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 11755
dda8d76d 11756 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
11757 if (symtab == NULL)
11758 continue;
11759
dda8d76d 11760 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 11761 {
dda8d76d
NC
11762 strtab = filedata->string_table;
11763 strtab_size = filedata->string_table_length;
c256ffe7 11764 }
dda8d76d 11765 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 11766 {
2cf0635d 11767 Elf_Internal_Shdr * string_sec;
252b5132 11768
dda8d76d 11769 string_sec = filedata->section_headers + section->sh_link;
252b5132 11770
dda8d76d 11771 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
11772 1, string_sec->sh_size,
11773 _("string table"));
c256ffe7 11774 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
11775 }
11776
ba5cdace 11777 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 11778 {
bb4d2ac2
L
11779 const char *version_string;
11780 enum versioned_symbol_info sym_info;
11781 unsigned short vna_other;
11782
5e220199 11783 printf ("%6d: ", si);
f7a99963
NC
11784 print_vma (psym->st_value, LONG_HEX);
11785 putchar (' ');
11786 print_vma (psym->st_size, DEC_5);
dda8d76d
NC
11787 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11788 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
11789 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11790 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11791 else
11792 {
11793 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11794
11795 printf (" %-7s", get_symbol_visibility (vis));
11796 /* Check to see if any other bits in the st_other field are set.
11797 Note - displaying this information disrupts the layout of the
11798 table being generated, but for the moment this case is very rare. */
11799 if (psym->st_other ^ vis)
dda8d76d 11800 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1 11801 }
dda8d76d 11802 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
c256ffe7 11803 print_symbol (25, psym->st_name < strtab_size
2b692964 11804 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 11805
bb4d2ac2 11806 version_string
dda8d76d 11807 = get_symbol_version_string (filedata,
bb4d2ac2
L
11808 section->sh_type == SHT_DYNSYM,
11809 strtab, strtab_size, si,
11810 psym, &sym_info, &vna_other);
11811 if (version_string)
252b5132 11812 {
bb4d2ac2
L
11813 if (sym_info == symbol_undefined)
11814 printf ("@%s (%d)", version_string, vna_other);
11815 else
11816 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
11817 version_string);
252b5132
RH
11818 }
11819
11820 putchar ('\n');
52c3c391
NC
11821
11822 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
dd905818
NC
11823 && si >= section->sh_info
11824 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
dda8d76d 11825 && filedata->file_header.e_machine != EM_MIPS
dd905818
NC
11826 /* Solaris binaries have been found to violate this requirement as
11827 well. Not sure if this is a bug or an ABI requirement. */
dda8d76d 11828 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
52c3c391 11829 warn (_("local symbol %u found at index >= %s's sh_info value of %u\n"),
dda8d76d 11830 si, printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11831 }
11832
11833 free (symtab);
dda8d76d 11834 if (strtab != filedata->string_table)
252b5132
RH
11835 free (strtab);
11836 }
11837 }
11838 else if (do_syms)
11839 printf
11840 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
11841
11842 if (do_histogram && buckets != NULL)
11843 {
2cf0635d
NC
11844 unsigned long * lengths;
11845 unsigned long * counts;
66543521
AM
11846 unsigned long hn;
11847 bfd_vma si;
11848 unsigned long maxlength = 0;
11849 unsigned long nzero_counts = 0;
11850 unsigned long nsyms = 0;
6bd6a03d 11851 char *visited;
252b5132 11852
d3a49aa8
AM
11853 printf (ngettext ("\nHistogram for bucket list length "
11854 "(total of %lu bucket):\n",
11855 "\nHistogram for bucket list length "
11856 "(total of %lu buckets):\n",
11857 (unsigned long) nbuckets),
66543521 11858 (unsigned long) nbuckets);
252b5132 11859
3f5e193b 11860 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
11861 if (lengths == NULL)
11862 {
8b73c356 11863 error (_("Out of memory allocating space for histogram buckets\n"));
32ec8896 11864 return FALSE;
252b5132 11865 }
6bd6a03d
AM
11866 visited = xcmalloc (nchains, 1);
11867 memset (visited, 0, nchains);
8b73c356
NC
11868
11869 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
11870 for (hn = 0; hn < nbuckets; ++hn)
11871 {
6bd6a03d 11872 for (si = buckets[hn]; si > 0; si = chains[si])
252b5132 11873 {
b34976b6 11874 ++nsyms;
252b5132 11875 if (maxlength < ++lengths[hn])
b34976b6 11876 ++maxlength;
6bd6a03d
AM
11877 if (si >= nchains || visited[si])
11878 {
11879 error (_("histogram chain is corrupt\n"));
11880 break;
11881 }
11882 visited[si] = 1;
252b5132
RH
11883 }
11884 }
6bd6a03d 11885 free (visited);
252b5132 11886
3f5e193b 11887 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
11888 if (counts == NULL)
11889 {
b2e951ec 11890 free (lengths);
8b73c356 11891 error (_("Out of memory allocating space for histogram counts\n"));
32ec8896 11892 return FALSE;
252b5132
RH
11893 }
11894
11895 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 11896 ++counts[lengths[hn]];
252b5132 11897
103f02d3 11898 if (nbuckets > 0)
252b5132 11899 {
66543521
AM
11900 unsigned long i;
11901 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 11902 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 11903 for (i = 1; i <= maxlength; ++i)
103f02d3 11904 {
66543521
AM
11905 nzero_counts += counts[i] * i;
11906 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11907 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
11908 (nzero_counts * 100.0) / nsyms);
11909 }
252b5132
RH
11910 }
11911
11912 free (counts);
11913 free (lengths);
11914 }
11915
11916 if (buckets != NULL)
11917 {
11918 free (buckets);
11919 free (chains);
11920 }
11921
d3a44ec6 11922 if (do_histogram && gnubuckets != NULL)
fdc90cb4 11923 {
2cf0635d
NC
11924 unsigned long * lengths;
11925 unsigned long * counts;
fdc90cb4
JJ
11926 unsigned long hn;
11927 unsigned long maxlength = 0;
11928 unsigned long nzero_counts = 0;
11929 unsigned long nsyms = 0;
fdc90cb4 11930
d3a49aa8
AM
11931 printf (ngettext ("\nHistogram for `.gnu.hash' bucket list length "
11932 "(total of %lu bucket):\n",
11933 "\nHistogram for `.gnu.hash' bucket list length "
11934 "(total of %lu buckets):\n",
11935 (unsigned long) ngnubuckets),
8b73c356
NC
11936 (unsigned long) ngnubuckets);
11937
3f5e193b 11938 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
11939 if (lengths == NULL)
11940 {
8b73c356 11941 error (_("Out of memory allocating space for gnu histogram buckets\n"));
32ec8896 11942 return FALSE;
fdc90cb4
JJ
11943 }
11944
fdc90cb4
JJ
11945 printf (_(" Length Number %% of total Coverage\n"));
11946
11947 for (hn = 0; hn < ngnubuckets; ++hn)
11948 if (gnubuckets[hn] != 0)
11949 {
11950 bfd_vma off, length = 1;
11951
6bd1a22c 11952 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
11953 /* PR 17531 file: 010-77222-0.004. */
11954 off < ngnuchains && (gnuchains[off] & 1) == 0;
11955 ++off)
fdc90cb4
JJ
11956 ++length;
11957 lengths[hn] = length;
11958 if (length > maxlength)
11959 maxlength = length;
11960 nsyms += length;
11961 }
11962
3f5e193b 11963 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
11964 if (counts == NULL)
11965 {
b2e951ec 11966 free (lengths);
8b73c356 11967 error (_("Out of memory allocating space for gnu histogram counts\n"));
32ec8896 11968 return FALSE;
fdc90cb4
JJ
11969 }
11970
11971 for (hn = 0; hn < ngnubuckets; ++hn)
11972 ++counts[lengths[hn]];
11973
11974 if (ngnubuckets > 0)
11975 {
11976 unsigned long j;
11977 printf (" 0 %-10lu (%5.1f%%)\n",
11978 counts[0], (counts[0] * 100.0) / ngnubuckets);
11979 for (j = 1; j <= maxlength; ++j)
11980 {
11981 nzero_counts += counts[j] * j;
11982 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11983 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
11984 (nzero_counts * 100.0) / nsyms);
11985 }
11986 }
11987
11988 free (counts);
11989 free (lengths);
11990 free (gnubuckets);
11991 free (gnuchains);
11992 }
11993
32ec8896 11994 return TRUE;
252b5132
RH
11995}
11996
32ec8896 11997static bfd_boolean
dda8d76d 11998process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 11999{
b4c96d0d 12000 unsigned int i;
252b5132
RH
12001
12002 if (dynamic_syminfo == NULL
12003 || !do_dynamic)
12004 /* No syminfo, this is ok. */
32ec8896 12005 return TRUE;
252b5132
RH
12006
12007 /* There better should be a dynamic symbol section. */
12008 if (dynamic_symbols == NULL || dynamic_strings == NULL)
32ec8896 12009 return FALSE;
252b5132
RH
12010
12011 if (dynamic_addr)
d3a49aa8
AM
12012 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12013 "contains %d entry:\n",
12014 "\nDynamic info segment at offset 0x%lx "
12015 "contains %d entries:\n",
12016 dynamic_syminfo_nent),
252b5132
RH
12017 dynamic_syminfo_offset, dynamic_syminfo_nent);
12018
12019 printf (_(" Num: Name BoundTo Flags\n"));
12020 for (i = 0; i < dynamic_syminfo_nent; ++i)
12021 {
12022 unsigned short int flags = dynamic_syminfo[i].si_flags;
12023
31104126 12024 printf ("%4d: ", i);
4082ef84
NC
12025 if (i >= num_dynamic_syms)
12026 printf (_("<corrupt index>"));
12027 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
12028 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
12029 else
2b692964 12030 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 12031 putchar (' ');
252b5132
RH
12032
12033 switch (dynamic_syminfo[i].si_boundto)
12034 {
12035 case SYMINFO_BT_SELF:
12036 fputs ("SELF ", stdout);
12037 break;
12038 case SYMINFO_BT_PARENT:
12039 fputs ("PARENT ", stdout);
12040 break;
12041 default:
12042 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
12043 && dynamic_syminfo[i].si_boundto < dynamic_nent
12044 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12045 {
d79b3d50 12046 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12047 putchar (' ' );
12048 }
252b5132
RH
12049 else
12050 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
12051 break;
12052 }
12053
12054 if (flags & SYMINFO_FLG_DIRECT)
12055 printf (" DIRECT");
12056 if (flags & SYMINFO_FLG_PASSTHRU)
12057 printf (" PASSTHRU");
12058 if (flags & SYMINFO_FLG_COPY)
12059 printf (" COPY");
12060 if (flags & SYMINFO_FLG_LAZYLOAD)
12061 printf (" LAZYLOAD");
12062
12063 puts ("");
12064 }
12065
32ec8896 12066 return TRUE;
252b5132
RH
12067}
12068
b32e566b
NC
12069#define IN_RANGE(START,END,ADDR,OFF) \
12070 (((ADDR) >= (START)) && ((ADDR) + (OFF) < (END)))
12071
cf13d699
NC
12072/* Check to see if the given reloc needs to be handled in a target specific
12073 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12074 FALSE.
12075
12076 If called with reloc == NULL, then this is a signal that reloc processing
12077 for the current section has finished, and any saved state should be
12078 discarded. */
09c11c86 12079
cf13d699 12080static bfd_boolean
dda8d76d
NC
12081target_specific_reloc_handling (Filedata * filedata,
12082 Elf_Internal_Rela * reloc,
12083 unsigned char * start,
12084 unsigned char * end,
12085 Elf_Internal_Sym * symtab,
12086 unsigned long num_syms)
252b5132 12087{
f84ce13b
NC
12088 unsigned int reloc_type = 0;
12089 unsigned long sym_index = 0;
12090
12091 if (reloc)
12092 {
dda8d76d 12093 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12094 sym_index = get_reloc_symindex (reloc->r_info);
12095 }
252b5132 12096
dda8d76d 12097 switch (filedata->file_header.e_machine)
252b5132 12098 {
13761a11
NC
12099 case EM_MSP430:
12100 case EM_MSP430_OLD:
12101 {
12102 static Elf_Internal_Sym * saved_sym = NULL;
12103
f84ce13b
NC
12104 if (reloc == NULL)
12105 {
12106 saved_sym = NULL;
12107 return TRUE;
12108 }
12109
13761a11
NC
12110 switch (reloc_type)
12111 {
12112 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12113 if (uses_msp430x_relocs (filedata))
13761a11 12114 break;
1a0670f3 12115 /* Fall through. */
13761a11 12116 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12117 /* PR 21139. */
12118 if (sym_index >= num_syms)
12119 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12120 sym_index);
12121 else
12122 saved_sym = symtab + sym_index;
13761a11
NC
12123 return TRUE;
12124
12125 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12126 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12127 goto handle_sym_diff;
0b4362b0 12128
13761a11
NC
12129 case 5: /* R_MSP430_16_BYTE */
12130 case 9: /* R_MSP430_8 */
dda8d76d 12131 if (uses_msp430x_relocs (filedata))
13761a11
NC
12132 break;
12133 goto handle_sym_diff;
12134
12135 case 2: /* R_MSP430_ABS16 */
12136 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12137 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12138 break;
12139 goto handle_sym_diff;
0b4362b0 12140
13761a11
NC
12141 handle_sym_diff:
12142 if (saved_sym != NULL)
12143 {
03f7786e 12144 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12145 bfd_vma value;
12146
f84ce13b
NC
12147 if (sym_index >= num_syms)
12148 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12149 sym_index);
03f7786e 12150 else
f84ce13b
NC
12151 {
12152 value = reloc->r_addend + (symtab[sym_index].st_value
12153 - saved_sym->st_value);
12154
b32e566b 12155 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12156 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12157 else
12158 /* PR 21137 */
12159 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12160 (long) reloc->r_offset);
f84ce13b 12161 }
13761a11
NC
12162
12163 saved_sym = NULL;
12164 return TRUE;
12165 }
12166 break;
12167
12168 default:
12169 if (saved_sym != NULL)
071436c6 12170 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12171 break;
12172 }
12173 break;
12174 }
12175
cf13d699
NC
12176 case EM_MN10300:
12177 case EM_CYGNUS_MN10300:
12178 {
12179 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12180
f84ce13b
NC
12181 if (reloc == NULL)
12182 {
12183 saved_sym = NULL;
12184 return TRUE;
12185 }
12186
cf13d699
NC
12187 switch (reloc_type)
12188 {
12189 case 34: /* R_MN10300_ALIGN */
12190 return TRUE;
12191 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12192 if (sym_index >= num_syms)
12193 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12194 sym_index);
12195 else
12196 saved_sym = symtab + sym_index;
cf13d699 12197 return TRUE;
f84ce13b 12198
cf13d699
NC
12199 case 1: /* R_MN10300_32 */
12200 case 2: /* R_MN10300_16 */
12201 if (saved_sym != NULL)
12202 {
03f7786e 12203 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12204 bfd_vma value;
252b5132 12205
f84ce13b
NC
12206 if (sym_index >= num_syms)
12207 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12208 sym_index);
03f7786e 12209 else
f84ce13b
NC
12210 {
12211 value = reloc->r_addend + (symtab[sym_index].st_value
12212 - saved_sym->st_value);
12213
b32e566b 12214 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12215 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12216 else
12217 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12218 (long) reloc->r_offset);
f84ce13b 12219 }
252b5132 12220
cf13d699
NC
12221 saved_sym = NULL;
12222 return TRUE;
12223 }
12224 break;
12225 default:
12226 if (saved_sym != NULL)
071436c6 12227 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12228 break;
12229 }
12230 break;
12231 }
6ff71e76
NC
12232
12233 case EM_RL78:
12234 {
12235 static bfd_vma saved_sym1 = 0;
12236 static bfd_vma saved_sym2 = 0;
12237 static bfd_vma value;
12238
f84ce13b
NC
12239 if (reloc == NULL)
12240 {
12241 saved_sym1 = saved_sym2 = 0;
12242 return TRUE;
12243 }
12244
6ff71e76
NC
12245 switch (reloc_type)
12246 {
12247 case 0x80: /* R_RL78_SYM. */
12248 saved_sym1 = saved_sym2;
f84ce13b
NC
12249 if (sym_index >= num_syms)
12250 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12251 sym_index);
12252 else
12253 {
12254 saved_sym2 = symtab[sym_index].st_value;
12255 saved_sym2 += reloc->r_addend;
12256 }
6ff71e76
NC
12257 return TRUE;
12258
12259 case 0x83: /* R_RL78_OPsub. */
12260 value = saved_sym1 - saved_sym2;
12261 saved_sym2 = saved_sym1 = 0;
12262 return TRUE;
12263 break;
12264
12265 case 0x41: /* R_RL78_ABS32. */
b32e566b 12266 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12267 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12268 else
12269 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12270 (long) reloc->r_offset);
6ff71e76
NC
12271 value = 0;
12272 return TRUE;
12273
12274 case 0x43: /* R_RL78_ABS16. */
b32e566b 12275 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12276 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12277 else
12278 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12279 (long) reloc->r_offset);
6ff71e76
NC
12280 value = 0;
12281 return TRUE;
12282
12283 default:
12284 break;
12285 }
12286 break;
12287 }
252b5132
RH
12288 }
12289
cf13d699 12290 return FALSE;
252b5132
RH
12291}
12292
aca88567
NC
12293/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12294 DWARF debug sections. This is a target specific test. Note - we do not
12295 go through the whole including-target-headers-multiple-times route, (as
12296 we have already done with <elf/h8.h>) because this would become very
12297 messy and even then this function would have to contain target specific
12298 information (the names of the relocs instead of their numeric values).
12299 FIXME: This is not the correct way to solve this problem. The proper way
12300 is to have target specific reloc sizing and typing functions created by
12301 the reloc-macros.h header, in the same way that it already creates the
12302 reloc naming functions. */
12303
12304static bfd_boolean
dda8d76d 12305is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12306{
d347c9df 12307 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12308 switch (filedata->file_header.e_machine)
aca88567 12309 {
41e92641 12310 case EM_386:
22abe556 12311 case EM_IAMCU:
41e92641 12312 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12313 case EM_68K:
12314 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12315 case EM_860:
12316 return reloc_type == 1; /* R_860_32. */
12317 case EM_960:
12318 return reloc_type == 2; /* R_960_32. */
a06ea964 12319 case EM_AARCH64:
9282b95a
JW
12320 return (reloc_type == 258
12321 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
d347c9df
PS
12322 case EM_ADAPTEVA_EPIPHANY:
12323 return reloc_type == 3;
aca88567 12324 case EM_ALPHA:
137b6b5f 12325 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12326 case EM_ARC:
12327 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12328 case EM_ARC_COMPACT:
12329 case EM_ARC_COMPACT2:
12330 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12331 case EM_ARM:
12332 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12333 case EM_AVR_OLD:
aca88567
NC
12334 case EM_AVR:
12335 return reloc_type == 1;
12336 case EM_BLACKFIN:
12337 return reloc_type == 0x12; /* R_byte4_data. */
12338 case EM_CRIS:
12339 return reloc_type == 3; /* R_CRIS_32. */
12340 case EM_CR16:
12341 return reloc_type == 3; /* R_CR16_NUM32. */
12342 case EM_CRX:
12343 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
12344 case EM_CSKY:
12345 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
12346 case EM_CYGNUS_FRV:
12347 return reloc_type == 1;
41e92641
NC
12348 case EM_CYGNUS_D10V:
12349 case EM_D10V:
12350 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12351 case EM_CYGNUS_D30V:
12352 case EM_D30V:
12353 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12354 case EM_DLX:
12355 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12356 case EM_CYGNUS_FR30:
12357 case EM_FR30:
12358 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12359 case EM_FT32:
12360 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12361 case EM_H8S:
12362 case EM_H8_300:
12363 case EM_H8_300H:
12364 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12365 case EM_IA_64:
262cdac7
AM
12366 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12367 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12368 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12369 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12370 case EM_IP2K_OLD:
12371 case EM_IP2K:
12372 return reloc_type == 2; /* R_IP2K_32. */
12373 case EM_IQ2000:
12374 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12375 case EM_LATTICEMICO32:
12376 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12377 case EM_M32C_OLD:
aca88567
NC
12378 case EM_M32C:
12379 return reloc_type == 3; /* R_M32C_32. */
12380 case EM_M32R:
12381 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12382 case EM_68HC11:
12383 case EM_68HC12:
12384 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824
JD
12385 case EM_S12Z:
12386 return reloc_type == 6; /* R_S12Z_EXT32. */
aca88567
NC
12387 case EM_MCORE:
12388 return reloc_type == 1; /* R_MCORE_ADDR32. */
12389 case EM_CYGNUS_MEP:
12390 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12391 case EM_METAG:
12392 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12393 case EM_MICROBLAZE:
12394 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12395 case EM_MIPS:
12396 return reloc_type == 2; /* R_MIPS_32. */
12397 case EM_MMIX:
12398 return reloc_type == 4; /* R_MMIX_32. */
12399 case EM_CYGNUS_MN10200:
12400 case EM_MN10200:
12401 return reloc_type == 1; /* R_MN10200_32. */
12402 case EM_CYGNUS_MN10300:
12403 case EM_MN10300:
12404 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12405 case EM_MOXIE:
12406 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12407 case EM_MSP430_OLD:
12408 case EM_MSP430:
13761a11 12409 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12410 case EM_MT:
12411 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12412 case EM_NDS32:
12413 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12414 case EM_ALTERA_NIOS2:
36591ba1 12415 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12416 case EM_NIOS32:
12417 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12418 case EM_OR1K:
12419 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12420 case EM_PARISC:
0df8ad28
NC
12421 return (reloc_type == 1 /* R_PARISC_DIR32. */
12422 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12423 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12424 case EM_PJ:
12425 case EM_PJ_OLD:
12426 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12427 case EM_PPC64:
12428 return reloc_type == 1; /* R_PPC64_ADDR32. */
12429 case EM_PPC:
12430 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12431 case EM_TI_PRU:
12432 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12433 case EM_RISCV:
12434 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12435 case EM_RL78:
12436 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12437 case EM_RX:
12438 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12439 case EM_S370:
12440 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12441 case EM_S390_OLD:
12442 case EM_S390:
12443 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12444 case EM_SCORE:
12445 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12446 case EM_SH:
12447 return reloc_type == 1; /* R_SH_DIR32. */
12448 case EM_SPARC32PLUS:
12449 case EM_SPARCV9:
12450 case EM_SPARC:
12451 return reloc_type == 3 /* R_SPARC_32. */
12452 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12453 case EM_SPU:
12454 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12455 case EM_TI_C6000:
12456 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12457 case EM_TILEGX:
12458 return reloc_type == 2; /* R_TILEGX_32. */
12459 case EM_TILEPRO:
12460 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12461 case EM_CYGNUS_V850:
12462 case EM_V850:
12463 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12464 case EM_V800:
12465 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12466 case EM_VAX:
12467 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12468 case EM_VISIUM:
12469 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12470 case EM_WEBASSEMBLY:
12471 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12472 case EM_X86_64:
8a9036a4 12473 case EM_L1OM:
7a9068fe 12474 case EM_K1OM:
aca88567 12475 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12476 case EM_XC16X:
12477 case EM_C166:
12478 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12479 case EM_XGATE:
12480 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12481 case EM_XSTORMY16:
12482 return reloc_type == 1; /* R_XSTROMY16_32. */
12483 case EM_XTENSA_OLD:
12484 case EM_XTENSA:
12485 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 12486 default:
bee0ee85
NC
12487 {
12488 static unsigned int prev_warn = 0;
12489
12490 /* Avoid repeating the same warning multiple times. */
dda8d76d 12491 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12492 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12493 filedata->file_header.e_machine);
12494 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12495 return FALSE;
12496 }
aca88567
NC
12497 }
12498}
12499
12500/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12501 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12502
12503static bfd_boolean
dda8d76d 12504is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12505{
dda8d76d 12506 switch (filedata->file_header.e_machine)
d347c9df 12507 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12508 {
41e92641 12509 case EM_386:
22abe556 12510 case EM_IAMCU:
3e0873ac 12511 return reloc_type == 2; /* R_386_PC32. */
aca88567 12512 case EM_68K:
3e0873ac 12513 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12514 case EM_AARCH64:
12515 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12516 case EM_ADAPTEVA_EPIPHANY:
12517 return reloc_type == 6;
aca88567
NC
12518 case EM_ALPHA:
12519 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12520 case EM_ARC_COMPACT:
12521 case EM_ARC_COMPACT2:
12522 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12523 case EM_ARM:
3e0873ac 12524 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12525 case EM_AVR_OLD:
12526 case EM_AVR:
12527 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12528 case EM_MICROBLAZE:
12529 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12530 case EM_OR1K:
12531 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 12532 case EM_PARISC:
85acf597 12533 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
12534 case EM_PPC:
12535 return reloc_type == 26; /* R_PPC_REL32. */
12536 case EM_PPC64:
3e0873ac 12537 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
12538 case EM_S390_OLD:
12539 case EM_S390:
3e0873ac 12540 return reloc_type == 5; /* R_390_PC32. */
aca88567 12541 case EM_SH:
3e0873ac 12542 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
12543 case EM_SPARC32PLUS:
12544 case EM_SPARCV9:
12545 case EM_SPARC:
3e0873ac 12546 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
12547 case EM_SPU:
12548 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
12549 case EM_TILEGX:
12550 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
12551 case EM_TILEPRO:
12552 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
12553 case EM_VISIUM:
12554 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 12555 case EM_X86_64:
8a9036a4 12556 case EM_L1OM:
7a9068fe 12557 case EM_K1OM:
3e0873ac 12558 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
12559 case EM_XTENSA_OLD:
12560 case EM_XTENSA:
12561 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
12562 default:
12563 /* Do not abort or issue an error message here. Not all targets use
12564 pc-relative 32-bit relocs in their DWARF debug information and we
12565 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
12566 more helpful warning message will be generated by apply_relocations
12567 anyway, so just return. */
aca88567
NC
12568 return FALSE;
12569 }
12570}
12571
12572/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12573 a 64-bit absolute RELA relocation used in DWARF debug sections. */
12574
12575static bfd_boolean
dda8d76d 12576is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12577{
dda8d76d 12578 switch (filedata->file_header.e_machine)
aca88567 12579 {
a06ea964
NC
12580 case EM_AARCH64:
12581 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
12582 case EM_ALPHA:
12583 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 12584 case EM_IA_64:
262cdac7
AM
12585 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
12586 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
12587 case EM_PARISC:
12588 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
12589 case EM_PPC64:
12590 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
12591 case EM_RISCV:
12592 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
12593 case EM_SPARC32PLUS:
12594 case EM_SPARCV9:
12595 case EM_SPARC:
714da62f
NC
12596 return reloc_type == 32 /* R_SPARC_64. */
12597 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 12598 case EM_X86_64:
8a9036a4 12599 case EM_L1OM:
7a9068fe 12600 case EM_K1OM:
aca88567 12601 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
12602 case EM_S390_OLD:
12603 case EM_S390:
aa137e4d
NC
12604 return reloc_type == 22; /* R_S390_64. */
12605 case EM_TILEGX:
12606 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 12607 case EM_MIPS:
aa137e4d 12608 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
12609 default:
12610 return FALSE;
12611 }
12612}
12613
85acf597
RH
12614/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
12615 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
12616
12617static bfd_boolean
dda8d76d 12618is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 12619{
dda8d76d 12620 switch (filedata->file_header.e_machine)
85acf597 12621 {
a06ea964
NC
12622 case EM_AARCH64:
12623 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 12624 case EM_ALPHA:
aa137e4d 12625 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 12626 case EM_IA_64:
262cdac7
AM
12627 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
12628 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 12629 case EM_PARISC:
aa137e4d 12630 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 12631 case EM_PPC64:
aa137e4d 12632 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
12633 case EM_SPARC32PLUS:
12634 case EM_SPARCV9:
12635 case EM_SPARC:
aa137e4d 12636 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 12637 case EM_X86_64:
8a9036a4 12638 case EM_L1OM:
7a9068fe 12639 case EM_K1OM:
aa137e4d 12640 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
12641 case EM_S390_OLD:
12642 case EM_S390:
aa137e4d
NC
12643 return reloc_type == 23; /* R_S390_PC64. */
12644 case EM_TILEGX:
12645 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
12646 default:
12647 return FALSE;
12648 }
12649}
12650
4dc3c23d
AM
12651/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12652 a 24-bit absolute RELA relocation used in DWARF debug sections. */
12653
12654static bfd_boolean
dda8d76d 12655is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 12656{
dda8d76d 12657 switch (filedata->file_header.e_machine)
4dc3c23d
AM
12658 {
12659 case EM_CYGNUS_MN10200:
12660 case EM_MN10200:
12661 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
12662 case EM_FT32:
12663 return reloc_type == 5; /* R_FT32_20. */
4dc3c23d
AM
12664 default:
12665 return FALSE;
12666 }
12667}
12668
aca88567
NC
12669/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12670 a 16-bit absolute RELA relocation used in DWARF debug sections. */
12671
12672static bfd_boolean
dda8d76d 12673is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 12674{
d347c9df 12675 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12676 switch (filedata->file_header.e_machine)
4b78141a 12677 {
886a2506
NC
12678 case EM_ARC:
12679 case EM_ARC_COMPACT:
12680 case EM_ARC_COMPACT2:
12681 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
12682 case EM_ADAPTEVA_EPIPHANY:
12683 return reloc_type == 5;
aca88567
NC
12684 case EM_AVR_OLD:
12685 case EM_AVR:
12686 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
12687 case EM_CYGNUS_D10V:
12688 case EM_D10V:
12689 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
12690 case EM_FT32:
12691 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
12692 case EM_H8S:
12693 case EM_H8_300:
12694 case EM_H8_300H:
aca88567
NC
12695 return reloc_type == R_H8_DIR16;
12696 case EM_IP2K_OLD:
12697 case EM_IP2K:
12698 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 12699 case EM_M32C_OLD:
f4236fe4
DD
12700 case EM_M32C:
12701 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
12702 case EM_CYGNUS_MN10200:
12703 case EM_MN10200:
12704 return reloc_type == 2; /* R_MN10200_16. */
12705 case EM_CYGNUS_MN10300:
12706 case EM_MN10300:
12707 return reloc_type == 2; /* R_MN10300_16. */
aca88567 12708 case EM_MSP430:
dda8d76d 12709 if (uses_msp430x_relocs (filedata))
13761a11 12710 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 12711 /* Fall through. */
78c8d46c 12712 case EM_MSP430_OLD:
aca88567 12713 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
12714 case EM_NDS32:
12715 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 12716 case EM_ALTERA_NIOS2:
36591ba1 12717 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
12718 case EM_NIOS32:
12719 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
12720 case EM_OR1K:
12721 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
12722 case EM_RISCV:
12723 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
12724 case EM_TI_PRU:
12725 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
12726 case EM_TI_C6000:
12727 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
12728 case EM_VISIUM:
12729 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
12730 case EM_XC16X:
12731 case EM_C166:
12732 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
12733 case EM_XGATE:
12734 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 12735 default:
aca88567 12736 return FALSE;
4b78141a
NC
12737 }
12738}
12739
39e07931
AS
12740/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12741 a 8-bit absolute RELA relocation used in DWARF debug sections. */
12742
12743static bfd_boolean
12744is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
12745{
12746 switch (filedata->file_header.e_machine)
12747 {
12748 case EM_RISCV:
12749 return reloc_type == 54; /* R_RISCV_SET8. */
12750 default:
12751 return FALSE;
12752 }
12753}
12754
12755/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12756 a 6-bit absolute RELA relocation used in DWARF debug sections. */
12757
12758static bfd_boolean
12759is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
12760{
12761 switch (filedata->file_header.e_machine)
12762 {
12763 case EM_RISCV:
12764 return reloc_type == 53; /* R_RISCV_SET6. */
12765 default:
12766 return FALSE;
12767 }
12768}
12769
03336641
JW
12770/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12771 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
12772
12773static bfd_boolean
12774is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12775{
12776 /* Please keep this table alpha-sorted for ease of visual lookup. */
12777 switch (filedata->file_header.e_machine)
12778 {
12779 case EM_RISCV:
12780 return reloc_type == 35; /* R_RISCV_ADD32. */
12781 default:
12782 return FALSE;
12783 }
12784}
12785
12786/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12787 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
12788
12789static bfd_boolean
12790is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12791{
12792 /* Please keep this table alpha-sorted for ease of visual lookup. */
12793 switch (filedata->file_header.e_machine)
12794 {
12795 case EM_RISCV:
12796 return reloc_type == 39; /* R_RISCV_SUB32. */
12797 default:
12798 return FALSE;
12799 }
12800}
12801
12802/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12803 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
12804
12805static bfd_boolean
12806is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12807{
12808 /* Please keep this table alpha-sorted for ease of visual lookup. */
12809 switch (filedata->file_header.e_machine)
12810 {
12811 case EM_RISCV:
12812 return reloc_type == 36; /* R_RISCV_ADD64. */
12813 default:
12814 return FALSE;
12815 }
12816}
12817
12818/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12819 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
12820
12821static bfd_boolean
12822is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12823{
12824 /* Please keep this table alpha-sorted for ease of visual lookup. */
12825 switch (filedata->file_header.e_machine)
12826 {
12827 case EM_RISCV:
12828 return reloc_type == 40; /* R_RISCV_SUB64. */
12829 default:
12830 return FALSE;
12831 }
12832}
12833
12834/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12835 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
12836
12837static bfd_boolean
12838is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12839{
12840 /* Please keep this table alpha-sorted for ease of visual lookup. */
12841 switch (filedata->file_header.e_machine)
12842 {
12843 case EM_RISCV:
12844 return reloc_type == 34; /* R_RISCV_ADD16. */
12845 default:
12846 return FALSE;
12847 }
12848}
12849
12850/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12851 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
12852
12853static bfd_boolean
12854is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12855{
12856 /* Please keep this table alpha-sorted for ease of visual lookup. */
12857 switch (filedata->file_header.e_machine)
12858 {
12859 case EM_RISCV:
12860 return reloc_type == 38; /* R_RISCV_SUB16. */
12861 default:
12862 return FALSE;
12863 }
12864}
12865
12866/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12867 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
12868
12869static bfd_boolean
12870is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12871{
12872 /* Please keep this table alpha-sorted for ease of visual lookup. */
12873 switch (filedata->file_header.e_machine)
12874 {
12875 case EM_RISCV:
12876 return reloc_type == 33; /* R_RISCV_ADD8. */
12877 default:
12878 return FALSE;
12879 }
12880}
12881
12882/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12883 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
12884
12885static bfd_boolean
12886is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12887{
12888 /* Please keep this table alpha-sorted for ease of visual lookup. */
12889 switch (filedata->file_header.e_machine)
12890 {
12891 case EM_RISCV:
12892 return reloc_type == 37; /* R_RISCV_SUB8. */
12893 default:
12894 return FALSE;
12895 }
12896}
12897
39e07931
AS
12898/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12899 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
12900
12901static bfd_boolean
12902is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12903{
12904 switch (filedata->file_header.e_machine)
12905 {
12906 case EM_RISCV:
12907 return reloc_type == 52; /* R_RISCV_SUB6. */
12908 default:
12909 return FALSE;
12910 }
12911}
12912
2a7b2e88
JK
12913/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
12914 relocation entries (possibly formerly used for SHT_GROUP sections). */
12915
12916static bfd_boolean
dda8d76d 12917is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 12918{
dda8d76d 12919 switch (filedata->file_header.e_machine)
2a7b2e88 12920 {
cb8f3167 12921 case EM_386: /* R_386_NONE. */
d347c9df 12922 case EM_68K: /* R_68K_NONE. */
cfb8c092 12923 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
12924 case EM_ALPHA: /* R_ALPHA_NONE. */
12925 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 12926 case EM_ARC: /* R_ARC_NONE. */
886a2506 12927 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 12928 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 12929 case EM_ARM: /* R_ARM_NONE. */
d347c9df 12930 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 12931 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
12932 case EM_FT32: /* R_FT32_NONE. */
12933 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 12934 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
12935 case EM_L1OM: /* R_X86_64_NONE. */
12936 case EM_M32R: /* R_M32R_NONE. */
12937 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 12938 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 12939 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
12940 case EM_NIOS32: /* R_NIOS_NONE. */
12941 case EM_OR1K: /* R_OR1K_NONE. */
12942 case EM_PARISC: /* R_PARISC_NONE. */
12943 case EM_PPC64: /* R_PPC64_NONE. */
12944 case EM_PPC: /* R_PPC_NONE. */
e23eba97 12945 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
12946 case EM_S390: /* R_390_NONE. */
12947 case EM_S390_OLD:
12948 case EM_SH: /* R_SH_NONE. */
12949 case EM_SPARC32PLUS:
12950 case EM_SPARC: /* R_SPARC_NONE. */
12951 case EM_SPARCV9:
aa137e4d
NC
12952 case EM_TILEGX: /* R_TILEGX_NONE. */
12953 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
12954 case EM_TI_C6000:/* R_C6000_NONE. */
12955 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 12956 case EM_XC16X:
f96bd6c2 12957 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 12958 return reloc_type == 0;
d347c9df 12959
a06ea964
NC
12960 case EM_AARCH64:
12961 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
12962 case EM_AVR_OLD:
12963 case EM_AVR:
12964 return (reloc_type == 0 /* R_AVR_NONE. */
12965 || reloc_type == 30 /* R_AVR_DIFF8. */
12966 || reloc_type == 31 /* R_AVR_DIFF16. */
12967 || reloc_type == 32 /* R_AVR_DIFF32. */);
12968 case EM_METAG:
12969 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
12970 case EM_NDS32:
12971 return (reloc_type == 0 /* R_XTENSA_NONE. */
12972 || reloc_type == 204 /* R_NDS32_DIFF8. */
12973 || reloc_type == 205 /* R_NDS32_DIFF16. */
12974 || reloc_type == 206 /* R_NDS32_DIFF32. */
12975 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
12976 case EM_TI_PRU:
12977 return (reloc_type == 0 /* R_PRU_NONE. */
12978 || reloc_type == 65 /* R_PRU_DIFF8. */
12979 || reloc_type == 66 /* R_PRU_DIFF16. */
12980 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
12981 case EM_XTENSA_OLD:
12982 case EM_XTENSA:
4dc3c23d
AM
12983 return (reloc_type == 0 /* R_XTENSA_NONE. */
12984 || reloc_type == 17 /* R_XTENSA_DIFF8. */
12985 || reloc_type == 18 /* R_XTENSA_DIFF16. */
12986 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
12987 }
12988 return FALSE;
12989}
12990
d1c4b12b
NC
12991/* Returns TRUE if there is a relocation against
12992 section NAME at OFFSET bytes. */
12993
12994bfd_boolean
12995reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
12996{
12997 Elf_Internal_Rela * relocs;
12998 Elf_Internal_Rela * rp;
12999
13000 if (dsec == NULL || dsec->reloc_info == NULL)
13001 return FALSE;
13002
13003 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13004
13005 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13006 if (rp->r_offset == offset)
13007 return TRUE;
13008
13009 return FALSE;
13010}
13011
cf13d699 13012/* Apply relocations to a section.
32ec8896
NC
13013 Returns TRUE upon success, FALSE otherwise.
13014 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13015 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13016 will be set to the number of relocs loaded.
13017
cf13d699 13018 Note: So far support has been added only for those relocations
32ec8896
NC
13019 which can be found in debug sections. FIXME: Add support for
13020 more relocations ? */
1b315056 13021
32ec8896 13022static bfd_boolean
dda8d76d 13023apply_relocations (Filedata * filedata,
d1c4b12b
NC
13024 const Elf_Internal_Shdr * section,
13025 unsigned char * start,
13026 bfd_size_type size,
1449284b 13027 void ** relocs_return,
d1c4b12b 13028 unsigned long * num_relocs_return)
1b315056 13029{
cf13d699 13030 Elf_Internal_Shdr * relsec;
0d2a7a93 13031 unsigned char * end = start + size;
32ec8896 13032 bfd_boolean res = TRUE;
cb8f3167 13033
d1c4b12b
NC
13034 if (relocs_return != NULL)
13035 {
13036 * (Elf_Internal_Rela **) relocs_return = NULL;
13037 * num_relocs_return = 0;
13038 }
13039
dda8d76d 13040 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13041 /* No relocs to apply. */
13042 return TRUE;
1b315056 13043
cf13d699 13044 /* Find the reloc section associated with the section. */
dda8d76d
NC
13045 for (relsec = filedata->section_headers;
13046 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13047 ++relsec)
252b5132 13048 {
41e92641
NC
13049 bfd_boolean is_rela;
13050 unsigned long num_relocs;
2cf0635d
NC
13051 Elf_Internal_Rela * relocs;
13052 Elf_Internal_Rela * rp;
13053 Elf_Internal_Shdr * symsec;
13054 Elf_Internal_Sym * symtab;
ba5cdace 13055 unsigned long num_syms;
2cf0635d 13056 Elf_Internal_Sym * sym;
252b5132 13057
41e92641 13058 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13059 || relsec->sh_info >= filedata->file_header.e_shnum
13060 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13061 || relsec->sh_size == 0
dda8d76d 13062 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13063 continue;
428409d5 13064
41e92641
NC
13065 is_rela = relsec->sh_type == SHT_RELA;
13066
13067 if (is_rela)
13068 {
dda8d76d 13069 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13070 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13071 return FALSE;
41e92641
NC
13072 }
13073 else
13074 {
dda8d76d 13075 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13076 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13077 return FALSE;
41e92641
NC
13078 }
13079
13080 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13081 if (filedata->file_header.e_machine == EM_SH)
41e92641 13082 is_rela = FALSE;
428409d5 13083
dda8d76d 13084 symsec = filedata->section_headers + relsec->sh_link;
1449284b
NC
13085 if (symsec->sh_type != SHT_SYMTAB
13086 && symsec->sh_type != SHT_DYNSYM)
32ec8896 13087 return FALSE;
dda8d76d 13088 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13089
41e92641 13090 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13091 {
41e92641
NC
13092 bfd_vma addend;
13093 unsigned int reloc_type;
13094 unsigned int reloc_size;
03336641
JW
13095 bfd_boolean reloc_inplace = FALSE;
13096 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13097 unsigned char * rloc;
ba5cdace 13098 unsigned long sym_index;
4b78141a 13099
dda8d76d 13100 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13101
dda8d76d 13102 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13103 continue;
dda8d76d 13104 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13105 continue;
dda8d76d
NC
13106 else if (is_32bit_abs_reloc (filedata, reloc_type)
13107 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13108 reloc_size = 4;
dda8d76d
NC
13109 else if (is_64bit_abs_reloc (filedata, reloc_type)
13110 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13111 reloc_size = 8;
dda8d76d 13112 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13113 reloc_size = 3;
dda8d76d 13114 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13115 reloc_size = 2;
39e07931
AS
13116 else if (is_8bit_abs_reloc (filedata, reloc_type)
13117 || is_6bit_abs_reloc (filedata, reloc_type))
13118 reloc_size = 1;
03336641
JW
13119 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13120 reloc_type))
13121 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13122 {
13123 reloc_size = 4;
13124 reloc_inplace = TRUE;
13125 }
13126 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13127 reloc_type))
13128 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13129 {
13130 reloc_size = 8;
13131 reloc_inplace = TRUE;
13132 }
13133 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13134 reloc_type))
13135 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13136 {
13137 reloc_size = 2;
13138 reloc_inplace = TRUE;
13139 }
13140 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13141 reloc_type))
13142 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13143 {
13144 reloc_size = 1;
13145 reloc_inplace = TRUE;
13146 }
39e07931
AS
13147 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13148 reloc_type)))
13149 {
13150 reloc_size = 1;
13151 reloc_inplace = TRUE;
13152 }
aca88567 13153 else
4b78141a 13154 {
bee0ee85 13155 static unsigned int prev_reloc = 0;
dda8d76d 13156
bee0ee85
NC
13157 if (reloc_type != prev_reloc)
13158 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13159 reloc_type, printable_section_name (filedata, section));
bee0ee85 13160 prev_reloc = reloc_type;
32ec8896 13161 res = FALSE;
4b78141a
NC
13162 continue;
13163 }
103f02d3 13164
91d6fa6a 13165 rloc = start + rp->r_offset;
c8da6823 13166 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
13167 {
13168 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13169 (unsigned long) rp->r_offset,
dda8d76d 13170 printable_section_name (filedata, section));
32ec8896 13171 res = FALSE;
700dd8b7
L
13172 continue;
13173 }
103f02d3 13174
ba5cdace
NC
13175 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13176 if (sym_index >= num_syms)
13177 {
13178 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13179 sym_index, printable_section_name (filedata, section));
32ec8896 13180 res = FALSE;
ba5cdace
NC
13181 continue;
13182 }
13183 sym = symtab + sym_index;
41e92641
NC
13184
13185 /* If the reloc has a symbol associated with it,
55f25fc3
L
13186 make sure that it is of an appropriate type.
13187
13188 Relocations against symbols without type can happen.
13189 Gcc -feliminate-dwarf2-dups may generate symbols
13190 without type for debug info.
13191
13192 Icc generates relocations against function symbols
13193 instead of local labels.
13194
13195 Relocations against object symbols can happen, eg when
13196 referencing a global array. For an example of this see
13197 the _clz.o binary in libgcc.a. */
aca88567 13198 if (sym != symtab
b8871f35 13199 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13200 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13201 {
d3a49aa8 13202 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13203 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13204 printable_section_name (filedata, relsec),
d3a49aa8 13205 (long int)(rp - relocs));
32ec8896 13206 res = FALSE;
aca88567 13207 continue;
5b18a4bc 13208 }
252b5132 13209
4dc3c23d
AM
13210 addend = 0;
13211 if (is_rela)
13212 addend += rp->r_addend;
c47320c3
AM
13213 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13214 partial_inplace. */
4dc3c23d 13215 if (!is_rela
dda8d76d 13216 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13217 && reloc_type == 1)
dda8d76d
NC
13218 || ((filedata->file_header.e_machine == EM_PJ
13219 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13220 && reloc_type == 1)
dda8d76d
NC
13221 || ((filedata->file_header.e_machine == EM_D30V
13222 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13223 && reloc_type == 12)
13224 || reloc_inplace)
39e07931
AS
13225 {
13226 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
13227 addend += byte_get (rloc, reloc_size) & 0x3f;
13228 else
13229 addend += byte_get (rloc, reloc_size);
13230 }
cb8f3167 13231
dda8d76d
NC
13232 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13233 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13234 {
13235 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13236 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13237 addend -= 8;
91d6fa6a 13238 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13239 reloc_size);
13240 }
39e07931
AS
13241 else if (is_6bit_abs_reloc (filedata, reloc_type)
13242 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
13243 {
13244 if (reloc_subtract)
13245 addend -= sym->st_value;
13246 else
13247 addend += sym->st_value;
13248 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
13249 byte_put (rloc, addend, reloc_size);
13250 }
03336641
JW
13251 else if (reloc_subtract)
13252 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13253 else
91d6fa6a 13254 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13255 }
252b5132 13256
5b18a4bc 13257 free (symtab);
f84ce13b
NC
13258 /* Let the target specific reloc processing code know that
13259 we have finished with these relocs. */
dda8d76d 13260 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13261
13262 if (relocs_return)
13263 {
13264 * (Elf_Internal_Rela **) relocs_return = relocs;
13265 * num_relocs_return = num_relocs;
13266 }
13267 else
13268 free (relocs);
13269
5b18a4bc
NC
13270 break;
13271 }
32ec8896
NC
13272
13273 return res;
5b18a4bc 13274}
103f02d3 13275
cf13d699 13276#ifdef SUPPORT_DISASSEMBLY
32ec8896 13277static bfd_boolean
dda8d76d 13278disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13279{
dda8d76d 13280 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13281
74e1a04b 13282 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13283
32ec8896 13284 return TRUE;
cf13d699
NC
13285}
13286#endif
13287
13288/* Reads in the contents of SECTION from FILE, returning a pointer
13289 to a malloc'ed buffer or NULL if something went wrong. */
13290
13291static char *
dda8d76d 13292get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13293{
dda8d76d 13294 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13295
13296 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13297 {
c6b78c96 13298 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13299 printable_section_name (filedata, section));
cf13d699
NC
13300 return NULL;
13301 }
13302
dda8d76d 13303 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13304 _("section contents"));
cf13d699
NC
13305}
13306
0e602686
NC
13307/* Uncompresses a section that was compressed using zlib, in place. */
13308
13309static bfd_boolean
dda8d76d
NC
13310uncompress_section_contents (unsigned char ** buffer,
13311 dwarf_size_type uncompressed_size,
13312 dwarf_size_type * size)
0e602686
NC
13313{
13314 dwarf_size_type compressed_size = *size;
13315 unsigned char * compressed_buffer = *buffer;
13316 unsigned char * uncompressed_buffer;
13317 z_stream strm;
13318 int rc;
13319
13320 /* It is possible the section consists of several compressed
13321 buffers concatenated together, so we uncompress in a loop. */
13322 /* PR 18313: The state field in the z_stream structure is supposed
13323 to be invisible to the user (ie us), but some compilers will
13324 still complain about it being used without initialisation. So
13325 we first zero the entire z_stream structure and then set the fields
13326 that we need. */
13327 memset (& strm, 0, sizeof strm);
13328 strm.avail_in = compressed_size;
13329 strm.next_in = (Bytef *) compressed_buffer;
13330 strm.avail_out = uncompressed_size;
13331 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13332
13333 rc = inflateInit (& strm);
13334 while (strm.avail_in > 0)
13335 {
13336 if (rc != Z_OK)
13337 goto fail;
13338 strm.next_out = ((Bytef *) uncompressed_buffer
13339 + (uncompressed_size - strm.avail_out));
13340 rc = inflate (&strm, Z_FINISH);
13341 if (rc != Z_STREAM_END)
13342 goto fail;
13343 rc = inflateReset (& strm);
13344 }
13345 rc = inflateEnd (& strm);
13346 if (rc != Z_OK
13347 || strm.avail_out != 0)
13348 goto fail;
13349
13350 *buffer = uncompressed_buffer;
13351 *size = uncompressed_size;
13352 return TRUE;
13353
13354 fail:
13355 free (uncompressed_buffer);
13356 /* Indicate decompression failure. */
13357 *buffer = NULL;
13358 return FALSE;
13359}
dd24e3da 13360
32ec8896 13361static bfd_boolean
dda8d76d 13362dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13363{
0e602686
NC
13364 Elf_Internal_Shdr * relsec;
13365 bfd_size_type num_bytes;
fd8008d8
L
13366 unsigned char * data;
13367 unsigned char * end;
13368 unsigned char * real_start;
13369 unsigned char * start;
0e602686 13370 bfd_boolean some_strings_shown;
cf13d699 13371
dda8d76d 13372 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13373 if (start == NULL)
c6b78c96
NC
13374 /* PR 21820: Do not fail if the section was empty. */
13375 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13376
0e602686 13377 num_bytes = section->sh_size;
cf13d699 13378
dda8d76d 13379 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13380
0e602686
NC
13381 if (decompress_dumps)
13382 {
13383 dwarf_size_type new_size = num_bytes;
13384 dwarf_size_type uncompressed_size = 0;
13385
13386 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13387 {
13388 Elf_Internal_Chdr chdr;
13389 unsigned int compression_header_size
ebdf1ebf
NC
13390 = get_compression_header (& chdr, (unsigned char *) start,
13391 num_bytes);
0e602686 13392
813dabb9 13393 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13394 {
813dabb9 13395 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13396 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13397 return FALSE;
813dabb9
L
13398 }
13399 else if (chdr.ch_addralign != section->sh_addralign)
13400 {
13401 warn (_("compressed section '%s' is corrupted\n"),
dda8d76d 13402 printable_section_name (filedata, section));
32ec8896 13403 return FALSE;
0e602686 13404 }
813dabb9
L
13405 uncompressed_size = chdr.ch_size;
13406 start += compression_header_size;
13407 new_size -= compression_header_size;
0e602686
NC
13408 }
13409 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13410 {
13411 /* Read the zlib header. In this case, it should be "ZLIB"
13412 followed by the uncompressed section size, 8 bytes in
13413 big-endian order. */
13414 uncompressed_size = start[4]; uncompressed_size <<= 8;
13415 uncompressed_size += start[5]; uncompressed_size <<= 8;
13416 uncompressed_size += start[6]; uncompressed_size <<= 8;
13417 uncompressed_size += start[7]; uncompressed_size <<= 8;
13418 uncompressed_size += start[8]; uncompressed_size <<= 8;
13419 uncompressed_size += start[9]; uncompressed_size <<= 8;
13420 uncompressed_size += start[10]; uncompressed_size <<= 8;
13421 uncompressed_size += start[11];
13422 start += 12;
13423 new_size -= 12;
13424 }
13425
1835f746
NC
13426 if (uncompressed_size)
13427 {
13428 if (uncompress_section_contents (& start,
13429 uncompressed_size, & new_size))
13430 num_bytes = new_size;
13431 else
13432 {
13433 error (_("Unable to decompress section %s\n"),
dda8d76d 13434 printable_section_name (filedata, section));
32ec8896 13435 return FALSE;
1835f746
NC
13436 }
13437 }
bc303e5d
NC
13438 else
13439 start = real_start;
0e602686 13440 }
fd8008d8 13441
cf13d699
NC
13442 /* If the section being dumped has relocations against it the user might
13443 be expecting these relocations to have been applied. Check for this
13444 case and issue a warning message in order to avoid confusion.
13445 FIXME: Maybe we ought to have an option that dumps a section with
13446 relocs applied ? */
dda8d76d
NC
13447 for (relsec = filedata->section_headers;
13448 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13449 ++relsec)
13450 {
13451 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13452 || relsec->sh_info >= filedata->file_header.e_shnum
13453 || filedata->section_headers + relsec->sh_info != section
cf13d699 13454 || relsec->sh_size == 0
dda8d76d 13455 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13456 continue;
13457
13458 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13459 break;
13460 }
13461
cf13d699
NC
13462 data = start;
13463 end = start + num_bytes;
13464 some_strings_shown = FALSE;
13465
13466 while (data < end)
13467 {
13468 while (!ISPRINT (* data))
13469 if (++ data >= end)
13470 break;
13471
13472 if (data < end)
13473 {
071436c6
NC
13474 size_t maxlen = end - data;
13475
cf13d699 13476#ifndef __MSVCRT__
c975cc98
NC
13477 /* PR 11128: Use two separate invocations in order to work
13478 around bugs in the Solaris 8 implementation of printf. */
13479 printf (" [%6tx] ", data - start);
cf13d699 13480#else
071436c6 13481 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 13482#endif
4082ef84
NC
13483 if (maxlen > 0)
13484 {
fd8008d8 13485 print_symbol ((int) maxlen, (const char *) data);
4082ef84 13486 putchar ('\n');
fd8008d8 13487 data += strnlen ((const char *) data, maxlen);
4082ef84
NC
13488 }
13489 else
13490 {
13491 printf (_("<corrupt>\n"));
13492 data = end;
13493 }
cf13d699
NC
13494 some_strings_shown = TRUE;
13495 }
13496 }
13497
13498 if (! some_strings_shown)
13499 printf (_(" No strings found in this section."));
13500
0e602686 13501 free (real_start);
cf13d699
NC
13502
13503 putchar ('\n');
32ec8896 13504 return TRUE;
cf13d699
NC
13505}
13506
32ec8896 13507static bfd_boolean
dda8d76d
NC
13508dump_section_as_bytes (Elf_Internal_Shdr * section,
13509 Filedata * filedata,
13510 bfd_boolean relocate)
cf13d699
NC
13511{
13512 Elf_Internal_Shdr * relsec;
0e602686
NC
13513 bfd_size_type bytes;
13514 bfd_size_type section_size;
13515 bfd_vma addr;
13516 unsigned char * data;
13517 unsigned char * real_start;
13518 unsigned char * start;
13519
dda8d76d 13520 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13521 if (start == NULL)
c6b78c96
NC
13522 /* PR 21820: Do not fail if the section was empty. */
13523 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 13524
0e602686 13525 section_size = section->sh_size;
cf13d699 13526
dda8d76d 13527 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13528
0e602686
NC
13529 if (decompress_dumps)
13530 {
13531 dwarf_size_type new_size = section_size;
13532 dwarf_size_type uncompressed_size = 0;
13533
13534 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13535 {
13536 Elf_Internal_Chdr chdr;
13537 unsigned int compression_header_size
ebdf1ebf 13538 = get_compression_header (& chdr, start, section_size);
0e602686 13539
813dabb9 13540 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13541 {
813dabb9 13542 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13543 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13544 return FALSE;
0e602686 13545 }
813dabb9
L
13546 else if (chdr.ch_addralign != section->sh_addralign)
13547 {
13548 warn (_("compressed section '%s' is corrupted\n"),
dda8d76d 13549 printable_section_name (filedata, section));
32ec8896 13550 return FALSE;
813dabb9
L
13551 }
13552 uncompressed_size = chdr.ch_size;
13553 start += compression_header_size;
13554 new_size -= compression_header_size;
0e602686
NC
13555 }
13556 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13557 {
13558 /* Read the zlib header. In this case, it should be "ZLIB"
13559 followed by the uncompressed section size, 8 bytes in
13560 big-endian order. */
13561 uncompressed_size = start[4]; uncompressed_size <<= 8;
13562 uncompressed_size += start[5]; uncompressed_size <<= 8;
13563 uncompressed_size += start[6]; uncompressed_size <<= 8;
13564 uncompressed_size += start[7]; uncompressed_size <<= 8;
13565 uncompressed_size += start[8]; uncompressed_size <<= 8;
13566 uncompressed_size += start[9]; uncompressed_size <<= 8;
13567 uncompressed_size += start[10]; uncompressed_size <<= 8;
13568 uncompressed_size += start[11];
13569 start += 12;
13570 new_size -= 12;
13571 }
13572
f055032e
NC
13573 if (uncompressed_size)
13574 {
13575 if (uncompress_section_contents (& start, uncompressed_size,
13576 & new_size))
bc303e5d
NC
13577 {
13578 section_size = new_size;
13579 }
f055032e
NC
13580 else
13581 {
13582 error (_("Unable to decompress section %s\n"),
dda8d76d 13583 printable_section_name (filedata, section));
bc303e5d 13584 /* FIXME: Print the section anyway ? */
32ec8896 13585 return FALSE;
f055032e
NC
13586 }
13587 }
bc303e5d
NC
13588 else
13589 start = real_start;
0e602686 13590 }
14ae95f2 13591
cf13d699
NC
13592 if (relocate)
13593 {
dda8d76d 13594 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
32ec8896 13595 return FALSE;
cf13d699
NC
13596 }
13597 else
13598 {
13599 /* If the section being dumped has relocations against it the user might
13600 be expecting these relocations to have been applied. Check for this
13601 case and issue a warning message in order to avoid confusion.
13602 FIXME: Maybe we ought to have an option that dumps a section with
13603 relocs applied ? */
dda8d76d
NC
13604 for (relsec = filedata->section_headers;
13605 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13606 ++relsec)
13607 {
13608 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13609 || relsec->sh_info >= filedata->file_header.e_shnum
13610 || filedata->section_headers + relsec->sh_info != section
cf13d699 13611 || relsec->sh_size == 0
dda8d76d 13612 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13613 continue;
13614
13615 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13616 break;
13617 }
13618 }
13619
13620 addr = section->sh_addr;
0e602686 13621 bytes = section_size;
cf13d699
NC
13622 data = start;
13623
13624 while (bytes)
13625 {
13626 int j;
13627 int k;
13628 int lbytes;
13629
13630 lbytes = (bytes > 16 ? 16 : bytes);
13631
13632 printf (" 0x%8.8lx ", (unsigned long) addr);
13633
13634 for (j = 0; j < 16; j++)
13635 {
13636 if (j < lbytes)
13637 printf ("%2.2x", data[j]);
13638 else
13639 printf (" ");
13640
13641 if ((j & 3) == 3)
13642 printf (" ");
13643 }
13644
13645 for (j = 0; j < lbytes; j++)
13646 {
13647 k = data[j];
13648 if (k >= ' ' && k < 0x7f)
13649 printf ("%c", k);
13650 else
13651 printf (".");
13652 }
13653
13654 putchar ('\n');
13655
13656 data += lbytes;
13657 addr += lbytes;
13658 bytes -= lbytes;
13659 }
13660
0e602686 13661 free (real_start);
cf13d699
NC
13662
13663 putchar ('\n');
32ec8896 13664 return TRUE;
cf13d699
NC
13665}
13666
32ec8896 13667static bfd_boolean
dda8d76d
NC
13668load_specific_debug_section (enum dwarf_section_display_enum debug,
13669 const Elf_Internal_Shdr * sec,
13670 void * data)
1007acb3 13671{
2cf0635d 13672 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 13673 char buf [64];
dda8d76d
NC
13674 Filedata * filedata = (Filedata *) data;
13675
19e6b90e 13676 if (section->start != NULL)
dda8d76d
NC
13677 {
13678 /* If it is already loaded, do nothing. */
13679 if (streq (section->filename, filedata->file_name))
13680 return TRUE;
13681 free (section->start);
13682 }
1007acb3 13683
19e6b90e
L
13684 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
13685 section->address = sec->sh_addr;
06614111 13686 section->user_data = NULL;
dda8d76d
NC
13687 section->filename = filedata->file_name;
13688 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
13689 sec->sh_offset, 1,
13690 sec->sh_size, buf);
59245841
NC
13691 if (section->start == NULL)
13692 section->size = 0;
13693 else
13694 {
77115a4a
L
13695 unsigned char *start = section->start;
13696 dwarf_size_type size = sec->sh_size;
dab394de 13697 dwarf_size_type uncompressed_size = 0;
77115a4a
L
13698
13699 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
13700 {
13701 Elf_Internal_Chdr chdr;
d8024a91
NC
13702 unsigned int compression_header_size;
13703
f53be977
L
13704 if (size < (is_32bit_elf
13705 ? sizeof (Elf32_External_Chdr)
13706 : sizeof (Elf64_External_Chdr)))
d8024a91
NC
13707 {
13708 warn (_("compressed section %s is too small to contain a compression header"),
13709 section->name);
32ec8896 13710 return FALSE;
d8024a91
NC
13711 }
13712
ebdf1ebf 13713 compression_header_size = get_compression_header (&chdr, start, size);
d8024a91 13714
813dabb9
L
13715 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
13716 {
13717 warn (_("section '%s' has unsupported compress type: %d\n"),
13718 section->name, chdr.ch_type);
32ec8896 13719 return FALSE;
813dabb9
L
13720 }
13721 else if (chdr.ch_addralign != sec->sh_addralign)
13722 {
13723 warn (_("compressed section '%s' is corrupted\n"),
13724 section->name);
32ec8896 13725 return FALSE;
813dabb9 13726 }
dab394de 13727 uncompressed_size = chdr.ch_size;
77115a4a
L
13728 start += compression_header_size;
13729 size -= compression_header_size;
13730 }
dab394de
L
13731 else if (size > 12 && streq ((char *) start, "ZLIB"))
13732 {
13733 /* Read the zlib header. In this case, it should be "ZLIB"
13734 followed by the uncompressed section size, 8 bytes in
13735 big-endian order. */
13736 uncompressed_size = start[4]; uncompressed_size <<= 8;
13737 uncompressed_size += start[5]; uncompressed_size <<= 8;
13738 uncompressed_size += start[6]; uncompressed_size <<= 8;
13739 uncompressed_size += start[7]; uncompressed_size <<= 8;
13740 uncompressed_size += start[8]; uncompressed_size <<= 8;
13741 uncompressed_size += start[9]; uncompressed_size <<= 8;
13742 uncompressed_size += start[10]; uncompressed_size <<= 8;
13743 uncompressed_size += start[11];
13744 start += 12;
13745 size -= 12;
13746 }
13747
1835f746 13748 if (uncompressed_size)
77115a4a 13749 {
1835f746
NC
13750 if (uncompress_section_contents (&start, uncompressed_size,
13751 &size))
13752 {
13753 /* Free the compressed buffer, update the section buffer
13754 and the section size if uncompress is successful. */
13755 free (section->start);
13756 section->start = start;
13757 }
13758 else
13759 {
13760 error (_("Unable to decompress section %s\n"),
dda8d76d 13761 printable_section_name (filedata, sec));
32ec8896 13762 return FALSE;
1835f746 13763 }
77115a4a 13764 }
bc303e5d 13765
77115a4a 13766 section->size = size;
59245841 13767 }
4a114e3e 13768
1b315056 13769 if (section->start == NULL)
32ec8896 13770 return FALSE;
1b315056 13771
19e6b90e 13772 if (debug_displays [debug].relocate)
32ec8896 13773 {
dda8d76d 13774 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
13775 & section->reloc_info, & section->num_relocs))
13776 return FALSE;
13777 }
d1c4b12b
NC
13778 else
13779 {
13780 section->reloc_info = NULL;
13781 section->num_relocs = 0;
13782 }
1007acb3 13783
32ec8896 13784 return TRUE;
1007acb3
L
13785}
13786
657d0d47
CC
13787/* If this is not NULL, load_debug_section will only look for sections
13788 within the list of sections given here. */
32ec8896 13789static unsigned int * section_subset = NULL;
657d0d47 13790
32ec8896 13791bfd_boolean
dda8d76d 13792load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 13793{
2cf0635d
NC
13794 struct dwarf_section * section = &debug_displays [debug].section;
13795 Elf_Internal_Shdr * sec;
dda8d76d
NC
13796 Filedata * filedata = (Filedata *) data;
13797
f425ec66
NC
13798 /* Without section headers we cannot find any sections. */
13799 if (filedata->section_headers == NULL)
13800 return FALSE;
13801
9c1ce108
AM
13802 if (filedata->string_table == NULL
13803 && filedata->file_header.e_shstrndx != SHN_UNDEF
13804 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
13805 {
13806 Elf_Internal_Shdr * strs;
13807
13808 /* Read in the string table, so that we have section names to scan. */
13809 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
13810
4dff97b2 13811 if (strs != NULL && strs->sh_size != 0)
dda8d76d 13812 {
9c1ce108
AM
13813 filedata->string_table
13814 = (char *) get_data (NULL, filedata, strs->sh_offset,
13815 1, strs->sh_size, _("string table"));
dda8d76d 13816
9c1ce108
AM
13817 filedata->string_table_length
13818 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
13819 }
13820 }
d966045b
DJ
13821
13822 /* Locate the debug section. */
dda8d76d 13823 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
13824 if (sec != NULL)
13825 section->name = section->uncompressed_name;
13826 else
13827 {
dda8d76d 13828 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
13829 if (sec != NULL)
13830 section->name = section->compressed_name;
13831 }
13832 if (sec == NULL)
32ec8896 13833 return FALSE;
d966045b 13834
657d0d47
CC
13835 /* If we're loading from a subset of sections, and we've loaded
13836 a section matching this name before, it's likely that it's a
13837 different one. */
13838 if (section_subset != NULL)
13839 free_debug_section (debug);
13840
dda8d76d 13841 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
13842}
13843
19e6b90e
L
13844void
13845free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 13846{
2cf0635d 13847 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 13848
19e6b90e
L
13849 if (section->start == NULL)
13850 return;
1007acb3 13851
19e6b90e
L
13852 free ((char *) section->start);
13853 section->start = NULL;
13854 section->address = 0;
13855 section->size = 0;
1007acb3
L
13856}
13857
32ec8896 13858static bfd_boolean
dda8d76d 13859display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 13860{
2cf0635d 13861 char * name = SECTION_NAME (section);
dda8d76d 13862 const char * print_name = printable_section_name (filedata, section);
19e6b90e 13863 bfd_size_type length;
32ec8896 13864 bfd_boolean result = TRUE;
3f5e193b 13865 int i;
1007acb3 13866
19e6b90e
L
13867 length = section->sh_size;
13868 if (length == 0)
1007acb3 13869 {
74e1a04b 13870 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 13871 return TRUE;
1007acb3 13872 }
5dff79d8
NC
13873 if (section->sh_type == SHT_NOBITS)
13874 {
13875 /* There is no point in dumping the contents of a debugging section
13876 which has the NOBITS type - the bits in the file will be random.
13877 This can happen when a file containing a .eh_frame section is
13878 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
13879 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
13880 print_name);
32ec8896 13881 return FALSE;
5dff79d8 13882 }
1007acb3 13883
0112cd26 13884 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 13885 name = ".debug_info";
1007acb3 13886
19e6b90e
L
13887 /* See if we know how to display the contents of this section. */
13888 for (i = 0; i < max; i++)
d85bf2ba
NC
13889 {
13890 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
13891 struct dwarf_section_display * display = debug_displays + i;
13892 struct dwarf_section * sec = & display->section;
d966045b 13893
d85bf2ba
NC
13894 if (streq (sec->uncompressed_name, name)
13895 || (id == line && const_strneq (name, ".debug_line."))
13896 || streq (sec->compressed_name, name))
13897 {
13898 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 13899
d85bf2ba
NC
13900 if (secondary)
13901 free_debug_section (id);
dda8d76d 13902
d85bf2ba
NC
13903 if (i == line && const_strneq (name, ".debug_line."))
13904 sec->name = name;
13905 else if (streq (sec->uncompressed_name, name))
13906 sec->name = sec->uncompressed_name;
13907 else
13908 sec->name = sec->compressed_name;
657d0d47 13909
d85bf2ba
NC
13910 if (load_specific_debug_section (id, section, filedata))
13911 {
13912 /* If this debug section is part of a CU/TU set in a .dwp file,
13913 restrict load_debug_section to the sections in that set. */
13914 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 13915
d85bf2ba 13916 result &= display->display (sec, filedata);
657d0d47 13917
d85bf2ba 13918 section_subset = NULL;
1007acb3 13919
d85bf2ba
NC
13920 if (secondary || (id != info && id != abbrev))
13921 free_debug_section (id);
13922 }
13923 break;
13924 }
13925 }
1007acb3 13926
19e6b90e 13927 if (i == max)
1007acb3 13928 {
74e1a04b 13929 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 13930 result = FALSE;
1007acb3
L
13931 }
13932
19e6b90e 13933 return result;
5b18a4bc 13934}
103f02d3 13935
aef1f6d0
DJ
13936/* Set DUMP_SECTS for all sections where dumps were requested
13937 based on section name. */
13938
13939static void
dda8d76d 13940initialise_dumps_byname (Filedata * filedata)
aef1f6d0 13941{
2cf0635d 13942 struct dump_list_entry * cur;
aef1f6d0
DJ
13943
13944 for (cur = dump_sects_byname; cur; cur = cur->next)
13945 {
13946 unsigned int i;
32ec8896 13947 bfd_boolean any = FALSE;
aef1f6d0 13948
dda8d76d
NC
13949 for (i = 0; i < filedata->file_header.e_shnum; i++)
13950 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 13951 {
dda8d76d 13952 request_dump_bynumber (filedata, i, cur->type);
32ec8896 13953 any = TRUE;
aef1f6d0
DJ
13954 }
13955
13956 if (!any)
13957 warn (_("Section '%s' was not dumped because it does not exist!\n"),
13958 cur->name);
13959 }
13960}
13961
32ec8896 13962static bfd_boolean
dda8d76d 13963process_section_contents (Filedata * filedata)
5b18a4bc 13964{
2cf0635d 13965 Elf_Internal_Shdr * section;
19e6b90e 13966 unsigned int i;
32ec8896 13967 bfd_boolean res = TRUE;
103f02d3 13968
19e6b90e 13969 if (! do_dump)
32ec8896 13970 return TRUE;
103f02d3 13971
dda8d76d 13972 initialise_dumps_byname (filedata);
aef1f6d0 13973
dda8d76d
NC
13974 for (i = 0, section = filedata->section_headers;
13975 i < filedata->file_header.e_shnum && i < filedata->num_dump_sects;
19e6b90e
L
13976 i++, section++)
13977 {
dda8d76d
NC
13978 dump_type dump = filedata->dump_sects[i];
13979
19e6b90e 13980#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
13981 if (dump & DISASS_DUMP)
13982 {
13983 if (! disassemble_section (section, filedata))
13984 res = FALSE;
13985 }
19e6b90e 13986#endif
dda8d76d 13987 if (dump & HEX_DUMP)
32ec8896 13988 {
dda8d76d 13989 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
13990 res = FALSE;
13991 }
103f02d3 13992
dda8d76d 13993 if (dump & RELOC_DUMP)
32ec8896 13994 {
dda8d76d 13995 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
13996 res = FALSE;
13997 }
09c11c86 13998
dda8d76d 13999 if (dump & STRING_DUMP)
32ec8896 14000 {
dda8d76d 14001 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
14002 res = FALSE;
14003 }
cf13d699 14004
dda8d76d 14005 if (dump & DEBUG_DUMP)
32ec8896 14006 {
dda8d76d 14007 if (! display_debug_section (i, section, filedata))
32ec8896
NC
14008 res = FALSE;
14009 }
5b18a4bc 14010 }
103f02d3 14011
19e6b90e
L
14012 /* Check to see if the user requested a
14013 dump of a section that does not exist. */
dda8d76d 14014 while (i < filedata->num_dump_sects)
0ee3043f 14015 {
dda8d76d 14016 if (filedata->dump_sects[i])
32ec8896
NC
14017 {
14018 warn (_("Section %d was not dumped because it does not exist!\n"), i);
14019 res = FALSE;
14020 }
0ee3043f
NC
14021 i++;
14022 }
32ec8896
NC
14023
14024 return res;
5b18a4bc 14025}
103f02d3 14026
5b18a4bc 14027static void
19e6b90e 14028process_mips_fpe_exception (int mask)
5b18a4bc 14029{
19e6b90e
L
14030 if (mask)
14031 {
32ec8896
NC
14032 bfd_boolean first = TRUE;
14033
19e6b90e 14034 if (mask & OEX_FPU_INEX)
32ec8896 14035 fputs ("INEX", stdout), first = FALSE;
19e6b90e 14036 if (mask & OEX_FPU_UFLO)
32ec8896 14037 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14038 if (mask & OEX_FPU_OFLO)
32ec8896 14039 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14040 if (mask & OEX_FPU_DIV0)
32ec8896 14041 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
14042 if (mask & OEX_FPU_INVAL)
14043 printf ("%sINVAL", first ? "" : "|");
14044 }
5b18a4bc 14045 else
19e6b90e 14046 fputs ("0", stdout);
5b18a4bc 14047}
103f02d3 14048
f6f0e17b
NC
14049/* Display's the value of TAG at location P. If TAG is
14050 greater than 0 it is assumed to be an unknown tag, and
14051 a message is printed to this effect. Otherwise it is
14052 assumed that a message has already been printed.
14053
14054 If the bottom bit of TAG is set it assumed to have a
14055 string value, otherwise it is assumed to have an integer
14056 value.
14057
14058 Returns an updated P pointing to the first unread byte
14059 beyond the end of TAG's value.
14060
14061 Reads at or beyond END will not be made. */
14062
14063static unsigned char *
60abdbed 14064display_tag_value (signed int tag,
f6f0e17b
NC
14065 unsigned char * p,
14066 const unsigned char * const end)
14067{
14068 unsigned long val;
14069
14070 if (tag > 0)
14071 printf (" Tag_unknown_%d: ", tag);
14072
14073 if (p >= end)
14074 {
4082ef84 14075 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
14076 }
14077 else if (tag & 1)
14078 {
071436c6
NC
14079 /* PR 17531 file: 027-19978-0.004. */
14080 size_t maxlen = (end - p) - 1;
14081
14082 putchar ('"');
4082ef84
NC
14083 if (maxlen > 0)
14084 {
14085 print_symbol ((int) maxlen, (const char *) p);
14086 p += strnlen ((char *) p, maxlen) + 1;
14087 }
14088 else
14089 {
14090 printf (_("<corrupt string tag>"));
14091 p = (unsigned char *) end;
14092 }
071436c6 14093 printf ("\"\n");
f6f0e17b
NC
14094 }
14095 else
14096 {
14097 unsigned int len;
14098
14099 val = read_uleb128 (p, &len, end);
14100 p += len;
14101 printf ("%ld (0x%lx)\n", val, val);
14102 }
14103
4082ef84 14104 assert (p <= end);
f6f0e17b
NC
14105 return p;
14106}
14107
53a346d8
CZ
14108/* ARC ABI attributes section. */
14109
14110static unsigned char *
14111display_arc_attribute (unsigned char * p,
14112 const unsigned char * const end)
14113{
14114 unsigned int tag;
14115 unsigned int len;
14116 unsigned int val;
14117
14118 tag = read_uleb128 (p, &len, end);
14119 p += len;
14120
14121 switch (tag)
14122 {
14123 case Tag_ARC_PCS_config:
14124 val = read_uleb128 (p, &len, end);
14125 p += len;
14126 printf (" Tag_ARC_PCS_config: ");
14127 switch (val)
14128 {
14129 case 0:
14130 printf (_("Absent/Non standard\n"));
14131 break;
14132 case 1:
14133 printf (_("Bare metal/mwdt\n"));
14134 break;
14135 case 2:
14136 printf (_("Bare metal/newlib\n"));
14137 break;
14138 case 3:
14139 printf (_("Linux/uclibc\n"));
14140 break;
14141 case 4:
14142 printf (_("Linux/glibc\n"));
14143 break;
14144 default:
14145 printf (_("Unknown\n"));
14146 break;
14147 }
14148 break;
14149
14150 case Tag_ARC_CPU_base:
14151 val = read_uleb128 (p, &len, end);
14152 p += len;
14153 printf (" Tag_ARC_CPU_base: ");
14154 switch (val)
14155 {
14156 default:
14157 case TAG_CPU_NONE:
14158 printf (_("Absent\n"));
14159 break;
14160 case TAG_CPU_ARC6xx:
14161 printf ("ARC6xx\n");
14162 break;
14163 case TAG_CPU_ARC7xx:
14164 printf ("ARC7xx\n");
14165 break;
14166 case TAG_CPU_ARCEM:
14167 printf ("ARCEM\n");
14168 break;
14169 case TAG_CPU_ARCHS:
14170 printf ("ARCHS\n");
14171 break;
14172 }
14173 break;
14174
14175 case Tag_ARC_CPU_variation:
14176 val = read_uleb128 (p, &len, end);
14177 p += len;
14178 printf (" Tag_ARC_CPU_variation: ");
14179 switch (val)
14180 {
14181 default:
14182 if (val > 0 && val < 16)
53a346d8 14183 printf ("Core%d\n", val);
d8cbc93b
JL
14184 else
14185 printf ("Unknown\n");
14186 break;
14187
53a346d8
CZ
14188 case 0:
14189 printf (_("Absent\n"));
14190 break;
14191 }
14192 break;
14193
14194 case Tag_ARC_CPU_name:
14195 printf (" Tag_ARC_CPU_name: ");
14196 p = display_tag_value (-1, p, end);
14197 break;
14198
14199 case Tag_ARC_ABI_rf16:
14200 val = read_uleb128 (p, &len, end);
14201 p += len;
14202 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
14203 break;
14204
14205 case Tag_ARC_ABI_osver:
14206 val = read_uleb128 (p, &len, end);
14207 p += len;
14208 printf (" Tag_ARC_ABI_osver: v%d\n", val);
14209 break;
14210
14211 case Tag_ARC_ABI_pic:
14212 case Tag_ARC_ABI_sda:
14213 val = read_uleb128 (p, &len, end);
14214 p += len;
14215 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
14216 : " Tag_ARC_ABI_pic: ");
14217 switch (val)
14218 {
14219 case 0:
14220 printf (_("Absent\n"));
14221 break;
14222 case 1:
14223 printf ("MWDT\n");
14224 break;
14225 case 2:
14226 printf ("GNU\n");
14227 break;
14228 default:
14229 printf (_("Unknown\n"));
14230 break;
14231 }
14232 break;
14233
14234 case Tag_ARC_ABI_tls:
14235 val = read_uleb128 (p, &len, end);
14236 p += len;
14237 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
14238 break;
14239
14240 case Tag_ARC_ABI_enumsize:
14241 val = read_uleb128 (p, &len, end);
14242 p += len;
14243 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
14244 _("smallest"));
14245 break;
14246
14247 case Tag_ARC_ABI_exceptions:
14248 val = read_uleb128 (p, &len, end);
14249 p += len;
14250 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
14251 : _("default"));
14252 break;
14253
14254 case Tag_ARC_ABI_double_size:
14255 val = read_uleb128 (p, &len, end);
14256 p += len;
14257 printf (" Tag_ARC_ABI_double_size: %d\n", val);
14258 break;
14259
14260 case Tag_ARC_ISA_config:
14261 printf (" Tag_ARC_ISA_config: ");
14262 p = display_tag_value (-1, p, end);
14263 break;
14264
14265 case Tag_ARC_ISA_apex:
14266 printf (" Tag_ARC_ISA_apex: ");
14267 p = display_tag_value (-1, p, end);
14268 break;
14269
14270 case Tag_ARC_ISA_mpy_option:
14271 val = read_uleb128 (p, &len, end);
14272 p += len;
14273 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
14274 break;
14275
db1e1b45 14276 case Tag_ARC_ATR_version:
14277 val = read_uleb128 (p, &len, end);
14278 p += len;
14279 printf (" Tag_ARC_ATR_version: %d\n", val);
14280 break;
14281
53a346d8
CZ
14282 default:
14283 return display_tag_value (tag & 1, p, end);
14284 }
14285
14286 return p;
14287}
14288
11c1ff18
PB
14289/* ARM EABI attributes section. */
14290typedef struct
14291{
70e99720 14292 unsigned int tag;
2cf0635d 14293 const char * name;
11c1ff18 14294 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 14295 unsigned int type;
2cf0635d 14296 const char ** table;
11c1ff18
PB
14297} arm_attr_public_tag;
14298
2cf0635d 14299static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 14300 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 14301 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
ff8646ee 14302 "v8-M.mainline"};
2cf0635d
NC
14303static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
14304static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 14305 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 14306static const char * arm_attr_tag_FP_arch[] =
bca38921 14307 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 14308 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 14309static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 14310static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
14311 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
14312 "NEON for ARMv8.1"};
2cf0635d 14313static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
14314 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
14315 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 14316static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 14317 {"V6", "SB", "TLS", "Unused"};
2cf0635d 14318static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 14319 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 14320static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 14321 {"Absolute", "PC-relative", "None"};
2cf0635d 14322static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 14323 {"None", "direct", "GOT-indirect"};
2cf0635d 14324static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 14325 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
14326static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
14327static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 14328 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
14329static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
14330static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
14331static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 14332 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 14333static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 14334 {"Unused", "small", "int", "forced to int"};
2cf0635d 14335static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 14336 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 14337static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 14338 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 14339static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 14340 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 14341static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
14342 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14343 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 14344static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
14345 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14346 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 14347static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 14348static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 14349 {"Not Allowed", "Allowed"};
2cf0635d 14350static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 14351 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
14352static const char * arm_attr_tag_DSP_extension[] =
14353 {"Follow architecture", "Allowed"};
dd24e3da 14354static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
14355 {"Not Allowed", "Allowed"};
14356static const char * arm_attr_tag_DIV_use[] =
dd24e3da 14357 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 14358 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
14359static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
14360static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 14361 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 14362 "TrustZone and Virtualization Extensions"};
dd24e3da 14363static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 14364 {"Not Allowed", "Allowed"};
11c1ff18
PB
14365
14366#define LOOKUP(id, name) \
14367 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 14368static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
14369{
14370 {4, "CPU_raw_name", 1, NULL},
14371 {5, "CPU_name", 1, NULL},
14372 LOOKUP(6, CPU_arch),
14373 {7, "CPU_arch_profile", 0, NULL},
14374 LOOKUP(8, ARM_ISA_use),
14375 LOOKUP(9, THUMB_ISA_use),
75375b3e 14376 LOOKUP(10, FP_arch),
11c1ff18 14377 LOOKUP(11, WMMX_arch),
f5f53991
AS
14378 LOOKUP(12, Advanced_SIMD_arch),
14379 LOOKUP(13, PCS_config),
11c1ff18
PB
14380 LOOKUP(14, ABI_PCS_R9_use),
14381 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 14382 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
14383 LOOKUP(17, ABI_PCS_GOT_use),
14384 LOOKUP(18, ABI_PCS_wchar_t),
14385 LOOKUP(19, ABI_FP_rounding),
14386 LOOKUP(20, ABI_FP_denormal),
14387 LOOKUP(21, ABI_FP_exceptions),
14388 LOOKUP(22, ABI_FP_user_exceptions),
14389 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
14390 {24, "ABI_align_needed", 0, NULL},
14391 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
14392 LOOKUP(26, ABI_enum_size),
14393 LOOKUP(27, ABI_HardFP_use),
14394 LOOKUP(28, ABI_VFP_args),
14395 LOOKUP(29, ABI_WMMX_args),
14396 LOOKUP(30, ABI_optimization_goals),
14397 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 14398 {32, "compatibility", 0, NULL},
f5f53991 14399 LOOKUP(34, CPU_unaligned_access),
75375b3e 14400 LOOKUP(36, FP_HP_extension),
8e79c3df 14401 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
14402 LOOKUP(42, MPextension_use),
14403 LOOKUP(44, DIV_use),
15afaa63 14404 LOOKUP(46, DSP_extension),
f5f53991
AS
14405 {64, "nodefaults", 0, NULL},
14406 {65, "also_compatible_with", 0, NULL},
14407 LOOKUP(66, T2EE_use),
14408 {67, "conformance", 1, NULL},
14409 LOOKUP(68, Virtualization_use),
cd21e546 14410 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
14411};
14412#undef LOOKUP
14413
11c1ff18 14414static unsigned char *
f6f0e17b
NC
14415display_arm_attribute (unsigned char * p,
14416 const unsigned char * const end)
11c1ff18 14417{
70e99720 14418 unsigned int tag;
11c1ff18 14419 unsigned int len;
70e99720 14420 unsigned int val;
2cf0635d 14421 arm_attr_public_tag * attr;
11c1ff18 14422 unsigned i;
70e99720 14423 unsigned int type;
11c1ff18 14424
f6f0e17b 14425 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
14426 p += len;
14427 attr = NULL;
2cf0635d 14428 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
14429 {
14430 if (arm_attr_public_tags[i].tag == tag)
14431 {
14432 attr = &arm_attr_public_tags[i];
14433 break;
14434 }
14435 }
14436
14437 if (attr)
14438 {
14439 printf (" Tag_%s: ", attr->name);
14440 switch (attr->type)
14441 {
14442 case 0:
14443 switch (tag)
14444 {
14445 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 14446 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14447 p += len;
14448 switch (val)
14449 {
2b692964
NC
14450 case 0: printf (_("None\n")); break;
14451 case 'A': printf (_("Application\n")); break;
14452 case 'R': printf (_("Realtime\n")); break;
14453 case 'M': printf (_("Microcontroller\n")); break;
14454 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
14455 default: printf ("??? (%d)\n", val); break;
14456 }
14457 break;
14458
75375b3e 14459 case 24: /* Tag_align_needed. */
f6f0e17b 14460 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14461 p += len;
14462 switch (val)
14463 {
2b692964
NC
14464 case 0: printf (_("None\n")); break;
14465 case 1: printf (_("8-byte\n")); break;
14466 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
14467 case 3: printf ("??? 3\n"); break;
14468 default:
14469 if (val <= 12)
dd24e3da 14470 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14471 1 << val);
14472 else
14473 printf ("??? (%d)\n", val);
14474 break;
14475 }
14476 break;
14477
14478 case 25: /* Tag_align_preserved. */
f6f0e17b 14479 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14480 p += len;
14481 switch (val)
14482 {
2b692964
NC
14483 case 0: printf (_("None\n")); break;
14484 case 1: printf (_("8-byte, except leaf SP\n")); break;
14485 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
14486 case 3: printf ("??? 3\n"); break;
14487 default:
14488 if (val <= 12)
dd24e3da 14489 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14490 1 << val);
14491 else
14492 printf ("??? (%d)\n", val);
14493 break;
14494 }
14495 break;
14496
11c1ff18 14497 case 32: /* Tag_compatibility. */
071436c6 14498 {
071436c6
NC
14499 val = read_uleb128 (p, &len, end);
14500 p += len;
071436c6 14501 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
14502 if (p < end - 1)
14503 {
14504 size_t maxlen = (end - p) - 1;
14505
14506 print_symbol ((int) maxlen, (const char *) p);
14507 p += strnlen ((char *) p, maxlen) + 1;
14508 }
14509 else
14510 {
14511 printf (_("<corrupt>"));
14512 p = (unsigned char *) end;
14513 }
071436c6 14514 putchar ('\n');
071436c6 14515 }
11c1ff18
PB
14516 break;
14517
f5f53991 14518 case 64: /* Tag_nodefaults. */
541a3cbd
NC
14519 /* PR 17531: file: 001-505008-0.01. */
14520 if (p < end)
14521 p++;
2b692964 14522 printf (_("True\n"));
f5f53991
AS
14523 break;
14524
14525 case 65: /* Tag_also_compatible_with. */
f6f0e17b 14526 val = read_uleb128 (p, &len, end);
f5f53991
AS
14527 p += len;
14528 if (val == 6 /* Tag_CPU_arch. */)
14529 {
f6f0e17b 14530 val = read_uleb128 (p, &len, end);
f5f53991 14531 p += len;
071436c6 14532 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
14533 printf ("??? (%d)\n", val);
14534 else
14535 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
14536 }
14537 else
14538 printf ("???\n");
071436c6
NC
14539 while (p < end && *(p++) != '\0' /* NUL terminator. */)
14540 ;
f5f53991
AS
14541 break;
14542
11c1ff18 14543 default:
bee0ee85
NC
14544 printf (_("<unknown: %d>\n"), tag);
14545 break;
11c1ff18
PB
14546 }
14547 return p;
14548
14549 case 1:
f6f0e17b 14550 return display_tag_value (-1, p, end);
11c1ff18 14551 case 2:
f6f0e17b 14552 return display_tag_value (0, p, end);
11c1ff18
PB
14553
14554 default:
14555 assert (attr->type & 0x80);
f6f0e17b 14556 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14557 p += len;
14558 type = attr->type & 0x7f;
14559 if (val >= type)
14560 printf ("??? (%d)\n", val);
14561 else
14562 printf ("%s\n", attr->table[val]);
14563 return p;
14564 }
14565 }
11c1ff18 14566
f6f0e17b 14567 return display_tag_value (tag, p, end);
11c1ff18
PB
14568}
14569
104d59d1 14570static unsigned char *
60bca95a 14571display_gnu_attribute (unsigned char * p,
60abdbed 14572 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 14573 const unsigned char * const end)
104d59d1
JM
14574{
14575 int tag;
14576 unsigned int len;
60abdbed 14577 unsigned int val;
104d59d1 14578
f6f0e17b 14579 tag = read_uleb128 (p, &len, end);
104d59d1
JM
14580 p += len;
14581
14582 /* Tag_compatibility is the only generic GNU attribute defined at
14583 present. */
14584 if (tag == 32)
14585 {
f6f0e17b 14586 val = read_uleb128 (p, &len, end);
104d59d1 14587 p += len;
071436c6
NC
14588
14589 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
14590 if (p == end)
14591 {
071436c6 14592 printf (_("<corrupt>\n"));
f6f0e17b
NC
14593 warn (_("corrupt vendor attribute\n"));
14594 }
14595 else
14596 {
4082ef84
NC
14597 if (p < end - 1)
14598 {
14599 size_t maxlen = (end - p) - 1;
071436c6 14600
4082ef84
NC
14601 print_symbol ((int) maxlen, (const char *) p);
14602 p += strnlen ((char *) p, maxlen) + 1;
14603 }
14604 else
14605 {
14606 printf (_("<corrupt>"));
14607 p = (unsigned char *) end;
14608 }
071436c6 14609 putchar ('\n');
f6f0e17b 14610 }
104d59d1
JM
14611 return p;
14612 }
14613
14614 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 14615 return display_proc_gnu_attribute (p, tag, end);
104d59d1 14616
f6f0e17b 14617 return display_tag_value (tag, p, end);
104d59d1
JM
14618}
14619
34c8bcba 14620static unsigned char *
f6f0e17b 14621display_power_gnu_attribute (unsigned char * p,
60abdbed 14622 unsigned int tag,
f6f0e17b 14623 const unsigned char * const end)
34c8bcba 14624{
34c8bcba 14625 unsigned int len;
005d79fd 14626 unsigned int val;
34c8bcba
JM
14627
14628 if (tag == Tag_GNU_Power_ABI_FP)
14629 {
f6f0e17b 14630 val = read_uleb128 (p, &len, end);
34c8bcba
JM
14631 p += len;
14632 printf (" Tag_GNU_Power_ABI_FP: ");
005d79fd
AM
14633 if (len == 0)
14634 {
14635 printf (_("<corrupt>\n"));
14636 return p;
14637 }
60bca95a 14638
005d79fd
AM
14639 if (val > 15)
14640 printf ("(%#x), ", val);
14641
14642 switch (val & 3)
34c8bcba
JM
14643 {
14644 case 0:
005d79fd 14645 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
14646 break;
14647 case 1:
005d79fd 14648 printf (_("hard float, "));
34c8bcba
JM
14649 break;
14650 case 2:
005d79fd 14651 printf (_("soft float, "));
34c8bcba 14652 break;
3c7b9897 14653 case 3:
005d79fd 14654 printf (_("single-precision hard float, "));
3c7b9897 14655 break;
005d79fd
AM
14656 }
14657
14658 switch (val & 0xC)
14659 {
14660 case 0:
14661 printf (_("unspecified long double\n"));
14662 break;
14663 case 4:
14664 printf (_("128-bit IBM long double\n"));
14665 break;
14666 case 8:
14667 printf (_("64-bit long double\n"));
14668 break;
14669 case 12:
14670 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
14671 break;
14672 }
14673 return p;
005d79fd 14674 }
34c8bcba 14675
c6e65352
DJ
14676 if (tag == Tag_GNU_Power_ABI_Vector)
14677 {
f6f0e17b 14678 val = read_uleb128 (p, &len, end);
c6e65352
DJ
14679 p += len;
14680 printf (" Tag_GNU_Power_ABI_Vector: ");
005d79fd
AM
14681 if (len == 0)
14682 {
14683 printf (_("<corrupt>\n"));
14684 return p;
14685 }
14686
14687 if (val > 3)
14688 printf ("(%#x), ", val);
14689
14690 switch (val & 3)
c6e65352
DJ
14691 {
14692 case 0:
005d79fd 14693 printf (_("unspecified\n"));
c6e65352
DJ
14694 break;
14695 case 1:
005d79fd 14696 printf (_("generic\n"));
c6e65352
DJ
14697 break;
14698 case 2:
14699 printf ("AltiVec\n");
14700 break;
14701 case 3:
14702 printf ("SPE\n");
14703 break;
c6e65352
DJ
14704 }
14705 return p;
005d79fd 14706 }
c6e65352 14707
f82e0623
NF
14708 if (tag == Tag_GNU_Power_ABI_Struct_Return)
14709 {
005d79fd
AM
14710 val = read_uleb128 (p, &len, end);
14711 p += len;
14712 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
14713 if (len == 0)
f6f0e17b 14714 {
005d79fd 14715 printf (_("<corrupt>\n"));
f6f0e17b
NC
14716 return p;
14717 }
0b4362b0 14718
005d79fd
AM
14719 if (val > 2)
14720 printf ("(%#x), ", val);
14721
14722 switch (val & 3)
14723 {
14724 case 0:
14725 printf (_("unspecified\n"));
14726 break;
14727 case 1:
14728 printf ("r3/r4\n");
14729 break;
14730 case 2:
14731 printf (_("memory\n"));
14732 break;
14733 case 3:
14734 printf ("???\n");
14735 break;
14736 }
f82e0623
NF
14737 return p;
14738 }
14739
f6f0e17b 14740 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
14741}
14742
643f7afb
AK
14743static unsigned char *
14744display_s390_gnu_attribute (unsigned char * p,
60abdbed 14745 unsigned int tag,
643f7afb
AK
14746 const unsigned char * const end)
14747{
14748 unsigned int len;
14749 int val;
14750
14751 if (tag == Tag_GNU_S390_ABI_Vector)
14752 {
14753 val = read_uleb128 (p, &len, end);
14754 p += len;
14755 printf (" Tag_GNU_S390_ABI_Vector: ");
14756
14757 switch (val)
14758 {
14759 case 0:
14760 printf (_("any\n"));
14761 break;
14762 case 1:
14763 printf (_("software\n"));
14764 break;
14765 case 2:
14766 printf (_("hardware\n"));
14767 break;
14768 default:
14769 printf ("??? (%d)\n", val);
14770 break;
14771 }
14772 return p;
14773 }
14774
14775 return display_tag_value (tag & 1, p, end);
14776}
14777
9e8c70f9 14778static void
60abdbed 14779display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
14780{
14781 if (mask)
14782 {
32ec8896 14783 bfd_boolean first = TRUE;
071436c6 14784
9e8c70f9 14785 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 14786 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 14787 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 14788 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 14789 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 14790 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 14791 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 14792 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 14793 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 14794 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 14795 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 14796 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 14797 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 14798 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 14799 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 14800 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 14801 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 14802 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 14803 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 14804 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 14805 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 14806 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 14807 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 14808 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 14809 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 14810 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 14811 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 14812 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 14813 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 14814 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 14815 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 14816 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
14817 }
14818 else
071436c6
NC
14819 fputc ('0', stdout);
14820 fputc ('\n', stdout);
9e8c70f9
DM
14821}
14822
3d68f91c 14823static void
60abdbed 14824display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
14825{
14826 if (mask)
14827 {
32ec8896 14828 bfd_boolean first = TRUE;
071436c6 14829
3d68f91c 14830 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 14831 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 14832 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 14833 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 14834 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 14835 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 14836 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 14837 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 14838 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 14839 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 14840 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 14841 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 14842 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 14843 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 14844 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 14845 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 14846 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 14847 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 14848 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 14849 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 14850 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 14851 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
14852 }
14853 else
071436c6
NC
14854 fputc ('0', stdout);
14855 fputc ('\n', stdout);
3d68f91c
JM
14856}
14857
9e8c70f9 14858static unsigned char *
f6f0e17b 14859display_sparc_gnu_attribute (unsigned char * p,
60abdbed 14860 unsigned int tag,
f6f0e17b 14861 const unsigned char * const end)
9e8c70f9 14862{
3d68f91c
JM
14863 unsigned int len;
14864 int val;
14865
9e8c70f9
DM
14866 if (tag == Tag_GNU_Sparc_HWCAPS)
14867 {
f6f0e17b 14868 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
14869 p += len;
14870 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
14871 display_sparc_hwcaps (val);
14872 return p;
3d68f91c
JM
14873 }
14874 if (tag == Tag_GNU_Sparc_HWCAPS2)
14875 {
14876 val = read_uleb128 (p, &len, end);
14877 p += len;
14878 printf (" Tag_GNU_Sparc_HWCAPS2: ");
14879 display_sparc_hwcaps2 (val);
14880 return p;
14881 }
9e8c70f9 14882
f6f0e17b 14883 return display_tag_value (tag, p, end);
9e8c70f9
DM
14884}
14885
351cdf24 14886static void
32ec8896 14887print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
14888{
14889 switch (val)
14890 {
14891 case Val_GNU_MIPS_ABI_FP_ANY:
14892 printf (_("Hard or soft float\n"));
14893 break;
14894 case Val_GNU_MIPS_ABI_FP_DOUBLE:
14895 printf (_("Hard float (double precision)\n"));
14896 break;
14897 case Val_GNU_MIPS_ABI_FP_SINGLE:
14898 printf (_("Hard float (single precision)\n"));
14899 break;
14900 case Val_GNU_MIPS_ABI_FP_SOFT:
14901 printf (_("Soft float\n"));
14902 break;
14903 case Val_GNU_MIPS_ABI_FP_OLD_64:
14904 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
14905 break;
14906 case Val_GNU_MIPS_ABI_FP_XX:
14907 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
14908 break;
14909 case Val_GNU_MIPS_ABI_FP_64:
14910 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
14911 break;
14912 case Val_GNU_MIPS_ABI_FP_64A:
14913 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
14914 break;
3350cc01
CM
14915 case Val_GNU_MIPS_ABI_FP_NAN2008:
14916 printf (_("NaN 2008 compatibility\n"));
14917 break;
351cdf24
MF
14918 default:
14919 printf ("??? (%d)\n", val);
14920 break;
14921 }
14922}
14923
2cf19d5c 14924static unsigned char *
f6f0e17b 14925display_mips_gnu_attribute (unsigned char * p,
60abdbed 14926 unsigned int tag,
f6f0e17b 14927 const unsigned char * const end)
2cf19d5c 14928{
2cf19d5c
JM
14929 if (tag == Tag_GNU_MIPS_ABI_FP)
14930 {
f6f0e17b 14931 unsigned int len;
32ec8896 14932 unsigned int val;
f6f0e17b
NC
14933
14934 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
14935 p += len;
14936 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 14937
351cdf24
MF
14938 print_mips_fp_abi_value (val);
14939
2cf19d5c
JM
14940 return p;
14941 }
14942
a9f58168
CF
14943 if (tag == Tag_GNU_MIPS_ABI_MSA)
14944 {
14945 unsigned int len;
32ec8896 14946 unsigned int val;
a9f58168
CF
14947
14948 val = read_uleb128 (p, &len, end);
14949 p += len;
14950 printf (" Tag_GNU_MIPS_ABI_MSA: ");
14951
14952 switch (val)
14953 {
14954 case Val_GNU_MIPS_ABI_MSA_ANY:
14955 printf (_("Any MSA or not\n"));
14956 break;
14957 case Val_GNU_MIPS_ABI_MSA_128:
14958 printf (_("128-bit MSA\n"));
14959 break;
14960 default:
14961 printf ("??? (%d)\n", val);
14962 break;
14963 }
14964 return p;
14965 }
14966
f6f0e17b 14967 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
14968}
14969
59e6276b 14970static unsigned char *
f6f0e17b
NC
14971display_tic6x_attribute (unsigned char * p,
14972 const unsigned char * const end)
59e6276b 14973{
60abdbed 14974 unsigned int tag;
59e6276b
JM
14975 unsigned int len;
14976 int val;
14977
f6f0e17b 14978 tag = read_uleb128 (p, &len, end);
59e6276b
JM
14979 p += len;
14980
14981 switch (tag)
14982 {
75fa6dc1 14983 case Tag_ISA:
f6f0e17b 14984 val = read_uleb128 (p, &len, end);
59e6276b 14985 p += len;
75fa6dc1 14986 printf (" Tag_ISA: ");
59e6276b
JM
14987
14988 switch (val)
14989 {
75fa6dc1 14990 case C6XABI_Tag_ISA_none:
59e6276b
JM
14991 printf (_("None\n"));
14992 break;
75fa6dc1 14993 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
14994 printf ("C62x\n");
14995 break;
75fa6dc1 14996 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
14997 printf ("C67x\n");
14998 break;
75fa6dc1 14999 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
15000 printf ("C67x+\n");
15001 break;
75fa6dc1 15002 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
15003 printf ("C64x\n");
15004 break;
75fa6dc1 15005 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
15006 printf ("C64x+\n");
15007 break;
75fa6dc1 15008 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
15009 printf ("C674x\n");
15010 break;
15011 default:
15012 printf ("??? (%d)\n", val);
15013 break;
15014 }
15015 return p;
15016
87779176 15017 case Tag_ABI_wchar_t:
f6f0e17b 15018 val = read_uleb128 (p, &len, end);
87779176
JM
15019 p += len;
15020 printf (" Tag_ABI_wchar_t: ");
15021 switch (val)
15022 {
15023 case 0:
15024 printf (_("Not used\n"));
15025 break;
15026 case 1:
15027 printf (_("2 bytes\n"));
15028 break;
15029 case 2:
15030 printf (_("4 bytes\n"));
15031 break;
15032 default:
15033 printf ("??? (%d)\n", val);
15034 break;
15035 }
15036 return p;
15037
15038 case Tag_ABI_stack_align_needed:
f6f0e17b 15039 val = read_uleb128 (p, &len, end);
87779176
JM
15040 p += len;
15041 printf (" Tag_ABI_stack_align_needed: ");
15042 switch (val)
15043 {
15044 case 0:
15045 printf (_("8-byte\n"));
15046 break;
15047 case 1:
15048 printf (_("16-byte\n"));
15049 break;
15050 default:
15051 printf ("??? (%d)\n", val);
15052 break;
15053 }
15054 return p;
15055
15056 case Tag_ABI_stack_align_preserved:
f6f0e17b 15057 val = read_uleb128 (p, &len, end);
87779176
JM
15058 p += len;
15059 printf (" Tag_ABI_stack_align_preserved: ");
15060 switch (val)
15061 {
15062 case 0:
15063 printf (_("8-byte\n"));
15064 break;
15065 case 1:
15066 printf (_("16-byte\n"));
15067 break;
15068 default:
15069 printf ("??? (%d)\n", val);
15070 break;
15071 }
15072 return p;
15073
b5593623 15074 case Tag_ABI_DSBT:
f6f0e17b 15075 val = read_uleb128 (p, &len, end);
b5593623
JM
15076 p += len;
15077 printf (" Tag_ABI_DSBT: ");
15078 switch (val)
15079 {
15080 case 0:
15081 printf (_("DSBT addressing not used\n"));
15082 break;
15083 case 1:
15084 printf (_("DSBT addressing used\n"));
15085 break;
15086 default:
15087 printf ("??? (%d)\n", val);
15088 break;
15089 }
15090 return p;
15091
87779176 15092 case Tag_ABI_PID:
f6f0e17b 15093 val = read_uleb128 (p, &len, end);
87779176
JM
15094 p += len;
15095 printf (" Tag_ABI_PID: ");
15096 switch (val)
15097 {
15098 case 0:
15099 printf (_("Data addressing position-dependent\n"));
15100 break;
15101 case 1:
15102 printf (_("Data addressing position-independent, GOT near DP\n"));
15103 break;
15104 case 2:
15105 printf (_("Data addressing position-independent, GOT far from DP\n"));
15106 break;
15107 default:
15108 printf ("??? (%d)\n", val);
15109 break;
15110 }
15111 return p;
15112
15113 case Tag_ABI_PIC:
f6f0e17b 15114 val = read_uleb128 (p, &len, end);
87779176
JM
15115 p += len;
15116 printf (" Tag_ABI_PIC: ");
15117 switch (val)
15118 {
15119 case 0:
15120 printf (_("Code addressing position-dependent\n"));
15121 break;
15122 case 1:
15123 printf (_("Code addressing position-independent\n"));
15124 break;
15125 default:
15126 printf ("??? (%d)\n", val);
15127 break;
15128 }
15129 return p;
15130
15131 case Tag_ABI_array_object_alignment:
f6f0e17b 15132 val = read_uleb128 (p, &len, end);
87779176
JM
15133 p += len;
15134 printf (" Tag_ABI_array_object_alignment: ");
15135 switch (val)
15136 {
15137 case 0:
15138 printf (_("8-byte\n"));
15139 break;
15140 case 1:
15141 printf (_("4-byte\n"));
15142 break;
15143 case 2:
15144 printf (_("16-byte\n"));
15145 break;
15146 default:
15147 printf ("??? (%d)\n", val);
15148 break;
15149 }
15150 return p;
15151
15152 case Tag_ABI_array_object_align_expected:
f6f0e17b 15153 val = read_uleb128 (p, &len, end);
87779176
JM
15154 p += len;
15155 printf (" Tag_ABI_array_object_align_expected: ");
15156 switch (val)
15157 {
15158 case 0:
15159 printf (_("8-byte\n"));
15160 break;
15161 case 1:
15162 printf (_("4-byte\n"));
15163 break;
15164 case 2:
15165 printf (_("16-byte\n"));
15166 break;
15167 default:
15168 printf ("??? (%d)\n", val);
15169 break;
15170 }
15171 return p;
15172
3cbd1c06 15173 case Tag_ABI_compatibility:
071436c6 15174 {
071436c6
NC
15175 val = read_uleb128 (p, &len, end);
15176 p += len;
15177 printf (" Tag_ABI_compatibility: ");
071436c6 15178 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15179 if (p < end - 1)
15180 {
15181 size_t maxlen = (end - p) - 1;
15182
15183 print_symbol ((int) maxlen, (const char *) p);
15184 p += strnlen ((char *) p, maxlen) + 1;
15185 }
15186 else
15187 {
15188 printf (_("<corrupt>"));
15189 p = (unsigned char *) end;
15190 }
071436c6 15191 putchar ('\n');
071436c6
NC
15192 return p;
15193 }
87779176
JM
15194
15195 case Tag_ABI_conformance:
071436c6 15196 {
4082ef84
NC
15197 printf (" Tag_ABI_conformance: \"");
15198 if (p < end - 1)
15199 {
15200 size_t maxlen = (end - p) - 1;
071436c6 15201
4082ef84
NC
15202 print_symbol ((int) maxlen, (const char *) p);
15203 p += strnlen ((char *) p, maxlen) + 1;
15204 }
15205 else
15206 {
15207 printf (_("<corrupt>"));
15208 p = (unsigned char *) end;
15209 }
071436c6 15210 printf ("\"\n");
071436c6
NC
15211 return p;
15212 }
59e6276b
JM
15213 }
15214
f6f0e17b
NC
15215 return display_tag_value (tag, p, end);
15216}
59e6276b 15217
f6f0e17b 15218static void
60abdbed 15219display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
15220{
15221 unsigned long addr = 0;
15222 size_t bytes = end - p;
15223
e0a31db1 15224 assert (end > p);
f6f0e17b 15225 while (bytes)
87779176 15226 {
f6f0e17b
NC
15227 int j;
15228 int k;
15229 int lbytes = (bytes > 16 ? 16 : bytes);
15230
15231 printf (" 0x%8.8lx ", addr);
15232
15233 for (j = 0; j < 16; j++)
15234 {
15235 if (j < lbytes)
15236 printf ("%2.2x", p[j]);
15237 else
15238 printf (" ");
15239
15240 if ((j & 3) == 3)
15241 printf (" ");
15242 }
15243
15244 for (j = 0; j < lbytes; j++)
15245 {
15246 k = p[j];
15247 if (k >= ' ' && k < 0x7f)
15248 printf ("%c", k);
15249 else
15250 printf (".");
15251 }
15252
15253 putchar ('\n');
15254
15255 p += lbytes;
15256 bytes -= lbytes;
15257 addr += lbytes;
87779176 15258 }
59e6276b 15259
f6f0e17b 15260 putchar ('\n');
59e6276b
JM
15261}
15262
13761a11
NC
15263static unsigned char *
15264display_msp430x_attribute (unsigned char * p,
15265 const unsigned char * const end)
15266{
15267 unsigned int len;
60abdbed
NC
15268 unsigned int val;
15269 unsigned int tag;
13761a11
NC
15270
15271 tag = read_uleb128 (p, & len, end);
15272 p += len;
0b4362b0 15273
13761a11
NC
15274 switch (tag)
15275 {
15276 case OFBA_MSPABI_Tag_ISA:
15277 val = read_uleb128 (p, &len, end);
15278 p += len;
15279 printf (" Tag_ISA: ");
15280 switch (val)
15281 {
15282 case 0: printf (_("None\n")); break;
15283 case 1: printf (_("MSP430\n")); break;
15284 case 2: printf (_("MSP430X\n")); break;
15285 default: printf ("??? (%d)\n", val); break;
15286 }
15287 break;
15288
15289 case OFBA_MSPABI_Tag_Code_Model:
15290 val = read_uleb128 (p, &len, end);
15291 p += len;
15292 printf (" Tag_Code_Model: ");
15293 switch (val)
15294 {
15295 case 0: printf (_("None\n")); break;
15296 case 1: printf (_("Small\n")); break;
15297 case 2: printf (_("Large\n")); break;
15298 default: printf ("??? (%d)\n", val); break;
15299 }
15300 break;
15301
15302 case OFBA_MSPABI_Tag_Data_Model:
15303 val = read_uleb128 (p, &len, end);
15304 p += len;
15305 printf (" Tag_Data_Model: ");
15306 switch (val)
15307 {
15308 case 0: printf (_("None\n")); break;
15309 case 1: printf (_("Small\n")); break;
15310 case 2: printf (_("Large\n")); break;
15311 case 3: printf (_("Restricted Large\n")); break;
15312 default: printf ("??? (%d)\n", val); break;
15313 }
15314 break;
15315
15316 default:
15317 printf (_(" <unknown tag %d>: "), tag);
15318
15319 if (tag & 1)
15320 {
071436c6 15321 putchar ('"');
4082ef84
NC
15322 if (p < end - 1)
15323 {
15324 size_t maxlen = (end - p) - 1;
15325
15326 print_symbol ((int) maxlen, (const char *) p);
15327 p += strnlen ((char *) p, maxlen) + 1;
15328 }
15329 else
15330 {
15331 printf (_("<corrupt>"));
15332 p = (unsigned char *) end;
15333 }
071436c6 15334 printf ("\"\n");
13761a11
NC
15335 }
15336 else
15337 {
15338 val = read_uleb128 (p, &len, end);
15339 p += len;
15340 printf ("%d (0x%x)\n", val, val);
15341 }
15342 break;
15343 }
15344
4082ef84 15345 assert (p <= end);
13761a11
NC
15346 return p;
15347}
15348
32ec8896 15349static bfd_boolean
dda8d76d 15350process_attributes (Filedata * filedata,
60bca95a 15351 const char * public_name,
104d59d1 15352 unsigned int proc_type,
f6f0e17b 15353 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 15354 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 15355{
2cf0635d 15356 Elf_Internal_Shdr * sect;
11c1ff18 15357 unsigned i;
32ec8896 15358 bfd_boolean res = TRUE;
11c1ff18
PB
15359
15360 /* Find the section header so that we get the size. */
dda8d76d
NC
15361 for (i = 0, sect = filedata->section_headers;
15362 i < filedata->file_header.e_shnum;
11c1ff18
PB
15363 i++, sect++)
15364 {
071436c6
NC
15365 unsigned char * contents;
15366 unsigned char * p;
15367
104d59d1 15368 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
15369 continue;
15370
dda8d76d 15371 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 15372 sect->sh_size, _("attributes"));
60bca95a 15373 if (contents == NULL)
32ec8896
NC
15374 {
15375 res = FALSE;
15376 continue;
15377 }
60bca95a 15378
11c1ff18 15379 p = contents;
60abdbed
NC
15380 /* The first character is the version of the attributes.
15381 Currently only version 1, (aka 'A') is recognised here. */
15382 if (*p != 'A')
32ec8896
NC
15383 {
15384 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
15385 res = FALSE;
15386 }
60abdbed 15387 else
11c1ff18 15388 {
071436c6
NC
15389 bfd_vma section_len;
15390
15391 section_len = sect->sh_size - 1;
11c1ff18 15392 p++;
60bca95a 15393
071436c6 15394 while (section_len > 0)
11c1ff18 15395 {
071436c6 15396 bfd_vma attr_len;
e9847026 15397 unsigned int namelen;
11c1ff18 15398 bfd_boolean public_section;
104d59d1 15399 bfd_boolean gnu_section;
11c1ff18 15400
071436c6 15401 if (section_len <= 4)
e0a31db1
NC
15402 {
15403 error (_("Tag section ends prematurely\n"));
32ec8896 15404 res = FALSE;
e0a31db1
NC
15405 break;
15406 }
071436c6 15407 attr_len = byte_get (p, 4);
11c1ff18 15408 p += 4;
60bca95a 15409
071436c6 15410 if (attr_len > section_len)
11c1ff18 15411 {
071436c6
NC
15412 error (_("Bad attribute length (%u > %u)\n"),
15413 (unsigned) attr_len, (unsigned) section_len);
15414 attr_len = section_len;
32ec8896 15415 res = FALSE;
11c1ff18 15416 }
74e1a04b 15417 /* PR 17531: file: 001-101425-0.004 */
071436c6 15418 else if (attr_len < 5)
74e1a04b 15419 {
071436c6 15420 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 15421 res = FALSE;
74e1a04b
NC
15422 break;
15423 }
e9847026 15424
071436c6
NC
15425 section_len -= attr_len;
15426 attr_len -= 4;
15427
15428 namelen = strnlen ((char *) p, attr_len) + 1;
15429 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
15430 {
15431 error (_("Corrupt attribute section name\n"));
32ec8896 15432 res = FALSE;
e9847026
NC
15433 break;
15434 }
15435
071436c6
NC
15436 printf (_("Attribute Section: "));
15437 print_symbol (INT_MAX, (const char *) p);
15438 putchar ('\n');
60bca95a
NC
15439
15440 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
15441 public_section = TRUE;
15442 else
15443 public_section = FALSE;
60bca95a
NC
15444
15445 if (streq ((char *) p, "gnu"))
104d59d1
JM
15446 gnu_section = TRUE;
15447 else
15448 gnu_section = FALSE;
60bca95a 15449
11c1ff18 15450 p += namelen;
071436c6 15451 attr_len -= namelen;
e0a31db1 15452
071436c6 15453 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 15454 {
e0a31db1 15455 int tag;
11c1ff18
PB
15456 int val;
15457 bfd_vma size;
071436c6 15458 unsigned char * end;
60bca95a 15459
e0a31db1 15460 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 15461 if (attr_len < 6)
e0a31db1
NC
15462 {
15463 error (_("Unused bytes at end of section\n"));
32ec8896 15464 res = FALSE;
e0a31db1
NC
15465 section_len = 0;
15466 break;
15467 }
15468
15469 tag = *(p++);
11c1ff18 15470 size = byte_get (p, 4);
071436c6 15471 if (size > attr_len)
11c1ff18 15472 {
e9847026 15473 error (_("Bad subsection length (%u > %u)\n"),
071436c6 15474 (unsigned) size, (unsigned) attr_len);
32ec8896 15475 res = FALSE;
071436c6 15476 size = attr_len;
11c1ff18 15477 }
e0a31db1
NC
15478 /* PR binutils/17531: Safe handling of corrupt files. */
15479 if (size < 6)
15480 {
15481 error (_("Bad subsection length (%u < 6)\n"),
15482 (unsigned) size);
32ec8896 15483 res = FALSE;
e0a31db1
NC
15484 section_len = 0;
15485 break;
15486 }
60bca95a 15487
071436c6 15488 attr_len -= size;
11c1ff18 15489 end = p + size - 1;
071436c6 15490 assert (end <= contents + sect->sh_size);
11c1ff18 15491 p += 4;
60bca95a 15492
11c1ff18
PB
15493 switch (tag)
15494 {
15495 case 1:
2b692964 15496 printf (_("File Attributes\n"));
11c1ff18
PB
15497 break;
15498 case 2:
2b692964 15499 printf (_("Section Attributes:"));
11c1ff18
PB
15500 goto do_numlist;
15501 case 3:
2b692964 15502 printf (_("Symbol Attributes:"));
1a0670f3 15503 /* Fall through. */
11c1ff18
PB
15504 do_numlist:
15505 for (;;)
15506 {
91d6fa6a 15507 unsigned int j;
60bca95a 15508
f6f0e17b 15509 val = read_uleb128 (p, &j, end);
91d6fa6a 15510 p += j;
11c1ff18
PB
15511 if (val == 0)
15512 break;
15513 printf (" %d", val);
15514 }
15515 printf ("\n");
15516 break;
15517 default:
2b692964 15518 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
15519 public_section = FALSE;
15520 break;
15521 }
60bca95a 15522
071436c6 15523 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
15524 {
15525 while (p < end)
f6f0e17b 15526 p = display_pub_attribute (p, end);
60abdbed 15527 assert (p == end);
104d59d1 15528 }
071436c6 15529 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
15530 {
15531 while (p < end)
15532 p = display_gnu_attribute (p,
f6f0e17b
NC
15533 display_proc_gnu_attribute,
15534 end);
60abdbed 15535 assert (p == end);
11c1ff18 15536 }
071436c6 15537 else if (p < end)
11c1ff18 15538 {
071436c6 15539 printf (_(" Unknown attribute:\n"));
f6f0e17b 15540 display_raw_attribute (p, end);
11c1ff18
PB
15541 p = end;
15542 }
071436c6
NC
15543 else
15544 attr_len = 0;
11c1ff18
PB
15545 }
15546 }
15547 }
d70c5fc7 15548
60bca95a 15549 free (contents);
11c1ff18 15550 }
32ec8896
NC
15551
15552 return res;
11c1ff18
PB
15553}
15554
ccb4c951
RS
15555/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
15556 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
15557 and return the VMA of the next entry, or -1 if there was a problem.
15558 Does not read from DATA_END or beyond. */
ccb4c951
RS
15559
15560static bfd_vma
82b1b41b
NC
15561print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
15562 unsigned char * data_end)
ccb4c951
RS
15563{
15564 printf (" ");
15565 print_vma (addr, LONG_HEX);
15566 printf (" ");
15567 if (addr < pltgot + 0xfff0)
15568 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
15569 else
15570 printf ("%10s", "");
15571 printf (" ");
15572 if (data == NULL)
2b692964 15573 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
15574 else
15575 {
15576 bfd_vma entry;
82b1b41b 15577 unsigned char * from = data + addr - pltgot;
ccb4c951 15578
82b1b41b
NC
15579 if (from + (is_32bit_elf ? 4 : 8) > data_end)
15580 {
15581 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
15582 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
15583 return (bfd_vma) -1;
15584 }
15585 else
15586 {
15587 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15588 print_vma (entry, LONG_HEX);
15589 }
ccb4c951
RS
15590 }
15591 return addr + (is_32bit_elf ? 4 : 8);
15592}
15593
861fb55a
DJ
15594/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
15595 PLTGOT. Print the Address and Initial fields of an entry at VMA
15596 ADDR and return the VMA of the next entry. */
15597
15598static bfd_vma
2cf0635d 15599print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
15600{
15601 printf (" ");
15602 print_vma (addr, LONG_HEX);
15603 printf (" ");
15604 if (data == NULL)
2b692964 15605 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
15606 else
15607 {
15608 bfd_vma entry;
15609
15610 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15611 print_vma (entry, LONG_HEX);
15612 }
15613 return addr + (is_32bit_elf ? 4 : 8);
15614}
15615
351cdf24
MF
15616static void
15617print_mips_ases (unsigned int mask)
15618{
15619 if (mask & AFL_ASE_DSP)
15620 fputs ("\n\tDSP ASE", stdout);
15621 if (mask & AFL_ASE_DSPR2)
15622 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
15623 if (mask & AFL_ASE_DSPR3)
15624 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
15625 if (mask & AFL_ASE_EVA)
15626 fputs ("\n\tEnhanced VA Scheme", stdout);
15627 if (mask & AFL_ASE_MCU)
15628 fputs ("\n\tMCU (MicroController) ASE", stdout);
15629 if (mask & AFL_ASE_MDMX)
15630 fputs ("\n\tMDMX ASE", stdout);
15631 if (mask & AFL_ASE_MIPS3D)
15632 fputs ("\n\tMIPS-3D ASE", stdout);
15633 if (mask & AFL_ASE_MT)
15634 fputs ("\n\tMT ASE", stdout);
15635 if (mask & AFL_ASE_SMARTMIPS)
15636 fputs ("\n\tSmartMIPS ASE", stdout);
15637 if (mask & AFL_ASE_VIRT)
15638 fputs ("\n\tVZ ASE", stdout);
15639 if (mask & AFL_ASE_MSA)
15640 fputs ("\n\tMSA ASE", stdout);
15641 if (mask & AFL_ASE_MIPS16)
15642 fputs ("\n\tMIPS16 ASE", stdout);
15643 if (mask & AFL_ASE_MICROMIPS)
15644 fputs ("\n\tMICROMIPS ASE", stdout);
15645 if (mask & AFL_ASE_XPA)
15646 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
15647 if (mask & AFL_ASE_MIPS16E2)
15648 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
15649 if (mask & AFL_ASE_CRC)
15650 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
15651 if (mask & AFL_ASE_GINV)
15652 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
15653 if (mask & AFL_ASE_LOONGSON_MMI)
15654 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
15655 if (mask & AFL_ASE_LOONGSON_CAM)
15656 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
15657 if (mask & AFL_ASE_LOONGSON_EXT)
15658 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
15659 if (mask & AFL_ASE_LOONGSON_EXT2)
15660 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
15661 if (mask == 0)
15662 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
15663 else if ((mask & ~AFL_ASE_MASK) != 0)
15664 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
15665}
15666
15667static void
15668print_mips_isa_ext (unsigned int isa_ext)
15669{
15670 switch (isa_ext)
15671 {
15672 case 0:
15673 fputs (_("None"), stdout);
15674 break;
15675 case AFL_EXT_XLR:
15676 fputs ("RMI XLR", stdout);
15677 break;
2c629856
N
15678 case AFL_EXT_OCTEON3:
15679 fputs ("Cavium Networks Octeon3", stdout);
15680 break;
351cdf24
MF
15681 case AFL_EXT_OCTEON2:
15682 fputs ("Cavium Networks Octeon2", stdout);
15683 break;
15684 case AFL_EXT_OCTEONP:
15685 fputs ("Cavium Networks OcteonP", stdout);
15686 break;
351cdf24
MF
15687 case AFL_EXT_OCTEON:
15688 fputs ("Cavium Networks Octeon", stdout);
15689 break;
15690 case AFL_EXT_5900:
15691 fputs ("Toshiba R5900", stdout);
15692 break;
15693 case AFL_EXT_4650:
15694 fputs ("MIPS R4650", stdout);
15695 break;
15696 case AFL_EXT_4010:
15697 fputs ("LSI R4010", stdout);
15698 break;
15699 case AFL_EXT_4100:
15700 fputs ("NEC VR4100", stdout);
15701 break;
15702 case AFL_EXT_3900:
15703 fputs ("Toshiba R3900", stdout);
15704 break;
15705 case AFL_EXT_10000:
15706 fputs ("MIPS R10000", stdout);
15707 break;
15708 case AFL_EXT_SB1:
15709 fputs ("Broadcom SB-1", stdout);
15710 break;
15711 case AFL_EXT_4111:
15712 fputs ("NEC VR4111/VR4181", stdout);
15713 break;
15714 case AFL_EXT_4120:
15715 fputs ("NEC VR4120", stdout);
15716 break;
15717 case AFL_EXT_5400:
15718 fputs ("NEC VR5400", stdout);
15719 break;
15720 case AFL_EXT_5500:
15721 fputs ("NEC VR5500", stdout);
15722 break;
15723 case AFL_EXT_LOONGSON_2E:
15724 fputs ("ST Microelectronics Loongson 2E", stdout);
15725 break;
15726 case AFL_EXT_LOONGSON_2F:
15727 fputs ("ST Microelectronics Loongson 2F", stdout);
15728 break;
38bf472a
MR
15729 case AFL_EXT_INTERAPTIV_MR2:
15730 fputs ("Imagination interAptiv MR2", stdout);
15731 break;
351cdf24 15732 default:
00ac7aa0 15733 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
15734 }
15735}
15736
32ec8896 15737static signed int
351cdf24
MF
15738get_mips_reg_size (int reg_size)
15739{
15740 return (reg_size == AFL_REG_NONE) ? 0
15741 : (reg_size == AFL_REG_32) ? 32
15742 : (reg_size == AFL_REG_64) ? 64
15743 : (reg_size == AFL_REG_128) ? 128
15744 : -1;
15745}
15746
32ec8896 15747static bfd_boolean
dda8d76d 15748process_mips_specific (Filedata * filedata)
5b18a4bc 15749{
2cf0635d 15750 Elf_Internal_Dyn * entry;
351cdf24 15751 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
15752 size_t liblist_offset = 0;
15753 size_t liblistno = 0;
15754 size_t conflictsno = 0;
15755 size_t options_offset = 0;
15756 size_t conflicts_offset = 0;
861fb55a
DJ
15757 size_t pltrelsz = 0;
15758 size_t pltrel = 0;
ccb4c951 15759 bfd_vma pltgot = 0;
861fb55a
DJ
15760 bfd_vma mips_pltgot = 0;
15761 bfd_vma jmprel = 0;
ccb4c951
RS
15762 bfd_vma local_gotno = 0;
15763 bfd_vma gotsym = 0;
15764 bfd_vma symtabno = 0;
32ec8896 15765 bfd_boolean res = TRUE;
103f02d3 15766
dda8d76d 15767 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
15768 display_mips_gnu_attribute))
15769 res = FALSE;
2cf19d5c 15770
dda8d76d 15771 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
15772
15773 if (sect != NULL)
15774 {
15775 Elf_External_ABIFlags_v0 *abiflags_ext;
15776 Elf_Internal_ABIFlags_v0 abiflags_in;
15777
15778 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
15779 {
15780 error (_("Corrupt MIPS ABI Flags section.\n"));
15781 res = FALSE;
15782 }
351cdf24
MF
15783 else
15784 {
dda8d76d 15785 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
15786 sect->sh_size, _("MIPS ABI Flags section"));
15787 if (abiflags_ext)
15788 {
15789 abiflags_in.version = BYTE_GET (abiflags_ext->version);
15790 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
15791 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
15792 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
15793 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
15794 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
15795 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
15796 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
15797 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
15798 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
15799 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
15800
15801 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
15802 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
15803 if (abiflags_in.isa_rev > 1)
15804 printf ("r%d", abiflags_in.isa_rev);
15805 printf ("\nGPR size: %d",
15806 get_mips_reg_size (abiflags_in.gpr_size));
15807 printf ("\nCPR1 size: %d",
15808 get_mips_reg_size (abiflags_in.cpr1_size));
15809 printf ("\nCPR2 size: %d",
15810 get_mips_reg_size (abiflags_in.cpr2_size));
15811 fputs ("\nFP ABI: ", stdout);
15812 print_mips_fp_abi_value (abiflags_in.fp_abi);
15813 fputs ("ISA Extension: ", stdout);
15814 print_mips_isa_ext (abiflags_in.isa_ext);
15815 fputs ("\nASEs:", stdout);
15816 print_mips_ases (abiflags_in.ases);
15817 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
15818 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
15819 fputc ('\n', stdout);
15820 free (abiflags_ext);
15821 }
15822 }
15823 }
15824
19e6b90e
L
15825 /* We have a lot of special sections. Thanks SGI! */
15826 if (dynamic_section == NULL)
bbdd9a68
MR
15827 {
15828 /* No dynamic information available. See if there is static GOT. */
dda8d76d 15829 sect = find_section (filedata, ".got");
bbdd9a68
MR
15830 if (sect != NULL)
15831 {
15832 unsigned char *data_end;
15833 unsigned char *data;
15834 bfd_vma ent, end;
15835 int addr_size;
15836
15837 pltgot = sect->sh_addr;
15838
15839 ent = pltgot;
15840 addr_size = (is_32bit_elf ? 4 : 8);
15841 end = pltgot + sect->sh_size;
15842
dda8d76d 15843 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
15844 end - pltgot, 1,
15845 _("Global Offset Table data"));
15846 /* PR 12855: Null data is handled gracefully throughout. */
15847 data_end = data + (end - pltgot);
15848
15849 printf (_("\nStatic GOT:\n"));
15850 printf (_(" Canonical gp value: "));
15851 print_vma (ent + 0x7ff0, LONG_HEX);
15852 printf ("\n\n");
15853
15854 /* In a dynamic binary GOT[0] is reserved for the dynamic
15855 loader to store the lazy resolver pointer, however in
15856 a static binary it may well have been omitted and GOT
15857 reduced to a table of addresses.
15858 PR 21344: Check for the entry being fully available
15859 before fetching it. */
15860 if (data
15861 && data + ent - pltgot + addr_size <= data_end
15862 && byte_get (data + ent - pltgot, addr_size) == 0)
15863 {
15864 printf (_(" Reserved entries:\n"));
15865 printf (_(" %*s %10s %*s\n"),
15866 addr_size * 2, _("Address"), _("Access"),
15867 addr_size * 2, _("Value"));
15868 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15869 printf ("\n");
15870 if (ent == (bfd_vma) -1)
15871 goto sgot_print_fail;
15872
15873 /* Check for the MSB of GOT[1] being set, identifying a
15874 GNU object. This entry will be used by some runtime
15875 loaders, to store the module pointer. Otherwise this
15876 is an ordinary local entry.
15877 PR 21344: Check for the entry being fully available
15878 before fetching it. */
15879 if (data
15880 && data + ent - pltgot + addr_size <= data_end
15881 && (byte_get (data + ent - pltgot, addr_size)
15882 >> (addr_size * 8 - 1)) != 0)
15883 {
15884 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15885 printf ("\n");
15886 if (ent == (bfd_vma) -1)
15887 goto sgot_print_fail;
15888 }
15889 printf ("\n");
15890 }
15891
f17e9d8a 15892 if (data != NULL && ent < end)
bbdd9a68
MR
15893 {
15894 printf (_(" Local entries:\n"));
15895 printf (" %*s %10s %*s\n",
15896 addr_size * 2, _("Address"), _("Access"),
15897 addr_size * 2, _("Value"));
15898 while (ent < end)
15899 {
15900 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15901 printf ("\n");
15902 if (ent == (bfd_vma) -1)
15903 goto sgot_print_fail;
15904 }
15905 printf ("\n");
15906 }
15907
15908 sgot_print_fail:
15909 if (data)
15910 free (data);
15911 }
15912 return res;
15913 }
252b5132 15914
071436c6
NC
15915 for (entry = dynamic_section;
15916 /* PR 17531 file: 012-50589-0.004. */
15917 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
15918 ++entry)
252b5132
RH
15919 switch (entry->d_tag)
15920 {
15921 case DT_MIPS_LIBLIST:
d93f0186 15922 liblist_offset
dda8d76d 15923 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 15924 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
15925 break;
15926 case DT_MIPS_LIBLISTNO:
15927 liblistno = entry->d_un.d_val;
15928 break;
15929 case DT_MIPS_OPTIONS:
dda8d76d 15930 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
15931 break;
15932 case DT_MIPS_CONFLICT:
d93f0186 15933 conflicts_offset
dda8d76d 15934 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 15935 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
15936 break;
15937 case DT_MIPS_CONFLICTNO:
15938 conflictsno = entry->d_un.d_val;
15939 break;
ccb4c951 15940 case DT_PLTGOT:
861fb55a
DJ
15941 pltgot = entry->d_un.d_ptr;
15942 break;
ccb4c951
RS
15943 case DT_MIPS_LOCAL_GOTNO:
15944 local_gotno = entry->d_un.d_val;
15945 break;
15946 case DT_MIPS_GOTSYM:
15947 gotsym = entry->d_un.d_val;
15948 break;
15949 case DT_MIPS_SYMTABNO:
15950 symtabno = entry->d_un.d_val;
15951 break;
861fb55a
DJ
15952 case DT_MIPS_PLTGOT:
15953 mips_pltgot = entry->d_un.d_ptr;
15954 break;
15955 case DT_PLTREL:
15956 pltrel = entry->d_un.d_val;
15957 break;
15958 case DT_PLTRELSZ:
15959 pltrelsz = entry->d_un.d_val;
15960 break;
15961 case DT_JMPREL:
15962 jmprel = entry->d_un.d_ptr;
15963 break;
252b5132
RH
15964 default:
15965 break;
15966 }
15967
15968 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
15969 {
2cf0635d 15970 Elf32_External_Lib * elib;
252b5132
RH
15971 size_t cnt;
15972
dda8d76d 15973 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
3f5e193b
NC
15974 liblistno,
15975 sizeof (Elf32_External_Lib),
9cf03b7e 15976 _("liblist section data"));
a6e9f9df 15977 if (elib)
252b5132 15978 {
d3a49aa8
AM
15979 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
15980 "\nSection '.liblist' contains %lu entries:\n",
15981 (unsigned long) liblistno),
a6e9f9df 15982 (unsigned long) liblistno);
2b692964 15983 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
15984 stdout);
15985
15986 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 15987 {
a6e9f9df 15988 Elf32_Lib liblist;
91d6fa6a 15989 time_t atime;
d5b07ef4 15990 char timebuf[128];
2cf0635d 15991 struct tm * tmp;
a6e9f9df
AM
15992
15993 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 15994 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
15995 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
15996 liblist.l_version = BYTE_GET (elib[cnt].l_version);
15997 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
15998
91d6fa6a 15999 tmp = gmtime (&atime);
e9e44622
JJ
16000 snprintf (timebuf, sizeof (timebuf),
16001 "%04u-%02u-%02uT%02u:%02u:%02u",
16002 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16003 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 16004
31104126 16005 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
16006 if (VALID_DYNAMIC_NAME (liblist.l_name))
16007 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
16008 else
2b692964 16009 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
16010 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
16011 liblist.l_version);
a6e9f9df
AM
16012
16013 if (liblist.l_flags == 0)
2b692964 16014 puts (_(" NONE"));
a6e9f9df
AM
16015 else
16016 {
16017 static const struct
252b5132 16018 {
2cf0635d 16019 const char * name;
a6e9f9df 16020 int bit;
252b5132 16021 }
a6e9f9df
AM
16022 l_flags_vals[] =
16023 {
16024 { " EXACT_MATCH", LL_EXACT_MATCH },
16025 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
16026 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
16027 { " EXPORTS", LL_EXPORTS },
16028 { " DELAY_LOAD", LL_DELAY_LOAD },
16029 { " DELTA", LL_DELTA }
16030 };
16031 int flags = liblist.l_flags;
16032 size_t fcnt;
16033
60bca95a 16034 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
16035 if ((flags & l_flags_vals[fcnt].bit) != 0)
16036 {
16037 fputs (l_flags_vals[fcnt].name, stdout);
16038 flags ^= l_flags_vals[fcnt].bit;
16039 }
16040 if (flags != 0)
16041 printf (" %#x", (unsigned int) flags);
252b5132 16042
a6e9f9df
AM
16043 puts ("");
16044 }
252b5132 16045 }
252b5132 16046
a6e9f9df
AM
16047 free (elib);
16048 }
32ec8896
NC
16049 else
16050 res = FALSE;
252b5132
RH
16051 }
16052
16053 if (options_offset != 0)
16054 {
2cf0635d 16055 Elf_External_Options * eopt;
2cf0635d
NC
16056 Elf_Internal_Options * iopt;
16057 Elf_Internal_Options * option;
252b5132
RH
16058 size_t offset;
16059 int cnt;
dda8d76d 16060 sect = filedata->section_headers;
252b5132
RH
16061
16062 /* Find the section header so that we get the size. */
dda8d76d 16063 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 16064 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
16065 if (sect == NULL)
16066 {
16067 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 16068 return FALSE;
071436c6 16069 }
252b5132 16070
dda8d76d 16071 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 16072 sect->sh_size, _("options"));
a6e9f9df 16073 if (eopt)
252b5132 16074 {
3f5e193b
NC
16075 iopt = (Elf_Internal_Options *)
16076 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
16077 if (iopt == NULL)
16078 {
fb324ee9 16079 error (_("Out of memory allocating space for MIPS options\n"));
32ec8896 16080 return FALSE;
a6e9f9df 16081 }
76da6bbe 16082
a6e9f9df
AM
16083 offset = cnt = 0;
16084 option = iopt;
252b5132 16085
82b1b41b 16086 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 16087 {
2cf0635d 16088 Elf_External_Options * eoption;
252b5132 16089
a6e9f9df 16090 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 16091
a6e9f9df
AM
16092 option->kind = BYTE_GET (eoption->kind);
16093 option->size = BYTE_GET (eoption->size);
16094 option->section = BYTE_GET (eoption->section);
16095 option->info = BYTE_GET (eoption->info);
76da6bbe 16096
82b1b41b
NC
16097 /* PR 17531: file: ffa0fa3b. */
16098 if (option->size < sizeof (* eopt)
16099 || offset + option->size > sect->sh_size)
16100 {
55325047 16101 error (_("Invalid size (%u) for MIPS option\n"), option->size);
32ec8896 16102 return FALSE;
82b1b41b 16103 }
a6e9f9df 16104 offset += option->size;
14ae95f2 16105
a6e9f9df
AM
16106 ++option;
16107 ++cnt;
16108 }
252b5132 16109
d3a49aa8
AM
16110 printf (ngettext ("\nSection '%s' contains %d entry:\n",
16111 "\nSection '%s' contains %d entries:\n",
16112 cnt),
dda8d76d 16113 printable_section_name (filedata, sect), cnt);
76da6bbe 16114
a6e9f9df 16115 option = iopt;
82b1b41b 16116 offset = 0;
252b5132 16117
a6e9f9df 16118 while (cnt-- > 0)
252b5132 16119 {
a6e9f9df
AM
16120 size_t len;
16121
16122 switch (option->kind)
252b5132 16123 {
a6e9f9df
AM
16124 case ODK_NULL:
16125 /* This shouldn't happen. */
16126 printf (" NULL %d %lx", option->section, option->info);
16127 break;
16128 case ODK_REGINFO:
16129 printf (" REGINFO ");
dda8d76d 16130 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df
AM
16131 {
16132 /* 32bit form. */
2cf0635d 16133 Elf32_External_RegInfo * ereg;
b34976b6 16134 Elf32_RegInfo reginfo;
a6e9f9df
AM
16135
16136 ereg = (Elf32_External_RegInfo *) (option + 1);
16137 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
16138 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
16139 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16140 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16141 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
16142 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
16143
16144 printf ("GPR %08lx GP 0x%lx\n",
16145 reginfo.ri_gprmask,
16146 (unsigned long) reginfo.ri_gp_value);
16147 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
16148 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
16149 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
16150 }
16151 else
16152 {
16153 /* 64 bit form. */
2cf0635d 16154 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
16155 Elf64_Internal_RegInfo reginfo;
16156
16157 ereg = (Elf64_External_RegInfo *) (option + 1);
16158 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
16159 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
16160 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16161 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16162 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 16163 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
16164
16165 printf ("GPR %08lx GP 0x",
16166 reginfo.ri_gprmask);
16167 printf_vma (reginfo.ri_gp_value);
16168 printf ("\n");
16169
16170 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
16171 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
16172 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
16173 }
16174 ++option;
16175 continue;
16176 case ODK_EXCEPTIONS:
16177 fputs (" EXCEPTIONS fpe_min(", stdout);
16178 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
16179 fputs (") fpe_max(", stdout);
16180 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
16181 fputs (")", stdout);
16182
16183 if (option->info & OEX_PAGE0)
16184 fputs (" PAGE0", stdout);
16185 if (option->info & OEX_SMM)
16186 fputs (" SMM", stdout);
16187 if (option->info & OEX_FPDBUG)
16188 fputs (" FPDBUG", stdout);
16189 if (option->info & OEX_DISMISS)
16190 fputs (" DISMISS", stdout);
16191 break;
16192 case ODK_PAD:
16193 fputs (" PAD ", stdout);
16194 if (option->info & OPAD_PREFIX)
16195 fputs (" PREFIX", stdout);
16196 if (option->info & OPAD_POSTFIX)
16197 fputs (" POSTFIX", stdout);
16198 if (option->info & OPAD_SYMBOL)
16199 fputs (" SYMBOL", stdout);
16200 break;
16201 case ODK_HWPATCH:
16202 fputs (" HWPATCH ", stdout);
16203 if (option->info & OHW_R4KEOP)
16204 fputs (" R4KEOP", stdout);
16205 if (option->info & OHW_R8KPFETCH)
16206 fputs (" R8KPFETCH", stdout);
16207 if (option->info & OHW_R5KEOP)
16208 fputs (" R5KEOP", stdout);
16209 if (option->info & OHW_R5KCVTL)
16210 fputs (" R5KCVTL", stdout);
16211 break;
16212 case ODK_FILL:
16213 fputs (" FILL ", stdout);
16214 /* XXX Print content of info word? */
16215 break;
16216 case ODK_TAGS:
16217 fputs (" TAGS ", stdout);
16218 /* XXX Print content of info word? */
16219 break;
16220 case ODK_HWAND:
16221 fputs (" HWAND ", stdout);
16222 if (option->info & OHWA0_R4KEOP_CHECKED)
16223 fputs (" R4KEOP_CHECKED", stdout);
16224 if (option->info & OHWA0_R4KEOP_CLEAN)
16225 fputs (" R4KEOP_CLEAN", stdout);
16226 break;
16227 case ODK_HWOR:
16228 fputs (" HWOR ", stdout);
16229 if (option->info & OHWA0_R4KEOP_CHECKED)
16230 fputs (" R4KEOP_CHECKED", stdout);
16231 if (option->info & OHWA0_R4KEOP_CLEAN)
16232 fputs (" R4KEOP_CLEAN", stdout);
16233 break;
16234 case ODK_GP_GROUP:
16235 printf (" GP_GROUP %#06lx self-contained %#06lx",
16236 option->info & OGP_GROUP,
16237 (option->info & OGP_SELF) >> 16);
16238 break;
16239 case ODK_IDENT:
16240 printf (" IDENT %#06lx self-contained %#06lx",
16241 option->info & OGP_GROUP,
16242 (option->info & OGP_SELF) >> 16);
16243 break;
16244 default:
16245 /* This shouldn't happen. */
16246 printf (" %3d ??? %d %lx",
16247 option->kind, option->section, option->info);
16248 break;
252b5132 16249 }
a6e9f9df 16250
2cf0635d 16251 len = sizeof (* eopt);
a6e9f9df 16252 while (len < option->size)
82b1b41b 16253 {
7e27a9d5 16254 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 16255
82b1b41b
NC
16256 if (ISPRINT (datum))
16257 printf ("%c", datum);
16258 else
16259 printf ("\\%03o", datum);
16260 len ++;
16261 }
a6e9f9df 16262 fputs ("\n", stdout);
82b1b41b
NC
16263
16264 offset += option->size;
252b5132 16265 ++option;
252b5132
RH
16266 }
16267
a6e9f9df 16268 free (eopt);
252b5132 16269 }
32ec8896
NC
16270 else
16271 res = FALSE;
252b5132
RH
16272 }
16273
16274 if (conflicts_offset != 0 && conflictsno != 0)
16275 {
2cf0635d 16276 Elf32_Conflict * iconf;
252b5132
RH
16277 size_t cnt;
16278
16279 if (dynamic_symbols == NULL)
16280 {
591a748a 16281 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 16282 return FALSE;
252b5132
RH
16283 }
16284
7296a62a
NC
16285 /* PR 21345 - print a slightly more helpful error message
16286 if we are sure that the cmalloc will fail. */
dda8d76d 16287 if (conflictsno * sizeof (* iconf) > filedata->file_size)
7296a62a
NC
16288 {
16289 error (_("Overlarge number of conflicts detected: %lx\n"),
16290 (long) conflictsno);
16291 return FALSE;
16292 }
16293
3f5e193b 16294 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
16295 if (iconf == NULL)
16296 {
8b73c356 16297 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 16298 return FALSE;
252b5132
RH
16299 }
16300
9ea033b2 16301 if (is_32bit_elf)
252b5132 16302 {
2cf0635d 16303 Elf32_External_Conflict * econf32;
a6e9f9df 16304
3f5e193b 16305 econf32 = (Elf32_External_Conflict *)
dda8d76d 16306 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16307 sizeof (* econf32), _("conflict"));
a6e9f9df 16308 if (!econf32)
32ec8896 16309 return FALSE;
252b5132
RH
16310
16311 for (cnt = 0; cnt < conflictsno; ++cnt)
16312 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
16313
16314 free (econf32);
252b5132
RH
16315 }
16316 else
16317 {
2cf0635d 16318 Elf64_External_Conflict * econf64;
a6e9f9df 16319
3f5e193b 16320 econf64 = (Elf64_External_Conflict *)
dda8d76d 16321 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16322 sizeof (* econf64), _("conflict"));
a6e9f9df 16323 if (!econf64)
32ec8896 16324 return FALSE;
252b5132
RH
16325
16326 for (cnt = 0; cnt < conflictsno; ++cnt)
16327 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
16328
16329 free (econf64);
252b5132
RH
16330 }
16331
d3a49aa8
AM
16332 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
16333 "\nSection '.conflict' contains %lu entries:\n",
16334 (unsigned long) conflictsno),
c7e7ca54 16335 (unsigned long) conflictsno);
252b5132
RH
16336 puts (_(" Num: Index Value Name"));
16337
16338 for (cnt = 0; cnt < conflictsno; ++cnt)
16339 {
b34976b6 16340 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
16341
16342 if (iconf[cnt] >= num_dynamic_syms)
16343 printf (_("<corrupt symbol index>"));
d79b3d50 16344 else
e0a31db1
NC
16345 {
16346 Elf_Internal_Sym * psym;
16347
16348 psym = & dynamic_symbols[iconf[cnt]];
16349 print_vma (psym->st_value, FULL_HEX);
16350 putchar (' ');
16351 if (VALID_DYNAMIC_NAME (psym->st_name))
16352 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
16353 else
16354 printf (_("<corrupt: %14ld>"), psym->st_name);
16355 }
31104126 16356 putchar ('\n');
252b5132
RH
16357 }
16358
252b5132
RH
16359 free (iconf);
16360 }
16361
ccb4c951
RS
16362 if (pltgot != 0 && local_gotno != 0)
16363 {
91d6fa6a 16364 bfd_vma ent, local_end, global_end;
bbeee7ea 16365 size_t i, offset;
2cf0635d 16366 unsigned char * data;
82b1b41b 16367 unsigned char * data_end;
bbeee7ea 16368 int addr_size;
ccb4c951 16369
91d6fa6a 16370 ent = pltgot;
ccb4c951
RS
16371 addr_size = (is_32bit_elf ? 4 : 8);
16372 local_end = pltgot + local_gotno * addr_size;
ccb4c951 16373
74e1a04b
NC
16374 /* PR binutils/17533 file: 012-111227-0.004 */
16375 if (symtabno < gotsym)
16376 {
16377 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 16378 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 16379 return FALSE;
74e1a04b 16380 }
82b1b41b 16381
74e1a04b 16382 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
16383 /* PR 17531: file: 54c91a34. */
16384 if (global_end < local_end)
16385 {
16386 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 16387 return FALSE;
82b1b41b 16388 }
948f632f 16389
dda8d76d
NC
16390 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
16391 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
16392 global_end - pltgot, 1,
16393 _("Global Offset Table data"));
919383ac 16394 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 16395 data_end = data + (global_end - pltgot);
59245841 16396
ccb4c951
RS
16397 printf (_("\nPrimary GOT:\n"));
16398 printf (_(" Canonical gp value: "));
16399 print_vma (pltgot + 0x7ff0, LONG_HEX);
16400 printf ("\n\n");
16401
16402 printf (_(" Reserved entries:\n"));
16403 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
16404 addr_size * 2, _("Address"), _("Access"),
16405 addr_size * 2, _("Initial"));
82b1b41b 16406 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 16407 printf (_(" Lazy resolver\n"));
82b1b41b
NC
16408 if (ent == (bfd_vma) -1)
16409 goto got_print_fail;
75ec1fdb 16410
c4ab9505
MR
16411 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
16412 This entry will be used by some runtime loaders, to store the
16413 module pointer. Otherwise this is an ordinary local entry.
16414 PR 21344: Check for the entry being fully available before
16415 fetching it. */
16416 if (data
16417 && data + ent - pltgot + addr_size <= data_end
16418 && (byte_get (data + ent - pltgot, addr_size)
16419 >> (addr_size * 8 - 1)) != 0)
16420 {
16421 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16422 printf (_(" Module pointer (GNU extension)\n"));
16423 if (ent == (bfd_vma) -1)
16424 goto got_print_fail;
ccb4c951
RS
16425 }
16426 printf ("\n");
16427
f17e9d8a 16428 if (data != NULL && ent < local_end)
ccb4c951
RS
16429 {
16430 printf (_(" Local entries:\n"));
cc5914eb 16431 printf (" %*s %10s %*s\n",
2b692964
NC
16432 addr_size * 2, _("Address"), _("Access"),
16433 addr_size * 2, _("Initial"));
91d6fa6a 16434 while (ent < local_end)
ccb4c951 16435 {
82b1b41b 16436 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16437 printf ("\n");
82b1b41b
NC
16438 if (ent == (bfd_vma) -1)
16439 goto got_print_fail;
ccb4c951
RS
16440 }
16441 printf ("\n");
16442 }
16443
f17e9d8a 16444 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
16445 {
16446 int sym_width;
16447
16448 printf (_(" Global entries:\n"));
cc5914eb 16449 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
16450 addr_size * 2, _("Address"),
16451 _("Access"),
2b692964 16452 addr_size * 2, _("Initial"),
9cf03b7e
NC
16453 addr_size * 2, _("Sym.Val."),
16454 _("Type"),
16455 /* Note for translators: "Ndx" = abbreviated form of "Index". */
16456 _("Ndx"), _("Name"));
0b4362b0 16457
ccb4c951 16458 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 16459
ccb4c951
RS
16460 for (i = gotsym; i < symtabno; i++)
16461 {
82b1b41b 16462 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16463 printf (" ");
e0a31db1
NC
16464
16465 if (dynamic_symbols == NULL)
16466 printf (_("<no dynamic symbols>"));
16467 else if (i < num_dynamic_syms)
16468 {
16469 Elf_Internal_Sym * psym = dynamic_symbols + i;
16470
16471 print_vma (psym->st_value, LONG_HEX);
16472 printf (" %-7s %3s ",
dda8d76d
NC
16473 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16474 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16475
16476 if (VALID_DYNAMIC_NAME (psym->st_name))
16477 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16478 else
16479 printf (_("<corrupt: %14ld>"), psym->st_name);
16480 }
ccb4c951 16481 else
7fc5ac57
JBG
16482 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
16483 (unsigned long) i);
e0a31db1 16484
ccb4c951 16485 printf ("\n");
82b1b41b
NC
16486 if (ent == (bfd_vma) -1)
16487 break;
ccb4c951
RS
16488 }
16489 printf ("\n");
16490 }
16491
82b1b41b 16492 got_print_fail:
ccb4c951
RS
16493 if (data)
16494 free (data);
16495 }
16496
861fb55a
DJ
16497 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
16498 {
91d6fa6a 16499 bfd_vma ent, end;
861fb55a
DJ
16500 size_t offset, rel_offset;
16501 unsigned long count, i;
2cf0635d 16502 unsigned char * data;
861fb55a 16503 int addr_size, sym_width;
2cf0635d 16504 Elf_Internal_Rela * rels;
861fb55a 16505
dda8d76d 16506 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
16507 if (pltrel == DT_RELA)
16508 {
dda8d76d 16509 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16510 return FALSE;
861fb55a
DJ
16511 }
16512 else
16513 {
dda8d76d 16514 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16515 return FALSE;
861fb55a
DJ
16516 }
16517
91d6fa6a 16518 ent = mips_pltgot;
861fb55a
DJ
16519 addr_size = (is_32bit_elf ? 4 : 8);
16520 end = mips_pltgot + (2 + count) * addr_size;
16521
dda8d76d
NC
16522 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
16523 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 16524 1, _("Procedure Linkage Table data"));
59245841 16525 if (data == NULL)
32ec8896 16526 return FALSE;
59245841 16527
9cf03b7e 16528 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
16529 printf (_(" Reserved entries:\n"));
16530 printf (_(" %*s %*s Purpose\n"),
2b692964 16531 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 16532 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16533 printf (_(" PLT lazy resolver\n"));
91d6fa6a 16534 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16535 printf (_(" Module pointer\n"));
861fb55a
DJ
16536 printf ("\n");
16537
16538 printf (_(" Entries:\n"));
cc5914eb 16539 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
16540 addr_size * 2, _("Address"),
16541 addr_size * 2, _("Initial"),
16542 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
16543 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
16544 for (i = 0; i < count; i++)
16545 {
df97ab2a 16546 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 16547
91d6fa6a 16548 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 16549 printf (" ");
e0a31db1 16550
df97ab2a
MF
16551 if (idx >= num_dynamic_syms)
16552 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 16553 else
e0a31db1 16554 {
df97ab2a 16555 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
16556
16557 print_vma (psym->st_value, LONG_HEX);
16558 printf (" %-7s %3s ",
dda8d76d
NC
16559 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16560 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16561 if (VALID_DYNAMIC_NAME (psym->st_name))
16562 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16563 else
16564 printf (_("<corrupt: %14ld>"), psym->st_name);
16565 }
861fb55a
DJ
16566 printf ("\n");
16567 }
16568 printf ("\n");
16569
16570 if (data)
16571 free (data);
16572 free (rels);
16573 }
16574
32ec8896 16575 return res;
252b5132
RH
16576}
16577
32ec8896 16578static bfd_boolean
dda8d76d 16579process_nds32_specific (Filedata * filedata)
35c08157
KLC
16580{
16581 Elf_Internal_Shdr *sect = NULL;
16582
dda8d76d 16583 sect = find_section (filedata, ".nds32_e_flags");
35c08157
KLC
16584 if (sect != NULL)
16585 {
16586 unsigned int *flag;
16587
16588 printf ("\nNDS32 elf flags section:\n");
dda8d76d 16589 flag = get_data (NULL, filedata, sect->sh_offset, 1,
35c08157
KLC
16590 sect->sh_size, _("NDS32 elf flags section"));
16591
32ec8896
NC
16592 if (! flag)
16593 return FALSE;
16594
35c08157
KLC
16595 switch ((*flag) & 0x3)
16596 {
16597 case 0:
16598 printf ("(VEC_SIZE):\tNo entry.\n");
16599 break;
16600 case 1:
16601 printf ("(VEC_SIZE):\t4 bytes\n");
16602 break;
16603 case 2:
16604 printf ("(VEC_SIZE):\t16 bytes\n");
16605 break;
16606 case 3:
16607 printf ("(VEC_SIZE):\treserved\n");
16608 break;
16609 }
16610 }
16611
16612 return TRUE;
16613}
16614
32ec8896 16615static bfd_boolean
dda8d76d 16616process_gnu_liblist (Filedata * filedata)
047b2264 16617{
2cf0635d
NC
16618 Elf_Internal_Shdr * section;
16619 Elf_Internal_Shdr * string_sec;
16620 Elf32_External_Lib * elib;
16621 char * strtab;
c256ffe7 16622 size_t strtab_size;
047b2264 16623 size_t cnt;
d3a49aa8 16624 unsigned long num_liblist;
047b2264 16625 unsigned i;
32ec8896 16626 bfd_boolean res = TRUE;
047b2264
JJ
16627
16628 if (! do_arch)
32ec8896 16629 return TRUE;
047b2264 16630
dda8d76d
NC
16631 for (i = 0, section = filedata->section_headers;
16632 i < filedata->file_header.e_shnum;
b34976b6 16633 i++, section++)
047b2264
JJ
16634 {
16635 switch (section->sh_type)
16636 {
16637 case SHT_GNU_LIBLIST:
dda8d76d 16638 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
16639 break;
16640
3f5e193b 16641 elib = (Elf32_External_Lib *)
dda8d76d 16642 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 16643 _("liblist section data"));
047b2264
JJ
16644
16645 if (elib == NULL)
32ec8896
NC
16646 {
16647 res = FALSE;
16648 break;
16649 }
047b2264 16650
dda8d76d
NC
16651 string_sec = filedata->section_headers + section->sh_link;
16652 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
16653 string_sec->sh_size,
16654 _("liblist string table"));
047b2264
JJ
16655 if (strtab == NULL
16656 || section->sh_entsize != sizeof (Elf32_External_Lib))
16657 {
16658 free (elib);
2842702f 16659 free (strtab);
32ec8896 16660 res = FALSE;
047b2264
JJ
16661 break;
16662 }
59245841 16663 strtab_size = string_sec->sh_size;
047b2264 16664
d3a49aa8
AM
16665 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
16666 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
16667 "\nLibrary list section '%s' contains %lu entries:\n",
16668 num_liblist),
dda8d76d 16669 printable_section_name (filedata, section),
d3a49aa8 16670 num_liblist);
047b2264 16671
2b692964 16672 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
16673
16674 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
16675 ++cnt)
16676 {
16677 Elf32_Lib liblist;
91d6fa6a 16678 time_t atime;
d5b07ef4 16679 char timebuf[128];
2cf0635d 16680 struct tm * tmp;
047b2264
JJ
16681
16682 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16683 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
16684 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16685 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16686 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16687
91d6fa6a 16688 tmp = gmtime (&atime);
e9e44622
JJ
16689 snprintf (timebuf, sizeof (timebuf),
16690 "%04u-%02u-%02uT%02u:%02u:%02u",
16691 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16692 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
16693
16694 printf ("%3lu: ", (unsigned long) cnt);
16695 if (do_wide)
c256ffe7 16696 printf ("%-20s", liblist.l_name < strtab_size
2b692964 16697 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 16698 else
c256ffe7 16699 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 16700 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
16701 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
16702 liblist.l_version, liblist.l_flags);
16703 }
16704
16705 free (elib);
2842702f 16706 free (strtab);
047b2264
JJ
16707 }
16708 }
16709
32ec8896 16710 return res;
047b2264
JJ
16711}
16712
9437c45b 16713static const char *
dda8d76d 16714get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
16715{
16716 static char buff[64];
103f02d3 16717
dda8d76d 16718 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
16719 switch (e_type)
16720 {
57346661 16721 case NT_AUXV:
1ec5cd37 16722 return _("NT_AUXV (auxiliary vector)");
57346661 16723 case NT_PRSTATUS:
1ec5cd37 16724 return _("NT_PRSTATUS (prstatus structure)");
57346661 16725 case NT_FPREGSET:
1ec5cd37 16726 return _("NT_FPREGSET (floating point registers)");
57346661 16727 case NT_PRPSINFO:
1ec5cd37 16728 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 16729 case NT_TASKSTRUCT:
1ec5cd37 16730 return _("NT_TASKSTRUCT (task structure)");
57346661 16731 case NT_PRXFPREG:
1ec5cd37 16732 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
16733 case NT_PPC_VMX:
16734 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
16735 case NT_PPC_VSX:
16736 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
16737 case NT_PPC_TAR:
16738 return _("NT_PPC_TAR (ppc TAR register)");
16739 case NT_PPC_PPR:
16740 return _("NT_PPC_PPR (ppc PPR register)");
16741 case NT_PPC_DSCR:
16742 return _("NT_PPC_DSCR (ppc DSCR register)");
16743 case NT_PPC_EBB:
16744 return _("NT_PPC_EBB (ppc EBB registers)");
16745 case NT_PPC_PMU:
16746 return _("NT_PPC_PMU (ppc PMU registers)");
16747 case NT_PPC_TM_CGPR:
16748 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
16749 case NT_PPC_TM_CFPR:
16750 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
16751 case NT_PPC_TM_CVMX:
16752 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
16753 case NT_PPC_TM_CVSX:
3fd21718 16754 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
16755 case NT_PPC_TM_SPR:
16756 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
16757 case NT_PPC_TM_CTAR:
16758 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
16759 case NT_PPC_TM_CPPR:
16760 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
16761 case NT_PPC_TM_CDSCR:
16762 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
16763 case NT_386_TLS:
16764 return _("NT_386_TLS (x86 TLS information)");
16765 case NT_386_IOPERM:
16766 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
16767 case NT_X86_XSTATE:
16768 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
16769 case NT_S390_HIGH_GPRS:
16770 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
16771 case NT_S390_TIMER:
16772 return _("NT_S390_TIMER (s390 timer register)");
16773 case NT_S390_TODCMP:
16774 return _("NT_S390_TODCMP (s390 TOD comparator register)");
16775 case NT_S390_TODPREG:
16776 return _("NT_S390_TODPREG (s390 TOD programmable register)");
16777 case NT_S390_CTRS:
16778 return _("NT_S390_CTRS (s390 control registers)");
16779 case NT_S390_PREFIX:
16780 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
16781 case NT_S390_LAST_BREAK:
16782 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
16783 case NT_S390_SYSTEM_CALL:
16784 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
16785 case NT_S390_TDB:
16786 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
16787 case NT_S390_VXRS_LOW:
16788 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
16789 case NT_S390_VXRS_HIGH:
16790 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
16791 case NT_S390_GS_CB:
16792 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
16793 case NT_S390_GS_BC:
16794 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
16795 case NT_ARM_VFP:
16796 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
16797 case NT_ARM_TLS:
16798 return _("NT_ARM_TLS (AArch TLS registers)");
16799 case NT_ARM_HW_BREAK:
16800 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
16801 case NT_ARM_HW_WATCH:
16802 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 16803 case NT_PSTATUS:
1ec5cd37 16804 return _("NT_PSTATUS (pstatus structure)");
57346661 16805 case NT_FPREGS:
1ec5cd37 16806 return _("NT_FPREGS (floating point registers)");
57346661 16807 case NT_PSINFO:
1ec5cd37 16808 return _("NT_PSINFO (psinfo structure)");
57346661 16809 case NT_LWPSTATUS:
1ec5cd37 16810 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 16811 case NT_LWPSINFO:
1ec5cd37 16812 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 16813 case NT_WIN32PSTATUS:
1ec5cd37 16814 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
16815 case NT_SIGINFO:
16816 return _("NT_SIGINFO (siginfo_t data)");
16817 case NT_FILE:
16818 return _("NT_FILE (mapped files)");
1ec5cd37
NC
16819 default:
16820 break;
16821 }
16822 else
16823 switch (e_type)
16824 {
16825 case NT_VERSION:
16826 return _("NT_VERSION (version)");
16827 case NT_ARCH:
16828 return _("NT_ARCH (architecture)");
9ef920e9 16829 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 16830 return _("OPEN");
9ef920e9 16831 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 16832 return _("func");
1ec5cd37
NC
16833 default:
16834 break;
16835 }
16836
e9e44622 16837 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 16838 return buff;
779fe533
NC
16839}
16840
32ec8896 16841static bfd_boolean
9ece1fa9
TT
16842print_core_note (Elf_Internal_Note *pnote)
16843{
16844 unsigned int addr_size = is_32bit_elf ? 4 : 8;
16845 bfd_vma count, page_size;
16846 unsigned char *descdata, *filenames, *descend;
16847
16848 if (pnote->type != NT_FILE)
04ac15ab
AS
16849 {
16850 if (do_wide)
16851 printf ("\n");
16852 return TRUE;
16853 }
9ece1fa9
TT
16854
16855#ifndef BFD64
16856 if (!is_32bit_elf)
16857 {
16858 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
16859 /* Still "successful". */
32ec8896 16860 return TRUE;
9ece1fa9
TT
16861 }
16862#endif
16863
16864 if (pnote->descsz < 2 * addr_size)
16865 {
32ec8896
NC
16866 error (_(" Malformed note - too short for header\n"));
16867 return FALSE;
9ece1fa9
TT
16868 }
16869
16870 descdata = (unsigned char *) pnote->descdata;
16871 descend = descdata + pnote->descsz;
16872
16873 if (descdata[pnote->descsz - 1] != '\0')
16874 {
32ec8896
NC
16875 error (_(" Malformed note - does not end with \\0\n"));
16876 return FALSE;
9ece1fa9
TT
16877 }
16878
16879 count = byte_get (descdata, addr_size);
16880 descdata += addr_size;
16881
16882 page_size = byte_get (descdata, addr_size);
16883 descdata += addr_size;
16884
5396a86e
AM
16885 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
16886 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 16887 {
32ec8896
NC
16888 error (_(" Malformed note - too short for supplied file count\n"));
16889 return FALSE;
9ece1fa9
TT
16890 }
16891
16892 printf (_(" Page size: "));
16893 print_vma (page_size, DEC);
16894 printf ("\n");
16895
16896 printf (_(" %*s%*s%*s\n"),
16897 (int) (2 + 2 * addr_size), _("Start"),
16898 (int) (4 + 2 * addr_size), _("End"),
16899 (int) (4 + 2 * addr_size), _("Page Offset"));
16900 filenames = descdata + count * 3 * addr_size;
595712bb 16901 while (count-- > 0)
9ece1fa9
TT
16902 {
16903 bfd_vma start, end, file_ofs;
16904
16905 if (filenames == descend)
16906 {
32ec8896
NC
16907 error (_(" Malformed note - filenames end too early\n"));
16908 return FALSE;
9ece1fa9
TT
16909 }
16910
16911 start = byte_get (descdata, addr_size);
16912 descdata += addr_size;
16913 end = byte_get (descdata, addr_size);
16914 descdata += addr_size;
16915 file_ofs = byte_get (descdata, addr_size);
16916 descdata += addr_size;
16917
16918 printf (" ");
16919 print_vma (start, FULL_HEX);
16920 printf (" ");
16921 print_vma (end, FULL_HEX);
16922 printf (" ");
16923 print_vma (file_ofs, FULL_HEX);
16924 printf ("\n %s\n", filenames);
16925
16926 filenames += 1 + strlen ((char *) filenames);
16927 }
16928
32ec8896 16929 return TRUE;
9ece1fa9
TT
16930}
16931
1118d252
RM
16932static const char *
16933get_gnu_elf_note_type (unsigned e_type)
16934{
1449284b 16935 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
16936 switch (e_type)
16937 {
16938 case NT_GNU_ABI_TAG:
16939 return _("NT_GNU_ABI_TAG (ABI version tag)");
16940 case NT_GNU_HWCAP:
16941 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
16942 case NT_GNU_BUILD_ID:
16943 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
16944 case NT_GNU_GOLD_VERSION:
16945 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
16946 case NT_GNU_PROPERTY_TYPE_0:
16947 return _("NT_GNU_PROPERTY_TYPE_0");
16948 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
16949 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
16950 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
16951 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 16952 default:
1449284b
NC
16953 {
16954 static char buff[64];
1118d252 16955
1449284b
NC
16956 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
16957 return buff;
16958 }
16959 }
1118d252
RM
16960}
16961
a9eafb08
L
16962static void
16963decode_x86_compat_isa (unsigned int bitmask)
16964{
16965 while (bitmask)
16966 {
16967 unsigned int bit = bitmask & (- bitmask);
16968
16969 bitmask &= ~ bit;
16970 switch (bit)
16971 {
16972 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
16973 printf ("i486");
16974 break;
16975 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
16976 printf ("586");
16977 break;
16978 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
16979 printf ("686");
16980 break;
16981 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
16982 printf ("SSE");
16983 break;
16984 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
16985 printf ("SSE2");
16986 break;
16987 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
16988 printf ("SSE3");
16989 break;
16990 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
16991 printf ("SSSE3");
16992 break;
16993 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
16994 printf ("SSE4_1");
16995 break;
16996 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
16997 printf ("SSE4_2");
16998 break;
16999 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
17000 printf ("AVX");
17001 break;
17002 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
17003 printf ("AVX2");
17004 break;
17005 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
17006 printf ("AVX512F");
17007 break;
17008 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
17009 printf ("AVX512CD");
17010 break;
17011 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
17012 printf ("AVX512ER");
17013 break;
17014 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
17015 printf ("AVX512PF");
17016 break;
17017 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
17018 printf ("AVX512VL");
17019 break;
17020 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
17021 printf ("AVX512DQ");
17022 break;
17023 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
17024 printf ("AVX512BW");
17025 break;
65b3d26e
L
17026 default:
17027 printf (_("<unknown: %x>"), bit);
17028 break;
a9eafb08
L
17029 }
17030 if (bitmask)
17031 printf (", ");
17032 }
17033}
17034
9ef920e9 17035static void
1fc87489 17036decode_x86_isa (unsigned int bitmask)
9ef920e9 17037{
90c745dc
L
17038 if (bitmask == GNU_PROPERTY_X86_UINT32_VALID)
17039 {
17040 printf (_("<None>"));
17041 return;
17042 }
17043 else
17044 bitmask &= ~GNU_PROPERTY_X86_UINT32_VALID;
17045
9ef920e9
NC
17046 while (bitmask)
17047 {
1fc87489 17048 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
17049
17050 bitmask &= ~ bit;
17051 switch (bit)
17052 {
a9eafb08
L
17053 case GNU_PROPERTY_X86_ISA_1_CMOV:
17054 printf ("CMOV");
17055 break;
17056 case GNU_PROPERTY_X86_ISA_1_SSE:
17057 printf ("SSE");
17058 break;
17059 case GNU_PROPERTY_X86_ISA_1_SSE2:
17060 printf ("SSE2");
17061 break;
17062 case GNU_PROPERTY_X86_ISA_1_SSE3:
17063 printf ("SSE3");
17064 break;
17065 case GNU_PROPERTY_X86_ISA_1_SSSE3:
17066 printf ("SSSE3");
17067 break;
17068 case GNU_PROPERTY_X86_ISA_1_SSE4_1:
17069 printf ("SSE4_1");
17070 break;
17071 case GNU_PROPERTY_X86_ISA_1_SSE4_2:
17072 printf ("SSE4_2");
17073 break;
17074 case GNU_PROPERTY_X86_ISA_1_AVX:
17075 printf ("AVX");
17076 break;
17077 case GNU_PROPERTY_X86_ISA_1_AVX2:
17078 printf ("AVX2");
17079 break;
17080 case GNU_PROPERTY_X86_ISA_1_FMA:
17081 printf ("FMA");
17082 break;
17083 case GNU_PROPERTY_X86_ISA_1_AVX512F:
17084 printf ("AVX512F");
17085 break;
17086 case GNU_PROPERTY_X86_ISA_1_AVX512CD:
17087 printf ("AVX512CD");
17088 break;
17089 case GNU_PROPERTY_X86_ISA_1_AVX512ER:
17090 printf ("AVX512ER");
17091 break;
17092 case GNU_PROPERTY_X86_ISA_1_AVX512PF:
17093 printf ("AVX512PF");
17094 break;
17095 case GNU_PROPERTY_X86_ISA_1_AVX512VL:
17096 printf ("AVX512VL");
17097 break;
17098 case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
17099 printf ("AVX512DQ");
17100 break;
17101 case GNU_PROPERTY_X86_ISA_1_AVX512BW:
17102 printf ("AVX512BW");
17103 break;
17104 case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
17105 printf ("AVX512_4FMAPS");
17106 break;
17107 case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
17108 printf ("AVX512_4VNNIW");
17109 break;
17110 case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
17111 printf ("AVX512_BITALG");
17112 break;
17113 case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
17114 printf ("AVX512_IFMA");
17115 break;
17116 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
17117 printf ("AVX512_VBMI");
17118 break;
17119 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
17120 printf ("AVX512_VBMI2");
17121 break;
17122 case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
17123 printf ("AVX512_VNNI");
17124 break;
65b3d26e
L
17125 default:
17126 printf (_("<unknown: %x>"), bit);
17127 break;
9ef920e9
NC
17128 }
17129 if (bitmask)
17130 printf (", ");
17131 }
17132}
17133
ee2fdd6f 17134static void
a9eafb08 17135decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 17136{
90c745dc
L
17137 if (bitmask == GNU_PROPERTY_X86_UINT32_VALID)
17138 {
17139 printf (_("<None>"));
17140 return;
17141 }
17142 else
17143 bitmask &= ~GNU_PROPERTY_X86_UINT32_VALID;
17144
ee2fdd6f
L
17145 while (bitmask)
17146 {
17147 unsigned int bit = bitmask & (- bitmask);
17148
17149 bitmask &= ~ bit;
17150 switch (bit)
17151 {
17152 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 17153 printf ("IBT");
ee2fdd6f 17154 break;
48580982 17155 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 17156 printf ("SHSTK");
48580982 17157 break;
ee2fdd6f
L
17158 default:
17159 printf (_("<unknown: %x>"), bit);
17160 break;
17161 }
17162 if (bitmask)
17163 printf (", ");
17164 }
17165}
17166
a9eafb08
L
17167static void
17168decode_x86_feature_2 (unsigned int bitmask)
17169{
90c745dc
L
17170 if (bitmask == GNU_PROPERTY_X86_UINT32_VALID)
17171 {
17172 printf (_("<None>"));
17173 return;
17174 }
17175 else
17176 bitmask &= ~GNU_PROPERTY_X86_UINT32_VALID;
17177
a9eafb08
L
17178 while (bitmask)
17179 {
17180 unsigned int bit = bitmask & (- bitmask);
17181
17182 bitmask &= ~ bit;
17183 switch (bit)
17184 {
17185 case GNU_PROPERTY_X86_FEATURE_2_X86:
17186 printf ("x86");
17187 break;
17188 case GNU_PROPERTY_X86_FEATURE_2_X87:
17189 printf ("x87");
17190 break;
17191 case GNU_PROPERTY_X86_FEATURE_2_MMX:
17192 printf ("MMX");
17193 break;
17194 case GNU_PROPERTY_X86_FEATURE_2_XMM:
17195 printf ("XMM");
17196 break;
17197 case GNU_PROPERTY_X86_FEATURE_2_YMM:
17198 printf ("YMM");
17199 break;
17200 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
17201 printf ("ZMM");
17202 break;
17203 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
17204 printf ("FXSR");
17205 break;
17206 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
17207 printf ("XSAVE");
17208 break;
17209 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
17210 printf ("XSAVEOPT");
17211 break;
17212 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
17213 printf ("XSAVEC");
17214 break;
65b3d26e
L
17215 default:
17216 printf (_("<unknown: %x>"), bit);
17217 break;
a9eafb08
L
17218 }
17219 if (bitmask)
17220 printf (", ");
17221 }
17222}
17223
9ef920e9 17224static void
dda8d76d 17225print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
17226{
17227 unsigned char * ptr = (unsigned char *) pnote->descdata;
17228 unsigned char * ptr_end = ptr + pnote->descsz;
17229 unsigned int size = is_32bit_elf ? 4 : 8;
17230
17231 printf (_(" Properties: "));
17232
1fc87489 17233 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
17234 {
17235 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
17236 return;
17237 }
17238
6ab2c4ed 17239 while (ptr < ptr_end)
9ef920e9 17240 {
1fc87489 17241 unsigned int j;
6ab2c4ed
MC
17242 unsigned int type;
17243 unsigned int datasz;
17244
17245 if ((size_t) (ptr_end - ptr) < 8)
17246 {
17247 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
17248 break;
17249 }
17250
17251 type = byte_get (ptr, 4);
17252 datasz = byte_get (ptr + 4, 4);
9ef920e9 17253
1fc87489 17254 ptr += 8;
9ef920e9 17255
6ab2c4ed 17256 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 17257 {
1fc87489
L
17258 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
17259 type, datasz);
9ef920e9 17260 break;
1fc87489 17261 }
9ef920e9 17262
1fc87489
L
17263 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
17264 {
dda8d76d
NC
17265 if (filedata->file_header.e_machine == EM_X86_64
17266 || filedata->file_header.e_machine == EM_IAMCU
17267 || filedata->file_header.e_machine == EM_386)
1fc87489 17268 {
aa7bca9b
L
17269 unsigned int bitmask;
17270
17271 if (datasz == 4)
17272 {
17273 bitmask = byte_get (ptr, 4);
90c745dc
L
17274 if ((filedata->file_header.e_type == ET_EXEC
17275 || filedata->file_header.e_type == ET_DYN)
17276 && !(bitmask & GNU_PROPERTY_X86_UINT32_VALID))
17277 printf ("Invalid ");
aa7bca9b
L
17278 }
17279 else
17280 bitmask = 0;
17281
1fc87489
L
17282 switch (type)
17283 {
17284 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 17285 if (datasz != 4)
aa7bca9b
L
17286 printf (_("x86 ISA used: <corrupt length: %#x> "),
17287 datasz);
1fc87489 17288 else
aa7bca9b
L
17289 {
17290 printf ("x86 ISA used: ");
17291 decode_x86_isa (bitmask);
17292 }
1fc87489 17293 goto next;
9ef920e9 17294
1fc87489 17295 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 17296 if (datasz != 4)
aa7bca9b
L
17297 printf (_("x86 ISA needed: <corrupt length: %#x> "),
17298 datasz);
1fc87489 17299 else
aa7bca9b
L
17300 {
17301 printf ("x86 ISA needed: ");
17302 decode_x86_isa (bitmask);
17303 }
1fc87489 17304 goto next;
9ef920e9 17305
ee2fdd6f 17306 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 17307 if (datasz != 4)
aa7bca9b
L
17308 printf (_("x86 feature: <corrupt length: %#x> "),
17309 datasz);
ee2fdd6f 17310 else
aa7bca9b
L
17311 {
17312 printf ("x86 feature: ");
a9eafb08
L
17313 decode_x86_feature_1 (bitmask);
17314 }
17315 goto next;
17316
17317 case GNU_PROPERTY_X86_FEATURE_2_USED:
17318 if (datasz != 4)
17319 printf (_("x86 feature used: <corrupt length: %#x> "),
17320 datasz);
17321 else
17322 {
17323 printf ("x86 feature used: ");
17324 decode_x86_feature_2 (bitmask);
17325 }
17326 goto next;
17327
17328 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
17329 if (datasz != 4)
17330 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
17331 else
17332 {
17333 printf ("x86 feature needed: ");
17334 decode_x86_feature_2 (bitmask);
17335 }
17336 goto next;
17337
17338 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
17339 if (datasz != 4)
17340 printf (_("x86 ISA used: <corrupt length: %#x> "),
17341 datasz);
17342 else
17343 {
17344 printf ("x86 ISA used: ");
17345 decode_x86_compat_isa (bitmask);
17346 }
17347 goto next;
17348
17349 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
17350 if (datasz != 4)
17351 printf (_("x86 ISA needed: <corrupt length: %#x> "),
17352 datasz);
17353 else
17354 {
17355 printf ("x86 ISA needed: ");
17356 decode_x86_compat_isa (bitmask);
aa7bca9b 17357 }
ee2fdd6f
L
17358 goto next;
17359
1fc87489
L
17360 default:
17361 break;
17362 }
17363 }
17364 }
17365 else
17366 {
17367 switch (type)
9ef920e9 17368 {
1fc87489
L
17369 case GNU_PROPERTY_STACK_SIZE:
17370 printf (_("stack size: "));
17371 if (datasz != size)
17372 printf (_("<corrupt length: %#x> "), datasz);
17373 else
17374 printf ("%#lx", (unsigned long) byte_get (ptr, size));
17375 goto next;
17376
17377 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
17378 printf ("no copy on protected ");
17379 if (datasz)
17380 printf (_("<corrupt length: %#x> "), datasz);
17381 goto next;
17382
17383 default:
9ef920e9
NC
17384 break;
17385 }
9ef920e9
NC
17386 }
17387
1fc87489
L
17388 if (type < GNU_PROPERTY_LOPROC)
17389 printf (_("<unknown type %#x data: "), type);
17390 else if (type < GNU_PROPERTY_LOUSER)
17391 printf (_("<procesor-specific type %#x data: "), type);
17392 else
17393 printf (_("<application-specific type %#x data: "), type);
17394 for (j = 0; j < datasz; ++j)
17395 printf ("%02x ", ptr[j] & 0xff);
17396 printf (">");
17397
17398next:
9ef920e9 17399 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
17400 if (ptr == ptr_end)
17401 break;
1fc87489 17402
6ab2c4ed
MC
17403 if (do_wide)
17404 printf (", ");
17405 else
17406 printf ("\n\t");
9ef920e9
NC
17407 }
17408
17409 printf ("\n");
17410}
17411
32ec8896 17412static bfd_boolean
dda8d76d 17413print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 17414{
1449284b 17415 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
17416 switch (pnote->type)
17417 {
17418 case NT_GNU_BUILD_ID:
17419 {
17420 unsigned long i;
17421
17422 printf (_(" Build ID: "));
17423 for (i = 0; i < pnote->descsz; ++i)
17424 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 17425 printf ("\n");
664f90a3
TT
17426 }
17427 break;
17428
17429 case NT_GNU_ABI_TAG:
17430 {
17431 unsigned long os, major, minor, subminor;
17432 const char *osname;
17433
3102e897
NC
17434 /* PR 17531: file: 030-599401-0.004. */
17435 if (pnote->descsz < 16)
17436 {
17437 printf (_(" <corrupt GNU_ABI_TAG>\n"));
17438 break;
17439 }
17440
664f90a3
TT
17441 os = byte_get ((unsigned char *) pnote->descdata, 4);
17442 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17443 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
17444 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
17445
17446 switch (os)
17447 {
17448 case GNU_ABI_TAG_LINUX:
17449 osname = "Linux";
17450 break;
17451 case GNU_ABI_TAG_HURD:
17452 osname = "Hurd";
17453 break;
17454 case GNU_ABI_TAG_SOLARIS:
17455 osname = "Solaris";
17456 break;
17457 case GNU_ABI_TAG_FREEBSD:
17458 osname = "FreeBSD";
17459 break;
17460 case GNU_ABI_TAG_NETBSD:
17461 osname = "NetBSD";
17462 break;
14ae95f2
RM
17463 case GNU_ABI_TAG_SYLLABLE:
17464 osname = "Syllable";
17465 break;
17466 case GNU_ABI_TAG_NACL:
17467 osname = "NaCl";
17468 break;
664f90a3
TT
17469 default:
17470 osname = "Unknown";
17471 break;
17472 }
17473
17474 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
17475 major, minor, subminor);
17476 }
17477 break;
926c5385
CC
17478
17479 case NT_GNU_GOLD_VERSION:
17480 {
17481 unsigned long i;
17482
17483 printf (_(" Version: "));
17484 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
17485 printf ("%c", pnote->descdata[i]);
17486 printf ("\n");
17487 }
17488 break;
1449284b
NC
17489
17490 case NT_GNU_HWCAP:
17491 {
17492 unsigned long num_entries, mask;
17493
17494 /* Hardware capabilities information. Word 0 is the number of entries.
17495 Word 1 is a bitmask of enabled entries. The rest of the descriptor
17496 is a series of entries, where each entry is a single byte followed
17497 by a nul terminated string. The byte gives the bit number to test
17498 if enabled in the bitmask. */
17499 printf (_(" Hardware Capabilities: "));
17500 if (pnote->descsz < 8)
17501 {
32ec8896
NC
17502 error (_("<corrupt GNU_HWCAP>\n"));
17503 return FALSE;
1449284b
NC
17504 }
17505 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
17506 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17507 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
17508 /* FIXME: Add code to display the entries... */
17509 }
17510 break;
17511
9ef920e9 17512 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 17513 print_gnu_property_note (filedata, pnote);
9ef920e9
NC
17514 break;
17515
1449284b
NC
17516 default:
17517 /* Handle unrecognised types. An error message should have already been
17518 created by get_gnu_elf_note_type(), so all that we need to do is to
17519 display the data. */
17520 {
17521 unsigned long i;
17522
17523 printf (_(" Description data: "));
17524 for (i = 0; i < pnote->descsz; ++i)
17525 printf ("%02x ", pnote->descdata[i] & 0xff);
17526 printf ("\n");
17527 }
17528 break;
664f90a3
TT
17529 }
17530
32ec8896 17531 return TRUE;
664f90a3
TT
17532}
17533
685080f2
NC
17534static const char *
17535get_v850_elf_note_type (enum v850_notes n_type)
17536{
17537 static char buff[64];
17538
17539 switch (n_type)
17540 {
17541 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
17542 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
17543 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
17544 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
17545 case V850_NOTE_CACHE_INFO: return _("Use of cache");
17546 case V850_NOTE_MMU_INFO: return _("Use of MMU");
17547 default:
17548 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
17549 return buff;
17550 }
17551}
17552
32ec8896 17553static bfd_boolean
685080f2
NC
17554print_v850_note (Elf_Internal_Note * pnote)
17555{
17556 unsigned int val;
17557
17558 if (pnote->descsz != 4)
32ec8896
NC
17559 return FALSE;
17560
685080f2
NC
17561 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
17562
17563 if (val == 0)
17564 {
17565 printf (_("not set\n"));
32ec8896 17566 return TRUE;
685080f2
NC
17567 }
17568
17569 switch (pnote->type)
17570 {
17571 case V850_NOTE_ALIGNMENT:
17572 switch (val)
17573 {
32ec8896
NC
17574 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
17575 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
17576 }
17577 break;
14ae95f2 17578
685080f2
NC
17579 case V850_NOTE_DATA_SIZE:
17580 switch (val)
17581 {
32ec8896
NC
17582 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
17583 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
17584 }
17585 break;
14ae95f2 17586
685080f2
NC
17587 case V850_NOTE_FPU_INFO:
17588 switch (val)
17589 {
32ec8896
NC
17590 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
17591 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
17592 }
17593 break;
14ae95f2 17594
685080f2
NC
17595 case V850_NOTE_MMU_INFO:
17596 case V850_NOTE_CACHE_INFO:
17597 case V850_NOTE_SIMD_INFO:
17598 if (val == EF_RH850_SIMD)
17599 {
17600 printf (_("yes\n"));
32ec8896 17601 return TRUE;
685080f2
NC
17602 }
17603 break;
17604
17605 default:
17606 /* An 'unknown note type' message will already have been displayed. */
17607 break;
17608 }
17609
17610 printf (_("unknown value: %x\n"), val);
32ec8896 17611 return FALSE;
685080f2
NC
17612}
17613
32ec8896 17614static bfd_boolean
c6056a74
SF
17615process_netbsd_elf_note (Elf_Internal_Note * pnote)
17616{
17617 unsigned int version;
17618
17619 switch (pnote->type)
17620 {
17621 case NT_NETBSD_IDENT:
17622 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
17623 if ((version / 10000) % 100)
17624 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
17625 version, version / 100000000, (version / 1000000) % 100,
17626 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 17627 'A' + (version / 10000) % 26);
c6056a74
SF
17628 else
17629 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
17630 version, version / 100000000, (version / 1000000) % 100,
15f205b1 17631 (version / 100) % 100);
32ec8896 17632 return TRUE;
c6056a74
SF
17633
17634 case NT_NETBSD_MARCH:
17635 printf (" NetBSD\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
17636 pnote->descdata);
32ec8896 17637 return TRUE;
c6056a74
SF
17638
17639 default:
32ec8896
NC
17640 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n", pnote->descsz,
17641 pnote->type);
17642 return FALSE;
c6056a74 17643 }
c6056a74
SF
17644}
17645
f4ddf30f 17646static const char *
dda8d76d 17647get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 17648{
f4ddf30f
JB
17649 switch (e_type)
17650 {
17651 case NT_FREEBSD_THRMISC:
17652 return _("NT_THRMISC (thrmisc structure)");
17653 case NT_FREEBSD_PROCSTAT_PROC:
17654 return _("NT_PROCSTAT_PROC (proc data)");
17655 case NT_FREEBSD_PROCSTAT_FILES:
17656 return _("NT_PROCSTAT_FILES (files data)");
17657 case NT_FREEBSD_PROCSTAT_VMMAP:
17658 return _("NT_PROCSTAT_VMMAP (vmmap data)");
17659 case NT_FREEBSD_PROCSTAT_GROUPS:
17660 return _("NT_PROCSTAT_GROUPS (groups data)");
17661 case NT_FREEBSD_PROCSTAT_UMASK:
17662 return _("NT_PROCSTAT_UMASK (umask data)");
17663 case NT_FREEBSD_PROCSTAT_RLIMIT:
17664 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
17665 case NT_FREEBSD_PROCSTAT_OSREL:
17666 return _("NT_PROCSTAT_OSREL (osreldate data)");
17667 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
17668 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
17669 case NT_FREEBSD_PROCSTAT_AUXV:
17670 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
17671 case NT_FREEBSD_PTLWPINFO:
17672 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 17673 }
dda8d76d 17674 return get_note_type (filedata, e_type);
f4ddf30f
JB
17675}
17676
9437c45b 17677static const char *
dda8d76d 17678get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
17679{
17680 static char buff[64];
17681
b4db1224 17682 if (e_type == NT_NETBSDCORE_PROCINFO)
dda8d76d 17683 return _("NetBSD procinfo structure");
9437c45b
JT
17684
17685 /* As of Jan 2002 there are no other machine-independent notes
17686 defined for NetBSD core files. If the note type is less
17687 than the start of the machine-dependent note types, we don't
17688 understand it. */
17689
b4db1224 17690 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 17691 {
e9e44622 17692 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
17693 return buff;
17694 }
17695
dda8d76d 17696 switch (filedata->file_header.e_machine)
9437c45b
JT
17697 {
17698 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
17699 and PT_GETFPREGS == mach+2. */
17700
17701 case EM_OLD_ALPHA:
17702 case EM_ALPHA:
17703 case EM_SPARC:
17704 case EM_SPARC32PLUS:
17705 case EM_SPARCV9:
17706 switch (e_type)
17707 {
2b692964 17708 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 17709 return _("PT_GETREGS (reg structure)");
2b692964 17710 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 17711 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17712 default:
17713 break;
17714 }
17715 break;
17716
17717 /* On all other arch's, PT_GETREGS == mach+1 and
17718 PT_GETFPREGS == mach+3. */
17719 default:
17720 switch (e_type)
17721 {
2b692964 17722 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 17723 return _("PT_GETREGS (reg structure)");
2b692964 17724 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 17725 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17726 default:
17727 break;
17728 }
17729 }
17730
9cf03b7e 17731 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 17732 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
17733 return buff;
17734}
17735
70616151
TT
17736static const char *
17737get_stapsdt_note_type (unsigned e_type)
17738{
17739 static char buff[64];
17740
17741 switch (e_type)
17742 {
17743 case NT_STAPSDT:
17744 return _("NT_STAPSDT (SystemTap probe descriptors)");
17745
17746 default:
17747 break;
17748 }
17749
17750 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17751 return buff;
17752}
17753
32ec8896 17754static bfd_boolean
c6a9fc58
TT
17755print_stapsdt_note (Elf_Internal_Note *pnote)
17756{
17757 int addr_size = is_32bit_elf ? 4 : 8;
17758 char *data = pnote->descdata;
17759 char *data_end = pnote->descdata + pnote->descsz;
17760 bfd_vma pc, base_addr, semaphore;
17761 char *provider, *probe, *arg_fmt;
17762
17763 pc = byte_get ((unsigned char *) data, addr_size);
17764 data += addr_size;
17765 base_addr = byte_get ((unsigned char *) data, addr_size);
17766 data += addr_size;
17767 semaphore = byte_get ((unsigned char *) data, addr_size);
17768 data += addr_size;
17769
17770 provider = data;
17771 data += strlen (data) + 1;
17772 probe = data;
17773 data += strlen (data) + 1;
17774 arg_fmt = data;
17775 data += strlen (data) + 1;
17776
17777 printf (_(" Provider: %s\n"), provider);
17778 printf (_(" Name: %s\n"), probe);
17779 printf (_(" Location: "));
17780 print_vma (pc, FULL_HEX);
17781 printf (_(", Base: "));
17782 print_vma (base_addr, FULL_HEX);
17783 printf (_(", Semaphore: "));
17784 print_vma (semaphore, FULL_HEX);
9cf03b7e 17785 printf ("\n");
c6a9fc58
TT
17786 printf (_(" Arguments: %s\n"), arg_fmt);
17787
17788 return data == data_end;
17789}
17790
00e98fc7
TG
17791static const char *
17792get_ia64_vms_note_type (unsigned e_type)
17793{
17794 static char buff[64];
17795
17796 switch (e_type)
17797 {
17798 case NT_VMS_MHD:
17799 return _("NT_VMS_MHD (module header)");
17800 case NT_VMS_LNM:
17801 return _("NT_VMS_LNM (language name)");
17802 case NT_VMS_SRC:
17803 return _("NT_VMS_SRC (source files)");
17804 case NT_VMS_TITLE:
9cf03b7e 17805 return "NT_VMS_TITLE";
00e98fc7
TG
17806 case NT_VMS_EIDC:
17807 return _("NT_VMS_EIDC (consistency check)");
17808 case NT_VMS_FPMODE:
17809 return _("NT_VMS_FPMODE (FP mode)");
17810 case NT_VMS_LINKTIME:
9cf03b7e 17811 return "NT_VMS_LINKTIME";
00e98fc7
TG
17812 case NT_VMS_IMGNAM:
17813 return _("NT_VMS_IMGNAM (image name)");
17814 case NT_VMS_IMGID:
17815 return _("NT_VMS_IMGID (image id)");
17816 case NT_VMS_LINKID:
17817 return _("NT_VMS_LINKID (link id)");
17818 case NT_VMS_IMGBID:
17819 return _("NT_VMS_IMGBID (build id)");
17820 case NT_VMS_GSTNAM:
17821 return _("NT_VMS_GSTNAM (sym table name)");
17822 case NT_VMS_ORIG_DYN:
9cf03b7e 17823 return "NT_VMS_ORIG_DYN";
00e98fc7 17824 case NT_VMS_PATCHTIME:
9cf03b7e 17825 return "NT_VMS_PATCHTIME";
00e98fc7
TG
17826 default:
17827 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17828 return buff;
17829 }
17830}
17831
32ec8896 17832static bfd_boolean
00e98fc7
TG
17833print_ia64_vms_note (Elf_Internal_Note * pnote)
17834{
17835 switch (pnote->type)
17836 {
17837 case NT_VMS_MHD:
17838 if (pnote->descsz > 36)
17839 {
17840 size_t l = strlen (pnote->descdata + 34);
17841 printf (_(" Creation date : %.17s\n"), pnote->descdata);
17842 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
17843 printf (_(" Module name : %s\n"), pnote->descdata + 34);
17844 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
17845 }
17846 else
17847 printf (_(" Invalid size\n"));
17848 break;
17849 case NT_VMS_LNM:
17850 printf (_(" Language: %s\n"), pnote->descdata);
17851 break;
17852#ifdef BFD64
17853 case NT_VMS_FPMODE:
9cf03b7e 17854 printf (_(" Floating Point mode: "));
4a5cb34f 17855 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 17856 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
17857 break;
17858 case NT_VMS_LINKTIME:
17859 printf (_(" Link time: "));
17860 print_vms_time
17861 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
17862 printf ("\n");
17863 break;
17864 case NT_VMS_PATCHTIME:
17865 printf (_(" Patch time: "));
17866 print_vms_time
17867 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
17868 printf ("\n");
17869 break;
17870 case NT_VMS_ORIG_DYN:
17871 printf (_(" Major id: %u, minor id: %u\n"),
17872 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
17873 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 17874 printf (_(" Last modified : "));
00e98fc7
TG
17875 print_vms_time
17876 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 17877 printf (_("\n Link flags : "));
4a5cb34f 17878 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 17879 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 17880 printf (_(" Header flags: 0x%08x\n"),
948f632f 17881 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
00e98fc7
TG
17882 printf (_(" Image id : %s\n"), pnote->descdata + 32);
17883 break;
17884#endif
17885 case NT_VMS_IMGNAM:
17886 printf (_(" Image name: %s\n"), pnote->descdata);
17887 break;
17888 case NT_VMS_GSTNAM:
17889 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
17890 break;
17891 case NT_VMS_IMGID:
17892 printf (_(" Image id: %s\n"), pnote->descdata);
17893 break;
17894 case NT_VMS_LINKID:
17895 printf (_(" Linker id: %s\n"), pnote->descdata);
17896 break;
17897 default:
32ec8896 17898 return FALSE;
00e98fc7 17899 }
32ec8896 17900 return TRUE;
00e98fc7
TG
17901}
17902
6f156d7a
NC
17903/* Find the symbol associated with a build attribute that is attached
17904 to address OFFSET. If PNAME is non-NULL then store the name of
17905 the symbol (if found) in the provided pointer, Returns NULL if a
17906 symbol could not be found. */
c799a79d 17907
6f156d7a
NC
17908static Elf_Internal_Sym *
17909get_symbol_for_build_attribute (Filedata * filedata,
17910 unsigned long offset,
17911 bfd_boolean is_open_attr,
17912 const char ** pname)
9ef920e9 17913{
dda8d76d 17914 static Filedata * saved_filedata = NULL;
c799a79d
NC
17915 static char * strtab;
17916 static unsigned long strtablen;
17917 static Elf_Internal_Sym * symtab;
17918 static unsigned long nsyms;
7296a62a
NC
17919 Elf_Internal_Sym * saved_sym = NULL;
17920 Elf_Internal_Sym * sym;
9ef920e9 17921
dda8d76d
NC
17922 if (filedata->section_headers != NULL
17923 && (saved_filedata == NULL || filedata != saved_filedata))
9ef920e9 17924 {
c799a79d 17925 Elf_Internal_Shdr * symsec;
9ef920e9 17926
c799a79d 17927 /* Load the symbol and string sections. */
dda8d76d
NC
17928 for (symsec = filedata->section_headers;
17929 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 17930 symsec ++)
9ef920e9 17931 {
c799a79d 17932 if (symsec->sh_type == SHT_SYMTAB)
9ef920e9 17933 {
dda8d76d 17934 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
9ef920e9 17935
dda8d76d 17936 if (symsec->sh_link < filedata->file_header.e_shnum)
c799a79d 17937 {
dda8d76d 17938 Elf_Internal_Shdr * strtab_sec = filedata->section_headers + symsec->sh_link;
c799a79d 17939
dda8d76d 17940 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
c799a79d
NC
17941 1, strtab_sec->sh_size,
17942 _("string table"));
17943 strtablen = strtab != NULL ? strtab_sec->sh_size : 0;
17944 }
9ef920e9
NC
17945 }
17946 }
dda8d76d 17947 saved_filedata = filedata;
9ef920e9
NC
17948 }
17949
c799a79d 17950 if (symtab == NULL || strtab == NULL)
6f156d7a 17951 return NULL;
9ef920e9 17952
c799a79d
NC
17953 /* Find a symbol whose value matches offset. */
17954 for (sym = symtab; sym < symtab + nsyms; sym ++)
17955 if (sym->st_value == offset)
17956 {
17957 if (sym->st_name >= strtablen)
17958 /* Huh ? This should not happen. */
17959 continue;
9ef920e9 17960
c799a79d
NC
17961 if (strtab[sym->st_name] == 0)
17962 continue;
9ef920e9 17963
8fd75781
NC
17964 /* The AArch64 and ARM architectures define mapping symbols
17965 (eg $d, $x, $t) which we want to ignore. */
17966 if (strtab[sym->st_name] == '$'
17967 && strtab[sym->st_name + 1] != 0
17968 && strtab[sym->st_name + 2] == 0)
17969 continue;
17970
c799a79d
NC
17971 if (is_open_attr)
17972 {
17973 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
17974 and FILE or OBJECT symbols over NOTYPE symbols. We skip
17975 FUNC symbols entirely. */
17976 switch (ELF_ST_TYPE (sym->st_info))
17977 {
c799a79d 17978 case STT_OBJECT:
6f156d7a 17979 case STT_FILE:
c799a79d 17980 saved_sym = sym;
6f156d7a
NC
17981 if (sym->st_size)
17982 {
17983 /* If the symbol has a size associated
17984 with it then we can stop searching. */
17985 sym = symtab + nsyms;
17986 }
c799a79d 17987 continue;
9ef920e9 17988
c799a79d
NC
17989 case STT_FUNC:
17990 /* Ignore function symbols. */
17991 continue;
17992
17993 default:
17994 break;
17995 }
17996
17997 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 17998 {
c799a79d
NC
17999 case STB_GLOBAL:
18000 if (saved_sym == NULL
18001 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
18002 saved_sym = sym;
18003 break;
c871dade 18004
c799a79d
NC
18005 case STB_LOCAL:
18006 if (saved_sym == NULL)
18007 saved_sym = sym;
18008 break;
18009
18010 default:
9ef920e9
NC
18011 break;
18012 }
18013 }
c799a79d
NC
18014 else
18015 {
18016 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
18017 continue;
18018
18019 saved_sym = sym;
18020 break;
18021 }
18022 }
18023
6f156d7a
NC
18024 if (saved_sym && pname)
18025 * pname = strtab + saved_sym->st_name;
18026
18027 return saved_sym;
c799a79d
NC
18028}
18029
d20e98ab
NC
18030/* Returns true iff addr1 and addr2 are in the same section. */
18031
18032static bfd_boolean
18033same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
18034{
18035 Elf_Internal_Shdr * a1;
18036 Elf_Internal_Shdr * a2;
18037
18038 a1 = find_section_by_address (filedata, addr1);
18039 a2 = find_section_by_address (filedata, addr2);
18040
18041 return a1 == a2 && a1 != NULL;
18042}
18043
c799a79d 18044static bfd_boolean
dda8d76d
NC
18045print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
18046 Filedata * filedata)
c799a79d 18047{
6f156d7a
NC
18048 static unsigned long global_offset = 0;
18049 static unsigned long global_end = 0;
18050 static unsigned long func_offset = 0;
18051 static unsigned long func_end = 0;
c871dade 18052
6f156d7a
NC
18053 Elf_Internal_Sym * sym;
18054 const char * name;
18055 unsigned long start;
18056 unsigned long end;
18057 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
18058
18059 switch (pnote->descsz)
c799a79d 18060 {
6f156d7a
NC
18061 case 0:
18062 /* A zero-length description means that the range of
18063 the previous note of the same type should be used. */
c799a79d 18064 if (is_open_attr)
c871dade 18065 {
6f156d7a
NC
18066 if (global_end > global_offset)
18067 printf (_(" Applies to region from %#lx to %#lx\n"),
18068 global_offset, global_end);
18069 else
18070 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
18071 }
18072 else
18073 {
6f156d7a
NC
18074 if (func_end > func_offset)
18075 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
18076 else
18077 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 18078 }
6f156d7a 18079 return TRUE;
9ef920e9 18080
6f156d7a
NC
18081 case 4:
18082 start = byte_get ((unsigned char *) pnote->descdata, 4);
18083 end = 0;
18084 break;
18085
18086 case 8:
18087 if (is_32bit_elf)
18088 {
18089 /* FIXME: We should check that version 3+ notes are being used here... */
18090 start = byte_get ((unsigned char *) pnote->descdata, 4);
18091 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18092 }
18093 else
18094 {
18095 start = byte_get ((unsigned char *) pnote->descdata, 8);
18096 end = 0;
18097 }
18098 break;
18099
18100 case 16:
18101 start = byte_get ((unsigned char *) pnote->descdata, 8);
18102 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
18103 break;
18104
18105 default:
c799a79d
NC
18106 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
18107 printf (_(" <invalid descsz>"));
18108 return FALSE;
18109 }
18110
6f156d7a
NC
18111 name = NULL;
18112 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
18113 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
18114 in order to avoid them being confused with the start address of the
18115 first function in the file... */
18116 if (sym == NULL && is_open_attr)
18117 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
18118 & name);
6f156d7a
NC
18119
18120 if (end == 0 && sym != NULL && sym->st_size > 0)
18121 end = start + sym->st_size;
c799a79d
NC
18122
18123 if (is_open_attr)
18124 {
d20e98ab
NC
18125 /* FIXME: Need to properly allow for section alignment.
18126 16 is just the alignment used on x86_64. */
18127 if (global_end > 0
18128 && start > BFD_ALIGN (global_end, 16)
18129 /* Build notes are not guaranteed to be organised in order of
18130 increasing address, but we should find the all of the notes
18131 for one section in the same place. */
18132 && same_section (filedata, start, global_end))
6f156d7a
NC
18133 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
18134 global_end + 1, start - 1);
18135
18136 printf (_(" Applies to region from %#lx"), start);
18137 global_offset = start;
18138
18139 if (end)
18140 {
18141 printf (_(" to %#lx"), end);
18142 global_end = end;
18143 }
c799a79d
NC
18144 }
18145 else
18146 {
6f156d7a
NC
18147 printf (_(" Applies to region from %#lx"), start);
18148 func_offset = start;
18149
18150 if (end)
18151 {
18152 printf (_(" to %#lx"), end);
18153 func_end = end;
18154 }
c799a79d
NC
18155 }
18156
6f156d7a
NC
18157 if (sym && name)
18158 printf (_(" (%s)"), name);
18159
18160 printf ("\n");
18161 return TRUE;
9ef920e9
NC
18162}
18163
18164static bfd_boolean
18165print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
18166{
1d15e434
NC
18167 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
18168 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
18169 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
18170 char name_type;
18171 char name_attribute;
1d15e434 18172 const char * expected_types;
9ef920e9
NC
18173 const char * name = pnote->namedata;
18174 const char * text;
88305e1b 18175 signed int left;
9ef920e9
NC
18176
18177 if (name == NULL || pnote->namesz < 2)
18178 {
18179 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 18180 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
18181 return FALSE;
18182 }
18183
6f156d7a
NC
18184 if (do_wide)
18185 left = 28;
18186 else
18187 left = 20;
88305e1b
NC
18188
18189 /* Version 2 of the spec adds a "GA" prefix to the name field. */
18190 if (name[0] == 'G' && name[1] == 'A')
18191 {
6f156d7a
NC
18192 if (pnote->namesz < 4)
18193 {
18194 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
18195 print_symbol (-20, _(" <corrupt name>"));
18196 return FALSE;
18197 }
18198
88305e1b
NC
18199 printf ("GA");
18200 name += 2;
18201 left -= 2;
18202 }
18203
9ef920e9
NC
18204 switch ((name_type = * name))
18205 {
18206 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
18207 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
18208 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
18209 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
18210 printf ("%c", * name);
88305e1b 18211 left --;
9ef920e9
NC
18212 break;
18213 default:
18214 error (_("unrecognised attribute type in name field: %d\n"), name_type);
18215 print_symbol (-20, _("<unknown name type>"));
18216 return FALSE;
18217 }
18218
9ef920e9
NC
18219 ++ name;
18220 text = NULL;
18221
18222 switch ((name_attribute = * name))
18223 {
18224 case GNU_BUILD_ATTRIBUTE_VERSION:
18225 text = _("<version>");
1d15e434 18226 expected_types = string_expected;
9ef920e9
NC
18227 ++ name;
18228 break;
18229 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
18230 text = _("<stack prot>");
75d7d298 18231 expected_types = "!+*";
9ef920e9
NC
18232 ++ name;
18233 break;
18234 case GNU_BUILD_ATTRIBUTE_RELRO:
18235 text = _("<relro>");
1d15e434 18236 expected_types = bool_expected;
9ef920e9
NC
18237 ++ name;
18238 break;
18239 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
18240 text = _("<stack size>");
1d15e434 18241 expected_types = number_expected;
9ef920e9
NC
18242 ++ name;
18243 break;
18244 case GNU_BUILD_ATTRIBUTE_TOOL:
18245 text = _("<tool>");
1d15e434 18246 expected_types = string_expected;
9ef920e9
NC
18247 ++ name;
18248 break;
18249 case GNU_BUILD_ATTRIBUTE_ABI:
18250 text = _("<ABI>");
18251 expected_types = "$*";
18252 ++ name;
18253 break;
18254 case GNU_BUILD_ATTRIBUTE_PIC:
18255 text = _("<PIC>");
1d15e434 18256 expected_types = number_expected;
9ef920e9
NC
18257 ++ name;
18258 break;
a8be5506
NC
18259 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
18260 text = _("<short enum>");
1d15e434 18261 expected_types = bool_expected;
a8be5506
NC
18262 ++ name;
18263 break;
9ef920e9
NC
18264 default:
18265 if (ISPRINT (* name))
18266 {
18267 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
18268
18269 if (len > left && ! do_wide)
18270 len = left;
75d7d298 18271 printf ("%.*s:", len, name);
9ef920e9 18272 left -= len;
0dd6ae21 18273 name += len;
9ef920e9
NC
18274 }
18275 else
18276 {
3e6b6445 18277 static char tmpbuf [128];
88305e1b 18278
3e6b6445
NC
18279 error (_("unrecognised byte in name field: %d\n"), * name);
18280 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
18281 text = tmpbuf;
18282 name ++;
9ef920e9
NC
18283 }
18284 expected_types = "*$!+";
18285 break;
18286 }
18287
18288 if (text)
88305e1b 18289 left -= printf ("%s", text);
9ef920e9
NC
18290
18291 if (strchr (expected_types, name_type) == NULL)
75d7d298 18292 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
18293
18294 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
18295 {
18296 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
18297 (unsigned long) pnote->namesz,
18298 (long) (name - pnote->namedata));
18299 return FALSE;
18300 }
18301
18302 if (left < 1 && ! do_wide)
18303 return TRUE;
18304
18305 switch (name_type)
18306 {
18307 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
18308 {
b06b2c92 18309 unsigned int bytes;
ddef72cd
NC
18310 unsigned long long val = 0;
18311 unsigned int shift = 0;
18312 char * decoded = NULL;
18313
b06b2c92
NC
18314 bytes = pnote->namesz - (name - pnote->namedata);
18315 if (bytes > 0)
18316 /* The -1 is because the name field is always 0 terminated, and we
18317 want to be able to ensure that the shift in the while loop below
18318 will not overflow. */
18319 -- bytes;
18320
ddef72cd
NC
18321 if (bytes > sizeof (val))
18322 {
3e6b6445
NC
18323 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
18324 bytes);
18325 bytes = sizeof (val);
ddef72cd 18326 }
3e6b6445
NC
18327 /* We do not bother to warn if bytes == 0 as this can
18328 happen with some early versions of the gcc plugin. */
9ef920e9
NC
18329
18330 while (bytes --)
18331 {
79a964dc
NC
18332 unsigned long byte = (* name ++) & 0xff;
18333
18334 val |= byte << shift;
9ef920e9
NC
18335 shift += 8;
18336 }
18337
75d7d298 18338 switch (name_attribute)
9ef920e9 18339 {
75d7d298 18340 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
18341 switch (val)
18342 {
75d7d298
NC
18343 case 0: decoded = "static"; break;
18344 case 1: decoded = "pic"; break;
18345 case 2: decoded = "PIC"; break;
18346 case 3: decoded = "pie"; break;
18347 case 4: decoded = "PIE"; break;
18348 default: break;
9ef920e9 18349 }
75d7d298
NC
18350 break;
18351 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
18352 switch (val)
9ef920e9 18353 {
75d7d298
NC
18354 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
18355 case 0: decoded = "off"; break;
18356 case 1: decoded = "on"; break;
18357 case 2: decoded = "all"; break;
18358 case 3: decoded = "strong"; break;
18359 case 4: decoded = "explicit"; break;
18360 default: break;
9ef920e9 18361 }
75d7d298
NC
18362 break;
18363 default:
18364 break;
9ef920e9
NC
18365 }
18366
75d7d298 18367 if (decoded != NULL)
3e6b6445
NC
18368 {
18369 print_symbol (-left, decoded);
18370 left = 0;
18371 }
18372 else if (val == 0)
18373 {
18374 printf ("0x0");
18375 left -= 3;
18376 }
9ef920e9 18377 else
75d7d298
NC
18378 {
18379 if (do_wide)
ddef72cd 18380 left -= printf ("0x%llx", val);
75d7d298 18381 else
ddef72cd 18382 left -= printf ("0x%-.*llx", left, val);
75d7d298 18383 }
9ef920e9
NC
18384 }
18385 break;
18386 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
18387 left -= print_symbol (- left, name);
18388 break;
18389 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
18390 left -= print_symbol (- left, "true");
18391 break;
18392 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
18393 left -= print_symbol (- left, "false");
18394 break;
18395 }
18396
18397 if (do_wide && left > 0)
18398 printf ("%-*s", left, " ");
18399
18400 return TRUE;
18401}
18402
6d118b09
NC
18403/* Note that by the ELF standard, the name field is already null byte
18404 terminated, and namesz includes the terminating null byte.
18405 I.E. the value of namesz for the name "FSF" is 4.
18406
e3c8793a 18407 If the value of namesz is zero, there is no name present. */
9ef920e9 18408
32ec8896 18409static bfd_boolean
9ef920e9 18410process_note (Elf_Internal_Note * pnote,
dda8d76d 18411 Filedata * filedata)
779fe533 18412{
2cf0635d
NC
18413 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
18414 const char * nt;
9437c45b
JT
18415
18416 if (pnote->namesz == 0)
1ec5cd37
NC
18417 /* If there is no note name, then use the default set of
18418 note type strings. */
dda8d76d 18419 nt = get_note_type (filedata, pnote->type);
1ec5cd37 18420
1118d252
RM
18421 else if (const_strneq (pnote->namedata, "GNU"))
18422 /* GNU-specific object file notes. */
18423 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
18424
18425 else if (const_strneq (pnote->namedata, "FreeBSD"))
18426 /* FreeBSD-specific core file notes. */
dda8d76d 18427 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 18428
0112cd26 18429 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 18430 /* NetBSD-specific core file notes. */
dda8d76d 18431 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 18432
c6056a74
SF
18433 else if (const_strneq (pnote->namedata, "NetBSD"))
18434 /* NetBSD-specific core file notes. */
18435 return process_netbsd_elf_note (pnote);
18436
b15fa79e
AM
18437 else if (strneq (pnote->namedata, "SPU/", 4))
18438 {
18439 /* SPU-specific core file notes. */
18440 nt = pnote->namedata + 4;
18441 name = "SPU";
18442 }
18443
00e98fc7
TG
18444 else if (const_strneq (pnote->namedata, "IPF/VMS"))
18445 /* VMS/ia64-specific file notes. */
18446 nt = get_ia64_vms_note_type (pnote->type);
18447
70616151
TT
18448 else if (const_strneq (pnote->namedata, "stapsdt"))
18449 nt = get_stapsdt_note_type (pnote->type);
18450
9437c45b 18451 else
1ec5cd37
NC
18452 /* Don't recognize this note name; just use the default set of
18453 note type strings. */
dda8d76d 18454 nt = get_note_type (filedata, pnote->type);
9437c45b 18455
1449284b 18456 printf (" ");
9ef920e9 18457
483767a3
AM
18458 if (((const_strneq (pnote->namedata, "GA")
18459 && strchr ("*$!+", pnote->namedata[2]) != NULL)
18460 || strchr ("*$!+", pnote->namedata[0]) != NULL)
18461 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
18462 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
18463 print_gnu_build_attribute_name (pnote);
18464 else
18465 print_symbol (-20, name);
18466
18467 if (do_wide)
18468 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
18469 else
18470 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
18471
18472 if (const_strneq (pnote->namedata, "IPF/VMS"))
18473 return print_ia64_vms_note (pnote);
664f90a3 18474 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 18475 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
18476 else if (const_strneq (pnote->namedata, "stapsdt"))
18477 return print_stapsdt_note (pnote);
9ece1fa9
TT
18478 else if (const_strneq (pnote->namedata, "CORE"))
18479 return print_core_note (pnote);
483767a3
AM
18480 else if (((const_strneq (pnote->namedata, "GA")
18481 && strchr ("*$!+", pnote->namedata[2]) != NULL)
18482 || strchr ("*$!+", pnote->namedata[0]) != NULL)
18483 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
18484 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 18485 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 18486
9ef920e9 18487 if (pnote->descsz)
1449284b
NC
18488 {
18489 unsigned long i;
18490
18491 printf (_(" description data: "));
18492 for (i = 0; i < pnote->descsz; i++)
18493 printf ("%02x ", pnote->descdata[i]);
04ac15ab
AS
18494 if (!do_wide)
18495 printf ("\n");
1449284b
NC
18496 }
18497
9ef920e9
NC
18498 if (do_wide)
18499 printf ("\n");
18500
32ec8896 18501 return TRUE;
1449284b 18502}
6d118b09 18503
32ec8896 18504static bfd_boolean
dda8d76d
NC
18505process_notes_at (Filedata * filedata,
18506 Elf_Internal_Shdr * section,
18507 bfd_vma offset,
82ed9683
L
18508 bfd_vma length,
18509 bfd_vma align)
779fe533 18510{
2cf0635d
NC
18511 Elf_External_Note * pnotes;
18512 Elf_External_Note * external;
4dff97b2
NC
18513 char * end;
18514 bfd_boolean res = TRUE;
103f02d3 18515
779fe533 18516 if (length <= 0)
32ec8896 18517 return FALSE;
103f02d3 18518
1449284b
NC
18519 if (section)
18520 {
dda8d76d 18521 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 18522 if (pnotes)
32ec8896 18523 {
dda8d76d 18524 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
32ec8896
NC
18525 return FALSE;
18526 }
1449284b
NC
18527 }
18528 else
82ed9683 18529 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 18530 _("notes"));
4dff97b2 18531
dd24e3da 18532 if (pnotes == NULL)
32ec8896 18533 return FALSE;
779fe533 18534
103f02d3 18535 external = pnotes;
103f02d3 18536
1449284b 18537 if (section)
dda8d76d 18538 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
18539 else
18540 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
18541 (unsigned long) offset, (unsigned long) length);
18542
82ed9683
L
18543 /* NB: Some note sections may have alignment value of 0 or 1. gABI
18544 specifies that notes should be aligned to 4 bytes in 32-bit
18545 objects and to 8 bytes in 64-bit objects. As a Linux extension,
18546 we also support 4 byte alignment in 64-bit objects. If section
18547 alignment is less than 4, we treate alignment as 4 bytes. */
18548 if (align < 4)
18549 align = 4;
18550 else if (align != 4 && align != 8)
18551 {
18552 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
18553 (long) align);
18554 return FALSE;
18555 }
18556
2aee03ae 18557 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 18558
c8071705
NC
18559 end = (char *) pnotes + length;
18560 while ((char *) external < end)
779fe533 18561 {
b34976b6 18562 Elf_Internal_Note inote;
15b42fb0 18563 size_t min_notesz;
4dff97b2 18564 char * next;
2cf0635d 18565 char * temp = NULL;
c8071705 18566 size_t data_remaining = end - (char *) external;
6d118b09 18567
dda8d76d 18568 if (!is_ia64_vms (filedata))
15b42fb0 18569 {
9dd3a467
NC
18570 /* PR binutils/15191
18571 Make sure that there is enough data to read. */
15b42fb0
AM
18572 min_notesz = offsetof (Elf_External_Note, name);
18573 if (data_remaining < min_notesz)
9dd3a467 18574 {
d3a49aa8
AM
18575 warn (ngettext ("Corrupt note: only %ld byte remains, "
18576 "not enough for a full note\n",
18577 "Corrupt note: only %ld bytes remain, "
18578 "not enough for a full note\n",
18579 data_remaining),
18580 (long) data_remaining);
9dd3a467
NC
18581 break;
18582 }
5396a86e
AM
18583 data_remaining -= min_notesz;
18584
15b42fb0
AM
18585 inote.type = BYTE_GET (external->type);
18586 inote.namesz = BYTE_GET (external->namesz);
18587 inote.namedata = external->name;
18588 inote.descsz = BYTE_GET (external->descsz);
276da9b3 18589 inote.descdata = ((char *) external
4dff97b2 18590 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 18591 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 18592 next = ((char *) external
4dff97b2 18593 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 18594 }
00e98fc7 18595 else
15b42fb0
AM
18596 {
18597 Elf64_External_VMS_Note *vms_external;
00e98fc7 18598
9dd3a467
NC
18599 /* PR binutils/15191
18600 Make sure that there is enough data to read. */
15b42fb0
AM
18601 min_notesz = offsetof (Elf64_External_VMS_Note, name);
18602 if (data_remaining < min_notesz)
9dd3a467 18603 {
d3a49aa8
AM
18604 warn (ngettext ("Corrupt note: only %ld byte remains, "
18605 "not enough for a full note\n",
18606 "Corrupt note: only %ld bytes remain, "
18607 "not enough for a full note\n",
18608 data_remaining),
18609 (long) data_remaining);
9dd3a467
NC
18610 break;
18611 }
5396a86e 18612 data_remaining -= min_notesz;
3e55a963 18613
15b42fb0
AM
18614 vms_external = (Elf64_External_VMS_Note *) external;
18615 inote.type = BYTE_GET (vms_external->type);
18616 inote.namesz = BYTE_GET (vms_external->namesz);
18617 inote.namedata = vms_external->name;
18618 inote.descsz = BYTE_GET (vms_external->descsz);
18619 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
18620 inote.descpos = offset + (inote.descdata - (char *) pnotes);
18621 next = inote.descdata + align_power (inote.descsz, 3);
18622 }
18623
5396a86e
AM
18624 /* PR 17531: file: 3443835e. */
18625 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
18626 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
18627 || (size_t) (inote.descdata - inote.namedata) > data_remaining
18628 || (size_t) (next - inote.descdata) < inote.descsz
18629 || ((size_t) (next - inote.descdata)
18630 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 18631 {
15b42fb0 18632 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 18633 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
18634 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
18635 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
18636 break;
18637 }
18638
15b42fb0 18639 external = (Elf_External_Note *) next;
dd24e3da 18640
6d118b09
NC
18641 /* Verify that name is null terminated. It appears that at least
18642 one version of Linux (RedHat 6.0) generates corefiles that don't
18643 comply with the ELF spec by failing to include the null byte in
18644 namesz. */
8b971f9f 18645 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 18646 {
5396a86e 18647 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 18648 {
5396a86e
AM
18649 temp = (char *) malloc (inote.namesz + 1);
18650 if (temp == NULL)
18651 {
18652 error (_("Out of memory allocating space for inote name\n"));
18653 res = FALSE;
18654 break;
18655 }
76da6bbe 18656
5396a86e
AM
18657 memcpy (temp, inote.namedata, inote.namesz);
18658 inote.namedata = temp;
18659 }
18660 inote.namedata[inote.namesz] = 0;
6d118b09
NC
18661 }
18662
dda8d76d 18663 if (! process_note (& inote, filedata))
6b4bf3bc 18664 res = FALSE;
103f02d3 18665
6d118b09
NC
18666 if (temp != NULL)
18667 {
18668 free (temp);
18669 temp = NULL;
18670 }
779fe533
NC
18671 }
18672
18673 free (pnotes);
103f02d3 18674
779fe533
NC
18675 return res;
18676}
18677
32ec8896 18678static bfd_boolean
dda8d76d 18679process_corefile_note_segments (Filedata * filedata)
779fe533 18680{
2cf0635d 18681 Elf_Internal_Phdr * segment;
b34976b6 18682 unsigned int i;
32ec8896 18683 bfd_boolean res = TRUE;
103f02d3 18684
dda8d76d 18685 if (! get_program_headers (filedata))
6b4bf3bc 18686 return TRUE;
103f02d3 18687
dda8d76d
NC
18688 for (i = 0, segment = filedata->program_headers;
18689 i < filedata->file_header.e_phnum;
b34976b6 18690 i++, segment++)
779fe533
NC
18691 {
18692 if (segment->p_type == PT_NOTE)
dda8d76d 18693 if (! process_notes_at (filedata, NULL,
32ec8896 18694 (bfd_vma) segment->p_offset,
82ed9683
L
18695 (bfd_vma) segment->p_filesz,
18696 (bfd_vma) segment->p_align))
32ec8896 18697 res = FALSE;
779fe533 18698 }
103f02d3 18699
779fe533
NC
18700 return res;
18701}
18702
32ec8896 18703static bfd_boolean
dda8d76d 18704process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
18705{
18706 Elf_External_Note * pnotes;
18707 Elf_External_Note * external;
c8071705 18708 char * end;
32ec8896 18709 bfd_boolean res = TRUE;
685080f2
NC
18710
18711 if (length <= 0)
32ec8896 18712 return FALSE;
685080f2 18713
dda8d76d 18714 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
18715 _("v850 notes"));
18716 if (pnotes == NULL)
32ec8896 18717 return FALSE;
685080f2
NC
18718
18719 external = pnotes;
c8071705 18720 end = (char*) pnotes + length;
685080f2
NC
18721
18722 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
18723 (unsigned long) offset, (unsigned long) length);
18724
c8071705 18725 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
18726 {
18727 Elf_External_Note * next;
18728 Elf_Internal_Note inote;
18729
18730 inote.type = BYTE_GET (external->type);
18731 inote.namesz = BYTE_GET (external->namesz);
18732 inote.namedata = external->name;
18733 inote.descsz = BYTE_GET (external->descsz);
18734 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
18735 inote.descpos = offset + (inote.descdata - (char *) pnotes);
18736
c8071705
NC
18737 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
18738 {
18739 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
18740 inote.descdata = inote.namedata;
18741 inote.namesz = 0;
18742 }
18743
685080f2
NC
18744 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
18745
c8071705 18746 if ( ((char *) next > end)
685080f2
NC
18747 || ((char *) next < (char *) pnotes))
18748 {
18749 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
18750 (unsigned long) ((char *) external - (char *) pnotes));
18751 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
18752 inote.type, inote.namesz, inote.descsz);
18753 break;
18754 }
18755
18756 external = next;
18757
18758 /* Prevent out-of-bounds indexing. */
c8071705 18759 if ( inote.namedata + inote.namesz > end
685080f2
NC
18760 || inote.namedata + inote.namesz < inote.namedata)
18761 {
18762 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
18763 (unsigned long) ((char *) external - (char *) pnotes));
18764 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
18765 inote.type, inote.namesz, inote.descsz);
18766 break;
18767 }
18768
18769 printf (" %s: ", get_v850_elf_note_type (inote.type));
18770
18771 if (! print_v850_note (& inote))
18772 {
32ec8896 18773 res = FALSE;
685080f2
NC
18774 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
18775 inote.namesz, inote.descsz);
18776 }
18777 }
18778
18779 free (pnotes);
18780
18781 return res;
18782}
18783
32ec8896 18784static bfd_boolean
dda8d76d 18785process_note_sections (Filedata * filedata)
1ec5cd37 18786{
2cf0635d 18787 Elf_Internal_Shdr * section;
1ec5cd37 18788 unsigned long i;
32ec8896
NC
18789 unsigned int n = 0;
18790 bfd_boolean res = TRUE;
1ec5cd37 18791
dda8d76d
NC
18792 for (i = 0, section = filedata->section_headers;
18793 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 18794 i++, section++)
685080f2
NC
18795 {
18796 if (section->sh_type == SHT_NOTE)
18797 {
dda8d76d 18798 if (! process_notes_at (filedata, section,
32ec8896 18799 (bfd_vma) section->sh_offset,
82ed9683
L
18800 (bfd_vma) section->sh_size,
18801 (bfd_vma) section->sh_addralign))
32ec8896 18802 res = FALSE;
685080f2
NC
18803 n++;
18804 }
18805
dda8d76d
NC
18806 if (( filedata->file_header.e_machine == EM_V800
18807 || filedata->file_header.e_machine == EM_V850
18808 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
18809 && section->sh_type == SHT_RENESAS_INFO)
18810 {
dda8d76d 18811 if (! process_v850_notes (filedata,
32ec8896
NC
18812 (bfd_vma) section->sh_offset,
18813 (bfd_vma) section->sh_size))
18814 res = FALSE;
685080f2
NC
18815 n++;
18816 }
18817 }
df565f32
NC
18818
18819 if (n == 0)
18820 /* Try processing NOTE segments instead. */
dda8d76d 18821 return process_corefile_note_segments (filedata);
1ec5cd37
NC
18822
18823 return res;
18824}
18825
32ec8896 18826static bfd_boolean
dda8d76d 18827process_notes (Filedata * filedata)
779fe533
NC
18828{
18829 /* If we have not been asked to display the notes then do nothing. */
18830 if (! do_notes)
32ec8896 18831 return TRUE;
103f02d3 18832
dda8d76d
NC
18833 if (filedata->file_header.e_type != ET_CORE)
18834 return process_note_sections (filedata);
103f02d3 18835
779fe533 18836 /* No program headers means no NOTE segment. */
dda8d76d
NC
18837 if (filedata->file_header.e_phnum > 0)
18838 return process_corefile_note_segments (filedata);
779fe533 18839
1ec5cd37 18840 printf (_("No note segments present in the core file.\n"));
32ec8896 18841 return TRUE;
779fe533
NC
18842}
18843
60abdbed
NC
18844static unsigned char *
18845display_public_gnu_attributes (unsigned char * start,
18846 const unsigned char * const end)
18847{
18848 printf (_(" Unknown GNU attribute: %s\n"), start);
18849
18850 start += strnlen ((char *) start, end - start);
18851 display_raw_attribute (start, end);
18852
18853 return (unsigned char *) end;
18854}
18855
18856static unsigned char *
18857display_generic_attribute (unsigned char * start,
18858 unsigned int tag,
18859 const unsigned char * const end)
18860{
18861 if (tag == 0)
18862 return (unsigned char *) end;
18863
18864 return display_tag_value (tag, start, end);
18865}
18866
32ec8896 18867static bfd_boolean
dda8d76d 18868process_arch_specific (Filedata * filedata)
252b5132 18869{
a952a375 18870 if (! do_arch)
32ec8896 18871 return TRUE;
a952a375 18872
dda8d76d 18873 switch (filedata->file_header.e_machine)
252b5132 18874 {
53a346d8
CZ
18875 case EM_ARC:
18876 case EM_ARC_COMPACT:
18877 case EM_ARC_COMPACT2:
dda8d76d 18878 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
18879 display_arc_attribute,
18880 display_generic_attribute);
11c1ff18 18881 case EM_ARM:
dda8d76d 18882 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
18883 display_arm_attribute,
18884 display_generic_attribute);
18885
252b5132 18886 case EM_MIPS:
4fe85591 18887 case EM_MIPS_RS3_LE:
dda8d76d 18888 return process_mips_specific (filedata);
60abdbed
NC
18889
18890 case EM_MSP430:
dda8d76d
NC
18891 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
18892 display_msp430x_attribute,
18893 display_generic_attribute);
60abdbed 18894
35c08157 18895 case EM_NDS32:
dda8d76d 18896 return process_nds32_specific (filedata);
60abdbed 18897
34c8bcba 18898 case EM_PPC:
b82317dd 18899 case EM_PPC64:
dda8d76d 18900 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18901 display_power_gnu_attribute);
18902
643f7afb
AK
18903 case EM_S390:
18904 case EM_S390_OLD:
dda8d76d 18905 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18906 display_s390_gnu_attribute);
18907
9e8c70f9
DM
18908 case EM_SPARC:
18909 case EM_SPARC32PLUS:
18910 case EM_SPARCV9:
dda8d76d 18911 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18912 display_sparc_gnu_attribute);
18913
59e6276b 18914 case EM_TI_C6000:
dda8d76d 18915 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
18916 display_tic6x_attribute,
18917 display_generic_attribute);
18918
252b5132 18919 default:
dda8d76d 18920 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
18921 display_public_gnu_attributes,
18922 display_generic_attribute);
252b5132 18923 }
252b5132
RH
18924}
18925
32ec8896 18926static bfd_boolean
dda8d76d 18927get_file_header (Filedata * filedata)
252b5132 18928{
9ea033b2 18929 /* Read in the identity array. */
dda8d76d 18930 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18931 return FALSE;
252b5132 18932
9ea033b2 18933 /* Determine how to read the rest of the header. */
dda8d76d 18934 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 18935 {
1a0670f3
AM
18936 default:
18937 case ELFDATANONE:
adab8cdc
AO
18938 case ELFDATA2LSB:
18939 byte_get = byte_get_little_endian;
18940 byte_put = byte_put_little_endian;
18941 break;
18942 case ELFDATA2MSB:
18943 byte_get = byte_get_big_endian;
18944 byte_put = byte_put_big_endian;
18945 break;
9ea033b2
NC
18946 }
18947
18948 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 18949 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
18950
18951 /* Read in the rest of the header. */
18952 if (is_32bit_elf)
18953 {
18954 Elf32_External_Ehdr ehdr32;
252b5132 18955
dda8d76d 18956 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18957 return FALSE;
103f02d3 18958
dda8d76d
NC
18959 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
18960 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
18961 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
18962 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
18963 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
18964 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
18965 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
18966 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
18967 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
18968 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
18969 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
18970 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
18971 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 18972 }
252b5132 18973 else
9ea033b2
NC
18974 {
18975 Elf64_External_Ehdr ehdr64;
a952a375
NC
18976
18977 /* If we have been compiled with sizeof (bfd_vma) == 4, then
18978 we will not be able to cope with the 64bit data found in
18979 64 ELF files. Detect this now and abort before we start
50c2245b 18980 overwriting things. */
a952a375
NC
18981 if (sizeof (bfd_vma) < 8)
18982 {
e3c8793a
NC
18983 error (_("This instance of readelf has been built without support for a\n\
1898464 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 18985 return FALSE;
a952a375 18986 }
103f02d3 18987
dda8d76d 18988 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18989 return FALSE;
103f02d3 18990
dda8d76d
NC
18991 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
18992 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
18993 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
18994 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
18995 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
18996 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
18997 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
18998 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
18999 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
19000 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
19001 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
19002 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
19003 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 19004 }
252b5132 19005
dda8d76d 19006 if (filedata->file_header.e_shoff)
7ece0d85
JJ
19007 {
19008 /* There may be some extensions in the first section header. Don't
19009 bomb if we can't read it. */
19010 if (is_32bit_elf)
dda8d76d 19011 get_32bit_section_headers (filedata, TRUE);
7ece0d85 19012 else
dda8d76d 19013 get_64bit_section_headers (filedata, TRUE);
7ece0d85 19014 }
560f3c1c 19015
32ec8896 19016 return TRUE;
252b5132
RH
19017}
19018
dda8d76d
NC
19019static void
19020close_file (Filedata * filedata)
19021{
19022 if (filedata)
19023 {
19024 if (filedata->handle)
19025 fclose (filedata->handle);
19026 free (filedata);
19027 }
19028}
19029
19030void
19031close_debug_file (void * data)
19032{
19033 close_file ((Filedata *) data);
19034}
19035
19036static Filedata *
19037open_file (const char * pathname)
19038{
19039 struct stat statbuf;
19040 Filedata * filedata = NULL;
19041
19042 if (stat (pathname, & statbuf) < 0
19043 || ! S_ISREG (statbuf.st_mode))
19044 goto fail;
19045
19046 filedata = calloc (1, sizeof * filedata);
19047 if (filedata == NULL)
19048 goto fail;
19049
19050 filedata->handle = fopen (pathname, "rb");
19051 if (filedata->handle == NULL)
19052 goto fail;
19053
19054 filedata->file_size = (bfd_size_type) statbuf.st_size;
19055 filedata->file_name = pathname;
19056
19057 if (! get_file_header (filedata))
19058 goto fail;
19059
19060 if (filedata->file_header.e_shoff)
19061 {
19062 bfd_boolean res;
19063
19064 /* Read the section headers again, this time for real. */
19065 if (is_32bit_elf)
19066 res = get_32bit_section_headers (filedata, FALSE);
19067 else
19068 res = get_64bit_section_headers (filedata, FALSE);
19069
19070 if (!res)
19071 goto fail;
19072 }
19073
19074 return filedata;
19075
19076 fail:
19077 if (filedata)
19078 {
19079 if (filedata->handle)
19080 fclose (filedata->handle);
19081 free (filedata);
19082 }
19083 return NULL;
19084}
19085
19086void *
19087open_debug_file (const char * pathname)
19088{
19089 return open_file (pathname);
19090}
19091
fb52b2f4
NC
19092/* Process one ELF object file according to the command line options.
19093 This file may actually be stored in an archive. The file is
32ec8896
NC
19094 positioned at the start of the ELF object. Returns TRUE if no
19095 problems were encountered, FALSE otherwise. */
fb52b2f4 19096
32ec8896 19097static bfd_boolean
dda8d76d 19098process_object (Filedata * filedata)
252b5132 19099{
dda8d76d 19100 Filedata * separates;
252b5132 19101 unsigned int i;
32ec8896 19102 bfd_boolean res = TRUE;
252b5132 19103
dda8d76d 19104 if (! get_file_header (filedata))
252b5132 19105 {
dda8d76d 19106 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 19107 return FALSE;
252b5132
RH
19108 }
19109
19110 /* Initialise per file variables. */
60bca95a 19111 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
19112 version_info[i] = 0;
19113
60bca95a 19114 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 19115 dynamic_info[i] = 0;
5115b233 19116 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
19117
19118 /* Process the file. */
19119 if (show_name)
dda8d76d 19120 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 19121
18bd398b
NC
19122 /* Initialise the dump_sects array from the cmdline_dump_sects array.
19123 Note we do this even if cmdline_dump_sects is empty because we
19124 must make sure that the dump_sets array is zeroed out before each
19125 object file is processed. */
dda8d76d
NC
19126 if (filedata->num_dump_sects > cmdline.num_dump_sects)
19127 memset (filedata->dump_sects, 0, filedata->num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 19128
dda8d76d 19129 if (cmdline.num_dump_sects > 0)
18bd398b 19130 {
dda8d76d 19131 if (filedata->num_dump_sects == 0)
18bd398b 19132 /* A sneaky way of allocating the dump_sects array. */
dda8d76d 19133 request_dump_bynumber (filedata, cmdline.num_dump_sects, 0);
18bd398b 19134
dda8d76d
NC
19135 assert (filedata->num_dump_sects >= cmdline.num_dump_sects);
19136 memcpy (filedata->dump_sects, cmdline.dump_sects,
19137 cmdline.num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 19138 }
d70c5fc7 19139
dda8d76d 19140 if (! process_file_header (filedata))
32ec8896 19141 return FALSE;
252b5132 19142
dda8d76d 19143 if (! process_section_headers (filedata))
2f62977e 19144 {
32ec8896
NC
19145 /* Without loaded section headers we cannot process lots of things. */
19146 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 19147
2f62977e 19148 if (! do_using_dynamic)
32ec8896 19149 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 19150 }
252b5132 19151
dda8d76d 19152 if (! process_section_groups (filedata))
32ec8896
NC
19153 /* Without loaded section groups we cannot process unwind. */
19154 do_unwind = FALSE;
d1f5c6e3 19155
dda8d76d
NC
19156 if (process_program_headers (filedata))
19157 process_dynamic_section (filedata);
32ec8896
NC
19158 else
19159 res = FALSE;
252b5132 19160
dda8d76d 19161 if (! process_relocs (filedata))
32ec8896 19162 res = FALSE;
252b5132 19163
dda8d76d 19164 if (! process_unwind (filedata))
32ec8896 19165 res = FALSE;
4d6ed7c8 19166
dda8d76d 19167 if (! process_symbol_table (filedata))
32ec8896 19168 res = FALSE;
252b5132 19169
dda8d76d 19170 if (! process_syminfo (filedata))
32ec8896 19171 res = FALSE;
252b5132 19172
dda8d76d 19173 if (! process_version_sections (filedata))
32ec8896 19174 res = FALSE;
252b5132 19175
82ed9683
L
19176 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
19177 separates = load_separate_debug_file (filedata, filedata->file_name);
19178 else
19179 separates = NULL;
dda8d76d
NC
19180
19181 if (! process_section_contents (filedata))
32ec8896 19182 res = FALSE;
f5842774 19183
dda8d76d
NC
19184 if (separates)
19185 {
19186 if (! process_section_headers (separates))
19187 res = FALSE;
19188 else if (! process_section_contents (separates))
19189 res = FALSE;
19190 }
19191
19192 if (! process_notes (filedata))
32ec8896 19193 res = FALSE;
103f02d3 19194
dda8d76d 19195 if (! process_gnu_liblist (filedata))
32ec8896 19196 res = FALSE;
047b2264 19197
dda8d76d 19198 if (! process_arch_specific (filedata))
32ec8896 19199 res = FALSE;
252b5132 19200
dda8d76d
NC
19201 free (filedata->program_headers);
19202 filedata->program_headers = NULL;
d93f0186 19203
dda8d76d
NC
19204 free (filedata->section_headers);
19205 filedata->section_headers = NULL;
252b5132 19206
dda8d76d
NC
19207 free (filedata->string_table);
19208 filedata->string_table = NULL;
19209 filedata->string_table_length = 0;
252b5132
RH
19210
19211 if (dynamic_strings)
19212 {
19213 free (dynamic_strings);
19214 dynamic_strings = NULL;
d79b3d50 19215 dynamic_strings_length = 0;
252b5132
RH
19216 }
19217
19218 if (dynamic_symbols)
19219 {
19220 free (dynamic_symbols);
19221 dynamic_symbols = NULL;
19936277 19222 num_dynamic_syms = 0;
252b5132
RH
19223 }
19224
19225 if (dynamic_syminfo)
19226 {
19227 free (dynamic_syminfo);
19228 dynamic_syminfo = NULL;
19229 }
ff78d6d6 19230
293c573e
MR
19231 if (dynamic_section)
19232 {
19233 free (dynamic_section);
19234 dynamic_section = NULL;
19235 }
19236
e4b17d5c
L
19237 if (section_headers_groups)
19238 {
19239 free (section_headers_groups);
19240 section_headers_groups = NULL;
19241 }
19242
19243 if (section_groups)
19244 {
2cf0635d
NC
19245 struct group_list * g;
19246 struct group_list * next;
e4b17d5c
L
19247
19248 for (i = 0; i < group_count; i++)
19249 {
19250 for (g = section_groups [i].root; g != NULL; g = next)
19251 {
19252 next = g->next;
19253 free (g);
19254 }
19255 }
19256
19257 free (section_groups);
19258 section_groups = NULL;
19259 }
19260
19e6b90e 19261 free_debug_memory ();
18bd398b 19262
32ec8896 19263 return res;
252b5132
RH
19264}
19265
2cf0635d 19266/* Process an ELF archive.
32ec8896
NC
19267 On entry the file is positioned just after the ARMAG string.
19268 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 19269
32ec8896 19270static bfd_boolean
dda8d76d 19271process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
19272{
19273 struct archive_info arch;
19274 struct archive_info nested_arch;
19275 size_t got;
32ec8896 19276 bfd_boolean ret = TRUE;
2cf0635d 19277
32ec8896 19278 show_name = TRUE;
2cf0635d
NC
19279
19280 /* The ARCH structure is used to hold information about this archive. */
19281 arch.file_name = NULL;
19282 arch.file = NULL;
19283 arch.index_array = NULL;
19284 arch.sym_table = NULL;
19285 arch.longnames = NULL;
19286
19287 /* The NESTED_ARCH structure is used as a single-item cache of information
19288 about a nested archive (when members of a thin archive reside within
19289 another regular archive file). */
19290 nested_arch.file_name = NULL;
19291 nested_arch.file = NULL;
19292 nested_arch.index_array = NULL;
19293 nested_arch.sym_table = NULL;
19294 nested_arch.longnames = NULL;
19295
dda8d76d
NC
19296 if (setup_archive (&arch, filedata->file_name, filedata->handle,
19297 is_thin_archive, do_archive_index) != 0)
2cf0635d 19298 {
32ec8896 19299 ret = FALSE;
2cf0635d 19300 goto out;
4145f1d5 19301 }
fb52b2f4 19302
4145f1d5
NC
19303 if (do_archive_index)
19304 {
2cf0635d 19305 if (arch.sym_table == NULL)
dda8d76d 19306 error (_("%s: unable to dump the index as none was found\n"), filedata->file_name);
4145f1d5
NC
19307 else
19308 {
591f7597 19309 unsigned long i, l;
4145f1d5
NC
19310 unsigned long current_pos;
19311
591f7597 19312 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
dda8d76d
NC
19313 filedata->file_name, (unsigned long) arch.index_num, arch.sym_size);
19314
19315 current_pos = ftell (filedata->handle);
4145f1d5 19316
2cf0635d 19317 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 19318 {
2cf0635d
NC
19319 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
19320 {
19321 char * member_name;
4145f1d5 19322
2cf0635d
NC
19323 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
19324
19325 if (member_name != NULL)
19326 {
19327 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
19328
19329 if (qualified_name != NULL)
19330 {
c2a7d3f5
NC
19331 printf (_("Contents of binary %s at offset "), qualified_name);
19332 (void) print_vma (arch.index_array[i], PREFIX_HEX);
19333 putchar ('\n');
2cf0635d
NC
19334 free (qualified_name);
19335 }
4145f1d5
NC
19336 }
19337 }
2cf0635d
NC
19338
19339 if (l >= arch.sym_size)
4145f1d5
NC
19340 {
19341 error (_("%s: end of the symbol table reached before the end of the index\n"),
dda8d76d 19342 filedata->file_name);
32ec8896 19343 ret = FALSE;
cb8f3167 19344 break;
4145f1d5 19345 }
591f7597
NC
19346 /* PR 17531: file: 0b6630b2. */
19347 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
19348 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
19349 }
19350
67ce483b 19351 if (arch.uses_64bit_indices)
c2a7d3f5
NC
19352 l = (l + 7) & ~ 7;
19353 else
19354 l += l & 1;
19355
2cf0635d 19356 if (l < arch.sym_size)
32ec8896 19357 {
d3a49aa8
AM
19358 error (ngettext ("%s: %ld byte remains in the symbol table, "
19359 "but without corresponding entries in "
19360 "the index table\n",
19361 "%s: %ld bytes remain in the symbol table, "
19362 "but without corresponding entries in "
19363 "the index table\n",
19364 arch.sym_size - l),
dda8d76d 19365 filedata->file_name, arch.sym_size - l);
32ec8896
NC
19366 ret = FALSE;
19367 }
4145f1d5 19368
dda8d76d 19369 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 19370 {
dda8d76d
NC
19371 error (_("%s: failed to seek back to start of object files in the archive\n"),
19372 filedata->file_name);
32ec8896 19373 ret = FALSE;
2cf0635d 19374 goto out;
4145f1d5 19375 }
fb52b2f4 19376 }
4145f1d5
NC
19377
19378 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
19379 && !do_segments && !do_header && !do_dump && !do_version
19380 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 19381 && !do_section_groups && !do_dyn_syms)
2cf0635d 19382 {
32ec8896 19383 ret = TRUE; /* Archive index only. */
2cf0635d
NC
19384 goto out;
19385 }
fb52b2f4
NC
19386 }
19387
fb52b2f4
NC
19388 while (1)
19389 {
2cf0635d
NC
19390 char * name;
19391 size_t namelen;
19392 char * qualified_name;
19393
19394 /* Read the next archive header. */
dda8d76d 19395 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
2cf0635d 19396 {
dda8d76d 19397 error (_("%s: failed to seek to next archive header\n"), filedata->file_name);
32ec8896 19398 return FALSE;
2cf0635d 19399 }
dda8d76d 19400 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d
NC
19401 if (got != sizeof arch.arhdr)
19402 {
19403 if (got == 0)
19404 break;
dda8d76d 19405 error (_("%s: failed to read archive header\n"), filedata->file_name);
32ec8896 19406 ret = FALSE;
2cf0635d
NC
19407 break;
19408 }
19409 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
19410 {
19411 error (_("%s: did not find a valid archive header\n"), arch.file_name);
32ec8896 19412 ret = FALSE;
2cf0635d
NC
19413 break;
19414 }
19415
19416 arch.next_arhdr_offset += sizeof arch.arhdr;
19417
19418 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
19419 if (archive_file_size & 01)
19420 ++archive_file_size;
19421
19422 name = get_archive_member_name (&arch, &nested_arch);
19423 if (name == NULL)
fb52b2f4 19424 {
dda8d76d 19425 error (_("%s: bad archive file name\n"), filedata->file_name);
32ec8896 19426 ret = FALSE;
d989285c 19427 break;
fb52b2f4 19428 }
2cf0635d 19429 namelen = strlen (name);
fb52b2f4 19430
2cf0635d
NC
19431 qualified_name = make_qualified_name (&arch, &nested_arch, name);
19432 if (qualified_name == NULL)
fb52b2f4 19433 {
dda8d76d 19434 error (_("%s: bad archive file name\n"), filedata->file_name);
32ec8896 19435 ret = FALSE;
d989285c 19436 break;
fb52b2f4
NC
19437 }
19438
2cf0635d
NC
19439 if (is_thin_archive && arch.nested_member_origin == 0)
19440 {
19441 /* This is a proxy for an external member of a thin archive. */
dda8d76d
NC
19442 Filedata * member_filedata;
19443 char * member_file_name = adjust_relative_path
19444 (filedata->file_name, name, namelen);
32ec8896 19445
2cf0635d
NC
19446 if (member_file_name == NULL)
19447 {
32ec8896 19448 ret = FALSE;
2cf0635d
NC
19449 break;
19450 }
19451
dda8d76d
NC
19452 member_filedata = open_file (member_file_name);
19453 if (member_filedata == NULL)
2cf0635d
NC
19454 {
19455 error (_("Input file '%s' is not readable.\n"), member_file_name);
19456 free (member_file_name);
32ec8896 19457 ret = FALSE;
2cf0635d
NC
19458 break;
19459 }
19460
19461 archive_file_offset = arch.nested_member_origin;
dda8d76d 19462 member_filedata->file_name = qualified_name;
2cf0635d 19463
dda8d76d 19464 if (! process_object (member_filedata))
32ec8896 19465 ret = FALSE;
2cf0635d 19466
dda8d76d 19467 close_file (member_filedata);
2cf0635d
NC
19468 free (member_file_name);
19469 }
19470 else if (is_thin_archive)
19471 {
eb02c04d
PK
19472 Filedata thin_filedata;
19473
19474 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 19475
a043396b
NC
19476 /* PR 15140: Allow for corrupt thin archives. */
19477 if (nested_arch.file == NULL)
19478 {
19479 error (_("%s: contains corrupt thin archive: %s\n"),
dda8d76d 19480 filedata->file_name, name);
32ec8896 19481 ret = FALSE;
a043396b
NC
19482 break;
19483 }
19484
2cf0635d
NC
19485 /* This is a proxy for a member of a nested archive. */
19486 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
19487
19488 /* The nested archive file will have been opened and setup by
19489 get_archive_member_name. */
19490 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
19491 {
19492 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
32ec8896 19493 ret = FALSE;
2cf0635d
NC
19494 break;
19495 }
19496
dda8d76d
NC
19497 thin_filedata.handle = nested_arch.file;
19498 thin_filedata.file_name = qualified_name;
19499
19500 if (! process_object (& thin_filedata))
32ec8896 19501 ret = FALSE;
2cf0635d
NC
19502 }
19503 else
19504 {
19505 archive_file_offset = arch.next_arhdr_offset;
19506 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 19507
6a6196fc 19508 filedata->file_name = qualified_name;
dda8d76d 19509 if (! process_object (filedata))
32ec8896 19510 ret = FALSE;
2cf0635d 19511 }
fb52b2f4 19512
dda8d76d 19513 if (filedata->dump_sects != NULL)
2b52916e 19514 {
dda8d76d
NC
19515 free (filedata->dump_sects);
19516 filedata->dump_sects = NULL;
19517 filedata->num_dump_sects = 0;
2b52916e
L
19518 }
19519
2cf0635d 19520 free (qualified_name);
fb52b2f4
NC
19521 }
19522
4145f1d5 19523 out:
2cf0635d
NC
19524 if (nested_arch.file != NULL)
19525 fclose (nested_arch.file);
19526 release_archive (&nested_arch);
19527 release_archive (&arch);
fb52b2f4 19528
d989285c 19529 return ret;
fb52b2f4
NC
19530}
19531
32ec8896 19532static bfd_boolean
2cf0635d 19533process_file (char * file_name)
fb52b2f4 19534{
dda8d76d 19535 Filedata * filedata = NULL;
fb52b2f4
NC
19536 struct stat statbuf;
19537 char armag[SARMAG];
32ec8896 19538 bfd_boolean ret = TRUE;
fb52b2f4
NC
19539
19540 if (stat (file_name, &statbuf) < 0)
19541 {
f24ddbdd
NC
19542 if (errno == ENOENT)
19543 error (_("'%s': No such file\n"), file_name);
19544 else
19545 error (_("Could not locate '%s'. System error message: %s\n"),
19546 file_name, strerror (errno));
32ec8896 19547 return FALSE;
f24ddbdd
NC
19548 }
19549
19550 if (! S_ISREG (statbuf.st_mode))
19551 {
19552 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 19553 return FALSE;
fb52b2f4
NC
19554 }
19555
dda8d76d
NC
19556 filedata = calloc (1, sizeof * filedata);
19557 if (filedata == NULL)
19558 {
19559 error (_("Out of memory allocating file data structure\n"));
19560 return FALSE;
19561 }
19562
19563 filedata->file_name = file_name;
19564 filedata->handle = fopen (file_name, "rb");
19565 if (filedata->handle == NULL)
fb52b2f4 19566 {
f24ddbdd 19567 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 19568 free (filedata);
32ec8896 19569 return FALSE;
fb52b2f4
NC
19570 }
19571
dda8d76d 19572 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 19573 {
4145f1d5 19574 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
19575 fclose (filedata->handle);
19576 free (filedata);
32ec8896 19577 return FALSE;
fb52b2f4
NC
19578 }
19579
dda8d76d 19580 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 19581
fb52b2f4 19582 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 19583 {
dda8d76d 19584 if (! process_archive (filedata, FALSE))
32ec8896
NC
19585 ret = FALSE;
19586 }
2cf0635d 19587 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 19588 {
dda8d76d 19589 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
19590 ret = FALSE;
19591 }
fb52b2f4
NC
19592 else
19593 {
4145f1d5
NC
19594 if (do_archive_index)
19595 error (_("File %s is not an archive so its index cannot be displayed.\n"),
19596 file_name);
19597
dda8d76d 19598 rewind (filedata->handle);
fb52b2f4 19599 archive_file_size = archive_file_offset = 0;
32ec8896 19600
dda8d76d 19601 if (! process_object (filedata))
32ec8896 19602 ret = FALSE;
fb52b2f4
NC
19603 }
19604
dda8d76d
NC
19605 fclose (filedata->handle);
19606 free (filedata);
32ec8896 19607
fb52b2f4
NC
19608 return ret;
19609}
19610
252b5132
RH
19611#ifdef SUPPORT_DISASSEMBLY
19612/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 19613 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 19614 symbols. */
252b5132
RH
19615
19616void
2cf0635d 19617print_address (unsigned int addr, FILE * outfile)
252b5132
RH
19618{
19619 fprintf (outfile,"0x%8.8x", addr);
19620}
19621
e3c8793a 19622/* Needed by the i386 disassembler. */
dda8d76d 19623
252b5132
RH
19624void
19625db_task_printsym (unsigned int addr)
19626{
19627 print_address (addr, stderr);
19628}
19629#endif
19630
19631int
2cf0635d 19632main (int argc, char ** argv)
252b5132 19633{
ff78d6d6
L
19634 int err;
19635
252b5132
RH
19636#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
19637 setlocale (LC_MESSAGES, "");
3882b010
L
19638#endif
19639#if defined (HAVE_SETLOCALE)
19640 setlocale (LC_CTYPE, "");
252b5132
RH
19641#endif
19642 bindtextdomain (PACKAGE, LOCALEDIR);
19643 textdomain (PACKAGE);
19644
869b9d07
MM
19645 expandargv (&argc, &argv);
19646
dda8d76d
NC
19647 cmdline.file_name = "<cmdline>";
19648 parse_args (& cmdline, argc, argv);
59f14fc0 19649
18bd398b 19650 if (optind < (argc - 1))
32ec8896 19651 show_name = TRUE;
5656ba2c
L
19652 else if (optind >= argc)
19653 {
19654 warn (_("Nothing to do.\n"));
19655 usage (stderr);
19656 }
18bd398b 19657
32ec8896 19658 err = FALSE;
252b5132 19659 while (optind < argc)
32ec8896
NC
19660 if (! process_file (argv[optind++]))
19661 err = TRUE;
252b5132 19662
dda8d76d
NC
19663 if (cmdline.dump_sects != NULL)
19664 free (cmdline.dump_sects);
252b5132 19665
32ec8896 19666 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 19667}
This page took 2.958923 seconds and 4 git commands to generate.