]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Prune BFD warnings for unknown GNU properties
[thirdparty/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;
fd503541 3407 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 3408 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3409 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3410 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3411 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3412 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3413 case 0:
3414 /* We simply ignore the field in this case to avoid confusion:
3415 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3416 extension. */
3417 break;
2b692964 3418 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3419 }
43521d43
TS
3420
3421 switch ((e_flags & EF_MIPS_ABI))
3422 {
3423 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3424 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3425 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3426 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3427 case 0:
3428 /* We simply ignore the field in this case to avoid confusion:
3429 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3430 This means it is likely to be an o32 file, but not for
3431 sure. */
3432 break;
2b692964 3433 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3434 }
3435
3436 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3437 strcat (buf, ", mdmx");
3438
3439 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3440 strcat (buf, ", mips16");
3441
df58fc94
RS
3442 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3443 strcat (buf, ", micromips");
3444
43521d43
TS
3445 switch ((e_flags & EF_MIPS_ARCH))
3446 {
3447 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3448 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3449 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3450 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3451 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3452 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3453 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3454 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3455 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3456 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3457 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3458 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3459 }
252b5132 3460 break;
351b4b40 3461
35c08157
KLC
3462 case EM_NDS32:
3463 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3464 break;
3465
fe944acf
FT
3466 case EM_NFP:
3467 switch (EF_NFP_MACH (e_flags))
3468 {
3469 case E_NFP_MACH_3200:
3470 strcat (buf, ", NFP-32xx");
3471 break;
3472 case E_NFP_MACH_6000:
3473 strcat (buf, ", NFP-6xxx");
3474 break;
3475 }
3476 break;
3477
e23eba97
NC
3478 case EM_RISCV:
3479 if (e_flags & EF_RISCV_RVC)
3480 strcat (buf, ", RVC");
2922d21d 3481
7f999549
JW
3482 if (e_flags & EF_RISCV_RVE)
3483 strcat (buf, ", RVE");
3484
2922d21d
AW
3485 switch (e_flags & EF_RISCV_FLOAT_ABI)
3486 {
3487 case EF_RISCV_FLOAT_ABI_SOFT:
3488 strcat (buf, ", soft-float ABI");
3489 break;
3490
3491 case EF_RISCV_FLOAT_ABI_SINGLE:
3492 strcat (buf, ", single-float ABI");
3493 break;
3494
3495 case EF_RISCV_FLOAT_ABI_DOUBLE:
3496 strcat (buf, ", double-float ABI");
3497 break;
3498
3499 case EF_RISCV_FLOAT_ABI_QUAD:
3500 strcat (buf, ", quad-float ABI");
3501 break;
3502 }
e23eba97
NC
3503 break;
3504
ccde1100
AO
3505 case EM_SH:
3506 switch ((e_flags & EF_SH_MACH_MASK))
3507 {
3508 case EF_SH1: strcat (buf, ", sh1"); break;
3509 case EF_SH2: strcat (buf, ", sh2"); break;
3510 case EF_SH3: strcat (buf, ", sh3"); break;
3511 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3512 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3513 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3514 case EF_SH3E: strcat (buf, ", sh3e"); break;
3515 case EF_SH4: strcat (buf, ", sh4"); break;
3516 case EF_SH5: strcat (buf, ", sh5"); break;
3517 case EF_SH2E: strcat (buf, ", sh2e"); break;
3518 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3519 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3520 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3521 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3522 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3523 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3524 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3525 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3526 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3527 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3528 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3529 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3530 }
3531
cec6a5b8
MR
3532 if (e_flags & EF_SH_PIC)
3533 strcat (buf, ", pic");
3534
3535 if (e_flags & EF_SH_FDPIC)
3536 strcat (buf, ", fdpic");
ccde1100 3537 break;
948f632f 3538
73589c9d
CS
3539 case EM_OR1K:
3540 if (e_flags & EF_OR1K_NODELAY)
3541 strcat (buf, ", no delay");
3542 break;
57346661 3543
351b4b40
RH
3544 case EM_SPARCV9:
3545 if (e_flags & EF_SPARC_32PLUS)
3546 strcat (buf, ", v8+");
3547
3548 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3549 strcat (buf, ", ultrasparcI");
3550
3551 if (e_flags & EF_SPARC_SUN_US3)
3552 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3553
3554 if (e_flags & EF_SPARC_HAL_R1)
3555 strcat (buf, ", halr1");
3556
3557 if (e_flags & EF_SPARC_LEDATA)
3558 strcat (buf, ", ledata");
3559
3560 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3561 strcat (buf, ", tso");
3562
3563 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3564 strcat (buf, ", pso");
3565
3566 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3567 strcat (buf, ", rmo");
3568 break;
7d466069 3569
103f02d3
UD
3570 case EM_PARISC:
3571 switch (e_flags & EF_PARISC_ARCH)
3572 {
3573 case EFA_PARISC_1_0:
3574 strcpy (buf, ", PA-RISC 1.0");
3575 break;
3576 case EFA_PARISC_1_1:
3577 strcpy (buf, ", PA-RISC 1.1");
3578 break;
3579 case EFA_PARISC_2_0:
3580 strcpy (buf, ", PA-RISC 2.0");
3581 break;
3582 default:
3583 break;
3584 }
3585 if (e_flags & EF_PARISC_TRAPNIL)
3586 strcat (buf, ", trapnil");
3587 if (e_flags & EF_PARISC_EXT)
3588 strcat (buf, ", ext");
3589 if (e_flags & EF_PARISC_LSB)
3590 strcat (buf, ", lsb");
3591 if (e_flags & EF_PARISC_WIDE)
3592 strcat (buf, ", wide");
3593 if (e_flags & EF_PARISC_NO_KABP)
3594 strcat (buf, ", no kabp");
3595 if (e_flags & EF_PARISC_LAZYSWAP)
3596 strcat (buf, ", lazyswap");
30800947 3597 break;
76da6bbe 3598
7d466069 3599 case EM_PJ:
2b0337b0 3600 case EM_PJ_OLD:
7d466069
ILT
3601 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3602 strcat (buf, ", new calling convention");
3603
3604 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3605 strcat (buf, ", gnu calling convention");
3606 break;
4d6ed7c8
NC
3607
3608 case EM_IA_64:
3609 if ((e_flags & EF_IA_64_ABI64))
3610 strcat (buf, ", 64-bit");
3611 else
3612 strcat (buf, ", 32-bit");
3613 if ((e_flags & EF_IA_64_REDUCEDFP))
3614 strcat (buf, ", reduced fp model");
3615 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3616 strcat (buf, ", no function descriptors, constant gp");
3617 else if ((e_flags & EF_IA_64_CONS_GP))
3618 strcat (buf, ", constant gp");
3619 if ((e_flags & EF_IA_64_ABSOLUTE))
3620 strcat (buf, ", absolute");
dda8d76d 3621 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3622 {
3623 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3624 strcat (buf, ", vms_linkages");
3625 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3626 {
3627 case EF_IA_64_VMS_COMCOD_SUCCESS:
3628 break;
3629 case EF_IA_64_VMS_COMCOD_WARNING:
3630 strcat (buf, ", warning");
3631 break;
3632 case EF_IA_64_VMS_COMCOD_ERROR:
3633 strcat (buf, ", error");
3634 break;
3635 case EF_IA_64_VMS_COMCOD_ABORT:
3636 strcat (buf, ", abort");
3637 break;
3638 default:
bee0ee85
NC
3639 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3640 e_flags & EF_IA_64_VMS_COMCOD);
3641 strcat (buf, ", <unknown>");
28f997cf
TG
3642 }
3643 }
4d6ed7c8 3644 break;
179d3252
JT
3645
3646 case EM_VAX:
3647 if ((e_flags & EF_VAX_NONPIC))
3648 strcat (buf, ", non-PIC");
3649 if ((e_flags & EF_VAX_DFLOAT))
3650 strcat (buf, ", D-Float");
3651 if ((e_flags & EF_VAX_GFLOAT))
3652 strcat (buf, ", G-Float");
3653 break;
c7927a3c 3654
619ed720
EB
3655 case EM_VISIUM:
3656 if (e_flags & EF_VISIUM_ARCH_MCM)
3657 strcat (buf, ", mcm");
3658 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3659 strcat (buf, ", mcm24");
3660 if (e_flags & EF_VISIUM_ARCH_GR6)
3661 strcat (buf, ", gr6");
3662 break;
3663
4046d87a 3664 case EM_RL78:
1740ba0c
NC
3665 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3666 {
3667 case E_FLAG_RL78_ANY_CPU: break;
3668 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3669 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3670 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3671 }
856ea05c
KP
3672 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3673 strcat (buf, ", 64-bit doubles");
4046d87a 3674 break;
0b4362b0 3675
c7927a3c
NC
3676 case EM_RX:
3677 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3678 strcat (buf, ", 64-bit doubles");
3679 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3680 strcat (buf, ", dsp");
d4cb0ea0 3681 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3682 strcat (buf, ", pid");
708e2187
NC
3683 if (e_flags & E_FLAG_RX_ABI)
3684 strcat (buf, ", RX ABI");
3525236c
NC
3685 if (e_flags & E_FLAG_RX_SINSNS_SET)
3686 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3687 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3688 if (e_flags & E_FLAG_RX_V2)
3689 strcat (buf, ", V2");
d4cb0ea0 3690 break;
55786da2
AK
3691
3692 case EM_S390:
3693 if (e_flags & EF_S390_HIGH_GPRS)
3694 strcat (buf, ", highgprs");
d4cb0ea0 3695 break;
40b36596
JM
3696
3697 case EM_TI_C6000:
3698 if ((e_flags & EF_C6000_REL))
3699 strcat (buf, ", relocatable module");
d4cb0ea0 3700 break;
13761a11
NC
3701
3702 case EM_MSP430:
3703 strcat (buf, _(": architecture variant: "));
3704 switch (e_flags & EF_MSP430_MACH)
3705 {
3706 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3707 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3708 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3709 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3710 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3711 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3712 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3713 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3714 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3715 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3716 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3717 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3718 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3719 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3720 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3721 default:
3722 strcat (buf, _(": unknown")); break;
3723 }
3724
3725 if (e_flags & ~ EF_MSP430_MACH)
3726 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3727 }
3728 }
3729
3730 return buf;
3731}
3732
252b5132 3733static const char *
dda8d76d 3734get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3735{
3736 static char buff[32];
3737
3738 switch (osabi)
3739 {
3740 case ELFOSABI_NONE: return "UNIX - System V";
3741 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3742 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3743 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3744 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3745 case ELFOSABI_AIX: return "UNIX - AIX";
3746 case ELFOSABI_IRIX: return "UNIX - IRIX";
3747 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3748 case ELFOSABI_TRU64: return "UNIX - TRU64";
3749 case ELFOSABI_MODESTO: return "Novell - Modesto";
3750 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3751 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3752 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3753 case ELFOSABI_AROS: return "AROS";
11636f9e 3754 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3755 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3756 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3757 default:
40b36596 3758 if (osabi >= 64)
dda8d76d 3759 switch (filedata->file_header.e_machine)
40b36596
JM
3760 {
3761 case EM_ARM:
3762 switch (osabi)
3763 {
3764 case ELFOSABI_ARM: return "ARM";
18a20338 3765 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3766 default:
3767 break;
3768 }
3769 break;
3770
3771 case EM_MSP430:
3772 case EM_MSP430_OLD:
619ed720 3773 case EM_VISIUM:
40b36596
JM
3774 switch (osabi)
3775 {
3776 case ELFOSABI_STANDALONE: return _("Standalone App");
3777 default:
3778 break;
3779 }
3780 break;
3781
3782 case EM_TI_C6000:
3783 switch (osabi)
3784 {
3785 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3786 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3787 default:
3788 break;
3789 }
3790 break;
3791
3792 default:
3793 break;
3794 }
e9e44622 3795 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3796 return buff;
3797 }
3798}
3799
a06ea964
NC
3800static const char *
3801get_aarch64_segment_type (unsigned long type)
3802{
3803 switch (type)
3804 {
32ec8896
NC
3805 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3806 default: return NULL;
a06ea964 3807 }
a06ea964
NC
3808}
3809
b294bdf8
MM
3810static const char *
3811get_arm_segment_type (unsigned long type)
3812{
3813 switch (type)
3814 {
32ec8896
NC
3815 case PT_ARM_EXIDX: return "EXIDX";
3816 default: return NULL;
b294bdf8 3817 }
b294bdf8
MM
3818}
3819
b4cbbe8f
AK
3820static const char *
3821get_s390_segment_type (unsigned long type)
3822{
3823 switch (type)
3824 {
3825 case PT_S390_PGSTE: return "S390_PGSTE";
3826 default: return NULL;
3827 }
3828}
3829
d3ba0551
AM
3830static const char *
3831get_mips_segment_type (unsigned long type)
252b5132
RH
3832{
3833 switch (type)
3834 {
32ec8896
NC
3835 case PT_MIPS_REGINFO: return "REGINFO";
3836 case PT_MIPS_RTPROC: return "RTPROC";
3837 case PT_MIPS_OPTIONS: return "OPTIONS";
3838 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3839 default: return NULL;
252b5132 3840 }
252b5132
RH
3841}
3842
103f02d3 3843static const char *
d3ba0551 3844get_parisc_segment_type (unsigned long type)
103f02d3
UD
3845{
3846 switch (type)
3847 {
3848 case PT_HP_TLS: return "HP_TLS";
3849 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3850 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3851 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3852 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3853 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3854 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3855 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3856 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3857 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3858 case PT_HP_PARALLEL: return "HP_PARALLEL";
3859 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3860 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3861 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3862 case PT_HP_STACK: return "HP_STACK";
3863 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3864 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3865 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3866 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3867 default: return NULL;
103f02d3 3868 }
103f02d3
UD
3869}
3870
4d6ed7c8 3871static const char *
d3ba0551 3872get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3873{
3874 switch (type)
3875 {
3876 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3877 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3878 case PT_HP_TLS: return "HP_TLS";
3879 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3880 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3881 case PT_IA_64_HP_STACK: return "HP_STACK";
32ec8896 3882 default: return NULL;
4d6ed7c8 3883 }
4d6ed7c8
NC
3884}
3885
40b36596
JM
3886static const char *
3887get_tic6x_segment_type (unsigned long type)
3888{
3889 switch (type)
3890 {
32ec8896
NC
3891 case PT_C6000_PHATTR: return "C6000_PHATTR";
3892 default: return NULL;
40b36596 3893 }
40b36596
JM
3894}
3895
5522f910
NC
3896static const char *
3897get_solaris_segment_type (unsigned long type)
3898{
3899 switch (type)
3900 {
3901 case 0x6464e550: return "PT_SUNW_UNWIND";
3902 case 0x6474e550: return "PT_SUNW_EH_FRAME";
3903 case 0x6ffffff7: return "PT_LOSUNW";
3904 case 0x6ffffffa: return "PT_SUNWBSS";
3905 case 0x6ffffffb: return "PT_SUNWSTACK";
3906 case 0x6ffffffc: return "PT_SUNWDTRACE";
3907 case 0x6ffffffd: return "PT_SUNWCAP";
3908 case 0x6fffffff: return "PT_HISUNW";
32ec8896 3909 default: return NULL;
5522f910
NC
3910 }
3911}
3912
252b5132 3913static const char *
dda8d76d 3914get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 3915{
b34976b6 3916 static char buff[32];
252b5132
RH
3917
3918 switch (p_type)
3919 {
b34976b6
AM
3920 case PT_NULL: return "NULL";
3921 case PT_LOAD: return "LOAD";
252b5132 3922 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3923 case PT_INTERP: return "INTERP";
3924 case PT_NOTE: return "NOTE";
3925 case PT_SHLIB: return "SHLIB";
3926 case PT_PHDR: return "PHDR";
13ae64f3 3927 case PT_TLS: return "TLS";
32ec8896 3928 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 3929 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3930 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3931
252b5132 3932 default:
a91e1603
L
3933 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
3934 {
3935 sprintf (buff, "GNU_MBIND+%#lx",
3936 p_type - PT_GNU_MBIND_LO);
3937 }
3938 else if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 3939 {
2cf0635d 3940 const char * result;
103f02d3 3941
dda8d76d 3942 switch (filedata->file_header.e_machine)
252b5132 3943 {
a06ea964
NC
3944 case EM_AARCH64:
3945 result = get_aarch64_segment_type (p_type);
3946 break;
b294bdf8
MM
3947 case EM_ARM:
3948 result = get_arm_segment_type (p_type);
3949 break;
252b5132 3950 case EM_MIPS:
4fe85591 3951 case EM_MIPS_RS3_LE:
252b5132
RH
3952 result = get_mips_segment_type (p_type);
3953 break;
103f02d3
UD
3954 case EM_PARISC:
3955 result = get_parisc_segment_type (p_type);
3956 break;
4d6ed7c8
NC
3957 case EM_IA_64:
3958 result = get_ia64_segment_type (p_type);
3959 break;
40b36596
JM
3960 case EM_TI_C6000:
3961 result = get_tic6x_segment_type (p_type);
3962 break;
b4cbbe8f
AK
3963 case EM_S390:
3964 case EM_S390_OLD:
3965 result = get_s390_segment_type (p_type);
3966 break;
252b5132
RH
3967 default:
3968 result = NULL;
3969 break;
3970 }
103f02d3 3971
252b5132
RH
3972 if (result != NULL)
3973 return result;
103f02d3 3974
1a9ccd70 3975 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
3976 }
3977 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3978 {
2cf0635d 3979 const char * result;
103f02d3 3980
dda8d76d 3981 switch (filedata->file_header.e_machine)
103f02d3
UD
3982 {
3983 case EM_PARISC:
3984 result = get_parisc_segment_type (p_type);
3985 break;
00428cca
AM
3986 case EM_IA_64:
3987 result = get_ia64_segment_type (p_type);
3988 break;
103f02d3 3989 default:
dda8d76d 3990 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5522f910
NC
3991 result = get_solaris_segment_type (p_type);
3992 else
3993 result = NULL;
103f02d3
UD
3994 break;
3995 }
3996
3997 if (result != NULL)
3998 return result;
3999
1a9ccd70 4000 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4001 }
252b5132 4002 else
e9e44622 4003 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4004
4005 return buff;
4006 }
4007}
4008
53a346d8
CZ
4009static const char *
4010get_arc_section_type_name (unsigned int sh_type)
4011{
4012 switch (sh_type)
4013 {
4014 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4015 default:
4016 break;
4017 }
4018 return NULL;
4019}
4020
252b5132 4021static const char *
d3ba0551 4022get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4023{
4024 switch (sh_type)
4025 {
b34976b6
AM
4026 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4027 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4028 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4029 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4030 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4031 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4032 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4033 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4034 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4035 case SHT_MIPS_RELD: return "MIPS_RELD";
4036 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4037 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4038 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4039 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4040 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4041 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4042 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4043 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4044 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4045 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4046 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4047 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4048 case SHT_MIPS_LINE: return "MIPS_LINE";
4049 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4050 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4051 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4052 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4053 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4054 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4055 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4056 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4057 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4058 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4059 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4060 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4061 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4062 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4063 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4064 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4065 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
4066 default:
4067 break;
4068 }
4069 return NULL;
4070}
4071
103f02d3 4072static const char *
d3ba0551 4073get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4074{
4075 switch (sh_type)
4076 {
4077 case SHT_PARISC_EXT: return "PARISC_EXT";
4078 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4079 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4080 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4081 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4082 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4083 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4084 default: return NULL;
103f02d3 4085 }
103f02d3
UD
4086}
4087
4d6ed7c8 4088static const char *
dda8d76d 4089get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4090{
18bd398b 4091 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4092 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4093 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4094
4d6ed7c8
NC
4095 switch (sh_type)
4096 {
148b93f2
NC
4097 case SHT_IA_64_EXT: return "IA_64_EXT";
4098 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4099 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4100 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4101 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4102 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4103 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4104 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4105 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4106 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4107 default:
4108 break;
4109 }
4110 return NULL;
4111}
4112
d2b2c203
DJ
4113static const char *
4114get_x86_64_section_type_name (unsigned int sh_type)
4115{
4116 switch (sh_type)
4117 {
4118 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4119 default: return NULL;
d2b2c203 4120 }
d2b2c203
DJ
4121}
4122
a06ea964
NC
4123static const char *
4124get_aarch64_section_type_name (unsigned int sh_type)
4125{
4126 switch (sh_type)
4127 {
32ec8896
NC
4128 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4129 default: return NULL;
a06ea964 4130 }
a06ea964
NC
4131}
4132
40a18ebd
NC
4133static const char *
4134get_arm_section_type_name (unsigned int sh_type)
4135{
4136 switch (sh_type)
4137 {
7f6fed87
NC
4138 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4139 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4140 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4141 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4142 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4143 default: return NULL;
40a18ebd 4144 }
40a18ebd
NC
4145}
4146
40b36596
JM
4147static const char *
4148get_tic6x_section_type_name (unsigned int sh_type)
4149{
4150 switch (sh_type)
4151 {
32ec8896
NC
4152 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4153 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4154 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4155 case SHT_TI_ICODE: return "TI_ICODE";
4156 case SHT_TI_XREF: return "TI_XREF";
4157 case SHT_TI_HANDLER: return "TI_HANDLER";
4158 case SHT_TI_INITINFO: return "TI_INITINFO";
4159 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4160 default: return NULL;
40b36596 4161 }
40b36596
JM
4162}
4163
13761a11
NC
4164static const char *
4165get_msp430x_section_type_name (unsigned int sh_type)
4166{
4167 switch (sh_type)
4168 {
32ec8896
NC
4169 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4170 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4171 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4172 default: return NULL;
13761a11
NC
4173 }
4174}
4175
fe944acf
FT
4176static const char *
4177get_nfp_section_type_name (unsigned int sh_type)
4178{
4179 switch (sh_type)
4180 {
4181 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4182 case SHT_NFP_INITREG: return "NFP_INITREG";
4183 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4184 default: return NULL;
4185 }
4186}
4187
685080f2
NC
4188static const char *
4189get_v850_section_type_name (unsigned int sh_type)
4190{
4191 switch (sh_type)
4192 {
32ec8896
NC
4193 case SHT_V850_SCOMMON: return "V850 Small Common";
4194 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4195 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4196 case SHT_RENESAS_IOP: return "RENESAS IOP";
4197 case SHT_RENESAS_INFO: return "RENESAS INFO";
4198 default: return NULL;
685080f2
NC
4199 }
4200}
4201
252b5132 4202static const char *
dda8d76d 4203get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4204{
b34976b6 4205 static char buff[32];
9fb71ee4 4206 const char * result;
252b5132
RH
4207
4208 switch (sh_type)
4209 {
4210 case SHT_NULL: return "NULL";
4211 case SHT_PROGBITS: return "PROGBITS";
4212 case SHT_SYMTAB: return "SYMTAB";
4213 case SHT_STRTAB: return "STRTAB";
4214 case SHT_RELA: return "RELA";
4215 case SHT_HASH: return "HASH";
4216 case SHT_DYNAMIC: return "DYNAMIC";
4217 case SHT_NOTE: return "NOTE";
4218 case SHT_NOBITS: return "NOBITS";
4219 case SHT_REL: return "REL";
4220 case SHT_SHLIB: return "SHLIB";
4221 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4222 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4223 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4224 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4225 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4226 case SHT_GROUP: return "GROUP";
67ce483b 4227 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4228 case SHT_GNU_verdef: return "VERDEF";
4229 case SHT_GNU_verneed: return "VERNEED";
4230 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4231 case 0x6ffffff0: return "VERSYM";
4232 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4233 case 0x7ffffffd: return "AUXILIARY";
4234 case 0x7fffffff: return "FILTER";
047b2264 4235 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4236
4237 default:
4238 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4239 {
dda8d76d 4240 switch (filedata->file_header.e_machine)
252b5132 4241 {
53a346d8
CZ
4242 case EM_ARC:
4243 case EM_ARC_COMPACT:
4244 case EM_ARC_COMPACT2:
4245 result = get_arc_section_type_name (sh_type);
4246 break;
252b5132 4247 case EM_MIPS:
4fe85591 4248 case EM_MIPS_RS3_LE:
252b5132
RH
4249 result = get_mips_section_type_name (sh_type);
4250 break;
103f02d3
UD
4251 case EM_PARISC:
4252 result = get_parisc_section_type_name (sh_type);
4253 break;
4d6ed7c8 4254 case EM_IA_64:
dda8d76d 4255 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4256 break;
d2b2c203 4257 case EM_X86_64:
8a9036a4 4258 case EM_L1OM:
7a9068fe 4259 case EM_K1OM:
d2b2c203
DJ
4260 result = get_x86_64_section_type_name (sh_type);
4261 break;
a06ea964
NC
4262 case EM_AARCH64:
4263 result = get_aarch64_section_type_name (sh_type);
4264 break;
40a18ebd
NC
4265 case EM_ARM:
4266 result = get_arm_section_type_name (sh_type);
4267 break;
40b36596
JM
4268 case EM_TI_C6000:
4269 result = get_tic6x_section_type_name (sh_type);
4270 break;
13761a11
NC
4271 case EM_MSP430:
4272 result = get_msp430x_section_type_name (sh_type);
4273 break;
fe944acf
FT
4274 case EM_NFP:
4275 result = get_nfp_section_type_name (sh_type);
4276 break;
685080f2
NC
4277 case EM_V800:
4278 case EM_V850:
4279 case EM_CYGNUS_V850:
4280 result = get_v850_section_type_name (sh_type);
4281 break;
252b5132
RH
4282 default:
4283 result = NULL;
4284 break;
4285 }
4286
4287 if (result != NULL)
4288 return result;
4289
9fb71ee4 4290 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4291 }
4292 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4293 {
dda8d76d 4294 switch (filedata->file_header.e_machine)
148b93f2
NC
4295 {
4296 case EM_IA_64:
dda8d76d 4297 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4298 break;
4299 default:
dda8d76d 4300 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4301 result = get_solaris_section_type (sh_type);
4302 else
1b4b80bf
NC
4303 {
4304 switch (sh_type)
4305 {
4306 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4307 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4308 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4309 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4310 default:
4311 result = NULL;
4312 break;
4313 }
4314 }
148b93f2
NC
4315 break;
4316 }
4317
4318 if (result != NULL)
4319 return result;
4320
9fb71ee4 4321 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4322 }
252b5132 4323 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4324 {
dda8d76d 4325 switch (filedata->file_header.e_machine)
685080f2
NC
4326 {
4327 case EM_V800:
4328 case EM_V850:
4329 case EM_CYGNUS_V850:
9fb71ee4 4330 result = get_v850_section_type_name (sh_type);
a9fb83be 4331 break;
685080f2 4332 default:
9fb71ee4 4333 result = NULL;
685080f2
NC
4334 break;
4335 }
4336
9fb71ee4
NC
4337 if (result != NULL)
4338 return result;
4339
4340 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4341 }
252b5132 4342 else
a7dbfd1c
NC
4343 /* This message is probably going to be displayed in a 15
4344 character wide field, so put the hex value first. */
4345 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4346
252b5132
RH
4347 return buff;
4348 }
4349}
4350
2979dc34 4351#define OPTION_DEBUG_DUMP 512
2c610e4b 4352#define OPTION_DYN_SYMS 513
fd2f0033
TT
4353#define OPTION_DWARF_DEPTH 514
4354#define OPTION_DWARF_START 515
4723351a 4355#define OPTION_DWARF_CHECK 516
2979dc34 4356
85b1c36d 4357static struct option options[] =
252b5132 4358{
b34976b6 4359 {"all", no_argument, 0, 'a'},
252b5132
RH
4360 {"file-header", no_argument, 0, 'h'},
4361 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4362 {"headers", no_argument, 0, 'e'},
4363 {"histogram", no_argument, 0, 'I'},
4364 {"segments", no_argument, 0, 'l'},
4365 {"sections", no_argument, 0, 'S'},
252b5132 4366 {"section-headers", no_argument, 0, 'S'},
f5842774 4367 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4368 {"section-details", no_argument, 0, 't'},
595cf52e 4369 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4370 {"symbols", no_argument, 0, 's'},
4371 {"syms", no_argument, 0, 's'},
2c610e4b 4372 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4373 {"relocs", no_argument, 0, 'r'},
4374 {"notes", no_argument, 0, 'n'},
4375 {"dynamic", no_argument, 0, 'd'},
a952a375 4376 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4377 {"version-info", no_argument, 0, 'V'},
4378 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4379 {"unwind", no_argument, 0, 'u'},
4145f1d5 4380 {"archive-index", no_argument, 0, 'c'},
b34976b6 4381 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4382 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4383 {"string-dump", required_argument, 0, 'p'},
0e602686 4384 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4385#ifdef SUPPORT_DISASSEMBLY
4386 {"instruction-dump", required_argument, 0, 'i'},
4387#endif
cf13d699 4388 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4389
fd2f0033
TT
4390 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4391 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4392 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4393
b34976b6
AM
4394 {"version", no_argument, 0, 'v'},
4395 {"wide", no_argument, 0, 'W'},
4396 {"help", no_argument, 0, 'H'},
4397 {0, no_argument, 0, 0}
252b5132
RH
4398};
4399
4400static void
2cf0635d 4401usage (FILE * stream)
252b5132 4402{
92f01d61
JM
4403 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4404 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4405 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4406 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4407 -h --file-header Display the ELF file header\n\
4408 -l --program-headers Display the program headers\n\
4409 --segments An alias for --program-headers\n\
4410 -S --section-headers Display the sections' header\n\
4411 --sections An alias for --section-headers\n\
f5842774 4412 -g --section-groups Display the section groups\n\
5477e8a0 4413 -t --section-details Display the section details\n\
8b53311e
NC
4414 -e --headers Equivalent to: -h -l -S\n\
4415 -s --syms Display the symbol table\n\
3f08eb35 4416 --symbols An alias for --syms\n\
2c610e4b 4417 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4418 -n --notes Display the core notes (if present)\n\
4419 -r --relocs Display the relocations (if present)\n\
4420 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4421 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4422 -V --version-info Display the version sections (if present)\n\
1b31d05e 4423 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4424 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4425 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
4426 -x --hex-dump=<number|name>\n\
4427 Dump the contents of section <number|name> as bytes\n\
4428 -p --string-dump=<number|name>\n\
4429 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4430 -R --relocated-dump=<number|name>\n\
4431 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4432 -z --decompress Decompress section before dumping it\n\
dda8d76d 4433 -w[lLiaprmfFsoRtUuTgAckK] or\n\
1ed06042 4434 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4435 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47 4436 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4437 =addr,=cu_index,=links,=follow-links]\n\
4438 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4439 fprintf (stream, _("\
4440 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4441 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4442 or deeper\n"));
252b5132 4443#ifdef SUPPORT_DISASSEMBLY
92f01d61 4444 fprintf (stream, _("\
09c11c86
NC
4445 -i --instruction-dump=<number|name>\n\
4446 Disassemble the contents of section <number|name>\n"));
252b5132 4447#endif
92f01d61 4448 fprintf (stream, _("\
8b53311e
NC
4449 -I --histogram Display histogram of bucket list lengths\n\
4450 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4451 @<file> Read options from <file>\n\
8b53311e
NC
4452 -H --help Display this information\n\
4453 -v --version Display the version number of readelf\n"));
1118d252 4454
92f01d61
JM
4455 if (REPORT_BUGS_TO[0] && stream == stdout)
4456 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4457
92f01d61 4458 exit (stream == stdout ? 0 : 1);
252b5132
RH
4459}
4460
18bd398b
NC
4461/* Record the fact that the user wants the contents of section number
4462 SECTION to be displayed using the method(s) encoded as flags bits
4463 in TYPE. Note, TYPE can be zero if we are creating the array for
4464 the first time. */
4465
252b5132 4466static void
dda8d76d 4467request_dump_bynumber (Filedata * filedata, unsigned int section, dump_type type)
252b5132 4468{
dda8d76d 4469 if (section >= filedata->num_dump_sects)
252b5132 4470 {
2cf0635d 4471 dump_type * new_dump_sects;
252b5132 4472
3f5e193b 4473 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4474 sizeof (* new_dump_sects));
252b5132
RH
4475
4476 if (new_dump_sects == NULL)
591a748a 4477 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4478 else
4479 {
dda8d76d 4480 if (filedata->dump_sects)
21b65bac
NC
4481 {
4482 /* Copy current flag settings. */
dda8d76d
NC
4483 memcpy (new_dump_sects, filedata->dump_sects,
4484 filedata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4485
dda8d76d 4486 free (filedata->dump_sects);
21b65bac 4487 }
252b5132 4488
dda8d76d
NC
4489 filedata->dump_sects = new_dump_sects;
4490 filedata->num_dump_sects = section + 1;
252b5132
RH
4491 }
4492 }
4493
dda8d76d
NC
4494 if (filedata->dump_sects)
4495 filedata->dump_sects[section] |= type;
252b5132
RH
4496}
4497
aef1f6d0
DJ
4498/* Request a dump by section name. */
4499
4500static void
2cf0635d 4501request_dump_byname (const char * section, dump_type type)
aef1f6d0 4502{
2cf0635d 4503 struct dump_list_entry * new_request;
aef1f6d0 4504
3f5e193b
NC
4505 new_request = (struct dump_list_entry *)
4506 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4507 if (!new_request)
591a748a 4508 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4509
4510 new_request->name = strdup (section);
4511 if (!new_request->name)
591a748a 4512 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4513
4514 new_request->type = type;
4515
4516 new_request->next = dump_sects_byname;
4517 dump_sects_byname = new_request;
4518}
4519
cf13d699 4520static inline void
dda8d76d 4521request_dump (Filedata * filedata, dump_type type)
cf13d699
NC
4522{
4523 int section;
4524 char * cp;
4525
4526 do_dump++;
4527 section = strtoul (optarg, & cp, 0);
4528
4529 if (! *cp && section >= 0)
dda8d76d 4530 request_dump_bynumber (filedata, section, type);
cf13d699
NC
4531 else
4532 request_dump_byname (optarg, type);
4533}
4534
252b5132 4535static void
dda8d76d 4536parse_args (Filedata * filedata, int argc, char ** argv)
252b5132
RH
4537{
4538 int c;
4539
4540 if (argc < 2)
92f01d61 4541 usage (stderr);
252b5132
RH
4542
4543 while ((c = getopt_long
0e602686 4544 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4545 {
252b5132
RH
4546 switch (c)
4547 {
4548 case 0:
4549 /* Long options. */
4550 break;
4551 case 'H':
92f01d61 4552 usage (stdout);
252b5132
RH
4553 break;
4554
4555 case 'a':
32ec8896
NC
4556 do_syms = TRUE;
4557 do_reloc = TRUE;
4558 do_unwind = TRUE;
4559 do_dynamic = TRUE;
4560 do_header = TRUE;
4561 do_sections = TRUE;
4562 do_section_groups = TRUE;
4563 do_segments = TRUE;
4564 do_version = TRUE;
4565 do_histogram = TRUE;
4566 do_arch = TRUE;
4567 do_notes = TRUE;
252b5132 4568 break;
f5842774 4569 case 'g':
32ec8896 4570 do_section_groups = TRUE;
f5842774 4571 break;
5477e8a0 4572 case 't':
595cf52e 4573 case 'N':
32ec8896
NC
4574 do_sections = TRUE;
4575 do_section_details = TRUE;
595cf52e 4576 break;
252b5132 4577 case 'e':
32ec8896
NC
4578 do_header = TRUE;
4579 do_sections = TRUE;
4580 do_segments = TRUE;
252b5132 4581 break;
a952a375 4582 case 'A':
32ec8896 4583 do_arch = TRUE;
a952a375 4584 break;
252b5132 4585 case 'D':
32ec8896 4586 do_using_dynamic = TRUE;
252b5132
RH
4587 break;
4588 case 'r':
32ec8896 4589 do_reloc = TRUE;
252b5132 4590 break;
4d6ed7c8 4591 case 'u':
32ec8896 4592 do_unwind = TRUE;
4d6ed7c8 4593 break;
252b5132 4594 case 'h':
32ec8896 4595 do_header = TRUE;
252b5132
RH
4596 break;
4597 case 'l':
32ec8896 4598 do_segments = TRUE;
252b5132
RH
4599 break;
4600 case 's':
32ec8896 4601 do_syms = TRUE;
252b5132
RH
4602 break;
4603 case 'S':
32ec8896 4604 do_sections = TRUE;
252b5132
RH
4605 break;
4606 case 'd':
32ec8896 4607 do_dynamic = TRUE;
252b5132 4608 break;
a952a375 4609 case 'I':
32ec8896 4610 do_histogram = TRUE;
a952a375 4611 break;
779fe533 4612 case 'n':
32ec8896 4613 do_notes = TRUE;
779fe533 4614 break;
4145f1d5 4615 case 'c':
32ec8896 4616 do_archive_index = TRUE;
4145f1d5 4617 break;
252b5132 4618 case 'x':
dda8d76d 4619 request_dump (filedata, HEX_DUMP);
aef1f6d0 4620 break;
09c11c86 4621 case 'p':
dda8d76d 4622 request_dump (filedata, STRING_DUMP);
cf13d699
NC
4623 break;
4624 case 'R':
dda8d76d 4625 request_dump (filedata, RELOC_DUMP);
09c11c86 4626 break;
0e602686 4627 case 'z':
32ec8896 4628 decompress_dumps = TRUE;
0e602686 4629 break;
252b5132 4630 case 'w':
32ec8896 4631 do_dump = TRUE;
252b5132 4632 if (optarg == 0)
613ff48b 4633 {
32ec8896 4634 do_debugging = TRUE;
613ff48b
CC
4635 dwarf_select_sections_all ();
4636 }
252b5132
RH
4637 else
4638 {
32ec8896 4639 do_debugging = FALSE;
4cb93e3b 4640 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4641 }
4642 break;
2979dc34 4643 case OPTION_DEBUG_DUMP:
32ec8896 4644 do_dump = TRUE;
2979dc34 4645 if (optarg == 0)
32ec8896 4646 do_debugging = TRUE;
2979dc34
JJ
4647 else
4648 {
32ec8896 4649 do_debugging = FALSE;
4cb93e3b 4650 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4651 }
4652 break;
fd2f0033
TT
4653 case OPTION_DWARF_DEPTH:
4654 {
4655 char *cp;
4656
4657 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4658 }
4659 break;
4660 case OPTION_DWARF_START:
4661 {
4662 char *cp;
4663
4664 dwarf_start_die = strtoul (optarg, & cp, 0);
4665 }
4666 break;
4723351a 4667 case OPTION_DWARF_CHECK:
32ec8896 4668 dwarf_check = TRUE;
4723351a 4669 break;
2c610e4b 4670 case OPTION_DYN_SYMS:
32ec8896 4671 do_dyn_syms = TRUE;
2c610e4b 4672 break;
252b5132
RH
4673#ifdef SUPPORT_DISASSEMBLY
4674 case 'i':
dda8d76d 4675 request_dump (filedata, DISASS_DUMP);
cf13d699 4676 break;
252b5132
RH
4677#endif
4678 case 'v':
4679 print_version (program_name);
4680 break;
4681 case 'V':
32ec8896 4682 do_version = TRUE;
252b5132 4683 break;
d974e256 4684 case 'W':
32ec8896 4685 do_wide = TRUE;
d974e256 4686 break;
252b5132 4687 default:
252b5132
RH
4688 /* xgettext:c-format */
4689 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4690 /* Fall through. */
252b5132 4691 case '?':
92f01d61 4692 usage (stderr);
252b5132
RH
4693 }
4694 }
4695
4d6ed7c8 4696 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4697 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4698 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4699 && !do_section_groups && !do_archive_index
4700 && !do_dyn_syms)
92f01d61 4701 usage (stderr);
252b5132
RH
4702}
4703
4704static const char *
d3ba0551 4705get_elf_class (unsigned int elf_class)
252b5132 4706{
b34976b6 4707 static char buff[32];
103f02d3 4708
252b5132
RH
4709 switch (elf_class)
4710 {
4711 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4712 case ELFCLASS32: return "ELF32";
4713 case ELFCLASS64: return "ELF64";
ab5e7794 4714 default:
e9e44622 4715 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4716 return buff;
252b5132
RH
4717 }
4718}
4719
4720static const char *
d3ba0551 4721get_data_encoding (unsigned int encoding)
252b5132 4722{
b34976b6 4723 static char buff[32];
103f02d3 4724
252b5132
RH
4725 switch (encoding)
4726 {
4727 case ELFDATANONE: return _("none");
33c63f9d
CM
4728 case ELFDATA2LSB: return _("2's complement, little endian");
4729 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4730 default:
e9e44622 4731 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4732 return buff;
252b5132
RH
4733 }
4734}
4735
dda8d76d 4736/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4737
32ec8896 4738static bfd_boolean
dda8d76d 4739process_file_header (Filedata * filedata)
252b5132 4740{
dda8d76d
NC
4741 Elf_Internal_Ehdr * header = & filedata->file_header;
4742
4743 if ( header->e_ident[EI_MAG0] != ELFMAG0
4744 || header->e_ident[EI_MAG1] != ELFMAG1
4745 || header->e_ident[EI_MAG2] != ELFMAG2
4746 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4747 {
4748 error
4749 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4750 return FALSE;
252b5132
RH
4751 }
4752
dda8d76d 4753 init_dwarf_regnames (header->e_machine);
2dc4cec1 4754
252b5132
RH
4755 if (do_header)
4756 {
32ec8896 4757 unsigned i;
252b5132
RH
4758
4759 printf (_("ELF Header:\n"));
4760 printf (_(" Magic: "));
b34976b6 4761 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4762 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4763 printf ("\n");
4764 printf (_(" Class: %s\n"),
dda8d76d 4765 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4766 printf (_(" Data: %s\n"),
dda8d76d 4767 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 4768 printf (_(" Version: %d%s\n"),
dda8d76d
NC
4769 header->e_ident[EI_VERSION],
4770 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 4771 ? _(" (current)")
dda8d76d 4772 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 4773 ? _(" <unknown>")
789be9f7 4774 : "")));
252b5132 4775 printf (_(" OS/ABI: %s\n"),
dda8d76d 4776 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 4777 printf (_(" ABI Version: %d\n"),
dda8d76d 4778 header->e_ident[EI_ABIVERSION]);
252b5132 4779 printf (_(" Type: %s\n"),
dda8d76d 4780 get_file_type (header->e_type));
252b5132 4781 printf (_(" Machine: %s\n"),
dda8d76d 4782 get_machine_name (header->e_machine));
252b5132 4783 printf (_(" Version: 0x%lx\n"),
e8a64888 4784 header->e_version);
76da6bbe 4785
f7a99963 4786 printf (_(" Entry point address: "));
e8a64888 4787 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 4788 printf (_("\n Start of program headers: "));
e8a64888 4789 print_vma (header->e_phoff, DEC);
f7a99963 4790 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 4791 print_vma (header->e_shoff, DEC);
f7a99963 4792 printf (_(" (bytes into file)\n"));
76da6bbe 4793
252b5132 4794 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 4795 header->e_flags,
dda8d76d 4796 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
4797 printf (_(" Size of this header: %u (bytes)\n"),
4798 header->e_ehsize);
4799 printf (_(" Size of program headers: %u (bytes)\n"),
4800 header->e_phentsize);
4801 printf (_(" Number of program headers: %u"),
4802 header->e_phnum);
dda8d76d
NC
4803 if (filedata->section_headers != NULL
4804 && header->e_phnum == PN_XNUM
4805 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
4806 {
4807 header->e_phnum = filedata->section_headers[0].sh_info;
4808 printf (" (%u)", header->e_phnum);
4809 }
2046a35d 4810 putc ('\n', stdout);
e8a64888
AM
4811 printf (_(" Size of section headers: %u (bytes)\n"),
4812 header->e_shentsize);
4813 printf (_(" Number of section headers: %u"),
4814 header->e_shnum);
dda8d76d 4815 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
4816 {
4817 header->e_shnum = filedata->section_headers[0].sh_size;
4818 printf (" (%u)", header->e_shnum);
4819 }
560f3c1c 4820 putc ('\n', stdout);
e8a64888
AM
4821 printf (_(" Section header string table index: %u"),
4822 header->e_shstrndx);
dda8d76d
NC
4823 if (filedata->section_headers != NULL
4824 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
4825 {
4826 header->e_shstrndx = filedata->section_headers[0].sh_link;
4827 printf (" (%u)", header->e_shstrndx);
4828 }
4829 if (header->e_shstrndx != SHN_UNDEF
4830 && header->e_shstrndx >= header->e_shnum)
4831 {
4832 header->e_shstrndx = SHN_UNDEF;
4833 printf (_(" <corrupt: out of range>"));
4834 }
560f3c1c
AM
4835 putc ('\n', stdout);
4836 }
4837
dda8d76d 4838 if (filedata->section_headers != NULL)
560f3c1c 4839 {
dda8d76d
NC
4840 if (header->e_phnum == PN_XNUM
4841 && filedata->section_headers[0].sh_info != 0)
4842 header->e_phnum = filedata->section_headers[0].sh_info;
4843 if (header->e_shnum == SHN_UNDEF)
4844 header->e_shnum = filedata->section_headers[0].sh_size;
4845 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
4846 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 4847 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
4848 header->e_shstrndx = SHN_UNDEF;
4849 free (filedata->section_headers);
4850 filedata->section_headers = NULL;
252b5132 4851 }
103f02d3 4852
32ec8896 4853 return TRUE;
9ea033b2
NC
4854}
4855
dda8d76d
NC
4856/* Read in the program headers from FILEDATA and store them in PHEADERS.
4857 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
4858
e0a31db1 4859static bfd_boolean
dda8d76d 4860get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4861{
2cf0635d
NC
4862 Elf32_External_Phdr * phdrs;
4863 Elf32_External_Phdr * external;
4864 Elf_Internal_Phdr * internal;
b34976b6 4865 unsigned int i;
dda8d76d
NC
4866 unsigned int size = filedata->file_header.e_phentsize;
4867 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4868
4869 /* PR binutils/17531: Cope with unexpected section header sizes. */
4870 if (size == 0 || num == 0)
4871 return FALSE;
4872 if (size < sizeof * phdrs)
4873 {
4874 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4875 return FALSE;
4876 }
4877 if (size > sizeof * phdrs)
4878 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4879
dda8d76d 4880 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
4881 size, num, _("program headers"));
4882 if (phdrs == NULL)
4883 return FALSE;
9ea033b2 4884
91d6fa6a 4885 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4886 i < filedata->file_header.e_phnum;
b34976b6 4887 i++, internal++, external++)
252b5132 4888 {
9ea033b2
NC
4889 internal->p_type = BYTE_GET (external->p_type);
4890 internal->p_offset = BYTE_GET (external->p_offset);
4891 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4892 internal->p_paddr = BYTE_GET (external->p_paddr);
4893 internal->p_filesz = BYTE_GET (external->p_filesz);
4894 internal->p_memsz = BYTE_GET (external->p_memsz);
4895 internal->p_flags = BYTE_GET (external->p_flags);
4896 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4897 }
4898
9ea033b2 4899 free (phdrs);
e0a31db1 4900 return TRUE;
252b5132
RH
4901}
4902
dda8d76d
NC
4903/* Read in the program headers from FILEDATA and store them in PHEADERS.
4904 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
4905
e0a31db1 4906static bfd_boolean
dda8d76d 4907get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4908{
2cf0635d
NC
4909 Elf64_External_Phdr * phdrs;
4910 Elf64_External_Phdr * external;
4911 Elf_Internal_Phdr * internal;
b34976b6 4912 unsigned int i;
dda8d76d
NC
4913 unsigned int size = filedata->file_header.e_phentsize;
4914 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4915
4916 /* PR binutils/17531: Cope with unexpected section header sizes. */
4917 if (size == 0 || num == 0)
4918 return FALSE;
4919 if (size < sizeof * phdrs)
4920 {
4921 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4922 return FALSE;
4923 }
4924 if (size > sizeof * phdrs)
4925 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4926
dda8d76d 4927 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 4928 size, num, _("program headers"));
a6e9f9df 4929 if (!phdrs)
e0a31db1 4930 return FALSE;
9ea033b2 4931
91d6fa6a 4932 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4933 i < filedata->file_header.e_phnum;
b34976b6 4934 i++, internal++, external++)
9ea033b2
NC
4935 {
4936 internal->p_type = BYTE_GET (external->p_type);
4937 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4938 internal->p_offset = BYTE_GET (external->p_offset);
4939 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4940 internal->p_paddr = BYTE_GET (external->p_paddr);
4941 internal->p_filesz = BYTE_GET (external->p_filesz);
4942 internal->p_memsz = BYTE_GET (external->p_memsz);
4943 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4944 }
4945
4946 free (phdrs);
e0a31db1 4947 return TRUE;
9ea033b2 4948}
252b5132 4949
32ec8896 4950/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 4951
32ec8896 4952static bfd_boolean
dda8d76d 4953get_program_headers (Filedata * filedata)
d93f0186 4954{
2cf0635d 4955 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4956
4957 /* Check cache of prior read. */
dda8d76d 4958 if (filedata->program_headers != NULL)
32ec8896 4959 return TRUE;
d93f0186 4960
82156ab7
NC
4961 /* Be kind to memory checkers by looking for
4962 e_phnum values which we know must be invalid. */
dda8d76d 4963 if (filedata->file_header.e_phnum
82156ab7 4964 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 4965 >= filedata->file_size)
82156ab7
NC
4966 {
4967 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 4968 filedata->file_header.e_phnum);
82156ab7
NC
4969 return FALSE;
4970 }
d93f0186 4971
dda8d76d 4972 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 4973 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4974 if (phdrs == NULL)
4975 {
8b73c356 4976 error (_("Out of memory reading %u program headers\n"),
dda8d76d 4977 filedata->file_header.e_phnum);
32ec8896 4978 return FALSE;
d93f0186
NC
4979 }
4980
4981 if (is_32bit_elf
dda8d76d
NC
4982 ? get_32bit_program_headers (filedata, phdrs)
4983 : get_64bit_program_headers (filedata, phdrs))
d93f0186 4984 {
dda8d76d 4985 filedata->program_headers = phdrs;
32ec8896 4986 return TRUE;
d93f0186
NC
4987 }
4988
4989 free (phdrs);
32ec8896 4990 return FALSE;
d93f0186
NC
4991}
4992
32ec8896 4993/* Returns TRUE if the program headers were loaded. */
2f62977e 4994
32ec8896 4995static bfd_boolean
dda8d76d 4996process_program_headers (Filedata * filedata)
252b5132 4997{
2cf0635d 4998 Elf_Internal_Phdr * segment;
b34976b6 4999 unsigned int i;
1a9ccd70 5000 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5001
dda8d76d 5002 if (filedata->file_header.e_phnum == 0)
252b5132 5003 {
82f2dbf7 5004 /* PR binutils/12467. */
dda8d76d 5005 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5006 {
5007 warn (_("possibly corrupt ELF header - it has a non-zero program"
5008 " header offset, but no program headers\n"));
5009 return FALSE;
5010 }
82f2dbf7 5011 else if (do_segments)
252b5132 5012 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5013 return TRUE;
252b5132
RH
5014 }
5015
5016 if (do_segments && !do_header)
5017 {
dda8d76d
NC
5018 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5019 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5020 printf (ngettext ("There is %d program header, starting at offset %s\n",
5021 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5022 filedata->file_header.e_phnum),
5023 filedata->file_header.e_phnum,
5024 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5025 }
5026
dda8d76d 5027 if (! get_program_headers (filedata))
6b4bf3bc 5028 return TRUE;
103f02d3 5029
252b5132
RH
5030 if (do_segments)
5031 {
dda8d76d 5032 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5033 printf (_("\nProgram Headers:\n"));
5034 else
5035 printf (_("\nProgram Headers:\n"));
76da6bbe 5036
f7a99963
NC
5037 if (is_32bit_elf)
5038 printf
5039 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5040 else if (do_wide)
5041 printf
5042 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5043 else
5044 {
5045 printf
5046 (_(" Type Offset VirtAddr PhysAddr\n"));
5047 printf
5048 (_(" FileSiz MemSiz Flags Align\n"));
5049 }
252b5132
RH
5050 }
5051
252b5132 5052 dynamic_addr = 0;
1b228002 5053 dynamic_size = 0;
252b5132 5054
dda8d76d
NC
5055 for (i = 0, segment = filedata->program_headers;
5056 i < filedata->file_header.e_phnum;
b34976b6 5057 i++, segment++)
252b5132
RH
5058 {
5059 if (do_segments)
5060 {
dda8d76d 5061 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5062
5063 if (is_32bit_elf)
5064 {
5065 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5066 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5067 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5068 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5069 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5070 printf ("%c%c%c ",
5071 (segment->p_flags & PF_R ? 'R' : ' '),
5072 (segment->p_flags & PF_W ? 'W' : ' '),
5073 (segment->p_flags & PF_X ? 'E' : ' '));
5074 printf ("%#lx", (unsigned long) segment->p_align);
5075 }
d974e256
JJ
5076 else if (do_wide)
5077 {
5078 if ((unsigned long) segment->p_offset == segment->p_offset)
5079 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5080 else
5081 {
5082 print_vma (segment->p_offset, FULL_HEX);
5083 putchar (' ');
5084 }
5085
5086 print_vma (segment->p_vaddr, FULL_HEX);
5087 putchar (' ');
5088 print_vma (segment->p_paddr, FULL_HEX);
5089 putchar (' ');
5090
5091 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5092 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5093 else
5094 {
5095 print_vma (segment->p_filesz, FULL_HEX);
5096 putchar (' ');
5097 }
5098
5099 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5100 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5101 else
5102 {
f48e6c45 5103 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5104 }
5105
5106 printf (" %c%c%c ",
5107 (segment->p_flags & PF_R ? 'R' : ' '),
5108 (segment->p_flags & PF_W ? 'W' : ' '),
5109 (segment->p_flags & PF_X ? 'E' : ' '));
5110
5111 if ((unsigned long) segment->p_align == segment->p_align)
5112 printf ("%#lx", (unsigned long) segment->p_align);
5113 else
5114 {
5115 print_vma (segment->p_align, PREFIX_HEX);
5116 }
5117 }
f7a99963
NC
5118 else
5119 {
5120 print_vma (segment->p_offset, FULL_HEX);
5121 putchar (' ');
5122 print_vma (segment->p_vaddr, FULL_HEX);
5123 putchar (' ');
5124 print_vma (segment->p_paddr, FULL_HEX);
5125 printf ("\n ");
5126 print_vma (segment->p_filesz, FULL_HEX);
5127 putchar (' ');
5128 print_vma (segment->p_memsz, FULL_HEX);
5129 printf (" %c%c%c ",
5130 (segment->p_flags & PF_R ? 'R' : ' '),
5131 (segment->p_flags & PF_W ? 'W' : ' '),
5132 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5133 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5134 }
252b5132 5135
1a9ccd70
NC
5136 putc ('\n', stdout);
5137 }
f54498b4 5138
252b5132
RH
5139 switch (segment->p_type)
5140 {
1a9ccd70 5141 case PT_LOAD:
502d895c
NC
5142#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5143 required by the ELF standard, several programs, including the Linux
5144 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5145 if (previous_load
5146 && previous_load->p_vaddr > segment->p_vaddr)
5147 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5148#endif
1a9ccd70
NC
5149 if (segment->p_memsz < segment->p_filesz)
5150 error (_("the segment's file size is larger than its memory size\n"));
5151 previous_load = segment;
5152 break;
5153
5154 case PT_PHDR:
5155 /* PR 20815 - Verify that the program header is loaded into memory. */
5156 if (i > 0 && previous_load != NULL)
5157 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5158 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5159 {
5160 unsigned int j;
5161
dda8d76d
NC
5162 for (j = 1; j < filedata->file_header.e_phnum; j++)
5163 if (filedata->program_headers[j].p_vaddr <= segment->p_vaddr
5164 && (filedata->program_headers[j].p_vaddr
5165 + filedata->program_headers[j].p_memsz)
1a9ccd70
NC
5166 >= (segment->p_vaddr + segment->p_filesz))
5167 break;
dda8d76d 5168 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5169 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5170 }
5171 break;
5172
252b5132
RH
5173 case PT_DYNAMIC:
5174 if (dynamic_addr)
5175 error (_("more than one dynamic segment\n"));
5176
20737c13
AM
5177 /* By default, assume that the .dynamic section is the first
5178 section in the DYNAMIC segment. */
5179 dynamic_addr = segment->p_offset;
5180 dynamic_size = segment->p_filesz;
5181
b2d38a17
NC
5182 /* Try to locate the .dynamic section. If there is
5183 a section header table, we can easily locate it. */
dda8d76d 5184 if (filedata->section_headers != NULL)
b2d38a17 5185 {
2cf0635d 5186 Elf_Internal_Shdr * sec;
b2d38a17 5187
dda8d76d 5188 sec = find_section (filedata, ".dynamic");
89fac5e3 5189 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5190 {
28f997cf
TG
5191 /* A corresponding .dynamic section is expected, but on
5192 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5193 if (!is_ia64_vms (filedata))
28f997cf 5194 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5195 break;
5196 }
5197
42bb2e33 5198 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
5199 {
5200 dynamic_size = 0;
5201 break;
5202 }
42bb2e33 5203
b2d38a17
NC
5204 dynamic_addr = sec->sh_offset;
5205 dynamic_size = sec->sh_size;
5206
5207 if (dynamic_addr < segment->p_offset
5208 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
5209 warn (_("the .dynamic section is not contained"
5210 " within the dynamic segment\n"));
b2d38a17 5211 else if (dynamic_addr > segment->p_offset)
20737c13
AM
5212 warn (_("the .dynamic section is not the first section"
5213 " in the dynamic segment.\n"));
b2d38a17 5214 }
39e224f6
MW
5215
5216 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5217 segment. Check this after matching against the section headers
5218 so we don't warn on debuginfo file (which have NOBITS .dynamic
5219 sections). */
dda8d76d 5220 if (dynamic_addr + dynamic_size >= filedata->file_size)
39e224f6
MW
5221 {
5222 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
5223 dynamic_addr = dynamic_size = 0;
5224 }
252b5132
RH
5225 break;
5226
5227 case PT_INTERP:
dda8d76d 5228 if (fseek (filedata->handle, archive_file_offset + (long) segment->p_offset,
fb52b2f4 5229 SEEK_SET))
252b5132
RH
5230 error (_("Unable to find program interpreter name\n"));
5231 else
5232 {
f8eae8b2 5233 char fmt [32];
9495b2e6 5234 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5235
5236 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5237 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5238
252b5132 5239 program_interpreter[0] = 0;
dda8d76d 5240 if (fscanf (filedata->handle, fmt, program_interpreter) <= 0)
7bd7b3ef 5241 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5242
5243 if (do_segments)
f54498b4 5244 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
5245 program_interpreter);
5246 }
5247 break;
5248 }
252b5132
RH
5249 }
5250
dda8d76d
NC
5251 if (do_segments
5252 && filedata->section_headers != NULL
5253 && filedata->string_table != NULL)
252b5132
RH
5254 {
5255 printf (_("\n Section to Segment mapping:\n"));
5256 printf (_(" Segment Sections...\n"));
5257
dda8d76d 5258 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5259 {
9ad5cbcf 5260 unsigned int j;
2cf0635d 5261 Elf_Internal_Shdr * section;
252b5132 5262
dda8d76d
NC
5263 segment = filedata->program_headers + i;
5264 section = filedata->section_headers + 1;
252b5132
RH
5265
5266 printf (" %2.2d ", i);
5267
dda8d76d 5268 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5269 {
f4638467
AM
5270 if (!ELF_TBSS_SPECIAL (section, segment)
5271 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5272 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5273 }
5274
5275 putc ('\n',stdout);
5276 }
5277 }
5278
32ec8896 5279 return TRUE;
252b5132
RH
5280}
5281
5282
d93f0186
NC
5283/* Find the file offset corresponding to VMA by using the program headers. */
5284
5285static long
dda8d76d 5286offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5287{
2cf0635d 5288 Elf_Internal_Phdr * seg;
d93f0186 5289
dda8d76d 5290 if (! get_program_headers (filedata))
d93f0186
NC
5291 {
5292 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5293 return (long) vma;
5294 }
5295
dda8d76d
NC
5296 for (seg = filedata->program_headers;
5297 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5298 ++seg)
5299 {
5300 if (seg->p_type != PT_LOAD)
5301 continue;
5302
5303 if (vma >= (seg->p_vaddr & -seg->p_align)
5304 && vma + size <= seg->p_vaddr + seg->p_filesz)
5305 return vma - seg->p_vaddr + seg->p_offset;
5306 }
5307
5308 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5309 (unsigned long) vma);
d93f0186
NC
5310 return (long) vma;
5311}
5312
5313
dda8d76d
NC
5314/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5315 If PROBE is true, this is just a probe and we do not generate any error
5316 messages if the load fails. */
049b0c3a
NC
5317
5318static bfd_boolean
dda8d76d 5319get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5320{
2cf0635d
NC
5321 Elf32_External_Shdr * shdrs;
5322 Elf_Internal_Shdr * internal;
dda8d76d
NC
5323 unsigned int i;
5324 unsigned int size = filedata->file_header.e_shentsize;
5325 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5326
5327 /* PR binutils/17531: Cope with unexpected section header sizes. */
5328 if (size == 0 || num == 0)
5329 return FALSE;
5330 if (size < sizeof * shdrs)
5331 {
5332 if (! probe)
5333 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5334 return FALSE;
5335 }
5336 if (!probe && size > sizeof * shdrs)
5337 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5338
dda8d76d 5339 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5340 size, num,
5341 probe ? NULL : _("section headers"));
5342 if (shdrs == NULL)
5343 return FALSE;
252b5132 5344
dda8d76d
NC
5345 free (filedata->section_headers);
5346 filedata->section_headers = (Elf_Internal_Shdr *)
5347 cmalloc (num, sizeof (Elf_Internal_Shdr));
5348 if (filedata->section_headers == NULL)
252b5132 5349 {
049b0c3a 5350 if (!probe)
8b73c356 5351 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5352 free (shdrs);
049b0c3a 5353 return FALSE;
252b5132
RH
5354 }
5355
dda8d76d 5356 for (i = 0, internal = filedata->section_headers;
560f3c1c 5357 i < num;
b34976b6 5358 i++, internal++)
252b5132
RH
5359 {
5360 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5361 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5362 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5363 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5364 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5365 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5366 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5367 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5368 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5369 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5370 if (!probe && internal->sh_link > num)
5371 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5372 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5373 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5374 }
5375
5376 free (shdrs);
049b0c3a 5377 return TRUE;
252b5132
RH
5378}
5379
dda8d76d
NC
5380/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5381
049b0c3a 5382static bfd_boolean
dda8d76d 5383get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5384{
dda8d76d
NC
5385 Elf64_External_Shdr * shdrs;
5386 Elf_Internal_Shdr * internal;
5387 unsigned int i;
5388 unsigned int size = filedata->file_header.e_shentsize;
5389 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5390
5391 /* PR binutils/17531: Cope with unexpected section header sizes. */
5392 if (size == 0 || num == 0)
5393 return FALSE;
dda8d76d 5394
049b0c3a
NC
5395 if (size < sizeof * shdrs)
5396 {
5397 if (! probe)
5398 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5399 return FALSE;
5400 }
dda8d76d 5401
049b0c3a
NC
5402 if (! probe && size > sizeof * shdrs)
5403 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5404
dda8d76d
NC
5405 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5406 filedata->file_header.e_shoff,
049b0c3a
NC
5407 size, num,
5408 probe ? NULL : _("section headers"));
5409 if (shdrs == NULL)
5410 return FALSE;
9ea033b2 5411
dda8d76d
NC
5412 free (filedata->section_headers);
5413 filedata->section_headers = (Elf_Internal_Shdr *)
5414 cmalloc (num, sizeof (Elf_Internal_Shdr));
5415 if (filedata->section_headers == NULL)
9ea033b2 5416 {
049b0c3a 5417 if (! probe)
8b73c356 5418 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5419 free (shdrs);
049b0c3a 5420 return FALSE;
9ea033b2
NC
5421 }
5422
dda8d76d 5423 for (i = 0, internal = filedata->section_headers;
560f3c1c 5424 i < num;
b34976b6 5425 i++, internal++)
9ea033b2
NC
5426 {
5427 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5428 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5429 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5430 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5431 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5432 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5433 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5434 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5435 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5436 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5437 if (!probe && internal->sh_link > num)
5438 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5439 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5440 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5441 }
5442
5443 free (shdrs);
049b0c3a 5444 return TRUE;
9ea033b2
NC
5445}
5446
252b5132 5447static Elf_Internal_Sym *
dda8d76d
NC
5448get_32bit_elf_symbols (Filedata * filedata,
5449 Elf_Internal_Shdr * section,
5450 unsigned long * num_syms_return)
252b5132 5451{
ba5cdace 5452 unsigned long number = 0;
dd24e3da 5453 Elf32_External_Sym * esyms = NULL;
ba5cdace 5454 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5455 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5456 Elf_Internal_Sym * psym;
b34976b6 5457 unsigned int j;
e3d39609 5458 elf_section_list * entry;
252b5132 5459
c9c1d674
EG
5460 if (section->sh_size == 0)
5461 {
5462 if (num_syms_return != NULL)
5463 * num_syms_return = 0;
5464 return NULL;
5465 }
5466
dd24e3da 5467 /* Run some sanity checks first. */
c9c1d674 5468 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5469 {
c9c1d674 5470 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5471 printable_section_name (filedata, section),
5472 (unsigned long) section->sh_entsize);
ba5cdace 5473 goto exit_point;
dd24e3da
NC
5474 }
5475
dda8d76d 5476 if (section->sh_size > filedata->file_size)
f54498b4
NC
5477 {
5478 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5479 printable_section_name (filedata, section),
5480 (unsigned long) section->sh_size);
f54498b4
NC
5481 goto exit_point;
5482 }
5483
dd24e3da
NC
5484 number = section->sh_size / section->sh_entsize;
5485
5486 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5487 {
c9c1d674 5488 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5489 (unsigned long) section->sh_size,
dda8d76d 5490 printable_section_name (filedata, section),
8066deb1 5491 (unsigned long) section->sh_entsize);
ba5cdace 5492 goto exit_point;
dd24e3da
NC
5493 }
5494
dda8d76d 5495 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5496 section->sh_size, _("symbols"));
dd24e3da 5497 if (esyms == NULL)
ba5cdace 5498 goto exit_point;
252b5132 5499
e3d39609
NC
5500 shndx = NULL;
5501 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5502 {
5503 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5504 continue;
5505
5506 if (shndx != NULL)
5507 {
5508 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5509 free (shndx);
5510 }
5511
5512 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5513 entry->hdr->sh_offset,
5514 1, entry->hdr->sh_size,
5515 _("symbol table section indices"));
5516 if (shndx == NULL)
5517 goto exit_point;
5518
5519 /* PR17531: file: heap-buffer-overflow */
5520 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5521 {
5522 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5523 printable_section_name (filedata, entry->hdr),
5524 (unsigned long) entry->hdr->sh_size,
5525 (unsigned long) section->sh_size);
5526 goto exit_point;
c9c1d674 5527 }
e3d39609 5528 }
9ad5cbcf 5529
3f5e193b 5530 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5531
5532 if (isyms == NULL)
5533 {
8b73c356
NC
5534 error (_("Out of memory reading %lu symbols\n"),
5535 (unsigned long) number);
dd24e3da 5536 goto exit_point;
252b5132
RH
5537 }
5538
dd24e3da 5539 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5540 {
5541 psym->st_name = BYTE_GET (esyms[j].st_name);
5542 psym->st_value = BYTE_GET (esyms[j].st_value);
5543 psym->st_size = BYTE_GET (esyms[j].st_size);
5544 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5545 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5546 psym->st_shndx
5547 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5548 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5549 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5550 psym->st_info = BYTE_GET (esyms[j].st_info);
5551 psym->st_other = BYTE_GET (esyms[j].st_other);
5552 }
5553
dd24e3da 5554 exit_point:
e3d39609
NC
5555 free (shndx);
5556 free (esyms);
252b5132 5557
ba5cdace
NC
5558 if (num_syms_return != NULL)
5559 * num_syms_return = isyms == NULL ? 0 : number;
5560
252b5132
RH
5561 return isyms;
5562}
5563
9ea033b2 5564static Elf_Internal_Sym *
dda8d76d
NC
5565get_64bit_elf_symbols (Filedata * filedata,
5566 Elf_Internal_Shdr * section,
5567 unsigned long * num_syms_return)
9ea033b2 5568{
ba5cdace
NC
5569 unsigned long number = 0;
5570 Elf64_External_Sym * esyms = NULL;
5571 Elf_External_Sym_Shndx * shndx = NULL;
5572 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5573 Elf_Internal_Sym * psym;
b34976b6 5574 unsigned int j;
e3d39609 5575 elf_section_list * entry;
9ea033b2 5576
c9c1d674
EG
5577 if (section->sh_size == 0)
5578 {
5579 if (num_syms_return != NULL)
5580 * num_syms_return = 0;
5581 return NULL;
5582 }
5583
dd24e3da 5584 /* Run some sanity checks first. */
c9c1d674 5585 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5586 {
c9c1d674 5587 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5588 printable_section_name (filedata, section),
8066deb1 5589 (unsigned long) section->sh_entsize);
ba5cdace 5590 goto exit_point;
dd24e3da
NC
5591 }
5592
dda8d76d 5593 if (section->sh_size > filedata->file_size)
f54498b4
NC
5594 {
5595 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5596 printable_section_name (filedata, section),
8066deb1 5597 (unsigned long) section->sh_size);
f54498b4
NC
5598 goto exit_point;
5599 }
5600
dd24e3da
NC
5601 number = section->sh_size / section->sh_entsize;
5602
5603 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5604 {
c9c1d674 5605 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5606 (unsigned long) section->sh_size,
dda8d76d 5607 printable_section_name (filedata, section),
8066deb1 5608 (unsigned long) section->sh_entsize);
ba5cdace 5609 goto exit_point;
dd24e3da
NC
5610 }
5611
dda8d76d 5612 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5613 section->sh_size, _("symbols"));
a6e9f9df 5614 if (!esyms)
ba5cdace 5615 goto exit_point;
9ea033b2 5616
e3d39609
NC
5617 shndx = NULL;
5618 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5619 {
5620 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5621 continue;
5622
5623 if (shndx != NULL)
5624 {
5625 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5626 free (shndx);
c9c1d674 5627 }
e3d39609
NC
5628
5629 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5630 entry->hdr->sh_offset,
5631 1, entry->hdr->sh_size,
5632 _("symbol table section indices"));
5633 if (shndx == NULL)
5634 goto exit_point;
5635
5636 /* PR17531: file: heap-buffer-overflow */
5637 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5638 {
5639 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5640 printable_section_name (filedata, entry->hdr),
5641 (unsigned long) entry->hdr->sh_size,
5642 (unsigned long) section->sh_size);
5643 goto exit_point;
5644 }
5645 }
9ad5cbcf 5646
3f5e193b 5647 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5648
5649 if (isyms == NULL)
5650 {
8b73c356
NC
5651 error (_("Out of memory reading %lu symbols\n"),
5652 (unsigned long) number);
ba5cdace 5653 goto exit_point;
9ea033b2
NC
5654 }
5655
ba5cdace 5656 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5657 {
5658 psym->st_name = BYTE_GET (esyms[j].st_name);
5659 psym->st_info = BYTE_GET (esyms[j].st_info);
5660 psym->st_other = BYTE_GET (esyms[j].st_other);
5661 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5662
4fbb74a6 5663 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5664 psym->st_shndx
5665 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5666 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5667 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5668
66543521
AM
5669 psym->st_value = BYTE_GET (esyms[j].st_value);
5670 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5671 }
5672
ba5cdace 5673 exit_point:
e3d39609
NC
5674 free (shndx);
5675 free (esyms);
ba5cdace
NC
5676
5677 if (num_syms_return != NULL)
5678 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5679
5680 return isyms;
5681}
5682
d1133906 5683static const char *
dda8d76d 5684get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5685{
5477e8a0 5686 static char buff[1024];
2cf0635d 5687 char * p = buff;
32ec8896
NC
5688 unsigned int field_size = is_32bit_elf ? 8 : 16;
5689 signed int sindex;
5690 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5691 bfd_vma os_flags = 0;
5692 bfd_vma proc_flags = 0;
5693 bfd_vma unknown_flags = 0;
148b93f2 5694 static const struct
5477e8a0 5695 {
2cf0635d 5696 const char * str;
32ec8896 5697 unsigned int len;
5477e8a0
L
5698 }
5699 flags [] =
5700 {
cfcac11d
NC
5701 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5702 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5703 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5704 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5705 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5706 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5707 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5708 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5709 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5710 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5711 /* IA-64 specific. */
5712 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5713 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5714 /* IA-64 OpenVMS specific. */
5715 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5716 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5717 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5718 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5719 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5720 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5721 /* Generic. */
cfcac11d 5722 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5723 /* SPARC specific. */
77115a4a 5724 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5725 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5726 /* ARM specific. */
5727 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5728 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5729 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5730 /* GNU specific. */
5731 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5732 /* VLE specific. */
5733 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5734 };
5735
5736 if (do_section_details)
5737 {
8d5ff12c
L
5738 sprintf (buff, "[%*.*lx]: ",
5739 field_size, field_size, (unsigned long) sh_flags);
5740 p += field_size + 4;
5477e8a0 5741 }
76da6bbe 5742
d1133906
NC
5743 while (sh_flags)
5744 {
5745 bfd_vma flag;
5746
5747 flag = sh_flags & - sh_flags;
5748 sh_flags &= ~ flag;
76da6bbe 5749
5477e8a0 5750 if (do_section_details)
d1133906 5751 {
5477e8a0
L
5752 switch (flag)
5753 {
91d6fa6a
NC
5754 case SHF_WRITE: sindex = 0; break;
5755 case SHF_ALLOC: sindex = 1; break;
5756 case SHF_EXECINSTR: sindex = 2; break;
5757 case SHF_MERGE: sindex = 3; break;
5758 case SHF_STRINGS: sindex = 4; break;
5759 case SHF_INFO_LINK: sindex = 5; break;
5760 case SHF_LINK_ORDER: sindex = 6; break;
5761 case SHF_OS_NONCONFORMING: sindex = 7; break;
5762 case SHF_GROUP: sindex = 8; break;
5763 case SHF_TLS: sindex = 9; break;
18ae9cc1 5764 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5765 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5766 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 5767
5477e8a0 5768 default:
91d6fa6a 5769 sindex = -1;
dda8d76d 5770 switch (filedata->file_header.e_machine)
148b93f2 5771 {
cfcac11d 5772 case EM_IA_64:
148b93f2 5773 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5774 sindex = 10;
148b93f2 5775 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5776 sindex = 11;
148b93f2 5777#ifdef BFD64
dda8d76d 5778 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
5779 switch (flag)
5780 {
91d6fa6a
NC
5781 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5782 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5783 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5784 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5785 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5786 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5787 default: break;
5788 }
5789#endif
cfcac11d
NC
5790 break;
5791
caa83f8b 5792 case EM_386:
22abe556 5793 case EM_IAMCU:
caa83f8b 5794 case EM_X86_64:
7f502d6c 5795 case EM_L1OM:
7a9068fe 5796 case EM_K1OM:
cfcac11d
NC
5797 case EM_OLD_SPARCV9:
5798 case EM_SPARC32PLUS:
5799 case EM_SPARCV9:
5800 case EM_SPARC:
18ae9cc1 5801 if (flag == SHF_ORDERED)
91d6fa6a 5802 sindex = 19;
cfcac11d 5803 break;
ac4c9b04
MG
5804
5805 case EM_ARM:
5806 switch (flag)
5807 {
5808 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5809 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5810 case SHF_COMDEF: sindex = 23; break;
5811 default: break;
5812 }
5813 break;
83eef883
AFB
5814 case EM_PPC:
5815 if (flag == SHF_PPC_VLE)
5816 sindex = 25;
5817 break;
ac4c9b04 5818
cfcac11d
NC
5819 default:
5820 break;
148b93f2 5821 }
5477e8a0
L
5822 }
5823
91d6fa6a 5824 if (sindex != -1)
5477e8a0 5825 {
8d5ff12c
L
5826 if (p != buff + field_size + 4)
5827 {
5828 if (size < (10 + 2))
bee0ee85
NC
5829 {
5830 warn (_("Internal error: not enough buffer room for section flag info"));
5831 return _("<unknown>");
5832 }
8d5ff12c
L
5833 size -= 2;
5834 *p++ = ',';
5835 *p++ = ' ';
5836 }
5837
91d6fa6a
NC
5838 size -= flags [sindex].len;
5839 p = stpcpy (p, flags [sindex].str);
5477e8a0 5840 }
3b22753a 5841 else if (flag & SHF_MASKOS)
8d5ff12c 5842 os_flags |= flag;
d1133906 5843 else if (flag & SHF_MASKPROC)
8d5ff12c 5844 proc_flags |= flag;
d1133906 5845 else
8d5ff12c 5846 unknown_flags |= flag;
5477e8a0
L
5847 }
5848 else
5849 {
5850 switch (flag)
5851 {
5852 case SHF_WRITE: *p = 'W'; break;
5853 case SHF_ALLOC: *p = 'A'; break;
5854 case SHF_EXECINSTR: *p = 'X'; break;
5855 case SHF_MERGE: *p = 'M'; break;
5856 case SHF_STRINGS: *p = 'S'; break;
5857 case SHF_INFO_LINK: *p = 'I'; break;
5858 case SHF_LINK_ORDER: *p = 'L'; break;
5859 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5860 case SHF_GROUP: *p = 'G'; break;
5861 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5862 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 5863 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 5864 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
5865
5866 default:
dda8d76d
NC
5867 if ((filedata->file_header.e_machine == EM_X86_64
5868 || filedata->file_header.e_machine == EM_L1OM
5869 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
5870 && flag == SHF_X86_64_LARGE)
5871 *p = 'l';
dda8d76d 5872 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 5873 && flag == SHF_ARM_PURECODE)
91f68a68 5874 *p = 'y';
dda8d76d 5875 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
5876 && flag == SHF_PPC_VLE)
5877 *p = 'v';
5477e8a0
L
5878 else if (flag & SHF_MASKOS)
5879 {
5880 *p = 'o';
5881 sh_flags &= ~ SHF_MASKOS;
5882 }
5883 else if (flag & SHF_MASKPROC)
5884 {
5885 *p = 'p';
5886 sh_flags &= ~ SHF_MASKPROC;
5887 }
5888 else
5889 *p = 'x';
5890 break;
5891 }
5892 p++;
d1133906
NC
5893 }
5894 }
76da6bbe 5895
8d5ff12c
L
5896 if (do_section_details)
5897 {
5898 if (os_flags)
5899 {
5900 size -= 5 + field_size;
5901 if (p != buff + field_size + 4)
5902 {
5903 if (size < (2 + 1))
bee0ee85
NC
5904 {
5905 warn (_("Internal error: not enough buffer room for section flag info"));
5906 return _("<unknown>");
5907 }
8d5ff12c
L
5908 size -= 2;
5909 *p++ = ',';
5910 *p++ = ' ';
5911 }
5912 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5913 (unsigned long) os_flags);
5914 p += 5 + field_size;
5915 }
5916 if (proc_flags)
5917 {
5918 size -= 7 + field_size;
5919 if (p != buff + field_size + 4)
5920 {
5921 if (size < (2 + 1))
bee0ee85
NC
5922 {
5923 warn (_("Internal error: not enough buffer room for section flag info"));
5924 return _("<unknown>");
5925 }
8d5ff12c
L
5926 size -= 2;
5927 *p++ = ',';
5928 *p++ = ' ';
5929 }
5930 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5931 (unsigned long) proc_flags);
5932 p += 7 + field_size;
5933 }
5934 if (unknown_flags)
5935 {
5936 size -= 10 + field_size;
5937 if (p != buff + field_size + 4)
5938 {
5939 if (size < (2 + 1))
bee0ee85
NC
5940 {
5941 warn (_("Internal error: not enough buffer room for section flag info"));
5942 return _("<unknown>");
5943 }
8d5ff12c
L
5944 size -= 2;
5945 *p++ = ',';
5946 *p++ = ' ';
5947 }
2b692964 5948 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5949 (unsigned long) unknown_flags);
5950 p += 10 + field_size;
5951 }
5952 }
5953
e9e44622 5954 *p = '\0';
d1133906
NC
5955 return buff;
5956}
5957
77115a4a 5958static unsigned int
ebdf1ebf 5959get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
5960{
5961 if (is_32bit_elf)
5962 {
5963 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 5964
ebdf1ebf
NC
5965 if (size < sizeof (* echdr))
5966 {
5967 error (_("Compressed section is too small even for a compression header\n"));
5968 return 0;
5969 }
5970
77115a4a
L
5971 chdr->ch_type = BYTE_GET (echdr->ch_type);
5972 chdr->ch_size = BYTE_GET (echdr->ch_size);
5973 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5974 return sizeof (*echdr);
5975 }
5976 else
5977 {
5978 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 5979
ebdf1ebf
NC
5980 if (size < sizeof (* echdr))
5981 {
5982 error (_("Compressed section is too small even for a compression header\n"));
5983 return 0;
5984 }
5985
77115a4a
L
5986 chdr->ch_type = BYTE_GET (echdr->ch_type);
5987 chdr->ch_size = BYTE_GET (echdr->ch_size);
5988 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5989 return sizeof (*echdr);
5990 }
5991}
5992
32ec8896 5993static bfd_boolean
dda8d76d 5994process_section_headers (Filedata * filedata)
252b5132 5995{
2cf0635d 5996 Elf_Internal_Shdr * section;
b34976b6 5997 unsigned int i;
252b5132 5998
dda8d76d 5999 filedata->section_headers = NULL;
252b5132 6000
dda8d76d 6001 if (filedata->file_header.e_shnum == 0)
252b5132 6002 {
82f2dbf7 6003 /* PR binutils/12467. */
dda8d76d 6004 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6005 {
6006 warn (_("possibly corrupt ELF file header - it has a non-zero"
6007 " section header offset, but no section headers\n"));
6008 return FALSE;
6009 }
82f2dbf7 6010 else if (do_sections)
252b5132
RH
6011 printf (_("\nThere are no sections in this file.\n"));
6012
32ec8896 6013 return TRUE;
252b5132
RH
6014 }
6015
6016 if (do_sections && !do_header)
d3a49aa8
AM
6017 printf (ngettext ("There is %d section header, "
6018 "starting at offset 0x%lx:\n",
6019 "There are %d section headers, "
6020 "starting at offset 0x%lx:\n",
dda8d76d
NC
6021 filedata->file_header.e_shnum),
6022 filedata->file_header.e_shnum,
6023 (unsigned long) filedata->file_header.e_shoff);
252b5132 6024
9ea033b2
NC
6025 if (is_32bit_elf)
6026 {
dda8d76d 6027 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6028 return FALSE;
6029 }
6030 else
6031 {
dda8d76d 6032 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6033 return FALSE;
9ea033b2 6034 }
252b5132
RH
6035
6036 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6037 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6038 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6039 {
dda8d76d 6040 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6041
c256ffe7
JJ
6042 if (section->sh_size != 0)
6043 {
dda8d76d
NC
6044 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6045 1, section->sh_size,
6046 _("string table"));
0de14b54 6047
dda8d76d 6048 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6049 }
252b5132
RH
6050 }
6051
6052 /* Scan the sections for the dynamic symbol table
e3c8793a 6053 and dynamic string table and debug sections. */
252b5132
RH
6054 dynamic_symbols = NULL;
6055 dynamic_strings = NULL;
6056 dynamic_syminfo = NULL;
6a40cf0c 6057 symtab_shndx_list = NULL;
103f02d3 6058
89fac5e3 6059 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6060 switch (filedata->file_header.e_machine)
89fac5e3
RS
6061 {
6062 case EM_MIPS:
6063 case EM_MIPS_RS3_LE:
6064 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6065 FDE addresses. However, the ABI also has a semi-official ILP32
6066 variant for which the normal FDE address size rules apply.
6067
6068 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6069 section, where XX is the size of longs in bits. Unfortunately,
6070 earlier compilers provided no way of distinguishing ILP32 objects
6071 from LP64 objects, so if there's any doubt, we should assume that
6072 the official LP64 form is being used. */
dda8d76d
NC
6073 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6074 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6075 eh_addr_size = 8;
6076 break;
0f56a26a
DD
6077
6078 case EM_H8_300:
6079 case EM_H8_300H:
dda8d76d 6080 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6081 {
6082 case E_H8_MACH_H8300:
6083 case E_H8_MACH_H8300HN:
6084 case E_H8_MACH_H8300SN:
6085 case E_H8_MACH_H8300SXN:
6086 eh_addr_size = 2;
6087 break;
6088 case E_H8_MACH_H8300H:
6089 case E_H8_MACH_H8300S:
6090 case E_H8_MACH_H8300SX:
6091 eh_addr_size = 4;
6092 break;
6093 }
f4236fe4
DD
6094 break;
6095
ff7eeb89 6096 case EM_M32C_OLD:
f4236fe4 6097 case EM_M32C:
dda8d76d 6098 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6099 {
6100 case EF_M32C_CPU_M16C:
6101 eh_addr_size = 2;
6102 break;
6103 }
6104 break;
89fac5e3
RS
6105 }
6106
76ca31c0
NC
6107#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6108 do \
6109 { \
6110 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6111 if (section->sh_entsize != expected_entsize) \
9dd3a467 6112 { \
76ca31c0
NC
6113 char buf[40]; \
6114 sprintf_vma (buf, section->sh_entsize); \
6115 /* Note: coded this way so that there is a single string for \
6116 translation. */ \
6117 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6118 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6119 (unsigned) expected_entsize); \
9dd3a467 6120 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6121 } \
6122 } \
08d8fa11 6123 while (0)
9dd3a467
NC
6124
6125#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
6126 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
6127 sizeof (Elf64_External_##type))
6128
dda8d76d
NC
6129 for (i = 0, section = filedata->section_headers;
6130 i < filedata->file_header.e_shnum;
b34976b6 6131 i++, section++)
252b5132 6132 {
2cf0635d 6133 char * name = SECTION_NAME (section);
252b5132
RH
6134
6135 if (section->sh_type == SHT_DYNSYM)
6136 {
6137 if (dynamic_symbols != NULL)
6138 {
6139 error (_("File contains multiple dynamic symbol tables\n"));
6140 continue;
6141 }
6142
08d8fa11 6143 CHECK_ENTSIZE (section, i, Sym);
dda8d76d 6144 dynamic_symbols = GET_ELF_SYMBOLS (filedata, section, & num_dynamic_syms);
252b5132
RH
6145 }
6146 else if (section->sh_type == SHT_STRTAB
18bd398b 6147 && streq (name, ".dynstr"))
252b5132
RH
6148 {
6149 if (dynamic_strings != NULL)
6150 {
6151 error (_("File contains multiple dynamic string tables\n"));
6152 continue;
6153 }
6154
dda8d76d 6155 dynamic_strings = (char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6156 1, section->sh_size,
6157 _("dynamic strings"));
59245841 6158 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 6159 }
9ad5cbcf
AM
6160 else if (section->sh_type == SHT_SYMTAB_SHNDX)
6161 {
6a40cf0c 6162 elf_section_list * entry = xmalloc (sizeof * entry);
dda8d76d 6163
6a40cf0c
NC
6164 entry->hdr = section;
6165 entry->next = symtab_shndx_list;
6166 symtab_shndx_list = entry;
9ad5cbcf 6167 }
08d8fa11
JJ
6168 else if (section->sh_type == SHT_SYMTAB)
6169 CHECK_ENTSIZE (section, i, Sym);
6170 else if (section->sh_type == SHT_GROUP)
6171 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6172 else if (section->sh_type == SHT_REL)
6173 CHECK_ENTSIZE (section, i, Rel);
6174 else if (section->sh_type == SHT_RELA)
6175 CHECK_ENTSIZE (section, i, Rela);
252b5132 6176 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 6177 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 6178 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47 6179 || do_debug_str || do_debug_loc || do_debug_ranges
d85bf2ba 6180 || do_debug_addr || do_debug_cu_index || do_debug_links)
1b315056
CS
6181 && (const_strneq (name, ".debug_")
6182 || const_strneq (name, ".zdebug_")))
252b5132 6183 {
1b315056
CS
6184 if (name[1] == 'z')
6185 name += sizeof (".zdebug_") - 1;
6186 else
6187 name += sizeof (".debug_") - 1;
252b5132
RH
6188
6189 if (do_debugging
4723351a
CC
6190 || (do_debug_info && const_strneq (name, "info"))
6191 || (do_debug_info && const_strneq (name, "types"))
6192 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6193 || (do_debug_lines && strcmp (name, "line") == 0)
6194 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6195 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6196 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6197 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6198 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6199 || (do_debug_aranges && const_strneq (name, "aranges"))
6200 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6201 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6202 || (do_debug_frames && const_strneq (name, "frame"))
6203 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6204 || (do_debug_macinfo && const_strneq (name, "macro"))
6205 || (do_debug_str && const_strneq (name, "str"))
6206 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6207 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6208 || (do_debug_addr && const_strneq (name, "addr"))
6209 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6210 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6211 )
dda8d76d 6212 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132 6213 }
a262ae96 6214 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6215 else if ((do_debugging || do_debug_info)
0112cd26 6216 && const_strneq (name, ".gnu.linkonce.wi."))
dda8d76d 6217 request_dump_bynumber (filedata, i, DEBUG_DUMP);
18bd398b 6218 else if (do_debug_frames && streq (name, ".eh_frame"))
dda8d76d 6219 request_dump_bynumber (filedata, i, DEBUG_DUMP);
61364358
JK
6220 else if (do_gdb_index && (streq (name, ".gdb_index")
6221 || streq (name, ".debug_names")))
dda8d76d 6222 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884
TG
6223 /* Trace sections for Itanium VMS. */
6224 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6225 || do_trace_aranges)
6226 && const_strneq (name, ".trace_"))
6227 {
6228 name += sizeof (".trace_") - 1;
6229
6230 if (do_debugging
6231 || (do_trace_info && streq (name, "info"))
6232 || (do_trace_abbrevs && streq (name, "abbrev"))
6233 || (do_trace_aranges && streq (name, "aranges"))
6234 )
dda8d76d 6235 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884 6236 }
dda8d76d
NC
6237 else if ((do_debugging || do_debug_links)
6238 && (const_strneq (name, ".gnu_debuglink")
6239 || const_strneq (name, ".gnu_debugaltlink")))
6240 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132
RH
6241 }
6242
6243 if (! do_sections)
32ec8896 6244 return TRUE;
252b5132 6245
dda8d76d 6246 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6247 printf (_("\nSection Headers:\n"));
6248 else
6249 printf (_("\nSection Header:\n"));
76da6bbe 6250
f7a99963 6251 if (is_32bit_elf)
595cf52e 6252 {
5477e8a0 6253 if (do_section_details)
595cf52e
L
6254 {
6255 printf (_(" [Nr] Name\n"));
5477e8a0 6256 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6257 }
6258 else
6259 printf
6260 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6261 }
d974e256 6262 else if (do_wide)
595cf52e 6263 {
5477e8a0 6264 if (do_section_details)
595cf52e
L
6265 {
6266 printf (_(" [Nr] Name\n"));
5477e8a0 6267 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6268 }
6269 else
6270 printf
6271 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6272 }
f7a99963
NC
6273 else
6274 {
5477e8a0 6275 if (do_section_details)
595cf52e
L
6276 {
6277 printf (_(" [Nr] Name\n"));
5477e8a0
L
6278 printf (_(" Type Address Offset Link\n"));
6279 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6280 }
6281 else
6282 {
6283 printf (_(" [Nr] Name Type Address Offset\n"));
6284 printf (_(" Size EntSize Flags Link Info Align\n"));
6285 }
f7a99963 6286 }
252b5132 6287
5477e8a0
L
6288 if (do_section_details)
6289 printf (_(" Flags\n"));
6290
dda8d76d
NC
6291 for (i = 0, section = filedata->section_headers;
6292 i < filedata->file_header.e_shnum;
b34976b6 6293 i++, section++)
252b5132 6294 {
dd905818
NC
6295 /* Run some sanity checks on the section header. */
6296
6297 /* Check the sh_link field. */
6298 switch (section->sh_type)
6299 {
6300 case SHT_SYMTAB_SHNDX:
6301 case SHT_GROUP:
6302 case SHT_HASH:
6303 case SHT_GNU_HASH:
6304 case SHT_GNU_versym:
6305 case SHT_REL:
6306 case SHT_RELA:
6307 if (section->sh_link < 1
dda8d76d
NC
6308 || section->sh_link >= filedata->file_header.e_shnum
6309 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6310 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6311 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6312 i, section->sh_link);
6313 break;
6314
6315 case SHT_DYNAMIC:
6316 case SHT_SYMTAB:
6317 case SHT_DYNSYM:
6318 case SHT_GNU_verneed:
6319 case SHT_GNU_verdef:
6320 case SHT_GNU_LIBLIST:
6321 if (section->sh_link < 1
dda8d76d
NC
6322 || section->sh_link >= filedata->file_header.e_shnum
6323 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6324 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6325 i, section->sh_link);
6326 break;
6327
6328 case SHT_INIT_ARRAY:
6329 case SHT_FINI_ARRAY:
6330 case SHT_PREINIT_ARRAY:
6331 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6332 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6333 i, section->sh_link);
6334 break;
6335
6336 default:
6337 /* FIXME: Add support for target specific section types. */
6338#if 0 /* Currently we do not check other section types as there are too
6339 many special cases. Stab sections for example have a type
6340 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6341 section. */
6342 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6343 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6344 i, section->sh_link);
6345#endif
6346 break;
6347 }
6348
6349 /* Check the sh_info field. */
6350 switch (section->sh_type)
6351 {
6352 case SHT_REL:
6353 case SHT_RELA:
6354 if (section->sh_info < 1
dda8d76d
NC
6355 || section->sh_info >= filedata->file_header.e_shnum
6356 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6357 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6358 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6359 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
dd905818 6360 /* FIXME: Are other section types valid ? */
dda8d76d 6361 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
dd905818
NC
6362 {
6363 if (section->sh_info == 0
bef7475f
NC
6364 && (filedata->file_header.e_type == ET_EXEC
6365 || filedata->file_header.e_type == ET_DYN
6366 /* These next two tests may be redundant, but
6367 they have been left in for paranoia's sake. */
6368 || streq (SECTION_NAME (section), ".rel.dyn")
dd905818 6369 || streq (SECTION_NAME (section), ".rela.dyn")))
bef7475f
NC
6370 /* Dynamic relocations apply to segments, not sections, so
6371 they do not need an sh_info value. */
6372 ;
dd905818
NC
6373 else
6374 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6375 i, section->sh_info);
6376 }
6377 break;
6378
6379 case SHT_DYNAMIC:
6380 case SHT_HASH:
6381 case SHT_SYMTAB_SHNDX:
6382 case SHT_INIT_ARRAY:
6383 case SHT_FINI_ARRAY:
6384 case SHT_PREINIT_ARRAY:
6385 if (section->sh_info != 0)
6386 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6387 i, section->sh_info);
6388 break;
6389
6390 case SHT_GROUP:
6391 case SHT_SYMTAB:
6392 case SHT_DYNSYM:
6393 /* A symbol index - we assume that it is valid. */
6394 break;
6395
6396 default:
6397 /* FIXME: Add support for target specific section types. */
6398 if (section->sh_type == SHT_NOBITS)
6399 /* NOBITS section headers with non-zero sh_info fields can be
6400 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6401 information. The stripped sections have their headers
6402 preserved but their types set to SHT_NOBITS. So do not check
6403 this type of section. */
dd905818
NC
6404 ;
6405 else if (section->sh_flags & SHF_INFO_LINK)
6406 {
dda8d76d 6407 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6408 warn (_("[%2u]: Expected link to another section in info field"), i);
6409 }
a91e1603
L
6410 else if (section->sh_type < SHT_LOOS
6411 && (section->sh_flags & SHF_GNU_MBIND) == 0
6412 && section->sh_info != 0)
dd905818
NC
6413 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6414 i, section->sh_info);
6415 break;
6416 }
6417
3e6b6445 6418 /* Check the sh_size field. */
dda8d76d 6419 if (section->sh_size > filedata->file_size
3e6b6445
NC
6420 && section->sh_type != SHT_NOBITS
6421 && section->sh_type != SHT_NULL
6422 && section->sh_type < SHT_LOOS)
6423 warn (_("Size of section %u is larger than the entire file!\n"), i);
6424
7bfd842d 6425 printf (" [%2u] ", i);
5477e8a0 6426 if (do_section_details)
dda8d76d 6427 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6428 else
74e1a04b 6429 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6430
ea52a088 6431 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6432 get_section_type_name (filedata, section->sh_type));
0b4362b0 6433
f7a99963
NC
6434 if (is_32bit_elf)
6435 {
cfcac11d
NC
6436 const char * link_too_big = NULL;
6437
f7a99963 6438 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6439
f7a99963
NC
6440 printf ( " %6.6lx %6.6lx %2.2lx",
6441 (unsigned long) section->sh_offset,
6442 (unsigned long) section->sh_size,
6443 (unsigned long) section->sh_entsize);
d1133906 6444
5477e8a0
L
6445 if (do_section_details)
6446 fputs (" ", stdout);
6447 else
dda8d76d 6448 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6449
dda8d76d 6450 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6451 {
6452 link_too_big = "";
6453 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6454 an error but it can have special values in Solaris binaries. */
dda8d76d 6455 switch (filedata->file_header.e_machine)
cfcac11d 6456 {
caa83f8b 6457 case EM_386:
22abe556 6458 case EM_IAMCU:
caa83f8b 6459 case EM_X86_64:
7f502d6c 6460 case EM_L1OM:
7a9068fe 6461 case EM_K1OM:
cfcac11d
NC
6462 case EM_OLD_SPARCV9:
6463 case EM_SPARC32PLUS:
6464 case EM_SPARCV9:
6465 case EM_SPARC:
6466 if (section->sh_link == (SHN_BEFORE & 0xffff))
6467 link_too_big = "BEFORE";
6468 else if (section->sh_link == (SHN_AFTER & 0xffff))
6469 link_too_big = "AFTER";
6470 break;
6471 default:
6472 break;
6473 }
6474 }
6475
6476 if (do_section_details)
6477 {
6478 if (link_too_big != NULL && * link_too_big)
6479 printf ("<%s> ", link_too_big);
6480 else
6481 printf ("%2u ", section->sh_link);
6482 printf ("%3u %2lu\n", section->sh_info,
6483 (unsigned long) section->sh_addralign);
6484 }
6485 else
6486 printf ("%2u %3u %2lu\n",
6487 section->sh_link,
6488 section->sh_info,
6489 (unsigned long) section->sh_addralign);
6490
6491 if (link_too_big && ! * link_too_big)
6492 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6493 i, section->sh_link);
f7a99963 6494 }
d974e256
JJ
6495 else if (do_wide)
6496 {
6497 print_vma (section->sh_addr, LONG_HEX);
6498
6499 if ((long) section->sh_offset == section->sh_offset)
6500 printf (" %6.6lx", (unsigned long) section->sh_offset);
6501 else
6502 {
6503 putchar (' ');
6504 print_vma (section->sh_offset, LONG_HEX);
6505 }
6506
6507 if ((unsigned long) section->sh_size == section->sh_size)
6508 printf (" %6.6lx", (unsigned long) section->sh_size);
6509 else
6510 {
6511 putchar (' ');
6512 print_vma (section->sh_size, LONG_HEX);
6513 }
6514
6515 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6516 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6517 else
6518 {
6519 putchar (' ');
6520 print_vma (section->sh_entsize, LONG_HEX);
6521 }
6522
5477e8a0
L
6523 if (do_section_details)
6524 fputs (" ", stdout);
6525 else
dda8d76d 6526 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6527
72de5009 6528 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6529
6530 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6531 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6532 else
6533 {
6534 print_vma (section->sh_addralign, DEC);
6535 putchar ('\n');
6536 }
6537 }
5477e8a0 6538 else if (do_section_details)
595cf52e 6539 {
55cc53e9 6540 putchar (' ');
595cf52e
L
6541 print_vma (section->sh_addr, LONG_HEX);
6542 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6543 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6544 else
6545 {
6546 printf (" ");
6547 print_vma (section->sh_offset, LONG_HEX);
6548 }
72de5009 6549 printf (" %u\n ", section->sh_link);
595cf52e 6550 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6551 putchar (' ');
595cf52e
L
6552 print_vma (section->sh_entsize, LONG_HEX);
6553
72de5009
AM
6554 printf (" %-16u %lu\n",
6555 section->sh_info,
595cf52e
L
6556 (unsigned long) section->sh_addralign);
6557 }
f7a99963
NC
6558 else
6559 {
6560 putchar (' ');
6561 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6562 if ((long) section->sh_offset == section->sh_offset)
6563 printf (" %8.8lx", (unsigned long) section->sh_offset);
6564 else
6565 {
6566 printf (" ");
6567 print_vma (section->sh_offset, LONG_HEX);
6568 }
f7a99963
NC
6569 printf ("\n ");
6570 print_vma (section->sh_size, LONG_HEX);
6571 printf (" ");
6572 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6573
dda8d76d 6574 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6575
72de5009
AM
6576 printf (" %2u %3u %lu\n",
6577 section->sh_link,
6578 section->sh_info,
f7a99963
NC
6579 (unsigned long) section->sh_addralign);
6580 }
5477e8a0
L
6581
6582 if (do_section_details)
77115a4a 6583 {
dda8d76d 6584 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6585 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6586 {
6587 /* Minimum section size is 12 bytes for 32-bit compression
6588 header + 12 bytes for compressed data header. */
6589 unsigned char buf[24];
d8024a91 6590
77115a4a 6591 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6592 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6593 sizeof (buf), _("compression header")))
6594 {
6595 Elf_Internal_Chdr chdr;
d8024a91 6596
ebdf1ebf 6597 (void) get_compression_header (&chdr, buf, sizeof (buf));
d8024a91 6598
77115a4a
L
6599 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6600 printf (" ZLIB, ");
6601 else
6602 printf (_(" [<unknown>: 0x%x], "),
6603 chdr.ch_type);
6604 print_vma (chdr.ch_size, LONG_HEX);
6605 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6606 }
6607 }
6608 }
252b5132
RH
6609 }
6610
5477e8a0 6611 if (!do_section_details)
3dbcc61d 6612 {
9fb71ee4
NC
6613 /* The ordering of the letters shown here matches the ordering of the
6614 corresponding SHF_xxx values, and hence the order in which these
6615 letters will be displayed to the user. */
6616 printf (_("Key to Flags:\n\
6617 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6618 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6619 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6620 if (filedata->file_header.e_machine == EM_X86_64
6621 || filedata->file_header.e_machine == EM_L1OM
6622 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6623 printf (_("l (large), "));
dda8d76d 6624 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6625 printf (_("y (purecode), "));
dda8d76d 6626 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6627 printf (_("v (VLE), "));
9fb71ee4 6628 printf ("p (processor specific)\n");
0b4362b0 6629 }
d1133906 6630
32ec8896 6631 return TRUE;
252b5132
RH
6632}
6633
f5842774
L
6634static const char *
6635get_group_flags (unsigned int flags)
6636{
1449284b 6637 static char buff[128];
220453ec 6638
6d913794
NC
6639 if (flags == 0)
6640 return "";
6641 else if (flags == GRP_COMDAT)
6642 return "COMDAT ";
f5842774 6643
6d913794
NC
6644 snprintf (buff, 14, _("[0x%x: "), flags);
6645
6646 flags &= ~ GRP_COMDAT;
6647 if (flags & GRP_MASKOS)
6648 {
6649 strcat (buff, "<OS specific>");
6650 flags &= ~ GRP_MASKOS;
f5842774 6651 }
6d913794
NC
6652
6653 if (flags & GRP_MASKPROC)
6654 {
6655 strcat (buff, "<PROC specific>");
6656 flags &= ~ GRP_MASKPROC;
6657 }
6658
6659 if (flags)
6660 strcat (buff, "<unknown>");
6661
6662 strcat (buff, "]");
f5842774
L
6663 return buff;
6664}
6665
32ec8896 6666static bfd_boolean
dda8d76d 6667process_section_groups (Filedata * filedata)
f5842774 6668{
2cf0635d 6669 Elf_Internal_Shdr * section;
f5842774 6670 unsigned int i;
2cf0635d
NC
6671 struct group * group;
6672 Elf_Internal_Shdr * symtab_sec;
6673 Elf_Internal_Shdr * strtab_sec;
6674 Elf_Internal_Sym * symtab;
ba5cdace 6675 unsigned long num_syms;
2cf0635d 6676 char * strtab;
c256ffe7 6677 size_t strtab_size;
d1f5c6e3
L
6678
6679 /* Don't process section groups unless needed. */
6680 if (!do_unwind && !do_section_groups)
32ec8896 6681 return TRUE;
f5842774 6682
dda8d76d 6683 if (filedata->file_header.e_shnum == 0)
f5842774
L
6684 {
6685 if (do_section_groups)
82f2dbf7 6686 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 6687
32ec8896 6688 return TRUE;
f5842774
L
6689 }
6690
dda8d76d 6691 if (filedata->section_headers == NULL)
f5842774
L
6692 {
6693 error (_("Section headers are not available!\n"));
fa1908fd 6694 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 6695 return FALSE;
f5842774
L
6696 }
6697
dda8d76d 6698 section_headers_groups = (struct group **) calloc (filedata->file_header.e_shnum,
3f5e193b 6699 sizeof (struct group *));
e4b17d5c
L
6700
6701 if (section_headers_groups == NULL)
6702 {
8b73c356 6703 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 6704 filedata->file_header.e_shnum);
32ec8896 6705 return FALSE;
e4b17d5c
L
6706 }
6707
f5842774 6708 /* Scan the sections for the group section. */
d1f5c6e3 6709 group_count = 0;
dda8d76d
NC
6710 for (i = 0, section = filedata->section_headers;
6711 i < filedata->file_header.e_shnum;
f5842774 6712 i++, section++)
e4b17d5c
L
6713 if (section->sh_type == SHT_GROUP)
6714 group_count++;
6715
d1f5c6e3
L
6716 if (group_count == 0)
6717 {
6718 if (do_section_groups)
6719 printf (_("\nThere are no section groups in this file.\n"));
6720
32ec8896 6721 return TRUE;
d1f5c6e3
L
6722 }
6723
3f5e193b 6724 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
6725
6726 if (section_groups == NULL)
6727 {
8b73c356
NC
6728 error (_("Out of memory reading %lu groups\n"),
6729 (unsigned long) group_count);
32ec8896 6730 return FALSE;
e4b17d5c
L
6731 }
6732
d1f5c6e3
L
6733 symtab_sec = NULL;
6734 strtab_sec = NULL;
6735 symtab = NULL;
ba5cdace 6736 num_syms = 0;
d1f5c6e3 6737 strtab = NULL;
c256ffe7 6738 strtab_size = 0;
dda8d76d
NC
6739 for (i = 0, section = filedata->section_headers, group = section_groups;
6740 i < filedata->file_header.e_shnum;
e4b17d5c 6741 i++, section++)
f5842774
L
6742 {
6743 if (section->sh_type == SHT_GROUP)
6744 {
dda8d76d 6745 const char * name = printable_section_name (filedata, section);
74e1a04b 6746 const char * group_name;
2cf0635d
NC
6747 unsigned char * start;
6748 unsigned char * indices;
f5842774 6749 unsigned int entry, j, size;
2cf0635d
NC
6750 Elf_Internal_Shdr * sec;
6751 Elf_Internal_Sym * sym;
f5842774
L
6752
6753 /* Get the symbol table. */
dda8d76d
NC
6754 if (section->sh_link >= filedata->file_header.e_shnum
6755 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 6756 != SHT_SYMTAB))
f5842774
L
6757 {
6758 error (_("Bad sh_link in group section `%s'\n"), name);
6759 continue;
6760 }
d1f5c6e3
L
6761
6762 if (symtab_sec != sec)
6763 {
6764 symtab_sec = sec;
6765 if (symtab)
6766 free (symtab);
dda8d76d 6767 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 6768 }
f5842774 6769
dd24e3da
NC
6770 if (symtab == NULL)
6771 {
6772 error (_("Corrupt header in group section `%s'\n"), name);
6773 continue;
6774 }
6775
ba5cdace
NC
6776 if (section->sh_info >= num_syms)
6777 {
6778 error (_("Bad sh_info in group section `%s'\n"), name);
6779 continue;
6780 }
6781
f5842774
L
6782 sym = symtab + section->sh_info;
6783
6784 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6785 {
4fbb74a6 6786 if (sym->st_shndx == 0
dda8d76d 6787 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
6788 {
6789 error (_("Bad sh_info in group section `%s'\n"), name);
6790 continue;
6791 }
ba2685cc 6792
dda8d76d 6793 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7
JJ
6794 strtab_sec = NULL;
6795 if (strtab)
6796 free (strtab);
f5842774 6797 strtab = NULL;
c256ffe7 6798 strtab_size = 0;
f5842774
L
6799 }
6800 else
6801 {
6802 /* Get the string table. */
dda8d76d 6803 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
6804 {
6805 strtab_sec = NULL;
6806 if (strtab)
6807 free (strtab);
6808 strtab = NULL;
6809 strtab_size = 0;
6810 }
6811 else if (strtab_sec
dda8d76d 6812 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
6813 {
6814 strtab_sec = sec;
6815 if (strtab)
6816 free (strtab);
071436c6 6817
dda8d76d 6818 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
6819 1, strtab_sec->sh_size,
6820 _("string table"));
c256ffe7 6821 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 6822 }
c256ffe7 6823 group_name = sym->st_name < strtab_size
2b692964 6824 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
6825 }
6826
c9c1d674
EG
6827 /* PR 17531: file: loop. */
6828 if (section->sh_entsize > section->sh_size)
6829 {
6830 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 6831 printable_section_name (filedata, section),
8066deb1
AM
6832 (unsigned long) section->sh_entsize,
6833 (unsigned long) section->sh_size);
c9c1d674
EG
6834 break;
6835 }
6836
dda8d76d 6837 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6838 1, section->sh_size,
6839 _("section data"));
59245841
NC
6840 if (start == NULL)
6841 continue;
f5842774
L
6842
6843 indices = start;
6844 size = (section->sh_size / section->sh_entsize) - 1;
6845 entry = byte_get (indices, 4);
6846 indices += 4;
e4b17d5c
L
6847
6848 if (do_section_groups)
6849 {
2b692964 6850 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6851 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6852
e4b17d5c
L
6853 printf (_(" [Index] Name\n"));
6854 }
6855
6856 group->group_index = i;
6857
f5842774
L
6858 for (j = 0; j < size; j++)
6859 {
2cf0635d 6860 struct group_list * g;
e4b17d5c 6861
f5842774
L
6862 entry = byte_get (indices, 4);
6863 indices += 4;
6864
dda8d76d 6865 if (entry >= filedata->file_header.e_shnum)
391cb864 6866 {
57028622
NC
6867 static unsigned num_group_errors = 0;
6868
6869 if (num_group_errors ++ < 10)
6870 {
6871 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 6872 entry, i, filedata->file_header.e_shnum - 1);
57028622 6873 if (num_group_errors == 10)
67ce483b 6874 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 6875 }
391cb864
L
6876 continue;
6877 }
391cb864 6878
4fbb74a6 6879 if (section_headers_groups [entry] != NULL)
e4b17d5c 6880 {
d1f5c6e3
L
6881 if (entry)
6882 {
57028622
NC
6883 static unsigned num_errs = 0;
6884
6885 if (num_errs ++ < 10)
6886 {
6887 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6888 entry, i,
6889 section_headers_groups [entry]->group_index);
6890 if (num_errs == 10)
6891 warn (_("Further error messages about already contained group sections suppressed\n"));
6892 }
d1f5c6e3
L
6893 continue;
6894 }
6895 else
6896 {
6897 /* Intel C/C++ compiler may put section 0 in a
32ec8896 6898 section group. We just warn it the first time
d1f5c6e3 6899 and ignore it afterwards. */
32ec8896 6900 static bfd_boolean warned = FALSE;
d1f5c6e3
L
6901 if (!warned)
6902 {
6903 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6904 section_headers_groups [entry]->group_index);
32ec8896 6905 warned = TRUE;
d1f5c6e3
L
6906 }
6907 }
e4b17d5c
L
6908 }
6909
4fbb74a6 6910 section_headers_groups [entry] = group;
e4b17d5c
L
6911
6912 if (do_section_groups)
6913 {
dda8d76d
NC
6914 sec = filedata->section_headers + entry;
6915 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
6916 }
6917
3f5e193b 6918 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6919 g->section_index = entry;
6920 g->next = group->root;
6921 group->root = g;
f5842774
L
6922 }
6923
f5842774
L
6924 if (start)
6925 free (start);
e4b17d5c
L
6926
6927 group++;
f5842774
L
6928 }
6929 }
6930
d1f5c6e3
L
6931 if (symtab)
6932 free (symtab);
6933 if (strtab)
6934 free (strtab);
32ec8896 6935 return TRUE;
f5842774
L
6936}
6937
28f997cf
TG
6938/* Data used to display dynamic fixups. */
6939
6940struct ia64_vms_dynfixup
6941{
6942 bfd_vma needed_ident; /* Library ident number. */
6943 bfd_vma needed; /* Index in the dstrtab of the library name. */
6944 bfd_vma fixup_needed; /* Index of the library. */
6945 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6946 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6947};
6948
6949/* Data used to display dynamic relocations. */
6950
6951struct ia64_vms_dynimgrela
6952{
6953 bfd_vma img_rela_cnt; /* Number of relocations. */
6954 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6955};
6956
6957/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6958 library). */
6959
32ec8896 6960static bfd_boolean
dda8d76d
NC
6961dump_ia64_vms_dynamic_fixups (Filedata * filedata,
6962 struct ia64_vms_dynfixup * fixup,
6963 const char * strtab,
6964 unsigned int strtab_sz)
28f997cf 6965{
32ec8896 6966 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 6967 long i;
32ec8896 6968 const char * lib_name;
28f997cf 6969
dda8d76d 6970 imfs = get_data (NULL, filedata, dynamic_addr + fixup->fixup_rela_off,
28f997cf
TG
6971 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6972 _("dynamic section image fixups"));
6973 if (!imfs)
32ec8896 6974 return FALSE;
28f997cf
TG
6975
6976 if (fixup->needed < strtab_sz)
6977 lib_name = strtab + fixup->needed;
6978 else
6979 {
32ec8896 6980 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 6981 (unsigned long) fixup->needed);
28f997cf
TG
6982 lib_name = "???";
6983 }
6984 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6985 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6986 printf
6987 (_("Seg Offset Type SymVec DataType\n"));
6988
6989 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6990 {
6991 unsigned int type;
6992 const char *rtype;
6993
6994 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6995 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6996 type = BYTE_GET (imfs [i].type);
6997 rtype = elf_ia64_reloc_type (type);
6998 if (rtype == NULL)
6999 printf (" 0x%08x ", type);
7000 else
7001 printf (" %-32s ", rtype);
7002 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7003 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7004 }
7005
7006 free (imfs);
32ec8896 7007 return TRUE;
28f997cf
TG
7008}
7009
7010/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7011
32ec8896 7012static bfd_boolean
dda8d76d 7013dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7014{
7015 Elf64_External_VMS_IMAGE_RELA *imrs;
7016 long i;
7017
dda8d76d 7018 imrs = get_data (NULL, filedata, dynamic_addr + imgrela->img_rela_off,
28f997cf 7019 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 7020 _("dynamic section image relocations"));
28f997cf 7021 if (!imrs)
32ec8896 7022 return FALSE;
28f997cf
TG
7023
7024 printf (_("\nImage relocs\n"));
7025 printf
7026 (_("Seg Offset Type Addend Seg Sym Off\n"));
7027
7028 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7029 {
7030 unsigned int type;
7031 const char *rtype;
7032
7033 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7034 printf ("%08" BFD_VMA_FMT "x ",
7035 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7036 type = BYTE_GET (imrs [i].type);
7037 rtype = elf_ia64_reloc_type (type);
7038 if (rtype == NULL)
7039 printf ("0x%08x ", type);
7040 else
7041 printf ("%-31s ", rtype);
7042 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7043 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7044 printf ("%08" BFD_VMA_FMT "x\n",
7045 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7046 }
7047
7048 free (imrs);
32ec8896 7049 return TRUE;
28f997cf
TG
7050}
7051
7052/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7053
32ec8896 7054static bfd_boolean
dda8d76d 7055process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7056{
7057 struct ia64_vms_dynfixup fixup;
7058 struct ia64_vms_dynimgrela imgrela;
7059 Elf_Internal_Dyn *entry;
28f997cf
TG
7060 bfd_vma strtab_off = 0;
7061 bfd_vma strtab_sz = 0;
7062 char *strtab = NULL;
32ec8896 7063 bfd_boolean res = TRUE;
28f997cf
TG
7064
7065 memset (&fixup, 0, sizeof (fixup));
7066 memset (&imgrela, 0, sizeof (imgrela));
7067
7068 /* Note: the order of the entries is specified by the OpenVMS specs. */
7069 for (entry = dynamic_section;
7070 entry < dynamic_section + dynamic_nent;
7071 entry++)
7072 {
7073 switch (entry->d_tag)
7074 {
7075 case DT_IA_64_VMS_STRTAB_OFFSET:
7076 strtab_off = entry->d_un.d_val;
7077 break;
7078 case DT_STRSZ:
7079 strtab_sz = entry->d_un.d_val;
7080 if (strtab == NULL)
dda8d76d 7081 strtab = get_data (NULL, filedata, dynamic_addr + strtab_off,
28f997cf
TG
7082 1, strtab_sz, _("dynamic string section"));
7083 break;
7084
7085 case DT_IA_64_VMS_NEEDED_IDENT:
7086 fixup.needed_ident = entry->d_un.d_val;
7087 break;
7088 case DT_NEEDED:
7089 fixup.needed = entry->d_un.d_val;
7090 break;
7091 case DT_IA_64_VMS_FIXUP_NEEDED:
7092 fixup.fixup_needed = entry->d_un.d_val;
7093 break;
7094 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7095 fixup.fixup_rela_cnt = entry->d_un.d_val;
7096 break;
7097 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7098 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7099 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7100 res = FALSE;
28f997cf 7101 break;
28f997cf
TG
7102 case DT_IA_64_VMS_IMG_RELA_CNT:
7103 imgrela.img_rela_cnt = entry->d_un.d_val;
7104 break;
7105 case DT_IA_64_VMS_IMG_RELA_OFF:
7106 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7107 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7108 res = FALSE;
28f997cf
TG
7109 break;
7110
7111 default:
7112 break;
7113 }
7114 }
7115
7116 if (strtab != NULL)
7117 free (strtab);
7118
7119 return res;
7120}
7121
85b1c36d 7122static struct
566b0d53 7123{
2cf0635d 7124 const char * name;
566b0d53
L
7125 int reloc;
7126 int size;
7127 int rela;
32ec8896
NC
7128}
7129 dynamic_relocations [] =
566b0d53 7130{
32ec8896
NC
7131 { "REL", DT_REL, DT_RELSZ, FALSE },
7132 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7133 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7134};
7135
252b5132 7136/* Process the reloc section. */
18bd398b 7137
32ec8896 7138static bfd_boolean
dda8d76d 7139process_relocs (Filedata * filedata)
252b5132 7140{
b34976b6
AM
7141 unsigned long rel_size;
7142 unsigned long rel_offset;
252b5132 7143
252b5132 7144 if (!do_reloc)
32ec8896 7145 return TRUE;
252b5132
RH
7146
7147 if (do_using_dynamic)
7148 {
32ec8896 7149 int is_rela;
2cf0635d 7150 const char * name;
32ec8896 7151 bfd_boolean has_dynamic_reloc;
566b0d53 7152 unsigned int i;
0de14b54 7153
32ec8896 7154 has_dynamic_reloc = FALSE;
252b5132 7155
566b0d53 7156 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7157 {
566b0d53
L
7158 is_rela = dynamic_relocations [i].rela;
7159 name = dynamic_relocations [i].name;
7160 rel_size = dynamic_info [dynamic_relocations [i].size];
7161 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 7162
32ec8896
NC
7163 if (rel_size)
7164 has_dynamic_reloc = TRUE;
566b0d53
L
7165
7166 if (is_rela == UNKNOWN)
aa903cfb 7167 {
566b0d53
L
7168 if (dynamic_relocations [i].reloc == DT_JMPREL)
7169 switch (dynamic_info[DT_PLTREL])
7170 {
7171 case DT_REL:
7172 is_rela = FALSE;
7173 break;
7174 case DT_RELA:
7175 is_rela = TRUE;
7176 break;
7177 }
aa903cfb 7178 }
252b5132 7179
566b0d53
L
7180 if (rel_size)
7181 {
7182 printf
7183 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7184 name, rel_offset, rel_size);
252b5132 7185
dda8d76d
NC
7186 dump_relocations (filedata,
7187 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7188 rel_size,
566b0d53 7189 dynamic_symbols, num_dynamic_syms,
bb4d2ac2 7190 dynamic_strings, dynamic_strings_length,
32ec8896 7191 is_rela, TRUE /* is_dynamic */);
566b0d53 7192 }
252b5132 7193 }
566b0d53 7194
dda8d76d
NC
7195 if (is_ia64_vms (filedata))
7196 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7197 has_dynamic_reloc = TRUE;
28f997cf 7198
566b0d53 7199 if (! has_dynamic_reloc)
252b5132
RH
7200 printf (_("\nThere are no dynamic relocations in this file.\n"));
7201 }
7202 else
7203 {
2cf0635d 7204 Elf_Internal_Shdr * section;
b34976b6 7205 unsigned long i;
32ec8896 7206 bfd_boolean found = FALSE;
252b5132 7207
dda8d76d
NC
7208 for (i = 0, section = filedata->section_headers;
7209 i < filedata->file_header.e_shnum;
b34976b6 7210 i++, section++)
252b5132
RH
7211 {
7212 if ( section->sh_type != SHT_RELA
7213 && section->sh_type != SHT_REL)
7214 continue;
7215
7216 rel_offset = section->sh_offset;
7217 rel_size = section->sh_size;
7218
7219 if (rel_size)
7220 {
2cf0635d 7221 Elf_Internal_Shdr * strsec;
b34976b6 7222 int is_rela;
d3a49aa8 7223 unsigned long num_rela;
103f02d3 7224
252b5132
RH
7225 printf (_("\nRelocation section "));
7226
dda8d76d 7227 if (filedata->string_table == NULL)
19936277 7228 printf ("%d", section->sh_name);
252b5132 7229 else
dda8d76d 7230 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7231
d3a49aa8
AM
7232 num_rela = rel_size / section->sh_entsize;
7233 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7234 " at offset 0x%lx contains %lu entries:\n",
7235 num_rela),
7236 rel_offset, num_rela);
252b5132 7237
d79b3d50
NC
7238 is_rela = section->sh_type == SHT_RELA;
7239
4fbb74a6 7240 if (section->sh_link != 0
dda8d76d 7241 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7242 {
2cf0635d
NC
7243 Elf_Internal_Shdr * symsec;
7244 Elf_Internal_Sym * symtab;
d79b3d50 7245 unsigned long nsyms;
c256ffe7 7246 unsigned long strtablen = 0;
2cf0635d 7247 char * strtab = NULL;
57346661 7248
dda8d76d 7249 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7250 if (symsec->sh_type != SHT_SYMTAB
7251 && symsec->sh_type != SHT_DYNSYM)
7252 continue;
7253
dda8d76d 7254 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
252b5132 7255
af3fc3bc
AM
7256 if (symtab == NULL)
7257 continue;
252b5132 7258
4fbb74a6 7259 if (symsec->sh_link != 0
dda8d76d 7260 && symsec->sh_link < filedata->file_header.e_shnum)
c256ffe7 7261 {
dda8d76d 7262 strsec = filedata->section_headers + symsec->sh_link;
103f02d3 7263
dda8d76d 7264 strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
071436c6
NC
7265 1, strsec->sh_size,
7266 _("string table"));
c256ffe7
JJ
7267 strtablen = strtab == NULL ? 0 : strsec->sh_size;
7268 }
252b5132 7269
dda8d76d 7270 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7271 symtab, nsyms, strtab, strtablen,
7272 is_rela,
7273 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
7274 if (strtab)
7275 free (strtab);
7276 free (symtab);
7277 }
7278 else
dda8d76d 7279 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7280 NULL, 0, NULL, 0, is_rela,
7281 FALSE /* is_dynamic */);
252b5132 7282
32ec8896 7283 found = TRUE;
252b5132
RH
7284 }
7285 }
7286
7287 if (! found)
45ac8f4f
NC
7288 {
7289 /* Users sometimes forget the -D option, so try to be helpful. */
7290 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7291 {
7292 if (dynamic_info [dynamic_relocations [i].size])
7293 {
7294 printf (_("\nThere are no static relocations in this file."));
7295 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7296
7297 break;
7298 }
7299 }
7300 if (i == ARRAY_SIZE (dynamic_relocations))
7301 printf (_("\nThere are no relocations in this file.\n"));
7302 }
252b5132
RH
7303 }
7304
32ec8896 7305 return TRUE;
252b5132
RH
7306}
7307
4d6ed7c8
NC
7308/* An absolute address consists of a section and an offset. If the
7309 section is NULL, the offset itself is the address, otherwise, the
7310 address equals to LOAD_ADDRESS(section) + offset. */
7311
7312struct absaddr
948f632f
DA
7313{
7314 unsigned short section;
7315 bfd_vma offset;
7316};
4d6ed7c8 7317
1949de15
L
7318#define ABSADDR(a) \
7319 ((a).section \
dda8d76d 7320 ? filedata->section_headers [(a).section].sh_addr + (a).offset \
1949de15
L
7321 : (a).offset)
7322
948f632f
DA
7323/* Find the nearest symbol at or below ADDR. Returns the symbol
7324 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7325
4d6ed7c8 7326static void
dda8d76d
NC
7327find_symbol_for_address (Filedata * filedata,
7328 Elf_Internal_Sym * symtab,
7329 unsigned long nsyms,
7330 const char * strtab,
7331 unsigned long strtab_size,
7332 struct absaddr addr,
7333 const char ** symname,
7334 bfd_vma * offset)
4d6ed7c8 7335{
d3ba0551 7336 bfd_vma dist = 0x100000;
2cf0635d 7337 Elf_Internal_Sym * sym;
948f632f
DA
7338 Elf_Internal_Sym * beg;
7339 Elf_Internal_Sym * end;
2cf0635d 7340 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7341
0b6ae522 7342 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7343 beg = symtab;
7344 end = symtab + nsyms;
0b6ae522 7345
948f632f 7346 while (beg < end)
4d6ed7c8 7347 {
948f632f
DA
7348 bfd_vma value;
7349
7350 sym = beg + (end - beg) / 2;
0b6ae522 7351
948f632f 7352 value = sym->st_value;
0b6ae522
DJ
7353 REMOVE_ARCH_BITS (value);
7354
948f632f 7355 if (sym->st_name != 0
4d6ed7c8 7356 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7357 && addr.offset >= value
7358 && addr.offset - value < dist)
4d6ed7c8
NC
7359 {
7360 best = sym;
0b6ae522 7361 dist = addr.offset - value;
4d6ed7c8
NC
7362 if (!dist)
7363 break;
7364 }
948f632f
DA
7365
7366 if (addr.offset < value)
7367 end = sym;
7368 else
7369 beg = sym + 1;
4d6ed7c8 7370 }
1b31d05e 7371
4d6ed7c8
NC
7372 if (best)
7373 {
57346661 7374 *symname = (best->st_name >= strtab_size
2b692964 7375 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7376 *offset = dist;
7377 return;
7378 }
1b31d05e 7379
4d6ed7c8
NC
7380 *symname = NULL;
7381 *offset = addr.offset;
7382}
7383
32ec8896 7384static /* signed */ int
948f632f
DA
7385symcmp (const void *p, const void *q)
7386{
7387 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7388 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7389
7390 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7391}
7392
7393/* Process the unwind section. */
7394
7395#include "unwind-ia64.h"
7396
7397struct ia64_unw_table_entry
7398{
7399 struct absaddr start;
7400 struct absaddr end;
7401 struct absaddr info;
7402};
7403
7404struct ia64_unw_aux_info
7405{
32ec8896
NC
7406 struct ia64_unw_table_entry * table; /* Unwind table. */
7407 unsigned long table_len; /* Length of unwind table. */
7408 unsigned char * info; /* Unwind info. */
7409 unsigned long info_size; /* Size of unwind info. */
7410 bfd_vma info_addr; /* Starting address of unwind info. */
7411 bfd_vma seg_base; /* Starting address of segment. */
7412 Elf_Internal_Sym * symtab; /* The symbol table. */
7413 unsigned long nsyms; /* Number of symbols. */
7414 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7415 unsigned long nfuns; /* Number of entries in funtab. */
7416 char * strtab; /* The string table. */
7417 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7418};
7419
32ec8896 7420static bfd_boolean
dda8d76d 7421dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7422{
2cf0635d 7423 struct ia64_unw_table_entry * tp;
948f632f 7424 unsigned long j, nfuns;
4d6ed7c8 7425 int in_body;
32ec8896 7426 bfd_boolean res = TRUE;
7036c0e1 7427
948f632f
DA
7428 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7429 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7430 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7431 aux->funtab[nfuns++] = aux->symtab[j];
7432 aux->nfuns = nfuns;
7433 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7434
4d6ed7c8
NC
7435 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7436 {
7437 bfd_vma stamp;
7438 bfd_vma offset;
2cf0635d
NC
7439 const unsigned char * dp;
7440 const unsigned char * head;
53774b7e 7441 const unsigned char * end;
2cf0635d 7442 const char * procname;
4d6ed7c8 7443
dda8d76d 7444 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7445 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7446
7447 fputs ("\n<", stdout);
7448
7449 if (procname)
7450 {
7451 fputs (procname, stdout);
7452
7453 if (offset)
7454 printf ("+%lx", (unsigned long) offset);
7455 }
7456
7457 fputs (">: [", stdout);
7458 print_vma (tp->start.offset, PREFIX_HEX);
7459 fputc ('-', stdout);
7460 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7461 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7462 (unsigned long) (tp->info.offset - aux->seg_base));
7463
53774b7e
NC
7464 /* PR 17531: file: 86232b32. */
7465 if (aux->info == NULL)
7466 continue;
7467
7468 /* PR 17531: file: 0997b4d1. */
7469 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
7470 {
7471 warn (_("Invalid offset %lx in table entry %ld\n"),
7472 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7473 res = FALSE;
53774b7e
NC
7474 continue;
7475 }
7476
1949de15 7477 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 7478 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7479
86f55779 7480 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7481 (unsigned) UNW_VER (stamp),
7482 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7483 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7484 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7485 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7486
7487 if (UNW_VER (stamp) != 1)
7488 {
2b692964 7489 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7490 continue;
7491 }
7492
7493 in_body = 0;
53774b7e
NC
7494 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7495 /* PR 17531: file: 16ceda89. */
7496 if (end > aux->info + aux->info_size)
7497 end = aux->info + aux->info_size;
7498 for (dp = head + 8; dp < end;)
b4477bc8 7499 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7500 }
948f632f
DA
7501
7502 free (aux->funtab);
32ec8896
NC
7503
7504 return res;
4d6ed7c8
NC
7505}
7506
53774b7e 7507static bfd_boolean
dda8d76d
NC
7508slurp_ia64_unwind_table (Filedata * filedata,
7509 struct ia64_unw_aux_info * aux,
7510 Elf_Internal_Shdr * sec)
4d6ed7c8 7511{
89fac5e3 7512 unsigned long size, nrelas, i;
2cf0635d
NC
7513 Elf_Internal_Phdr * seg;
7514 struct ia64_unw_table_entry * tep;
7515 Elf_Internal_Shdr * relsec;
7516 Elf_Internal_Rela * rela;
7517 Elf_Internal_Rela * rp;
7518 unsigned char * table;
7519 unsigned char * tp;
7520 Elf_Internal_Sym * sym;
7521 const char * relname;
4d6ed7c8 7522
53774b7e
NC
7523 aux->table_len = 0;
7524
4d6ed7c8
NC
7525 /* First, find the starting address of the segment that includes
7526 this section: */
7527
dda8d76d 7528 if (filedata->file_header.e_phnum)
4d6ed7c8 7529 {
dda8d76d 7530 if (! get_program_headers (filedata))
53774b7e 7531 return FALSE;
4d6ed7c8 7532
dda8d76d
NC
7533 for (seg = filedata->program_headers;
7534 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7535 ++seg)
4d6ed7c8
NC
7536 {
7537 if (seg->p_type != PT_LOAD)
7538 continue;
7539
7540 if (sec->sh_addr >= seg->p_vaddr
7541 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7542 {
7543 aux->seg_base = seg->p_vaddr;
7544 break;
7545 }
7546 }
4d6ed7c8
NC
7547 }
7548
7549 /* Second, build the unwind table from the contents of the unwind section: */
7550 size = sec->sh_size;
dda8d76d 7551 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7552 _("unwind table"));
a6e9f9df 7553 if (!table)
53774b7e 7554 return FALSE;
4d6ed7c8 7555
53774b7e 7556 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7557 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7558 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7559 tep = aux->table;
53774b7e
NC
7560
7561 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7562 {
7563 tep->start.section = SHN_UNDEF;
7564 tep->end.section = SHN_UNDEF;
7565 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7566 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7567 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7568 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7569 tep->start.offset += aux->seg_base;
7570 tep->end.offset += aux->seg_base;
7571 tep->info.offset += aux->seg_base;
7572 }
7573 free (table);
7574
41e92641 7575 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7576 for (relsec = filedata->section_headers;
7577 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7578 ++relsec)
7579 {
7580 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7581 || relsec->sh_info >= filedata->file_header.e_shnum
7582 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7583 continue;
7584
dda8d76d 7585 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7586 & rela, & nrelas))
53774b7e
NC
7587 {
7588 free (aux->table);
7589 aux->table = NULL;
7590 aux->table_len = 0;
7591 return FALSE;
7592 }
4d6ed7c8
NC
7593
7594 for (rp = rela; rp < rela + nrelas; ++rp)
7595 {
dda8d76d 7596 relname = elf_ia64_reloc_type (get_reloc_type (filedata, rp->r_info));
aca88567 7597 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 7598
82b1b41b
NC
7599 /* PR 17531: file: 9fa67536. */
7600 if (relname == NULL)
7601 {
dda8d76d
NC
7602 warn (_("Skipping unknown relocation type: %u\n"),
7603 get_reloc_type (filedata, rp->r_info));
82b1b41b
NC
7604 continue;
7605 }
948f632f 7606
0112cd26 7607 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7608 {
82b1b41b 7609 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7610 continue;
7611 }
7612
89fac5e3 7613 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7614
53774b7e
NC
7615 /* PR 17531: file: 5bc8d9bf. */
7616 if (i >= aux->table_len)
7617 {
7618 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7619 continue;
7620 }
7621
7622 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7623 {
7624 case 0:
7625 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7626 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7627 break;
7628 case 1:
7629 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7630 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7631 break;
7632 case 2:
7633 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7634 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7635 break;
7636 default:
7637 break;
7638 }
7639 }
7640
7641 free (rela);
7642 }
7643
53774b7e 7644 return TRUE;
4d6ed7c8
NC
7645}
7646
32ec8896 7647static bfd_boolean
dda8d76d 7648ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7649{
2cf0635d
NC
7650 Elf_Internal_Shdr * sec;
7651 Elf_Internal_Shdr * unwsec = NULL;
7652 Elf_Internal_Shdr * strsec;
89fac5e3 7653 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7654 struct ia64_unw_aux_info aux;
32ec8896 7655 bfd_boolean res = TRUE;
f1467e33 7656
4d6ed7c8
NC
7657 memset (& aux, 0, sizeof (aux));
7658
dda8d76d 7659 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7660 {
c256ffe7 7661 if (sec->sh_type == SHT_SYMTAB
dda8d76d 7662 && sec->sh_link < filedata->file_header.e_shnum)
4d6ed7c8 7663 {
dda8d76d 7664 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
4d6ed7c8 7665
dda8d76d 7666 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
7667 if (aux.strtab != NULL)
7668 {
7669 error (_("Multiple auxillary string tables encountered\n"));
7670 free (aux.strtab);
32ec8896 7671 res = FALSE;
4082ef84 7672 }
dda8d76d 7673 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
7674 1, strsec->sh_size,
7675 _("string table"));
c256ffe7 7676 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
7677 }
7678 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7679 unwcount++;
7680 }
7681
7682 if (!unwcount)
7683 printf (_("\nThere are no unwind sections in this file.\n"));
7684
7685 while (unwcount-- > 0)
7686 {
2cf0635d 7687 char * suffix;
579f31ac
JJ
7688 size_t len, len2;
7689
dda8d76d
NC
7690 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
7691 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
7692 if (sec->sh_type == SHT_IA_64_UNWIND)
7693 {
7694 unwsec = sec;
7695 break;
7696 }
4082ef84
NC
7697 /* We have already counted the number of SHT_IA64_UNWIND
7698 sections so the loop above should never fail. */
7699 assert (unwsec != NULL);
579f31ac
JJ
7700
7701 unwstart = i + 1;
7702 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7703
e4b17d5c
L
7704 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7705 {
7706 /* We need to find which section group it is in. */
4082ef84 7707 struct group_list * g;
e4b17d5c 7708
4082ef84
NC
7709 if (section_headers_groups == NULL
7710 || section_headers_groups [i] == NULL)
dda8d76d 7711 i = filedata->file_header.e_shnum;
4082ef84 7712 else
e4b17d5c 7713 {
4082ef84 7714 g = section_headers_groups [i]->root;
18bd398b 7715
4082ef84
NC
7716 for (; g != NULL; g = g->next)
7717 {
dda8d76d 7718 sec = filedata->section_headers + g->section_index;
e4b17d5c 7719
4082ef84
NC
7720 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7721 break;
7722 }
7723
7724 if (g == NULL)
dda8d76d 7725 i = filedata->file_header.e_shnum;
4082ef84 7726 }
e4b17d5c 7727 }
18bd398b 7728 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7729 {
18bd398b 7730 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7731 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7732 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7733 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7734 ++i, ++sec)
18bd398b
NC
7735 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7736 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7737 break;
7738 }
7739 else
7740 {
7741 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7742 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7743 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7744 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7745 suffix = "";
18bd398b 7746 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 7747 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7748 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7749 ++i, ++sec)
18bd398b
NC
7750 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
7751 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7752 break;
7753 }
7754
dda8d76d 7755 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
7756 {
7757 printf (_("\nCould not find unwind info section for "));
7758
dda8d76d 7759 if (filedata->string_table == NULL)
579f31ac
JJ
7760 printf ("%d", unwsec->sh_name);
7761 else
dda8d76d 7762 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
7763 }
7764 else
4d6ed7c8 7765 {
4d6ed7c8 7766 aux.info_addr = sec->sh_addr;
dda8d76d 7767 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
7768 sec->sh_size,
7769 _("unwind info"));
59245841 7770 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 7771
579f31ac 7772 printf (_("\nUnwind section "));
4d6ed7c8 7773
dda8d76d 7774 if (filedata->string_table == NULL)
579f31ac
JJ
7775 printf ("%d", unwsec->sh_name);
7776 else
dda8d76d 7777 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 7778
579f31ac 7779 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 7780 (unsigned long) unwsec->sh_offset,
89fac5e3 7781 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 7782
dda8d76d 7783 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 7784 && aux.table_len > 0)
dda8d76d 7785 dump_ia64_unwind (filedata, & aux);
579f31ac
JJ
7786
7787 if (aux.table)
7788 free ((char *) aux.table);
7789 if (aux.info)
7790 free ((char *) aux.info);
7791 aux.table = NULL;
7792 aux.info = NULL;
7793 }
4d6ed7c8 7794 }
4d6ed7c8 7795
4d6ed7c8
NC
7796 if (aux.symtab)
7797 free (aux.symtab);
7798 if (aux.strtab)
7799 free ((char *) aux.strtab);
32ec8896
NC
7800
7801 return res;
4d6ed7c8
NC
7802}
7803
3f5e193b 7804struct hppa_unw_table_entry
32ec8896
NC
7805{
7806 struct absaddr start;
7807 struct absaddr end;
7808 unsigned int Cannot_unwind:1; /* 0 */
7809 unsigned int Millicode:1; /* 1 */
7810 unsigned int Millicode_save_sr0:1; /* 2 */
7811 unsigned int Region_description:2; /* 3..4 */
7812 unsigned int reserved1:1; /* 5 */
7813 unsigned int Entry_SR:1; /* 6 */
7814 unsigned int Entry_FR:4; /* Number saved 7..10 */
7815 unsigned int Entry_GR:5; /* Number saved 11..15 */
7816 unsigned int Args_stored:1; /* 16 */
7817 unsigned int Variable_Frame:1; /* 17 */
7818 unsigned int Separate_Package_Body:1; /* 18 */
7819 unsigned int Frame_Extension_Millicode:1; /* 19 */
7820 unsigned int Stack_Overflow_Check:1; /* 20 */
7821 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
7822 unsigned int Ada_Region:1; /* 22 */
7823 unsigned int cxx_info:1; /* 23 */
7824 unsigned int cxx_try_catch:1; /* 24 */
7825 unsigned int sched_entry_seq:1; /* 25 */
7826 unsigned int reserved2:1; /* 26 */
7827 unsigned int Save_SP:1; /* 27 */
7828 unsigned int Save_RP:1; /* 28 */
7829 unsigned int Save_MRP_in_frame:1; /* 29 */
7830 unsigned int extn_ptr_defined:1; /* 30 */
7831 unsigned int Cleanup_defined:1; /* 31 */
7832
7833 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
7834 unsigned int HP_UX_interrupt_marker:1; /* 1 */
7835 unsigned int Large_frame:1; /* 2 */
7836 unsigned int Pseudo_SP_Set:1; /* 3 */
7837 unsigned int reserved4:1; /* 4 */
7838 unsigned int Total_frame_size:27; /* 5..31 */
7839};
3f5e193b 7840
57346661 7841struct hppa_unw_aux_info
948f632f 7842{
32ec8896
NC
7843 struct hppa_unw_table_entry * table; /* Unwind table. */
7844 unsigned long table_len; /* Length of unwind table. */
7845 bfd_vma seg_base; /* Starting address of segment. */
7846 Elf_Internal_Sym * symtab; /* The symbol table. */
7847 unsigned long nsyms; /* Number of symbols. */
7848 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7849 unsigned long nfuns; /* Number of entries in funtab. */
7850 char * strtab; /* The string table. */
7851 unsigned long strtab_size; /* Size of string table. */
948f632f 7852};
57346661 7853
32ec8896 7854static bfd_boolean
dda8d76d 7855dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 7856{
2cf0635d 7857 struct hppa_unw_table_entry * tp;
948f632f 7858 unsigned long j, nfuns;
32ec8896 7859 bfd_boolean res = TRUE;
948f632f
DA
7860
7861 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7862 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7863 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7864 aux->funtab[nfuns++] = aux->symtab[j];
7865 aux->nfuns = nfuns;
7866 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 7867
57346661
AM
7868 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7869 {
7870 bfd_vma offset;
2cf0635d 7871 const char * procname;
57346661 7872
dda8d76d 7873 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
7874 aux->strtab_size, tp->start, &procname,
7875 &offset);
7876
7877 fputs ("\n<", stdout);
7878
7879 if (procname)
7880 {
7881 fputs (procname, stdout);
7882
7883 if (offset)
7884 printf ("+%lx", (unsigned long) offset);
7885 }
7886
7887 fputs (">: [", stdout);
7888 print_vma (tp->start.offset, PREFIX_HEX);
7889 fputc ('-', stdout);
7890 print_vma (tp->end.offset, PREFIX_HEX);
7891 printf ("]\n\t");
7892
18bd398b
NC
7893#define PF(_m) if (tp->_m) printf (#_m " ");
7894#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
7895 PF(Cannot_unwind);
7896 PF(Millicode);
7897 PF(Millicode_save_sr0);
18bd398b 7898 /* PV(Region_description); */
57346661
AM
7899 PF(Entry_SR);
7900 PV(Entry_FR);
7901 PV(Entry_GR);
7902 PF(Args_stored);
7903 PF(Variable_Frame);
7904 PF(Separate_Package_Body);
7905 PF(Frame_Extension_Millicode);
7906 PF(Stack_Overflow_Check);
7907 PF(Two_Instruction_SP_Increment);
7908 PF(Ada_Region);
7909 PF(cxx_info);
7910 PF(cxx_try_catch);
7911 PF(sched_entry_seq);
7912 PF(Save_SP);
7913 PF(Save_RP);
7914 PF(Save_MRP_in_frame);
7915 PF(extn_ptr_defined);
7916 PF(Cleanup_defined);
7917 PF(MPE_XL_interrupt_marker);
7918 PF(HP_UX_interrupt_marker);
7919 PF(Large_frame);
7920 PF(Pseudo_SP_Set);
7921 PV(Total_frame_size);
7922#undef PF
7923#undef PV
7924 }
7925
18bd398b 7926 printf ("\n");
948f632f
DA
7927
7928 free (aux->funtab);
32ec8896
NC
7929
7930 return res;
57346661
AM
7931}
7932
32ec8896 7933static bfd_boolean
dda8d76d
NC
7934slurp_hppa_unwind_table (Filedata * filedata,
7935 struct hppa_unw_aux_info * aux,
7936 Elf_Internal_Shdr * sec)
57346661 7937{
1c0751b2 7938 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7939 Elf_Internal_Phdr * seg;
7940 struct hppa_unw_table_entry * tep;
7941 Elf_Internal_Shdr * relsec;
7942 Elf_Internal_Rela * rela;
7943 Elf_Internal_Rela * rp;
7944 unsigned char * table;
7945 unsigned char * tp;
7946 Elf_Internal_Sym * sym;
7947 const char * relname;
57346661 7948
57346661
AM
7949 /* First, find the starting address of the segment that includes
7950 this section. */
dda8d76d 7951 if (filedata->file_header.e_phnum)
57346661 7952 {
dda8d76d 7953 if (! get_program_headers (filedata))
32ec8896 7954 return FALSE;
57346661 7955
dda8d76d
NC
7956 for (seg = filedata->program_headers;
7957 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
7958 ++seg)
7959 {
7960 if (seg->p_type != PT_LOAD)
7961 continue;
7962
7963 if (sec->sh_addr >= seg->p_vaddr
7964 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7965 {
7966 aux->seg_base = seg->p_vaddr;
7967 break;
7968 }
7969 }
7970 }
7971
7972 /* Second, build the unwind table from the contents of the unwind
7973 section. */
7974 size = sec->sh_size;
dda8d76d 7975 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7976 _("unwind table"));
57346661 7977 if (!table)
32ec8896 7978 return FALSE;
57346661 7979
1c0751b2
DA
7980 unw_ent_size = 16;
7981 nentries = size / unw_ent_size;
7982 size = unw_ent_size * nentries;
57346661 7983
3f5e193b
NC
7984 tep = aux->table = (struct hppa_unw_table_entry *)
7985 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7986
1c0751b2 7987 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7988 {
7989 unsigned int tmp1, tmp2;
7990
7991 tep->start.section = SHN_UNDEF;
7992 tep->end.section = SHN_UNDEF;
7993
1c0751b2
DA
7994 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7995 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7996 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7997 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7998
7999 tep->start.offset += aux->seg_base;
8000 tep->end.offset += aux->seg_base;
57346661
AM
8001
8002 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8003 tep->Millicode = (tmp1 >> 30) & 0x1;
8004 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8005 tep->Region_description = (tmp1 >> 27) & 0x3;
8006 tep->reserved1 = (tmp1 >> 26) & 0x1;
8007 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8008 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8009 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8010 tep->Args_stored = (tmp1 >> 15) & 0x1;
8011 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8012 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8013 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8014 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8015 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8016 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8017 tep->cxx_info = (tmp1 >> 8) & 0x1;
8018 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8019 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8020 tep->reserved2 = (tmp1 >> 5) & 0x1;
8021 tep->Save_SP = (tmp1 >> 4) & 0x1;
8022 tep->Save_RP = (tmp1 >> 3) & 0x1;
8023 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8024 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8025 tep->Cleanup_defined = tmp1 & 0x1;
8026
8027 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8028 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8029 tep->Large_frame = (tmp2 >> 29) & 0x1;
8030 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8031 tep->reserved4 = (tmp2 >> 27) & 0x1;
8032 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8033 }
8034 free (table);
8035
8036 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8037 for (relsec = filedata->section_headers;
8038 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8039 ++relsec)
8040 {
8041 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8042 || relsec->sh_info >= filedata->file_header.e_shnum
8043 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8044 continue;
8045
dda8d76d 8046 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8047 & rela, & nrelas))
32ec8896 8048 return FALSE;
57346661
AM
8049
8050 for (rp = rela; rp < rela + nrelas; ++rp)
8051 {
dda8d76d 8052 relname = elf_hppa_reloc_type (get_reloc_type (filedata, rp->r_info));
aca88567 8053 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
8054
8055 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8056 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
8057 {
8058 warn (_("Skipping unexpected relocation type %s\n"), relname);
8059 continue;
8060 }
8061
8062 i = rp->r_offset / unw_ent_size;
8063
89fac5e3 8064 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
8065 {
8066 case 0:
8067 aux->table[i].start.section = sym->st_shndx;
1e456d54 8068 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8069 break;
8070 case 1:
8071 aux->table[i].end.section = sym->st_shndx;
1e456d54 8072 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8073 break;
8074 default:
8075 break;
8076 }
8077 }
8078
8079 free (rela);
8080 }
8081
1c0751b2 8082 aux->table_len = nentries;
57346661 8083
32ec8896 8084 return TRUE;
57346661
AM
8085}
8086
32ec8896 8087static bfd_boolean
dda8d76d 8088hppa_process_unwind (Filedata * filedata)
57346661 8089{
57346661 8090 struct hppa_unw_aux_info aux;
2cf0635d
NC
8091 Elf_Internal_Shdr * unwsec = NULL;
8092 Elf_Internal_Shdr * strsec;
8093 Elf_Internal_Shdr * sec;
18bd398b 8094 unsigned long i;
32ec8896 8095 bfd_boolean res = TRUE;
57346661 8096
dda8d76d 8097 if (filedata->string_table == NULL)
32ec8896 8098 return FALSE;
1b31d05e
NC
8099
8100 memset (& aux, 0, sizeof (aux));
57346661 8101
dda8d76d 8102 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8103 {
c256ffe7 8104 if (sec->sh_type == SHT_SYMTAB
dda8d76d 8105 && sec->sh_link < filedata->file_header.e_shnum)
57346661 8106 {
dda8d76d 8107 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
57346661 8108
dda8d76d 8109 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
8110 if (aux.strtab != NULL)
8111 {
8112 error (_("Multiple auxillary string tables encountered\n"));
8113 free (aux.strtab);
32ec8896 8114 res = FALSE;
4082ef84 8115 }
dda8d76d 8116 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
8117 1, strsec->sh_size,
8118 _("string table"));
c256ffe7 8119 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 8120 }
18bd398b 8121 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8122 unwsec = sec;
8123 }
8124
8125 if (!unwsec)
8126 printf (_("\nThere are no unwind sections in this file.\n"));
8127
dda8d76d 8128 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8129 {
18bd398b 8130 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8131 {
d3a49aa8 8132 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size + 8);
dda8d76d 8133
d3a49aa8
AM
8134 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8135 "contains %lu entry:\n",
8136 "\nUnwind section '%s' at offset 0x%lx "
8137 "contains %lu entries:\n",
8138 num_unwind),
dda8d76d 8139 printable_section_name (filedata, sec),
57346661 8140 (unsigned long) sec->sh_offset,
d3a49aa8 8141 num_unwind);
57346661 8142
dda8d76d 8143 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8144 res = FALSE;
66b09c7e
S
8145
8146 if (res && aux.table_len > 0)
32ec8896 8147 {
dda8d76d 8148 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8149 res = FALSE;
8150 }
57346661
AM
8151
8152 if (aux.table)
8153 free ((char *) aux.table);
8154 aux.table = NULL;
8155 }
8156 }
8157
8158 if (aux.symtab)
8159 free (aux.symtab);
8160 if (aux.strtab)
8161 free ((char *) aux.strtab);
32ec8896
NC
8162
8163 return res;
57346661
AM
8164}
8165
0b6ae522
DJ
8166struct arm_section
8167{
a734115a
NC
8168 unsigned char * data; /* The unwind data. */
8169 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8170 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8171 unsigned long nrelas; /* The number of relocations. */
8172 unsigned int rel_type; /* REL or RELA ? */
8173 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8174};
8175
8176struct arm_unw_aux_info
8177{
dda8d76d 8178 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8179 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8180 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8181 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8182 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8183 char * strtab; /* The file's string table. */
8184 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8185};
8186
8187static const char *
dda8d76d
NC
8188arm_print_vma_and_name (Filedata * filedata,
8189 struct arm_unw_aux_info * aux,
8190 bfd_vma fn,
8191 struct absaddr addr)
0b6ae522
DJ
8192{
8193 const char *procname;
8194 bfd_vma sym_offset;
8195
8196 if (addr.section == SHN_UNDEF)
8197 addr.offset = fn;
8198
dda8d76d 8199 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8200 aux->strtab_size, addr, &procname,
8201 &sym_offset);
8202
8203 print_vma (fn, PREFIX_HEX);
8204
8205 if (procname)
8206 {
8207 fputs (" <", stdout);
8208 fputs (procname, stdout);
8209
8210 if (sym_offset)
8211 printf ("+0x%lx", (unsigned long) sym_offset);
8212 fputc ('>', stdout);
8213 }
8214
8215 return procname;
8216}
8217
8218static void
8219arm_free_section (struct arm_section *arm_sec)
8220{
8221 if (arm_sec->data != NULL)
8222 free (arm_sec->data);
8223
8224 if (arm_sec->rela != NULL)
8225 free (arm_sec->rela);
8226}
8227
a734115a
NC
8228/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8229 cached section and install SEC instead.
8230 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8231 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8232 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8233 relocation's offset in ADDR.
1b31d05e
NC
8234 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8235 into the string table of the symbol associated with the reloc. If no
8236 reloc was applied store -1 there.
8237 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8238
8239static bfd_boolean
dda8d76d
NC
8240get_unwind_section_word (Filedata * filedata,
8241 struct arm_unw_aux_info * aux,
1b31d05e
NC
8242 struct arm_section * arm_sec,
8243 Elf_Internal_Shdr * sec,
8244 bfd_vma word_offset,
8245 unsigned int * wordp,
8246 struct absaddr * addr,
8247 bfd_vma * sym_name)
0b6ae522
DJ
8248{
8249 Elf_Internal_Rela *rp;
8250 Elf_Internal_Sym *sym;
8251 const char * relname;
8252 unsigned int word;
8253 bfd_boolean wrapped;
8254
e0a31db1
NC
8255 if (sec == NULL || arm_sec == NULL)
8256 return FALSE;
8257
0b6ae522
DJ
8258 addr->section = SHN_UNDEF;
8259 addr->offset = 0;
8260
1b31d05e
NC
8261 if (sym_name != NULL)
8262 *sym_name = (bfd_vma) -1;
8263
a734115a 8264 /* If necessary, update the section cache. */
0b6ae522
DJ
8265 if (sec != arm_sec->sec)
8266 {
8267 Elf_Internal_Shdr *relsec;
8268
8269 arm_free_section (arm_sec);
8270
8271 arm_sec->sec = sec;
dda8d76d 8272 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8273 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8274 arm_sec->rela = NULL;
8275 arm_sec->nrelas = 0;
8276
dda8d76d
NC
8277 for (relsec = filedata->section_headers;
8278 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8279 ++relsec)
8280 {
dda8d76d
NC
8281 if (relsec->sh_info >= filedata->file_header.e_shnum
8282 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8283 /* PR 15745: Check the section type as well. */
8284 || (relsec->sh_type != SHT_REL
8285 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8286 continue;
8287
a734115a 8288 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8289 if (relsec->sh_type == SHT_REL)
8290 {
dda8d76d 8291 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8292 relsec->sh_size,
8293 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8294 return FALSE;
0b6ae522 8295 }
1ae40aa4 8296 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8297 {
dda8d76d 8298 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8299 relsec->sh_size,
8300 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8301 return FALSE;
0b6ae522 8302 }
1ae40aa4 8303 break;
0b6ae522
DJ
8304 }
8305
8306 arm_sec->next_rela = arm_sec->rela;
8307 }
8308
a734115a 8309 /* If there is no unwind data we can do nothing. */
0b6ae522 8310 if (arm_sec->data == NULL)
a734115a 8311 return FALSE;
0b6ae522 8312
e0a31db1 8313 /* If the offset is invalid then fail. */
f32ba729
NC
8314 if (/* PR 21343 *//* PR 18879 */
8315 sec->sh_size < 4
8316 || word_offset > (sec->sh_size - 4)
1a915552 8317 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8318 return FALSE;
8319
a734115a 8320 /* Get the word at the required offset. */
0b6ae522
DJ
8321 word = byte_get (arm_sec->data + word_offset, 4);
8322
0eff7165
NC
8323 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8324 if (arm_sec->rela == NULL)
8325 {
8326 * wordp = word;
8327 return TRUE;
8328 }
8329
a734115a 8330 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8331 wrapped = FALSE;
8332 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8333 {
8334 bfd_vma prelval, offset;
8335
8336 if (rp->r_offset > word_offset && !wrapped)
8337 {
8338 rp = arm_sec->rela;
8339 wrapped = TRUE;
8340 }
8341 if (rp->r_offset > word_offset)
8342 break;
8343
8344 if (rp->r_offset & 3)
8345 {
8346 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8347 (unsigned long) rp->r_offset);
8348 continue;
8349 }
8350
8351 if (rp->r_offset < word_offset)
8352 continue;
8353
74e1a04b
NC
8354 /* PR 17531: file: 027-161405-0.004 */
8355 if (aux->symtab == NULL)
8356 continue;
8357
0b6ae522
DJ
8358 if (arm_sec->rel_type == SHT_REL)
8359 {
8360 offset = word & 0x7fffffff;
8361 if (offset & 0x40000000)
8362 offset |= ~ (bfd_vma) 0x7fffffff;
8363 }
a734115a 8364 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8365 offset = rp->r_addend;
a734115a 8366 else
74e1a04b
NC
8367 {
8368 error (_("Unknown section relocation type %d encountered\n"),
8369 arm_sec->rel_type);
8370 break;
8371 }
0b6ae522 8372
071436c6
NC
8373 /* PR 17531 file: 027-1241568-0.004. */
8374 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8375 {
8376 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8377 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8378 break;
8379 }
8380
8381 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8382 offset += sym->st_value;
8383 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8384
a734115a 8385 /* Check that we are processing the expected reloc type. */
dda8d76d 8386 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8387 {
8388 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8389 if (relname == NULL)
8390 {
8391 warn (_("Skipping unknown ARM relocation type: %d\n"),
8392 (int) ELF32_R_TYPE (rp->r_info));
8393 continue;
8394 }
a734115a
NC
8395
8396 if (streq (relname, "R_ARM_NONE"))
8397 continue;
0b4362b0 8398
a734115a
NC
8399 if (! streq (relname, "R_ARM_PREL31"))
8400 {
071436c6 8401 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8402 continue;
8403 }
8404 }
dda8d76d 8405 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8406 {
8407 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8408 if (relname == NULL)
8409 {
8410 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8411 (int) ELF32_R_TYPE (rp->r_info));
8412 continue;
8413 }
0b4362b0 8414
a734115a
NC
8415 if (streq (relname, "R_C6000_NONE"))
8416 continue;
8417
8418 if (! streq (relname, "R_C6000_PREL31"))
8419 {
071436c6 8420 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8421 continue;
8422 }
8423
8424 prelval >>= 1;
8425 }
8426 else
74e1a04b
NC
8427 {
8428 /* This function currently only supports ARM and TI unwinders. */
8429 warn (_("Only TI and ARM unwinders are currently supported\n"));
8430 break;
8431 }
fa197c1c 8432
0b6ae522
DJ
8433 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8434 addr->section = sym->st_shndx;
8435 addr->offset = offset;
74e1a04b 8436
1b31d05e
NC
8437 if (sym_name)
8438 * sym_name = sym->st_name;
0b6ae522
DJ
8439 break;
8440 }
8441
8442 *wordp = word;
8443 arm_sec->next_rela = rp;
8444
a734115a 8445 return TRUE;
0b6ae522
DJ
8446}
8447
a734115a
NC
8448static const char *tic6x_unwind_regnames[16] =
8449{
0b4362b0
RM
8450 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8451 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8452 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8453};
fa197c1c 8454
0b6ae522 8455static void
fa197c1c 8456decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8457{
fa197c1c
PB
8458 int i;
8459
8460 for (i = 12; mask; mask >>= 1, i--)
8461 {
8462 if (mask & 1)
8463 {
8464 fputs (tic6x_unwind_regnames[i], stdout);
8465 if (mask > 1)
8466 fputs (", ", stdout);
8467 }
8468 }
8469}
0b6ae522
DJ
8470
8471#define ADVANCE \
8472 if (remaining == 0 && more_words) \
8473 { \
8474 data_offset += 4; \
dda8d76d 8475 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8476 data_offset, & word, & addr, NULL)) \
32ec8896 8477 return FALSE; \
0b6ae522
DJ
8478 remaining = 4; \
8479 more_words--; \
8480 } \
8481
8482#define GET_OP(OP) \
8483 ADVANCE; \
8484 if (remaining) \
8485 { \
8486 remaining--; \
8487 (OP) = word >> 24; \
8488 word <<= 8; \
8489 } \
8490 else \
8491 { \
2b692964 8492 printf (_("[Truncated opcode]\n")); \
32ec8896 8493 return FALSE; \
0b6ae522 8494 } \
cc5914eb 8495 printf ("0x%02x ", OP)
0b6ae522 8496
32ec8896 8497static bfd_boolean
dda8d76d
NC
8498decode_arm_unwind_bytecode (Filedata * filedata,
8499 struct arm_unw_aux_info * aux,
948f632f
DA
8500 unsigned int word,
8501 unsigned int remaining,
8502 unsigned int more_words,
8503 bfd_vma data_offset,
8504 Elf_Internal_Shdr * data_sec,
8505 struct arm_section * data_arm_sec)
fa197c1c
PB
8506{
8507 struct absaddr addr;
32ec8896 8508 bfd_boolean res = TRUE;
0b6ae522
DJ
8509
8510 /* Decode the unwinding instructions. */
8511 while (1)
8512 {
8513 unsigned int op, op2;
8514
8515 ADVANCE;
8516 if (remaining == 0)
8517 break;
8518 remaining--;
8519 op = word >> 24;
8520 word <<= 8;
8521
cc5914eb 8522 printf (" 0x%02x ", op);
0b6ae522
DJ
8523
8524 if ((op & 0xc0) == 0x00)
8525 {
8526 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8527
cc5914eb 8528 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8529 }
8530 else if ((op & 0xc0) == 0x40)
8531 {
8532 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8533
cc5914eb 8534 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8535 }
8536 else if ((op & 0xf0) == 0x80)
8537 {
8538 GET_OP (op2);
8539 if (op == 0x80 && op2 == 0)
8540 printf (_("Refuse to unwind"));
8541 else
8542 {
8543 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8544 bfd_boolean first = TRUE;
0b6ae522 8545 int i;
2b692964 8546
0b6ae522
DJ
8547 printf ("pop {");
8548 for (i = 0; i < 12; i++)
8549 if (mask & (1 << i))
8550 {
8551 if (first)
32ec8896 8552 first = FALSE;
0b6ae522
DJ
8553 else
8554 printf (", ");
8555 printf ("r%d", 4 + i);
8556 }
8557 printf ("}");
8558 }
8559 }
8560 else if ((op & 0xf0) == 0x90)
8561 {
8562 if (op == 0x9d || op == 0x9f)
8563 printf (_(" [Reserved]"));
8564 else
cc5914eb 8565 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8566 }
8567 else if ((op & 0xf0) == 0xa0)
8568 {
8569 int end = 4 + (op & 0x07);
32ec8896 8570 bfd_boolean first = TRUE;
0b6ae522 8571 int i;
61865e30 8572
0b6ae522
DJ
8573 printf (" pop {");
8574 for (i = 4; i <= end; i++)
8575 {
8576 if (first)
32ec8896 8577 first = FALSE;
0b6ae522
DJ
8578 else
8579 printf (", ");
8580 printf ("r%d", i);
8581 }
8582 if (op & 0x08)
8583 {
1b31d05e 8584 if (!first)
0b6ae522
DJ
8585 printf (", ");
8586 printf ("r14");
8587 }
8588 printf ("}");
8589 }
8590 else if (op == 0xb0)
8591 printf (_(" finish"));
8592 else if (op == 0xb1)
8593 {
8594 GET_OP (op2);
8595 if (op2 == 0 || (op2 & 0xf0) != 0)
8596 printf (_("[Spare]"));
8597 else
8598 {
8599 unsigned int mask = op2 & 0x0f;
32ec8896 8600 bfd_boolean first = TRUE;
0b6ae522 8601 int i;
61865e30 8602
0b6ae522
DJ
8603 printf ("pop {");
8604 for (i = 0; i < 12; i++)
8605 if (mask & (1 << i))
8606 {
8607 if (first)
32ec8896 8608 first = FALSE;
0b6ae522
DJ
8609 else
8610 printf (", ");
8611 printf ("r%d", i);
8612 }
8613 printf ("}");
8614 }
8615 }
8616 else if (op == 0xb2)
8617 {
b115cf96 8618 unsigned char buf[9];
0b6ae522
DJ
8619 unsigned int i, len;
8620 unsigned long offset;
61865e30 8621
b115cf96 8622 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8623 {
8624 GET_OP (buf[i]);
8625 if ((buf[i] & 0x80) == 0)
8626 break;
8627 }
4082ef84 8628 if (i == sizeof (buf))
32ec8896
NC
8629 {
8630 error (_("corrupt change to vsp"));
8631 res = FALSE;
8632 }
4082ef84
NC
8633 else
8634 {
8635 offset = read_uleb128 (buf, &len, buf + i + 1);
8636 assert (len == i + 1);
8637 offset = offset * 4 + 0x204;
8638 printf ("vsp = vsp + %ld", offset);
8639 }
0b6ae522 8640 }
61865e30 8641 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8642 {
61865e30
NC
8643 unsigned int first, last;
8644
8645 GET_OP (op2);
8646 first = op2 >> 4;
8647 last = op2 & 0x0f;
8648 if (op == 0xc8)
8649 first = first + 16;
8650 printf ("pop {D%d", first);
8651 if (last)
8652 printf ("-D%d", first + last);
8653 printf ("}");
8654 }
8655 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8656 {
8657 unsigned int count = op & 0x07;
8658
8659 printf ("pop {D8");
8660 if (count)
8661 printf ("-D%d", 8 + count);
8662 printf ("}");
8663 }
8664 else if (op >= 0xc0 && op <= 0xc5)
8665 {
8666 unsigned int count = op & 0x07;
8667
8668 printf (" pop {wR10");
8669 if (count)
8670 printf ("-wR%d", 10 + count);
8671 printf ("}");
8672 }
8673 else if (op == 0xc6)
8674 {
8675 unsigned int first, last;
8676
8677 GET_OP (op2);
8678 first = op2 >> 4;
8679 last = op2 & 0x0f;
8680 printf ("pop {wR%d", first);
8681 if (last)
8682 printf ("-wR%d", first + last);
8683 printf ("}");
8684 }
8685 else if (op == 0xc7)
8686 {
8687 GET_OP (op2);
8688 if (op2 == 0 || (op2 & 0xf0) != 0)
8689 printf (_("[Spare]"));
0b6ae522
DJ
8690 else
8691 {
61865e30 8692 unsigned int mask = op2 & 0x0f;
32ec8896 8693 bfd_boolean first = TRUE;
61865e30
NC
8694 int i;
8695
8696 printf ("pop {");
8697 for (i = 0; i < 4; i++)
8698 if (mask & (1 << i))
8699 {
8700 if (first)
32ec8896 8701 first = FALSE;
61865e30
NC
8702 else
8703 printf (", ");
8704 printf ("wCGR%d", i);
8705 }
8706 printf ("}");
0b6ae522
DJ
8707 }
8708 }
61865e30 8709 else
32ec8896
NC
8710 {
8711 printf (_(" [unsupported opcode]"));
8712 res = FALSE;
8713 }
8714
0b6ae522
DJ
8715 printf ("\n");
8716 }
32ec8896
NC
8717
8718 return res;
fa197c1c
PB
8719}
8720
32ec8896 8721static bfd_boolean
dda8d76d
NC
8722decode_tic6x_unwind_bytecode (Filedata * filedata,
8723 struct arm_unw_aux_info * aux,
948f632f
DA
8724 unsigned int word,
8725 unsigned int remaining,
8726 unsigned int more_words,
8727 bfd_vma data_offset,
8728 Elf_Internal_Shdr * data_sec,
8729 struct arm_section * data_arm_sec)
fa197c1c
PB
8730{
8731 struct absaddr addr;
8732
8733 /* Decode the unwinding instructions. */
8734 while (1)
8735 {
8736 unsigned int op, op2;
8737
8738 ADVANCE;
8739 if (remaining == 0)
8740 break;
8741 remaining--;
8742 op = word >> 24;
8743 word <<= 8;
8744
9cf03b7e 8745 printf (" 0x%02x ", op);
fa197c1c
PB
8746
8747 if ((op & 0xc0) == 0x00)
8748 {
8749 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 8750 printf (" sp = sp + %d", offset);
fa197c1c
PB
8751 }
8752 else if ((op & 0xc0) == 0x80)
8753 {
8754 GET_OP (op2);
8755 if (op == 0x80 && op2 == 0)
8756 printf (_("Refuse to unwind"));
8757 else
8758 {
8759 unsigned int mask = ((op & 0x1f) << 8) | op2;
8760 if (op & 0x20)
8761 printf ("pop compact {");
8762 else
8763 printf ("pop {");
8764
8765 decode_tic6x_unwind_regmask (mask);
8766 printf("}");
8767 }
8768 }
8769 else if ((op & 0xf0) == 0xc0)
8770 {
8771 unsigned int reg;
8772 unsigned int nregs;
8773 unsigned int i;
8774 const char *name;
a734115a
NC
8775 struct
8776 {
32ec8896
NC
8777 unsigned int offset;
8778 unsigned int reg;
fa197c1c
PB
8779 } regpos[16];
8780
8781 /* Scan entire instruction first so that GET_OP output is not
8782 interleaved with disassembly. */
8783 nregs = 0;
8784 for (i = 0; nregs < (op & 0xf); i++)
8785 {
8786 GET_OP (op2);
8787 reg = op2 >> 4;
8788 if (reg != 0xf)
8789 {
8790 regpos[nregs].offset = i * 2;
8791 regpos[nregs].reg = reg;
8792 nregs++;
8793 }
8794
8795 reg = op2 & 0xf;
8796 if (reg != 0xf)
8797 {
8798 regpos[nregs].offset = i * 2 + 1;
8799 regpos[nregs].reg = reg;
8800 nregs++;
8801 }
8802 }
8803
8804 printf (_("pop frame {"));
8805 reg = nregs - 1;
8806 for (i = i * 2; i > 0; i--)
8807 {
8808 if (regpos[reg].offset == i - 1)
8809 {
8810 name = tic6x_unwind_regnames[regpos[reg].reg];
8811 if (reg > 0)
8812 reg--;
8813 }
8814 else
8815 name = _("[pad]");
8816
8817 fputs (name, stdout);
8818 if (i > 1)
8819 printf (", ");
8820 }
8821
8822 printf ("}");
8823 }
8824 else if (op == 0xd0)
8825 printf (" MOV FP, SP");
8826 else if (op == 0xd1)
8827 printf (" __c6xabi_pop_rts");
8828 else if (op == 0xd2)
8829 {
8830 unsigned char buf[9];
8831 unsigned int i, len;
8832 unsigned long offset;
a734115a 8833
fa197c1c
PB
8834 for (i = 0; i < sizeof (buf); i++)
8835 {
8836 GET_OP (buf[i]);
8837 if ((buf[i] & 0x80) == 0)
8838 break;
8839 }
0eff7165
NC
8840 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
8841 if (i == sizeof (buf))
8842 {
0eff7165 8843 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 8844 return FALSE;
0eff7165 8845 }
948f632f 8846
f6f0e17b 8847 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
8848 assert (len == i + 1);
8849 offset = offset * 8 + 0x408;
8850 printf (_("sp = sp + %ld"), offset);
8851 }
8852 else if ((op & 0xf0) == 0xe0)
8853 {
8854 if ((op & 0x0f) == 7)
8855 printf (" RETURN");
8856 else
8857 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
8858 }
8859 else
8860 {
8861 printf (_(" [unsupported opcode]"));
8862 }
8863 putchar ('\n');
8864 }
32ec8896
NC
8865
8866 return TRUE;
fa197c1c
PB
8867}
8868
8869static bfd_vma
dda8d76d 8870arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
8871{
8872 bfd_vma offset;
8873
8874 offset = word & 0x7fffffff;
8875 if (offset & 0x40000000)
8876 offset |= ~ (bfd_vma) 0x7fffffff;
8877
dda8d76d 8878 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
8879 offset <<= 1;
8880
8881 return offset + where;
8882}
8883
32ec8896 8884static bfd_boolean
dda8d76d
NC
8885decode_arm_unwind (Filedata * filedata,
8886 struct arm_unw_aux_info * aux,
1b31d05e
NC
8887 unsigned int word,
8888 unsigned int remaining,
8889 bfd_vma data_offset,
8890 Elf_Internal_Shdr * data_sec,
8891 struct arm_section * data_arm_sec)
fa197c1c
PB
8892{
8893 int per_index;
8894 unsigned int more_words = 0;
37e14bc3 8895 struct absaddr addr;
1b31d05e 8896 bfd_vma sym_name = (bfd_vma) -1;
97953bab 8897 bfd_boolean res = TRUE;
fa197c1c
PB
8898
8899 if (remaining == 0)
8900 {
1b31d05e
NC
8901 /* Fetch the first word.
8902 Note - when decoding an object file the address extracted
8903 here will always be 0. So we also pass in the sym_name
8904 parameter so that we can find the symbol associated with
8905 the personality routine. */
dda8d76d 8906 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 8907 & word, & addr, & sym_name))
32ec8896 8908 return FALSE;
1b31d05e 8909
fa197c1c
PB
8910 remaining = 4;
8911 }
8912
8913 if ((word & 0x80000000) == 0)
8914 {
8915 /* Expand prel31 for personality routine. */
8916 bfd_vma fn;
8917 const char *procname;
8918
dda8d76d 8919 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 8920 printf (_(" Personality routine: "));
1b31d05e
NC
8921 if (fn == 0
8922 && addr.section == SHN_UNDEF && addr.offset == 0
8923 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
8924 {
8925 procname = aux->strtab + sym_name;
8926 print_vma (fn, PREFIX_HEX);
8927 if (procname)
8928 {
8929 fputs (" <", stdout);
8930 fputs (procname, stdout);
8931 fputc ('>', stdout);
8932 }
8933 }
8934 else
dda8d76d 8935 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
8936 fputc ('\n', stdout);
8937
8938 /* The GCC personality routines use the standard compact
8939 encoding, starting with one byte giving the number of
8940 words. */
8941 if (procname != NULL
8942 && (const_strneq (procname, "__gcc_personality_v0")
8943 || const_strneq (procname, "__gxx_personality_v0")
8944 || const_strneq (procname, "__gcj_personality_v0")
8945 || const_strneq (procname, "__gnu_objc_personality_v0")))
8946 {
8947 remaining = 0;
8948 more_words = 1;
8949 ADVANCE;
8950 if (!remaining)
8951 {
8952 printf (_(" [Truncated data]\n"));
32ec8896 8953 return FALSE;
fa197c1c
PB
8954 }
8955 more_words = word >> 24;
8956 word <<= 8;
8957 remaining--;
8958 per_index = -1;
8959 }
8960 else
32ec8896 8961 return TRUE;
fa197c1c
PB
8962 }
8963 else
8964 {
1b31d05e 8965 /* ARM EHABI Section 6.3:
0b4362b0 8966
1b31d05e 8967 An exception-handling table entry for the compact model looks like:
0b4362b0 8968
1b31d05e
NC
8969 31 30-28 27-24 23-0
8970 -- ----- ----- ----
8971 1 0 index Data for personalityRoutine[index] */
8972
dda8d76d 8973 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 8974 && (word & 0x70000000))
32ec8896
NC
8975 {
8976 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
8977 res = FALSE;
8978 }
1b31d05e 8979
fa197c1c 8980 per_index = (word >> 24) & 0x7f;
1b31d05e 8981 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
8982 if (per_index == 0)
8983 {
8984 more_words = 0;
8985 word <<= 8;
8986 remaining--;
8987 }
8988 else if (per_index < 3)
8989 {
8990 more_words = (word >> 16) & 0xff;
8991 word <<= 16;
8992 remaining -= 2;
8993 }
8994 }
8995
dda8d76d 8996 switch (filedata->file_header.e_machine)
fa197c1c
PB
8997 {
8998 case EM_ARM:
8999 if (per_index < 3)
9000 {
dda8d76d 9001 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9002 data_offset, data_sec, data_arm_sec))
9003 res = FALSE;
fa197c1c
PB
9004 }
9005 else
1b31d05e
NC
9006 {
9007 warn (_("Unknown ARM compact model index encountered\n"));
9008 printf (_(" [reserved]\n"));
32ec8896 9009 res = FALSE;
1b31d05e 9010 }
fa197c1c
PB
9011 break;
9012
9013 case EM_TI_C6000:
9014 if (per_index < 3)
9015 {
dda8d76d 9016 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9017 data_offset, data_sec, data_arm_sec))
9018 res = FALSE;
fa197c1c
PB
9019 }
9020 else if (per_index < 5)
9021 {
9022 if (((word >> 17) & 0x7f) == 0x7f)
9023 printf (_(" Restore stack from frame pointer\n"));
9024 else
9025 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9026 printf (_(" Registers restored: "));
9027 if (per_index == 4)
9028 printf (" (compact) ");
9029 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9030 putchar ('\n');
9031 printf (_(" Return register: %s\n"),
9032 tic6x_unwind_regnames[word & 0xf]);
9033 }
9034 else
1b31d05e 9035 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9036 break;
9037
9038 default:
74e1a04b 9039 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9040 filedata->file_header.e_machine);
32ec8896 9041 res = FALSE;
fa197c1c 9042 }
0b6ae522
DJ
9043
9044 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9045
9046 return res;
0b6ae522
DJ
9047}
9048
32ec8896 9049static bfd_boolean
dda8d76d
NC
9050dump_arm_unwind (Filedata * filedata,
9051 struct arm_unw_aux_info * aux,
9052 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9053{
9054 struct arm_section exidx_arm_sec, extab_arm_sec;
9055 unsigned int i, exidx_len;
948f632f 9056 unsigned long j, nfuns;
32ec8896 9057 bfd_boolean res = TRUE;
0b6ae522
DJ
9058
9059 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9060 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9061 exidx_len = exidx_sec->sh_size / 8;
9062
948f632f
DA
9063 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9064 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9065 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9066 aux->funtab[nfuns++] = aux->symtab[j];
9067 aux->nfuns = nfuns;
9068 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9069
0b6ae522
DJ
9070 for (i = 0; i < exidx_len; i++)
9071 {
9072 unsigned int exidx_fn, exidx_entry;
9073 struct absaddr fn_addr, entry_addr;
9074 bfd_vma fn;
9075
9076 fputc ('\n', stdout);
9077
dda8d76d 9078 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9079 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9080 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9081 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9082 {
948f632f 9083 free (aux->funtab);
1b31d05e
NC
9084 arm_free_section (& exidx_arm_sec);
9085 arm_free_section (& extab_arm_sec);
32ec8896 9086 return FALSE;
0b6ae522
DJ
9087 }
9088
83c257ca
NC
9089 /* ARM EHABI, Section 5:
9090 An index table entry consists of 2 words.
9091 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9092 if (exidx_fn & 0x80000000)
32ec8896
NC
9093 {
9094 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9095 res = FALSE;
9096 }
83c257ca 9097
dda8d76d 9098 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9099
dda8d76d 9100 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9101 fputs (": ", stdout);
9102
9103 if (exidx_entry == 1)
9104 {
9105 print_vma (exidx_entry, PREFIX_HEX);
9106 fputs (" [cantunwind]\n", stdout);
9107 }
9108 else if (exidx_entry & 0x80000000)
9109 {
9110 print_vma (exidx_entry, PREFIX_HEX);
9111 fputc ('\n', stdout);
dda8d76d 9112 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9113 }
9114 else
9115 {
8f73510c 9116 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9117 Elf_Internal_Shdr *table_sec;
9118
9119 fputs ("@", stdout);
dda8d76d 9120 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9121 print_vma (table, PREFIX_HEX);
9122 printf ("\n");
9123
9124 /* Locate the matching .ARM.extab. */
9125 if (entry_addr.section != SHN_UNDEF
dda8d76d 9126 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9127 {
dda8d76d 9128 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9129 table_offset = entry_addr.offset;
1a915552
NC
9130 /* PR 18879 */
9131 if (table_offset > table_sec->sh_size
9132 || ((bfd_signed_vma) table_offset) < 0)
9133 {
9134 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9135 (unsigned long) table_offset,
dda8d76d 9136 printable_section_name (filedata, table_sec));
32ec8896 9137 res = FALSE;
1a915552
NC
9138 continue;
9139 }
0b6ae522
DJ
9140 }
9141 else
9142 {
dda8d76d 9143 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9144 if (table_sec != NULL)
9145 table_offset = table - table_sec->sh_addr;
9146 }
32ec8896 9147
0b6ae522
DJ
9148 if (table_sec == NULL)
9149 {
9150 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9151 (unsigned long) table);
32ec8896 9152 res = FALSE;
0b6ae522
DJ
9153 continue;
9154 }
32ec8896 9155
dda8d76d 9156 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9157 &extab_arm_sec))
9158 res = FALSE;
0b6ae522
DJ
9159 }
9160 }
9161
9162 printf ("\n");
9163
948f632f 9164 free (aux->funtab);
0b6ae522
DJ
9165 arm_free_section (&exidx_arm_sec);
9166 arm_free_section (&extab_arm_sec);
32ec8896
NC
9167
9168 return res;
0b6ae522
DJ
9169}
9170
fa197c1c 9171/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9172
32ec8896 9173static bfd_boolean
dda8d76d 9174arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9175{
9176 struct arm_unw_aux_info aux;
9177 Elf_Internal_Shdr *unwsec = NULL;
9178 Elf_Internal_Shdr *strsec;
9179 Elf_Internal_Shdr *sec;
9180 unsigned long i;
fa197c1c 9181 unsigned int sec_type;
32ec8896 9182 bfd_boolean res = TRUE;
0b6ae522 9183
dda8d76d 9184 switch (filedata->file_header.e_machine)
fa197c1c
PB
9185 {
9186 case EM_ARM:
9187 sec_type = SHT_ARM_EXIDX;
9188 break;
9189
9190 case EM_TI_C6000:
9191 sec_type = SHT_C6000_UNWIND;
9192 break;
9193
0b4362b0 9194 default:
74e1a04b 9195 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9196 filedata->file_header.e_machine);
32ec8896 9197 return FALSE;
fa197c1c
PB
9198 }
9199
dda8d76d 9200 if (filedata->string_table == NULL)
32ec8896 9201 return FALSE;
1b31d05e
NC
9202
9203 memset (& aux, 0, sizeof (aux));
dda8d76d 9204 aux.filedata = filedata;
0b6ae522 9205
dda8d76d 9206 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9207 {
dda8d76d 9208 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < filedata->file_header.e_shnum)
0b6ae522 9209 {
dda8d76d 9210 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
0b6ae522 9211
dda8d76d 9212 strsec = filedata->section_headers + sec->sh_link;
74e1a04b
NC
9213
9214 /* PR binutils/17531 file: 011-12666-0.004. */
9215 if (aux.strtab != NULL)
9216 {
4082ef84 9217 error (_("Multiple string tables found in file.\n"));
74e1a04b 9218 free (aux.strtab);
32ec8896 9219 res = FALSE;
74e1a04b 9220 }
dda8d76d 9221 aux.strtab = get_data (NULL, filedata, strsec->sh_offset,
0b6ae522
DJ
9222 1, strsec->sh_size, _("string table"));
9223 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
9224 }
fa197c1c 9225 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9226 unwsec = sec;
9227 }
9228
1b31d05e 9229 if (unwsec == NULL)
0b6ae522 9230 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9231 else
dda8d76d 9232 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9233 {
9234 if (sec->sh_type == sec_type)
9235 {
d3a49aa8
AM
9236 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9237 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9238 "contains %lu entry:\n",
9239 "\nUnwind section '%s' at offset 0x%lx "
9240 "contains %lu entries:\n",
9241 num_unwind),
dda8d76d 9242 printable_section_name (filedata, sec),
1b31d05e 9243 (unsigned long) sec->sh_offset,
d3a49aa8 9244 num_unwind);
0b6ae522 9245
dda8d76d 9246 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9247 res = FALSE;
1b31d05e
NC
9248 }
9249 }
0b6ae522
DJ
9250
9251 if (aux.symtab)
9252 free (aux.symtab);
9253 if (aux.strtab)
9254 free ((char *) aux.strtab);
32ec8896
NC
9255
9256 return res;
0b6ae522
DJ
9257}
9258
32ec8896 9259static bfd_boolean
dda8d76d 9260process_unwind (Filedata * filedata)
57346661 9261{
2cf0635d
NC
9262 struct unwind_handler
9263 {
32ec8896 9264 unsigned int machtype;
dda8d76d 9265 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9266 } handlers[] =
9267 {
0b6ae522 9268 { EM_ARM, arm_process_unwind },
57346661
AM
9269 { EM_IA_64, ia64_process_unwind },
9270 { EM_PARISC, hppa_process_unwind },
fa197c1c 9271 { EM_TI_C6000, arm_process_unwind },
32ec8896 9272 { 0, NULL }
57346661
AM
9273 };
9274 int i;
9275
9276 if (!do_unwind)
32ec8896 9277 return TRUE;
57346661
AM
9278
9279 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9280 if (filedata->file_header.e_machine == handlers[i].machtype)
9281 return handlers[i].handler (filedata);
57346661 9282
1b31d05e 9283 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9284 get_machine_name (filedata->file_header.e_machine));
32ec8896 9285 return TRUE;
57346661
AM
9286}
9287
252b5132 9288static void
2cf0635d 9289dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
9290{
9291 switch (entry->d_tag)
9292 {
9293 case DT_MIPS_FLAGS:
9294 if (entry->d_un.d_val == 0)
4b68bca3 9295 printf (_("NONE"));
252b5132
RH
9296 else
9297 {
9298 static const char * opts[] =
9299 {
9300 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9301 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9302 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9303 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9304 "RLD_ORDER_SAFE"
9305 };
9306 unsigned int cnt;
32ec8896 9307 bfd_boolean first = TRUE;
2b692964 9308
60bca95a 9309 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9310 if (entry->d_un.d_val & (1 << cnt))
9311 {
9312 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9313 first = FALSE;
252b5132 9314 }
252b5132
RH
9315 }
9316 break;
103f02d3 9317
252b5132 9318 case DT_MIPS_IVERSION:
d79b3d50 9319 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 9320 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9321 else
76ca31c0
NC
9322 {
9323 char buf[40];
9324 sprintf_vma (buf, entry->d_un.d_ptr);
9325 /* Note: coded this way so that there is a single string for translation. */
9326 printf (_("<corrupt: %s>"), buf);
9327 }
252b5132 9328 break;
103f02d3 9329
252b5132
RH
9330 case DT_MIPS_TIME_STAMP:
9331 {
d5b07ef4 9332 char timebuf[128];
2cf0635d 9333 struct tm * tmp;
91d6fa6a 9334 time_t atime = entry->d_un.d_val;
82b1b41b 9335
91d6fa6a 9336 tmp = gmtime (&atime);
82b1b41b
NC
9337 /* PR 17531: file: 6accc532. */
9338 if (tmp == NULL)
9339 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9340 else
9341 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9342 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9343 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9344 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9345 }
9346 break;
103f02d3 9347
252b5132
RH
9348 case DT_MIPS_RLD_VERSION:
9349 case DT_MIPS_LOCAL_GOTNO:
9350 case DT_MIPS_CONFLICTNO:
9351 case DT_MIPS_LIBLISTNO:
9352 case DT_MIPS_SYMTABNO:
9353 case DT_MIPS_UNREFEXTNO:
9354 case DT_MIPS_HIPAGENO:
9355 case DT_MIPS_DELTA_CLASS_NO:
9356 case DT_MIPS_DELTA_INSTANCE_NO:
9357 case DT_MIPS_DELTA_RELOC_NO:
9358 case DT_MIPS_DELTA_SYM_NO:
9359 case DT_MIPS_DELTA_CLASSSYM_NO:
9360 case DT_MIPS_COMPACT_SIZE:
c69075ac 9361 print_vma (entry->d_un.d_val, DEC);
252b5132 9362 break;
103f02d3
UD
9363
9364 default:
4b68bca3 9365 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9366 }
4b68bca3 9367 putchar ('\n');
103f02d3
UD
9368}
9369
103f02d3 9370static void
2cf0635d 9371dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9372{
9373 switch (entry->d_tag)
9374 {
9375 case DT_HP_DLD_FLAGS:
9376 {
9377 static struct
9378 {
9379 long int bit;
2cf0635d 9380 const char * str;
5e220199
NC
9381 }
9382 flags[] =
9383 {
9384 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9385 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9386 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9387 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9388 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9389 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9390 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9391 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9392 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9393 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9394 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9395 { DT_HP_GST, "HP_GST" },
9396 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9397 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9398 { DT_HP_NODELETE, "HP_NODELETE" },
9399 { DT_HP_GROUP, "HP_GROUP" },
9400 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9401 };
32ec8896 9402 bfd_boolean first = TRUE;
5e220199 9403 size_t cnt;
f7a99963 9404 bfd_vma val = entry->d_un.d_val;
103f02d3 9405
60bca95a 9406 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9407 if (val & flags[cnt].bit)
30800947
NC
9408 {
9409 if (! first)
9410 putchar (' ');
9411 fputs (flags[cnt].str, stdout);
32ec8896 9412 first = FALSE;
30800947
NC
9413 val ^= flags[cnt].bit;
9414 }
76da6bbe 9415
103f02d3 9416 if (val != 0 || first)
f7a99963
NC
9417 {
9418 if (! first)
9419 putchar (' ');
9420 print_vma (val, HEX);
9421 }
103f02d3
UD
9422 }
9423 break;
76da6bbe 9424
252b5132 9425 default:
f7a99963
NC
9426 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9427 break;
252b5132 9428 }
35b1837e 9429 putchar ('\n');
252b5132
RH
9430}
9431
28f997cf
TG
9432#ifdef BFD64
9433
9434/* VMS vs Unix time offset and factor. */
9435
9436#define VMS_EPOCH_OFFSET 35067168000000000LL
9437#define VMS_GRANULARITY_FACTOR 10000000
9438
9439/* Display a VMS time in a human readable format. */
9440
9441static void
9442print_vms_time (bfd_int64_t vmstime)
9443{
9444 struct tm *tm;
9445 time_t unxtime;
9446
9447 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9448 tm = gmtime (&unxtime);
9449 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9450 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9451 tm->tm_hour, tm->tm_min, tm->tm_sec);
9452}
9453#endif /* BFD64 */
9454
ecc51f48 9455static void
2cf0635d 9456dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9457{
9458 switch (entry->d_tag)
9459 {
0de14b54 9460 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9461 /* First 3 slots reserved. */
ecc51f48
NC
9462 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9463 printf (" -- ");
9464 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9465 break;
9466
28f997cf
TG
9467 case DT_IA_64_VMS_LINKTIME:
9468#ifdef BFD64
9469 print_vms_time (entry->d_un.d_val);
9470#endif
9471 break;
9472
9473 case DT_IA_64_VMS_LNKFLAGS:
9474 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9475 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9476 printf (" CALL_DEBUG");
9477 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9478 printf (" NOP0BUFS");
9479 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9480 printf (" P0IMAGE");
9481 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9482 printf (" MKTHREADS");
9483 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9484 printf (" UPCALLS");
9485 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9486 printf (" IMGSTA");
9487 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9488 printf (" INITIALIZE");
9489 if (entry->d_un.d_val & VMS_LF_MAIN)
9490 printf (" MAIN");
9491 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9492 printf (" EXE_INIT");
9493 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9494 printf (" TBK_IN_IMG");
9495 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9496 printf (" DBG_IN_IMG");
9497 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9498 printf (" TBK_IN_DSF");
9499 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9500 printf (" DBG_IN_DSF");
9501 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9502 printf (" SIGNATURES");
9503 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9504 printf (" REL_SEG_OFF");
9505 break;
9506
bdf4d63a
JJ
9507 default:
9508 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9509 break;
ecc51f48 9510 }
bdf4d63a 9511 putchar ('\n');
ecc51f48
NC
9512}
9513
32ec8896 9514static bfd_boolean
dda8d76d 9515get_32bit_dynamic_section (Filedata * filedata)
252b5132 9516{
2cf0635d
NC
9517 Elf32_External_Dyn * edyn;
9518 Elf32_External_Dyn * ext;
9519 Elf_Internal_Dyn * entry;
103f02d3 9520
dda8d76d 9521 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9522 dynamic_size, _("dynamic section"));
a6e9f9df 9523 if (!edyn)
32ec8896 9524 return FALSE;
103f02d3 9525
071436c6
NC
9526 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9527 might not have the luxury of section headers. Look for the DT_NULL
9528 terminator to determine the number of entries. */
ba2685cc 9529 for (ext = edyn, dynamic_nent = 0;
53c3012c 9530 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9531 ext++)
9532 {
9533 dynamic_nent++;
9534 if (BYTE_GET (ext->d_tag) == DT_NULL)
9535 break;
9536 }
252b5132 9537
3f5e193b
NC
9538 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9539 sizeof (* entry));
b2d38a17 9540 if (dynamic_section == NULL)
252b5132 9541 {
8b73c356
NC
9542 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9543 (unsigned long) dynamic_nent);
9ea033b2 9544 free (edyn);
32ec8896 9545 return FALSE;
9ea033b2 9546 }
252b5132 9547
fb514b26 9548 for (ext = edyn, entry = dynamic_section;
ba2685cc 9549 entry < dynamic_section + dynamic_nent;
fb514b26 9550 ext++, entry++)
9ea033b2 9551 {
fb514b26
AM
9552 entry->d_tag = BYTE_GET (ext->d_tag);
9553 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9554 }
9555
9ea033b2
NC
9556 free (edyn);
9557
32ec8896 9558 return TRUE;
9ea033b2
NC
9559}
9560
32ec8896 9561static bfd_boolean
dda8d76d 9562get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9563{
2cf0635d
NC
9564 Elf64_External_Dyn * edyn;
9565 Elf64_External_Dyn * ext;
9566 Elf_Internal_Dyn * entry;
103f02d3 9567
071436c6 9568 /* Read in the data. */
dda8d76d 9569 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9570 dynamic_size, _("dynamic section"));
a6e9f9df 9571 if (!edyn)
32ec8896 9572 return FALSE;
103f02d3 9573
071436c6
NC
9574 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9575 might not have the luxury of section headers. Look for the DT_NULL
9576 terminator to determine the number of entries. */
ba2685cc 9577 for (ext = edyn, dynamic_nent = 0;
53c3012c
AM
9578 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
9579 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9580 ext++)
9581 {
9582 dynamic_nent++;
66543521 9583 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9584 break;
9585 }
252b5132 9586
3f5e193b
NC
9587 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9588 sizeof (* entry));
b2d38a17 9589 if (dynamic_section == NULL)
252b5132 9590 {
8b73c356
NC
9591 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9592 (unsigned long) dynamic_nent);
252b5132 9593 free (edyn);
32ec8896 9594 return FALSE;
252b5132
RH
9595 }
9596
071436c6 9597 /* Convert from external to internal formats. */
fb514b26 9598 for (ext = edyn, entry = dynamic_section;
ba2685cc 9599 entry < dynamic_section + dynamic_nent;
fb514b26 9600 ext++, entry++)
252b5132 9601 {
66543521
AM
9602 entry->d_tag = BYTE_GET (ext->d_tag);
9603 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9604 }
9605
9606 free (edyn);
9607
32ec8896 9608 return TRUE;
9ea033b2
NC
9609}
9610
e9e44622
JJ
9611static void
9612print_dynamic_flags (bfd_vma flags)
d1133906 9613{
32ec8896 9614 bfd_boolean first = TRUE;
13ae64f3 9615
d1133906
NC
9616 while (flags)
9617 {
9618 bfd_vma flag;
9619
9620 flag = flags & - flags;
9621 flags &= ~ flag;
9622
e9e44622 9623 if (first)
32ec8896 9624 first = FALSE;
e9e44622
JJ
9625 else
9626 putc (' ', stdout);
13ae64f3 9627
d1133906
NC
9628 switch (flag)
9629 {
e9e44622
JJ
9630 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9631 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9632 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9633 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9634 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9635 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9636 }
9637 }
e9e44622 9638 puts ("");
d1133906
NC
9639}
9640
b2d38a17
NC
9641/* Parse and display the contents of the dynamic section. */
9642
32ec8896 9643static bfd_boolean
dda8d76d 9644process_dynamic_section (Filedata * filedata)
9ea033b2 9645{
2cf0635d 9646 Elf_Internal_Dyn * entry;
9ea033b2
NC
9647
9648 if (dynamic_size == 0)
9649 {
9650 if (do_dynamic)
b2d38a17 9651 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 9652
32ec8896 9653 return TRUE;
9ea033b2
NC
9654 }
9655
9656 if (is_32bit_elf)
9657 {
dda8d76d 9658 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
9659 return FALSE;
9660 }
9661 else
9662 {
dda8d76d 9663 if (! get_64bit_dynamic_section (filedata))
32ec8896 9664 return FALSE;
9ea033b2 9665 }
9ea033b2 9666
252b5132
RH
9667 /* Find the appropriate symbol table. */
9668 if (dynamic_symbols == NULL)
9669 {
86dba8ee
AM
9670 for (entry = dynamic_section;
9671 entry < dynamic_section + dynamic_nent;
9672 ++entry)
252b5132 9673 {
c8286bd1 9674 Elf_Internal_Shdr section;
252b5132
RH
9675
9676 if (entry->d_tag != DT_SYMTAB)
9677 continue;
9678
9679 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
9680
9681 /* Since we do not know how big the symbol table is,
9682 we default to reading in the entire file (!) and
9683 processing that. This is overkill, I know, but it
e3c8793a 9684 should work. */
dda8d76d
NC
9685 section.sh_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
9686 if ((bfd_size_type) section.sh_offset > filedata->file_size)
7296a62a
NC
9687 {
9688 /* See PR 21379 for a reproducer. */
9689 error (_("Invalid DT_SYMTAB entry: %lx"), (long) section.sh_offset);
9690 return FALSE;
9691 }
252b5132 9692
fb52b2f4
NC
9693 if (archive_file_offset != 0)
9694 section.sh_size = archive_file_size - section.sh_offset;
9695 else
dda8d76d 9696 section.sh_size = filedata->file_size - section.sh_offset;
252b5132 9697
9ea033b2 9698 if (is_32bit_elf)
9ad5cbcf 9699 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 9700 else
9ad5cbcf 9701 section.sh_entsize = sizeof (Elf64_External_Sym);
dda8d76d 9702 section.sh_name = filedata->string_table_length;
252b5132 9703
e3d39609
NC
9704 if (dynamic_symbols != NULL)
9705 {
9706 error (_("Multiple dynamic symbol table sections found\n"));
9707 free (dynamic_symbols);
9708 }
dda8d76d 9709 dynamic_symbols = GET_ELF_SYMBOLS (filedata, &section, & num_dynamic_syms);
19936277 9710 if (num_dynamic_syms < 1)
252b5132
RH
9711 {
9712 error (_("Unable to determine the number of symbols to load\n"));
9713 continue;
9714 }
252b5132
RH
9715 }
9716 }
9717
9718 /* Similarly find a string table. */
9719 if (dynamic_strings == NULL)
9720 {
86dba8ee
AM
9721 for (entry = dynamic_section;
9722 entry < dynamic_section + dynamic_nent;
9723 ++entry)
252b5132
RH
9724 {
9725 unsigned long offset;
b34976b6 9726 long str_tab_len;
252b5132
RH
9727
9728 if (entry->d_tag != DT_STRTAB)
9729 continue;
9730
9731 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
9732
9733 /* Since we do not know how big the string table is,
9734 we default to reading in the entire file (!) and
9735 processing that. This is overkill, I know, but it
e3c8793a 9736 should work. */
252b5132 9737
dda8d76d 9738 offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
fb52b2f4
NC
9739
9740 if (archive_file_offset != 0)
9741 str_tab_len = archive_file_size - offset;
9742 else
86c6c6df 9743 str_tab_len = filedata->file_size - offset;
252b5132
RH
9744
9745 if (str_tab_len < 1)
9746 {
9747 error
9748 (_("Unable to determine the length of the dynamic string table\n"));
9749 continue;
9750 }
9751
e3d39609
NC
9752 if (dynamic_strings != NULL)
9753 {
9754 error (_("Multiple dynamic string tables found\n"));
9755 free (dynamic_strings);
9756 }
9757
dda8d76d 9758 dynamic_strings = (char *) get_data (NULL, filedata, offset, 1,
3f5e193b
NC
9759 str_tab_len,
9760 _("dynamic string table"));
59245841 9761 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
9762 }
9763 }
9764
9765 /* And find the syminfo section if available. */
9766 if (dynamic_syminfo == NULL)
9767 {
3e8bba36 9768 unsigned long syminsz = 0;
252b5132 9769
86dba8ee
AM
9770 for (entry = dynamic_section;
9771 entry < dynamic_section + dynamic_nent;
9772 ++entry)
252b5132
RH
9773 {
9774 if (entry->d_tag == DT_SYMINENT)
9775 {
9776 /* Note: these braces are necessary to avoid a syntax
9777 error from the SunOS4 C compiler. */
049b0c3a
NC
9778 /* PR binutils/17531: A corrupt file can trigger this test.
9779 So do not use an assert, instead generate an error message. */
9780 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 9781 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 9782 (int) entry->d_un.d_val);
252b5132
RH
9783 }
9784 else if (entry->d_tag == DT_SYMINSZ)
9785 syminsz = entry->d_un.d_val;
9786 else if (entry->d_tag == DT_SYMINFO)
dda8d76d 9787 dynamic_syminfo_offset = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 9788 syminsz);
252b5132
RH
9789 }
9790
9791 if (dynamic_syminfo_offset != 0 && syminsz != 0)
9792 {
2cf0635d
NC
9793 Elf_External_Syminfo * extsyminfo;
9794 Elf_External_Syminfo * extsym;
9795 Elf_Internal_Syminfo * syminfo;
252b5132
RH
9796
9797 /* There is a syminfo section. Read the data. */
3f5e193b 9798 extsyminfo = (Elf_External_Syminfo *)
dda8d76d 9799 get_data (NULL, filedata, dynamic_syminfo_offset, 1, syminsz,
3f5e193b 9800 _("symbol information"));
a6e9f9df 9801 if (!extsyminfo)
32ec8896 9802 return FALSE;
252b5132 9803
e3d39609
NC
9804 if (dynamic_syminfo != NULL)
9805 {
9806 error (_("Multiple dynamic symbol information sections found\n"));
9807 free (dynamic_syminfo);
9808 }
3f5e193b 9809 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
9810 if (dynamic_syminfo == NULL)
9811 {
8b73c356
NC
9812 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
9813 (unsigned long) syminsz);
32ec8896 9814 return FALSE;
252b5132
RH
9815 }
9816
9817 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
9818 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
9819 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
9820 ++syminfo, ++extsym)
252b5132 9821 {
86dba8ee
AM
9822 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
9823 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
9824 }
9825
9826 free (extsyminfo);
9827 }
9828 }
9829
9830 if (do_dynamic && dynamic_addr)
d3a49aa8
AM
9831 printf (ngettext ("\nDynamic section at offset 0x%lx "
9832 "contains %lu entry:\n",
9833 "\nDynamic section at offset 0x%lx "
9834 "contains %lu entries:\n",
9835 dynamic_nent),
8b73c356 9836 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
9837 if (do_dynamic)
9838 printf (_(" Tag Type Name/Value\n"));
9839
86dba8ee
AM
9840 for (entry = dynamic_section;
9841 entry < dynamic_section + dynamic_nent;
9842 entry++)
252b5132
RH
9843 {
9844 if (do_dynamic)
f7a99963 9845 {
2cf0635d 9846 const char * dtype;
e699b9ff 9847
f7a99963
NC
9848 putchar (' ');
9849 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 9850 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 9851 printf (" (%s)%*s", dtype,
32ec8896 9852 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 9853 }
252b5132
RH
9854
9855 switch (entry->d_tag)
9856 {
d1133906
NC
9857 case DT_FLAGS:
9858 if (do_dynamic)
e9e44622 9859 print_dynamic_flags (entry->d_un.d_val);
d1133906 9860 break;
76da6bbe 9861
252b5132
RH
9862 case DT_AUXILIARY:
9863 case DT_FILTER:
019148e4
L
9864 case DT_CONFIG:
9865 case DT_DEPAUDIT:
9866 case DT_AUDIT:
252b5132
RH
9867 if (do_dynamic)
9868 {
019148e4 9869 switch (entry->d_tag)
b34976b6 9870 {
019148e4
L
9871 case DT_AUXILIARY:
9872 printf (_("Auxiliary library"));
9873 break;
9874
9875 case DT_FILTER:
9876 printf (_("Filter library"));
9877 break;
9878
b34976b6 9879 case DT_CONFIG:
019148e4
L
9880 printf (_("Configuration file"));
9881 break;
9882
9883 case DT_DEPAUDIT:
9884 printf (_("Dependency audit library"));
9885 break;
9886
9887 case DT_AUDIT:
9888 printf (_("Audit library"));
9889 break;
9890 }
252b5132 9891
d79b3d50
NC
9892 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9893 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9894 else
f7a99963
NC
9895 {
9896 printf (": ");
9897 print_vma (entry->d_un.d_val, PREFIX_HEX);
9898 putchar ('\n');
9899 }
252b5132
RH
9900 }
9901 break;
9902
dcefbbbd 9903 case DT_FEATURE:
252b5132
RH
9904 if (do_dynamic)
9905 {
9906 printf (_("Flags:"));
86f55779 9907
252b5132
RH
9908 if (entry->d_un.d_val == 0)
9909 printf (_(" None\n"));
9910 else
9911 {
9912 unsigned long int val = entry->d_un.d_val;
86f55779 9913
252b5132
RH
9914 if (val & DTF_1_PARINIT)
9915 {
9916 printf (" PARINIT");
9917 val ^= DTF_1_PARINIT;
9918 }
dcefbbbd
L
9919 if (val & DTF_1_CONFEXP)
9920 {
9921 printf (" CONFEXP");
9922 val ^= DTF_1_CONFEXP;
9923 }
252b5132
RH
9924 if (val != 0)
9925 printf (" %lx", val);
9926 puts ("");
9927 }
9928 }
9929 break;
9930
9931 case DT_POSFLAG_1:
9932 if (do_dynamic)
9933 {
9934 printf (_("Flags:"));
86f55779 9935
252b5132
RH
9936 if (entry->d_un.d_val == 0)
9937 printf (_(" None\n"));
9938 else
9939 {
9940 unsigned long int val = entry->d_un.d_val;
86f55779 9941
252b5132
RH
9942 if (val & DF_P1_LAZYLOAD)
9943 {
9944 printf (" LAZYLOAD");
9945 val ^= DF_P1_LAZYLOAD;
9946 }
9947 if (val & DF_P1_GROUPPERM)
9948 {
9949 printf (" GROUPPERM");
9950 val ^= DF_P1_GROUPPERM;
9951 }
9952 if (val != 0)
9953 printf (" %lx", val);
9954 puts ("");
9955 }
9956 }
9957 break;
9958
9959 case DT_FLAGS_1:
9960 if (do_dynamic)
9961 {
9962 printf (_("Flags:"));
9963 if (entry->d_un.d_val == 0)
9964 printf (_(" None\n"));
9965 else
9966 {
9967 unsigned long int val = entry->d_un.d_val;
86f55779 9968
252b5132
RH
9969 if (val & DF_1_NOW)
9970 {
9971 printf (" NOW");
9972 val ^= DF_1_NOW;
9973 }
9974 if (val & DF_1_GLOBAL)
9975 {
9976 printf (" GLOBAL");
9977 val ^= DF_1_GLOBAL;
9978 }
9979 if (val & DF_1_GROUP)
9980 {
9981 printf (" GROUP");
9982 val ^= DF_1_GROUP;
9983 }
9984 if (val & DF_1_NODELETE)
9985 {
9986 printf (" NODELETE");
9987 val ^= DF_1_NODELETE;
9988 }
9989 if (val & DF_1_LOADFLTR)
9990 {
9991 printf (" LOADFLTR");
9992 val ^= DF_1_LOADFLTR;
9993 }
9994 if (val & DF_1_INITFIRST)
9995 {
9996 printf (" INITFIRST");
9997 val ^= DF_1_INITFIRST;
9998 }
9999 if (val & DF_1_NOOPEN)
10000 {
10001 printf (" NOOPEN");
10002 val ^= DF_1_NOOPEN;
10003 }
10004 if (val & DF_1_ORIGIN)
10005 {
10006 printf (" ORIGIN");
10007 val ^= DF_1_ORIGIN;
10008 }
10009 if (val & DF_1_DIRECT)
10010 {
10011 printf (" DIRECT");
10012 val ^= DF_1_DIRECT;
10013 }
10014 if (val & DF_1_TRANS)
10015 {
10016 printf (" TRANS");
10017 val ^= DF_1_TRANS;
10018 }
10019 if (val & DF_1_INTERPOSE)
10020 {
10021 printf (" INTERPOSE");
10022 val ^= DF_1_INTERPOSE;
10023 }
f7db6139 10024 if (val & DF_1_NODEFLIB)
dcefbbbd 10025 {
f7db6139
L
10026 printf (" NODEFLIB");
10027 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10028 }
10029 if (val & DF_1_NODUMP)
10030 {
10031 printf (" NODUMP");
10032 val ^= DF_1_NODUMP;
10033 }
34b60028 10034 if (val & DF_1_CONFALT)
dcefbbbd 10035 {
34b60028
L
10036 printf (" CONFALT");
10037 val ^= DF_1_CONFALT;
10038 }
10039 if (val & DF_1_ENDFILTEE)
10040 {
10041 printf (" ENDFILTEE");
10042 val ^= DF_1_ENDFILTEE;
10043 }
10044 if (val & DF_1_DISPRELDNE)
10045 {
10046 printf (" DISPRELDNE");
10047 val ^= DF_1_DISPRELDNE;
10048 }
10049 if (val & DF_1_DISPRELPND)
10050 {
10051 printf (" DISPRELPND");
10052 val ^= DF_1_DISPRELPND;
10053 }
10054 if (val & DF_1_NODIRECT)
10055 {
10056 printf (" NODIRECT");
10057 val ^= DF_1_NODIRECT;
10058 }
10059 if (val & DF_1_IGNMULDEF)
10060 {
10061 printf (" IGNMULDEF");
10062 val ^= DF_1_IGNMULDEF;
10063 }
10064 if (val & DF_1_NOKSYMS)
10065 {
10066 printf (" NOKSYMS");
10067 val ^= DF_1_NOKSYMS;
10068 }
10069 if (val & DF_1_NOHDR)
10070 {
10071 printf (" NOHDR");
10072 val ^= DF_1_NOHDR;
10073 }
10074 if (val & DF_1_EDITED)
10075 {
10076 printf (" EDITED");
10077 val ^= DF_1_EDITED;
10078 }
10079 if (val & DF_1_NORELOC)
10080 {
10081 printf (" NORELOC");
10082 val ^= DF_1_NORELOC;
10083 }
10084 if (val & DF_1_SYMINTPOSE)
10085 {
10086 printf (" SYMINTPOSE");
10087 val ^= DF_1_SYMINTPOSE;
10088 }
10089 if (val & DF_1_GLOBAUDIT)
10090 {
10091 printf (" GLOBAUDIT");
10092 val ^= DF_1_GLOBAUDIT;
10093 }
10094 if (val & DF_1_SINGLETON)
10095 {
10096 printf (" SINGLETON");
10097 val ^= DF_1_SINGLETON;
dcefbbbd 10098 }
5c383f02
RO
10099 if (val & DF_1_STUB)
10100 {
10101 printf (" STUB");
10102 val ^= DF_1_STUB;
10103 }
10104 if (val & DF_1_PIE)
10105 {
10106 printf (" PIE");
10107 val ^= DF_1_PIE;
10108 }
b1202ffa
L
10109 if (val & DF_1_KMOD)
10110 {
10111 printf (" KMOD");
10112 val ^= DF_1_KMOD;
10113 }
10114 if (val & DF_1_WEAKFILTER)
10115 {
10116 printf (" WEAKFILTER");
10117 val ^= DF_1_WEAKFILTER;
10118 }
10119 if (val & DF_1_NOCOMMON)
10120 {
10121 printf (" NOCOMMON");
10122 val ^= DF_1_NOCOMMON;
10123 }
252b5132
RH
10124 if (val != 0)
10125 printf (" %lx", val);
10126 puts ("");
10127 }
10128 }
10129 break;
10130
10131 case DT_PLTREL:
566b0d53 10132 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10133 if (do_dynamic)
dda8d76d 10134 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10135 break;
10136
10137 case DT_NULL :
10138 case DT_NEEDED :
10139 case DT_PLTGOT :
10140 case DT_HASH :
10141 case DT_STRTAB :
10142 case DT_SYMTAB :
10143 case DT_RELA :
10144 case DT_INIT :
10145 case DT_FINI :
10146 case DT_SONAME :
10147 case DT_RPATH :
10148 case DT_SYMBOLIC:
10149 case DT_REL :
10150 case DT_DEBUG :
10151 case DT_TEXTREL :
10152 case DT_JMPREL :
019148e4 10153 case DT_RUNPATH :
252b5132
RH
10154 dynamic_info[entry->d_tag] = entry->d_un.d_val;
10155
10156 if (do_dynamic)
10157 {
2cf0635d 10158 char * name;
252b5132 10159
d79b3d50
NC
10160 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
10161 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10162 else
d79b3d50 10163 name = NULL;
252b5132
RH
10164
10165 if (name)
10166 {
10167 switch (entry->d_tag)
10168 {
10169 case DT_NEEDED:
10170 printf (_("Shared library: [%s]"), name);
10171
18bd398b 10172 if (streq (name, program_interpreter))
f7a99963 10173 printf (_(" program interpreter"));
252b5132
RH
10174 break;
10175
10176 case DT_SONAME:
f7a99963 10177 printf (_("Library soname: [%s]"), name);
252b5132
RH
10178 break;
10179
10180 case DT_RPATH:
f7a99963 10181 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10182 break;
10183
019148e4
L
10184 case DT_RUNPATH:
10185 printf (_("Library runpath: [%s]"), name);
10186 break;
10187
252b5132 10188 default:
f7a99963
NC
10189 print_vma (entry->d_un.d_val, PREFIX_HEX);
10190 break;
252b5132
RH
10191 }
10192 }
10193 else
f7a99963
NC
10194 print_vma (entry->d_un.d_val, PREFIX_HEX);
10195
10196 putchar ('\n');
252b5132
RH
10197 }
10198 break;
10199
10200 case DT_PLTRELSZ:
10201 case DT_RELASZ :
10202 case DT_STRSZ :
10203 case DT_RELSZ :
10204 case DT_RELAENT :
10205 case DT_SYMENT :
10206 case DT_RELENT :
566b0d53 10207 dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10208 /* Fall through. */
252b5132
RH
10209 case DT_PLTPADSZ:
10210 case DT_MOVEENT :
10211 case DT_MOVESZ :
10212 case DT_INIT_ARRAYSZ:
10213 case DT_FINI_ARRAYSZ:
047b2264
JJ
10214 case DT_GNU_CONFLICTSZ:
10215 case DT_GNU_LIBLISTSZ:
252b5132 10216 if (do_dynamic)
f7a99963
NC
10217 {
10218 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10219 printf (_(" (bytes)\n"));
f7a99963 10220 }
252b5132
RH
10221 break;
10222
10223 case DT_VERDEFNUM:
10224 case DT_VERNEEDNUM:
10225 case DT_RELACOUNT:
10226 case DT_RELCOUNT:
10227 if (do_dynamic)
f7a99963
NC
10228 {
10229 print_vma (entry->d_un.d_val, UNSIGNED);
10230 putchar ('\n');
10231 }
252b5132
RH
10232 break;
10233
10234 case DT_SYMINSZ:
10235 case DT_SYMINENT:
10236 case DT_SYMINFO:
10237 case DT_USED:
10238 case DT_INIT_ARRAY:
10239 case DT_FINI_ARRAY:
10240 if (do_dynamic)
10241 {
d79b3d50
NC
10242 if (entry->d_tag == DT_USED
10243 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 10244 {
2cf0635d 10245 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10246
b34976b6 10247 if (*name)
252b5132
RH
10248 {
10249 printf (_("Not needed object: [%s]\n"), name);
10250 break;
10251 }
10252 }
103f02d3 10253
f7a99963
NC
10254 print_vma (entry->d_un.d_val, PREFIX_HEX);
10255 putchar ('\n');
252b5132
RH
10256 }
10257 break;
10258
10259 case DT_BIND_NOW:
10260 /* The value of this entry is ignored. */
35b1837e
AM
10261 if (do_dynamic)
10262 putchar ('\n');
252b5132 10263 break;
103f02d3 10264
047b2264
JJ
10265 case DT_GNU_PRELINKED:
10266 if (do_dynamic)
10267 {
2cf0635d 10268 struct tm * tmp;
91d6fa6a 10269 time_t atime = entry->d_un.d_val;
047b2264 10270
91d6fa6a 10271 tmp = gmtime (&atime);
071436c6
NC
10272 /* PR 17533 file: 041-1244816-0.004. */
10273 if (tmp == NULL)
5a2cbcf4
L
10274 printf (_("<corrupt time val: %lx"),
10275 (unsigned long) atime);
071436c6
NC
10276 else
10277 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10278 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10279 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10280
10281 }
10282 break;
10283
fdc90cb4
JJ
10284 case DT_GNU_HASH:
10285 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10286 if (do_dynamic)
10287 {
10288 print_vma (entry->d_un.d_val, PREFIX_HEX);
10289 putchar ('\n');
10290 }
10291 break;
10292
252b5132
RH
10293 default:
10294 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 10295 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
10296 entry->d_un.d_val;
10297
10298 if (do_dynamic)
10299 {
dda8d76d 10300 switch (filedata->file_header.e_machine)
252b5132
RH
10301 {
10302 case EM_MIPS:
4fe85591 10303 case EM_MIPS_RS3_LE:
b2d38a17 10304 dynamic_section_mips_val (entry);
252b5132 10305 break;
103f02d3 10306 case EM_PARISC:
b2d38a17 10307 dynamic_section_parisc_val (entry);
103f02d3 10308 break;
ecc51f48 10309 case EM_IA_64:
b2d38a17 10310 dynamic_section_ia64_val (entry);
ecc51f48 10311 break;
252b5132 10312 default:
f7a99963
NC
10313 print_vma (entry->d_un.d_val, PREFIX_HEX);
10314 putchar ('\n');
252b5132
RH
10315 }
10316 }
10317 break;
10318 }
10319 }
10320
32ec8896 10321 return TRUE;
252b5132
RH
10322}
10323
10324static char *
d3ba0551 10325get_ver_flags (unsigned int flags)
252b5132 10326{
6d4f21f6 10327 static char buff[128];
252b5132
RH
10328
10329 buff[0] = 0;
10330
10331 if (flags == 0)
10332 return _("none");
10333
10334 if (flags & VER_FLG_BASE)
7bb1ad17 10335 strcat (buff, "BASE");
252b5132
RH
10336
10337 if (flags & VER_FLG_WEAK)
10338 {
10339 if (flags & VER_FLG_BASE)
7bb1ad17 10340 strcat (buff, " | ");
252b5132 10341
7bb1ad17 10342 strcat (buff, "WEAK");
252b5132
RH
10343 }
10344
44ec90b9
RO
10345 if (flags & VER_FLG_INFO)
10346 {
10347 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 10348 strcat (buff, " | ");
44ec90b9 10349
7bb1ad17 10350 strcat (buff, "INFO");
44ec90b9
RO
10351 }
10352
10353 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
10354 {
10355 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
10356 strcat (buff, " | ");
10357
10358 strcat (buff, _("<unknown>"));
10359 }
252b5132
RH
10360
10361 return buff;
10362}
10363
10364/* Display the contents of the version sections. */
98fb390a 10365
32ec8896 10366static bfd_boolean
dda8d76d 10367process_version_sections (Filedata * filedata)
252b5132 10368{
2cf0635d 10369 Elf_Internal_Shdr * section;
b34976b6 10370 unsigned i;
32ec8896 10371 bfd_boolean found = FALSE;
252b5132
RH
10372
10373 if (! do_version)
32ec8896 10374 return TRUE;
252b5132 10375
dda8d76d
NC
10376 for (i = 0, section = filedata->section_headers;
10377 i < filedata->file_header.e_shnum;
b34976b6 10378 i++, section++)
252b5132
RH
10379 {
10380 switch (section->sh_type)
10381 {
10382 case SHT_GNU_verdef:
10383 {
2cf0635d 10384 Elf_External_Verdef * edefs;
452bf675
AM
10385 unsigned long idx;
10386 unsigned long cnt;
2cf0635d 10387 char * endbuf;
252b5132 10388
32ec8896 10389 found = TRUE;
252b5132 10390
d3a49aa8
AM
10391 printf (ngettext ("\nVersion definition section '%s' "
10392 "contains %u entry:\n",
10393 "\nVersion definition section '%s' "
10394 "contains %u entries:\n",
10395 section->sh_info),
dda8d76d 10396 printable_section_name (filedata, section),
74e1a04b 10397 section->sh_info);
252b5132
RH
10398
10399 printf (_(" Addr: 0x"));
10400 printf_vma (section->sh_addr);
233f82cf 10401 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10402 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10403 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10404
3f5e193b 10405 edefs = (Elf_External_Verdef *)
dda8d76d 10406 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 10407 _("version definition section"));
a6e9f9df
AM
10408 if (!edefs)
10409 break;
59245841 10410 endbuf = (char *) edefs + section->sh_size;
252b5132 10411
1445030f 10412 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 10413 {
2cf0635d
NC
10414 char * vstart;
10415 Elf_External_Verdef * edef;
b34976b6 10416 Elf_Internal_Verdef ent;
2cf0635d 10417 Elf_External_Verdaux * eaux;
b34976b6 10418 Elf_Internal_Verdaux aux;
452bf675 10419 unsigned long isum;
b34976b6 10420 int j;
103f02d3 10421
252b5132 10422 vstart = ((char *) edefs) + idx;
54806181
AM
10423 if (vstart + sizeof (*edef) > endbuf)
10424 break;
252b5132
RH
10425
10426 edef = (Elf_External_Verdef *) vstart;
10427
10428 ent.vd_version = BYTE_GET (edef->vd_version);
10429 ent.vd_flags = BYTE_GET (edef->vd_flags);
10430 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
10431 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
10432 ent.vd_hash = BYTE_GET (edef->vd_hash);
10433 ent.vd_aux = BYTE_GET (edef->vd_aux);
10434 ent.vd_next = BYTE_GET (edef->vd_next);
10435
452bf675 10436 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
10437 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
10438
10439 printf (_(" Index: %d Cnt: %d "),
10440 ent.vd_ndx, ent.vd_cnt);
10441
452bf675 10442 /* Check for overflow. */
1445030f 10443 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
10444 break;
10445
252b5132
RH
10446 vstart += ent.vd_aux;
10447
1445030f
AM
10448 if (vstart + sizeof (*eaux) > endbuf)
10449 break;
252b5132
RH
10450 eaux = (Elf_External_Verdaux *) vstart;
10451
10452 aux.vda_name = BYTE_GET (eaux->vda_name);
10453 aux.vda_next = BYTE_GET (eaux->vda_next);
10454
d79b3d50
NC
10455 if (VALID_DYNAMIC_NAME (aux.vda_name))
10456 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
10457 else
10458 printf (_("Name index: %ld\n"), aux.vda_name);
10459
10460 isum = idx + ent.vd_aux;
10461
b34976b6 10462 for (j = 1; j < ent.vd_cnt; j++)
252b5132 10463 {
1445030f
AM
10464 if (aux.vda_next < sizeof (*eaux)
10465 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
10466 {
10467 warn (_("Invalid vda_next field of %lx\n"),
10468 aux.vda_next);
10469 j = ent.vd_cnt;
10470 break;
10471 }
dd24e3da 10472 /* Check for overflow. */
7e26601c 10473 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
10474 break;
10475
252b5132
RH
10476 isum += aux.vda_next;
10477 vstart += aux.vda_next;
10478
54806181
AM
10479 if (vstart + sizeof (*eaux) > endbuf)
10480 break;
1445030f 10481 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
10482
10483 aux.vda_name = BYTE_GET (eaux->vda_name);
10484 aux.vda_next = BYTE_GET (eaux->vda_next);
10485
d79b3d50 10486 if (VALID_DYNAMIC_NAME (aux.vda_name))
452bf675 10487 printf (_(" %#06lx: Parent %d: %s\n"),
d79b3d50 10488 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132 10489 else
452bf675 10490 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
10491 isum, j, aux.vda_name);
10492 }
dd24e3da 10493
54806181
AM
10494 if (j < ent.vd_cnt)
10495 printf (_(" Version def aux past end of section\n"));
252b5132 10496
c9f02c3e
MR
10497 /* PR 17531:
10498 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
10499 if (ent.vd_next < sizeof (*edef)
10500 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
10501 {
10502 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
10503 cnt = section->sh_info;
10504 break;
10505 }
452bf675 10506 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
10507 break;
10508
252b5132
RH
10509 idx += ent.vd_next;
10510 }
dd24e3da 10511
54806181
AM
10512 if (cnt < section->sh_info)
10513 printf (_(" Version definition past end of section\n"));
252b5132
RH
10514
10515 free (edefs);
10516 }
10517 break;
103f02d3 10518
252b5132
RH
10519 case SHT_GNU_verneed:
10520 {
2cf0635d 10521 Elf_External_Verneed * eneed;
452bf675
AM
10522 unsigned long idx;
10523 unsigned long cnt;
2cf0635d 10524 char * endbuf;
252b5132 10525
32ec8896 10526 found = TRUE;
252b5132 10527
d3a49aa8
AM
10528 printf (ngettext ("\nVersion needs section '%s' "
10529 "contains %u entry:\n",
10530 "\nVersion needs section '%s' "
10531 "contains %u entries:\n",
10532 section->sh_info),
dda8d76d 10533 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
10534
10535 printf (_(" Addr: 0x"));
10536 printf_vma (section->sh_addr);
72de5009 10537 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10538 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10539 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10540
dda8d76d 10541 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
10542 section->sh_offset, 1,
10543 section->sh_size,
9cf03b7e 10544 _("Version Needs section"));
a6e9f9df
AM
10545 if (!eneed)
10546 break;
59245841 10547 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
10548
10549 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
10550 {
2cf0635d 10551 Elf_External_Verneed * entry;
b34976b6 10552 Elf_Internal_Verneed ent;
452bf675 10553 unsigned long isum;
b34976b6 10554 int j;
2cf0635d 10555 char * vstart;
252b5132
RH
10556
10557 vstart = ((char *) eneed) + idx;
54806181
AM
10558 if (vstart + sizeof (*entry) > endbuf)
10559 break;
252b5132
RH
10560
10561 entry = (Elf_External_Verneed *) vstart;
10562
10563 ent.vn_version = BYTE_GET (entry->vn_version);
10564 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
10565 ent.vn_file = BYTE_GET (entry->vn_file);
10566 ent.vn_aux = BYTE_GET (entry->vn_aux);
10567 ent.vn_next = BYTE_GET (entry->vn_next);
10568
452bf675 10569 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 10570
d79b3d50
NC
10571 if (VALID_DYNAMIC_NAME (ent.vn_file))
10572 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
10573 else
10574 printf (_(" File: %lx"), ent.vn_file);
10575
10576 printf (_(" Cnt: %d\n"), ent.vn_cnt);
10577
dd24e3da 10578 /* Check for overflow. */
7e26601c 10579 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 10580 break;
252b5132
RH
10581 vstart += ent.vn_aux;
10582
10583 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
10584 {
2cf0635d 10585 Elf_External_Vernaux * eaux;
b34976b6 10586 Elf_Internal_Vernaux aux;
252b5132 10587
54806181
AM
10588 if (vstart + sizeof (*eaux) > endbuf)
10589 break;
252b5132
RH
10590 eaux = (Elf_External_Vernaux *) vstart;
10591
10592 aux.vna_hash = BYTE_GET (eaux->vna_hash);
10593 aux.vna_flags = BYTE_GET (eaux->vna_flags);
10594 aux.vna_other = BYTE_GET (eaux->vna_other);
10595 aux.vna_name = BYTE_GET (eaux->vna_name);
10596 aux.vna_next = BYTE_GET (eaux->vna_next);
10597
d79b3d50 10598 if (VALID_DYNAMIC_NAME (aux.vna_name))
452bf675 10599 printf (_(" %#06lx: Name: %s"),
d79b3d50 10600 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 10601 else
452bf675 10602 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
10603 isum, aux.vna_name);
10604
10605 printf (_(" Flags: %s Version: %d\n"),
10606 get_ver_flags (aux.vna_flags), aux.vna_other);
10607
1445030f
AM
10608 if (aux.vna_next < sizeof (*eaux)
10609 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
10610 {
10611 warn (_("Invalid vna_next field of %lx\n"),
10612 aux.vna_next);
10613 j = ent.vn_cnt;
10614 break;
10615 }
1445030f
AM
10616 /* Check for overflow. */
10617 if (aux.vna_next > (size_t) (endbuf - vstart))
10618 break;
252b5132
RH
10619 isum += aux.vna_next;
10620 vstart += aux.vna_next;
10621 }
9cf03b7e 10622
54806181 10623 if (j < ent.vn_cnt)
9cf03b7e 10624 warn (_("Missing Version Needs auxillary information\n"));
252b5132 10625
1445030f
AM
10626 if (ent.vn_next < sizeof (*entry)
10627 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 10628 {
452bf675 10629 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
10630 cnt = section->sh_info;
10631 break;
10632 }
1445030f
AM
10633 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
10634 break;
252b5132
RH
10635 idx += ent.vn_next;
10636 }
9cf03b7e 10637
54806181 10638 if (cnt < section->sh_info)
9cf03b7e 10639 warn (_("Missing Version Needs information\n"));
103f02d3 10640
252b5132
RH
10641 free (eneed);
10642 }
10643 break;
10644
10645 case SHT_GNU_versym:
10646 {
2cf0635d 10647 Elf_Internal_Shdr * link_section;
8b73c356
NC
10648 size_t total;
10649 unsigned int cnt;
2cf0635d
NC
10650 unsigned char * edata;
10651 unsigned short * data;
10652 char * strtab;
10653 Elf_Internal_Sym * symbols;
10654 Elf_Internal_Shdr * string_sec;
ba5cdace 10655 unsigned long num_syms;
d3ba0551 10656 long off;
252b5132 10657
dda8d76d 10658 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10659 break;
10660
dda8d76d 10661 link_section = filedata->section_headers + section->sh_link;
08d8fa11 10662 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 10663
dda8d76d 10664 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10665 break;
10666
32ec8896 10667 found = TRUE;
252b5132 10668
dda8d76d 10669 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
10670 if (symbols == NULL)
10671 break;
252b5132 10672
dda8d76d 10673 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 10674
dda8d76d 10675 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
10676 string_sec->sh_size,
10677 _("version string table"));
a6e9f9df 10678 if (!strtab)
0429c154
MS
10679 {
10680 free (symbols);
10681 break;
10682 }
252b5132 10683
d3a49aa8
AM
10684 printf (ngettext ("\nVersion symbols section '%s' "
10685 "contains %lu entry:\n",
10686 "\nVersion symbols section '%s' "
10687 "contains %lu entries:\n",
10688 total),
dda8d76d 10689 printable_section_name (filedata, section), (unsigned long) total);
252b5132
RH
10690
10691 printf (_(" Addr: "));
10692 printf_vma (section->sh_addr);
72de5009 10693 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10694 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10695 printable_section_name (filedata, link_section));
252b5132 10696
dda8d76d 10697 off = offset_from_vma (filedata,
d3ba0551
AM
10698 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10699 total * sizeof (short));
dda8d76d 10700 edata = (unsigned char *) get_data (NULL, filedata, off, total,
3f5e193b
NC
10701 sizeof (short),
10702 _("version symbol data"));
a6e9f9df
AM
10703 if (!edata)
10704 {
10705 free (strtab);
0429c154 10706 free (symbols);
a6e9f9df
AM
10707 break;
10708 }
252b5132 10709
3f5e193b 10710 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
10711
10712 for (cnt = total; cnt --;)
b34976b6
AM
10713 data[cnt] = byte_get (edata + cnt * sizeof (short),
10714 sizeof (short));
252b5132
RH
10715
10716 free (edata);
10717
10718 for (cnt = 0; cnt < total; cnt += 4)
10719 {
10720 int j, nn;
ab273396
AM
10721 char *name;
10722 char *invalid = _("*invalid*");
252b5132
RH
10723
10724 printf (" %03x:", cnt);
10725
10726 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 10727 switch (data[cnt + j])
252b5132
RH
10728 {
10729 case 0:
10730 fputs (_(" 0 (*local*) "), stdout);
10731 break;
10732
10733 case 1:
10734 fputs (_(" 1 (*global*) "), stdout);
10735 break;
10736
10737 default:
c244d050
NC
10738 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
10739 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 10740
dd24e3da 10741 /* If this index value is greater than the size of the symbols
ba5cdace
NC
10742 array, break to avoid an out-of-bounds read. */
10743 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
10744 {
10745 warn (_("invalid index into symbol array\n"));
10746 break;
10747 }
10748
ab273396
AM
10749 name = NULL;
10750 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 10751 {
b34976b6
AM
10752 Elf_Internal_Verneed ivn;
10753 unsigned long offset;
252b5132 10754
d93f0186 10755 offset = offset_from_vma
dda8d76d 10756 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 10757 sizeof (Elf_External_Verneed));
252b5132 10758
b34976b6 10759 do
252b5132 10760 {
b34976b6
AM
10761 Elf_Internal_Vernaux ivna;
10762 Elf_External_Verneed evn;
10763 Elf_External_Vernaux evna;
10764 unsigned long a_off;
252b5132 10765
dda8d76d 10766 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
10767 _("version need")) == NULL)
10768 break;
0b4362b0 10769
252b5132
RH
10770 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10771 ivn.vn_next = BYTE_GET (evn.vn_next);
10772
10773 a_off = offset + ivn.vn_aux;
10774
10775 do
10776 {
dda8d76d 10777 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
10778 1, _("version need aux (2)")) == NULL)
10779 {
10780 ivna.vna_next = 0;
10781 ivna.vna_other = 0;
10782 }
10783 else
10784 {
10785 ivna.vna_next = BYTE_GET (evna.vna_next);
10786 ivna.vna_other = BYTE_GET (evna.vna_other);
10787 }
252b5132
RH
10788
10789 a_off += ivna.vna_next;
10790 }
b34976b6 10791 while (ivna.vna_other != data[cnt + j]
252b5132
RH
10792 && ivna.vna_next != 0);
10793
b34976b6 10794 if (ivna.vna_other == data[cnt + j])
252b5132
RH
10795 {
10796 ivna.vna_name = BYTE_GET (evna.vna_name);
10797
54806181 10798 if (ivna.vna_name >= string_sec->sh_size)
ab273396 10799 name = invalid;
54806181
AM
10800 else
10801 name = strtab + ivna.vna_name;
252b5132
RH
10802 break;
10803 }
10804
10805 offset += ivn.vn_next;
10806 }
10807 while (ivn.vn_next);
10808 }
00d93f34 10809
ab273396 10810 if (data[cnt + j] != 0x8001
b34976b6 10811 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10812 {
b34976b6
AM
10813 Elf_Internal_Verdef ivd;
10814 Elf_External_Verdef evd;
10815 unsigned long offset;
252b5132 10816
d93f0186 10817 offset = offset_from_vma
dda8d76d 10818 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 10819 sizeof evd);
252b5132
RH
10820
10821 do
10822 {
dda8d76d 10823 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
10824 _("version def")) == NULL)
10825 {
10826 ivd.vd_next = 0;
948f632f 10827 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
10828 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
10829 break;
59245841
NC
10830 }
10831 else
10832 {
10833 ivd.vd_next = BYTE_GET (evd.vd_next);
10834 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10835 }
252b5132
RH
10836
10837 offset += ivd.vd_next;
10838 }
c244d050 10839 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
10840 && ivd.vd_next != 0);
10841
c244d050 10842 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 10843 {
b34976b6
AM
10844 Elf_External_Verdaux evda;
10845 Elf_Internal_Verdaux ivda;
252b5132
RH
10846
10847 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10848
dda8d76d 10849 if (get_data (&evda, filedata,
59245841
NC
10850 offset - ivd.vd_next + ivd.vd_aux,
10851 sizeof (evda), 1,
10852 _("version def aux")) == NULL)
10853 break;
252b5132
RH
10854
10855 ivda.vda_name = BYTE_GET (evda.vda_name);
10856
54806181 10857 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
10858 name = invalid;
10859 else if (name != NULL && name != invalid)
10860 name = _("*both*");
54806181
AM
10861 else
10862 name = strtab + ivda.vda_name;
252b5132
RH
10863 }
10864 }
ab273396
AM
10865 if (name != NULL)
10866 nn += printf ("(%s%-*s",
10867 name,
10868 12 - (int) strlen (name),
10869 ")");
252b5132
RH
10870
10871 if (nn < 18)
10872 printf ("%*c", 18 - nn, ' ');
10873 }
10874
10875 putchar ('\n');
10876 }
10877
10878 free (data);
10879 free (strtab);
10880 free (symbols);
10881 }
10882 break;
103f02d3 10883
252b5132
RH
10884 default:
10885 break;
10886 }
10887 }
10888
10889 if (! found)
10890 printf (_("\nNo version information found in this file.\n"));
10891
32ec8896 10892 return TRUE;
252b5132
RH
10893}
10894
d1133906 10895static const char *
dda8d76d 10896get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 10897{
b34976b6 10898 static char buff[32];
252b5132
RH
10899
10900 switch (binding)
10901 {
b34976b6
AM
10902 case STB_LOCAL: return "LOCAL";
10903 case STB_GLOBAL: return "GLOBAL";
10904 case STB_WEAK: return "WEAK";
252b5132
RH
10905 default:
10906 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
10907 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
10908 binding);
252b5132 10909 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
10910 {
10911 if (binding == STB_GNU_UNIQUE
dda8d76d 10912 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9c55345c 10913 /* GNU is still using the default value 0. */
dda8d76d 10914 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
3e7a7d11
NC
10915 return "UNIQUE";
10916 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
10917 }
252b5132 10918 else
e9e44622 10919 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
10920 return buff;
10921 }
10922}
10923
d1133906 10924static const char *
dda8d76d 10925get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 10926{
b34976b6 10927 static char buff[32];
252b5132
RH
10928
10929 switch (type)
10930 {
b34976b6
AM
10931 case STT_NOTYPE: return "NOTYPE";
10932 case STT_OBJECT: return "OBJECT";
10933 case STT_FUNC: return "FUNC";
10934 case STT_SECTION: return "SECTION";
10935 case STT_FILE: return "FILE";
10936 case STT_COMMON: return "COMMON";
10937 case STT_TLS: return "TLS";
15ab5209
DB
10938 case STT_RELC: return "RELC";
10939 case STT_SRELC: return "SRELC";
252b5132
RH
10940 default:
10941 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 10942 {
dda8d76d 10943 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 10944 return "THUMB_FUNC";
103f02d3 10945
dda8d76d 10946 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
10947 return "REGISTER";
10948
dda8d76d 10949 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
10950 return "PARISC_MILLI";
10951
e9e44622 10952 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 10953 }
252b5132 10954 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 10955 {
dda8d76d 10956 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
10957 {
10958 if (type == STT_HP_OPAQUE)
10959 return "HP_OPAQUE";
10960 if (type == STT_HP_STUB)
10961 return "HP_STUB";
10962 }
10963
d8045f23 10964 if (type == STT_GNU_IFUNC
dda8d76d
NC
10965 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
10966 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 10967 /* GNU is still using the default value 0. */
dda8d76d 10968 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
d8045f23
NC
10969 return "IFUNC";
10970
e9e44622 10971 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 10972 }
252b5132 10973 else
e9e44622 10974 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
10975 return buff;
10976 }
10977}
10978
d1133906 10979static const char *
d3ba0551 10980get_symbol_visibility (unsigned int visibility)
d1133906
NC
10981{
10982 switch (visibility)
10983 {
b34976b6
AM
10984 case STV_DEFAULT: return "DEFAULT";
10985 case STV_INTERNAL: return "INTERNAL";
10986 case STV_HIDDEN: return "HIDDEN";
d1133906 10987 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
10988 default:
10989 error (_("Unrecognized visibility value: %u"), visibility);
10990 return _("<unknown>");
d1133906
NC
10991 }
10992}
10993
fd85a6a1
NC
10994static const char *
10995get_solaris_symbol_visibility (unsigned int visibility)
10996{
10997 switch (visibility)
10998 {
10999 case 4: return "EXPORTED";
11000 case 5: return "SINGLETON";
11001 case 6: return "ELIMINATE";
11002 default: return get_symbol_visibility (visibility);
11003 }
11004}
11005
5e2b0d47
NC
11006static const char *
11007get_mips_symbol_other (unsigned int other)
11008{
11009 switch (other)
11010 {
32ec8896
NC
11011 case STO_OPTIONAL: return "OPTIONAL";
11012 case STO_MIPS_PLT: return "MIPS PLT";
11013 case STO_MIPS_PIC: return "MIPS PIC";
11014 case STO_MICROMIPS: return "MICROMIPS";
11015 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11016 case STO_MIPS16: return "MIPS16";
11017 default: return NULL;
5e2b0d47
NC
11018 }
11019}
11020
28f997cf 11021static const char *
dda8d76d 11022get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11023{
dda8d76d 11024 if (is_ia64_vms (filedata))
28f997cf
TG
11025 {
11026 static char res[32];
11027
11028 res[0] = 0;
11029
11030 /* Function types is for images and .STB files only. */
dda8d76d 11031 switch (filedata->file_header.e_type)
28f997cf
TG
11032 {
11033 case ET_DYN:
11034 case ET_EXEC:
11035 switch (VMS_ST_FUNC_TYPE (other))
11036 {
11037 case VMS_SFT_CODE_ADDR:
11038 strcat (res, " CA");
11039 break;
11040 case VMS_SFT_SYMV_IDX:
11041 strcat (res, " VEC");
11042 break;
11043 case VMS_SFT_FD:
11044 strcat (res, " FD");
11045 break;
11046 case VMS_SFT_RESERVE:
11047 strcat (res, " RSV");
11048 break;
11049 default:
bee0ee85
NC
11050 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11051 VMS_ST_FUNC_TYPE (other));
11052 strcat (res, " <unknown>");
11053 break;
28f997cf
TG
11054 }
11055 break;
11056 default:
11057 break;
11058 }
11059 switch (VMS_ST_LINKAGE (other))
11060 {
11061 case VMS_STL_IGNORE:
11062 strcat (res, " IGN");
11063 break;
11064 case VMS_STL_RESERVE:
11065 strcat (res, " RSV");
11066 break;
11067 case VMS_STL_STD:
11068 strcat (res, " STD");
11069 break;
11070 case VMS_STL_LNK:
11071 strcat (res, " LNK");
11072 break;
11073 default:
bee0ee85
NC
11074 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11075 VMS_ST_LINKAGE (other));
11076 strcat (res, " <unknown>");
11077 break;
28f997cf
TG
11078 }
11079
11080 if (res[0] != 0)
11081 return res + 1;
11082 else
11083 return res;
11084 }
11085 return NULL;
11086}
11087
6911b7dc
AM
11088static const char *
11089get_ppc64_symbol_other (unsigned int other)
11090{
11091 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
11092 {
11093 static char buf[32];
11094 snprintf (buf, sizeof buf, _("<localentry>: %d"),
11095 PPC64_LOCAL_ENTRY_OFFSET (other));
11096 return buf;
11097 }
11098 return NULL;
11099}
11100
5e2b0d47 11101static const char *
dda8d76d 11102get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11103{
11104 const char * result = NULL;
11105 static char buff [32];
11106
11107 if (other == 0)
11108 return "";
11109
dda8d76d 11110 switch (filedata->file_header.e_machine)
5e2b0d47
NC
11111 {
11112 case EM_MIPS:
11113 result = get_mips_symbol_other (other);
28f997cf
TG
11114 break;
11115 case EM_IA_64:
dda8d76d 11116 result = get_ia64_symbol_other (filedata, other);
28f997cf 11117 break;
6911b7dc
AM
11118 case EM_PPC64:
11119 result = get_ppc64_symbol_other (other);
11120 break;
5e2b0d47 11121 default:
fd85a6a1 11122 result = NULL;
5e2b0d47
NC
11123 break;
11124 }
11125
11126 if (result)
11127 return result;
11128
11129 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11130 return buff;
11131}
11132
d1133906 11133static const char *
dda8d76d 11134get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11135{
b34976b6 11136 static char buff[32];
5cf1065c 11137
252b5132
RH
11138 switch (type)
11139 {
b34976b6
AM
11140 case SHN_UNDEF: return "UND";
11141 case SHN_ABS: return "ABS";
11142 case SHN_COMMON: return "COM";
252b5132 11143 default:
9ce701e2 11144 if (type == SHN_IA_64_ANSI_COMMON
dda8d76d
NC
11145 && filedata->file_header.e_machine == EM_IA_64
11146 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9ce701e2 11147 return "ANSI_COM";
dda8d76d
NC
11148 else if ((filedata->file_header.e_machine == EM_X86_64
11149 || filedata->file_header.e_machine == EM_L1OM
11150 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
11151 && type == SHN_X86_64_LCOMMON)
11152 return "LARGE_COM";
ac145307 11153 else if ((type == SHN_MIPS_SCOMMON
dda8d76d 11154 && filedata->file_header.e_machine == EM_MIPS)
ac145307 11155 || (type == SHN_TIC6X_SCOMMON
dda8d76d 11156 && filedata->file_header.e_machine == EM_TI_C6000))
172553c7
TS
11157 return "SCOM";
11158 else if (type == SHN_MIPS_SUNDEFINED
dda8d76d 11159 && filedata->file_header.e_machine == EM_MIPS)
172553c7 11160 return "SUND";
9ce701e2 11161 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 11162 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 11163 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
11164 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11165 else if (type >= SHN_LORESERVE)
11166 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
dda8d76d 11167 else if (type >= filedata->file_header.e_shnum)
e0a31db1 11168 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 11169 else
232e7cb8 11170 sprintf (buff, "%3d", type);
5cf1065c 11171 break;
252b5132 11172 }
5cf1065c
NC
11173
11174 return buff;
252b5132
RH
11175}
11176
66543521 11177static bfd_vma *
dda8d76d 11178get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
252b5132 11179{
2cf0635d
NC
11180 unsigned char * e_data;
11181 bfd_vma * i_data;
252b5132 11182
57028622
NC
11183 /* If the size_t type is smaller than the bfd_size_type, eg because
11184 you are building a 32-bit tool on a 64-bit host, then make sure
11185 that when (number) is cast to (size_t) no information is lost. */
11186 if (sizeof (size_t) < sizeof (bfd_size_type)
11187 && (bfd_size_type) ((size_t) number) != number)
11188 {
66cfc0fd
AM
11189 error (_("Size truncation prevents reading %s elements of size %u\n"),
11190 bfd_vmatoa ("u", number), ent_size);
57028622
NC
11191 return NULL;
11192 }
948f632f 11193
3102e897
NC
11194 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
11195 attempting to allocate memory when the read is bound to fail. */
dda8d76d 11196 if (ent_size * number > filedata->file_size)
3102e897 11197 {
66cfc0fd
AM
11198 error (_("Invalid number of dynamic entries: %s\n"),
11199 bfd_vmatoa ("u", number));
3102e897
NC
11200 return NULL;
11201 }
11202
57028622 11203 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
11204 if (e_data == NULL)
11205 {
66cfc0fd
AM
11206 error (_("Out of memory reading %s dynamic entries\n"),
11207 bfd_vmatoa ("u", number));
252b5132
RH
11208 return NULL;
11209 }
11210
dda8d76d 11211 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
252b5132 11212 {
66cfc0fd
AM
11213 error (_("Unable to read in %s bytes of dynamic data\n"),
11214 bfd_vmatoa ("u", number * ent_size));
3102e897 11215 free (e_data);
252b5132
RH
11216 return NULL;
11217 }
11218
57028622 11219 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
11220 if (i_data == NULL)
11221 {
66cfc0fd
AM
11222 error (_("Out of memory allocating space for %s dynamic entries\n"),
11223 bfd_vmatoa ("u", number));
252b5132
RH
11224 free (e_data);
11225 return NULL;
11226 }
11227
11228 while (number--)
66543521 11229 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
11230
11231 free (e_data);
11232
11233 return i_data;
11234}
11235
6bd1a22c 11236static void
dda8d76d 11237print_dynamic_symbol (Filedata * filedata, bfd_vma si, unsigned long hn)
6bd1a22c 11238{
2cf0635d 11239 Elf_Internal_Sym * psym;
6bd1a22c
L
11240 int n;
11241
6bd1a22c
L
11242 n = print_vma (si, DEC_5);
11243 if (n < 5)
0b4362b0 11244 fputs (&" "[n], stdout);
6bd1a22c 11245 printf (" %3lu: ", hn);
e0a31db1
NC
11246
11247 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
11248 {
3102e897
NC
11249 printf (_("<No info available for dynamic symbol number %lu>\n"),
11250 (unsigned long) si);
e0a31db1
NC
11251 return;
11252 }
11253
11254 psym = dynamic_symbols + si;
6bd1a22c
L
11255 print_vma (psym->st_value, LONG_HEX);
11256 putchar (' ');
11257 print_vma (psym->st_size, DEC_5);
11258
dda8d76d
NC
11259 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11260 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
fd85a6a1 11261
dda8d76d 11262 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11263 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11264 else
11265 {
11266 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11267
11268 printf (" %-7s", get_symbol_visibility (vis));
11269 /* Check to see if any other bits in the st_other field are set.
11270 Note - displaying this information disrupts the layout of the
11271 table being generated, but for the moment this case is very
11272 rare. */
11273 if (psym->st_other ^ vis)
dda8d76d 11274 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1
NC
11275 }
11276
dda8d76d 11277 printf (" %3.3s ", get_symbol_index_type (filedata, psym->st_shndx));
6bd1a22c
L
11278 if (VALID_DYNAMIC_NAME (psym->st_name))
11279 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11280 else
2b692964 11281 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
11282 putchar ('\n');
11283}
11284
bb4d2ac2 11285static const char *
dda8d76d 11286get_symbol_version_string (Filedata * filedata,
1449284b
NC
11287 bfd_boolean is_dynsym,
11288 const char * strtab,
11289 unsigned long int strtab_size,
11290 unsigned int si,
11291 Elf_Internal_Sym * psym,
11292 enum versioned_symbol_info * sym_info,
11293 unsigned short * vna_other)
bb4d2ac2 11294{
ab273396
AM
11295 unsigned char data[2];
11296 unsigned short vers_data;
11297 unsigned long offset;
bb4d2ac2 11298
ab273396
AM
11299 if (!is_dynsym
11300 || version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
11301 return NULL;
bb4d2ac2 11302
dda8d76d 11303 offset = offset_from_vma (filedata, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11304 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11305
dda8d76d 11306 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11307 sizeof (data), 1, _("version data")) == NULL)
11308 return NULL;
11309
11310 vers_data = byte_get (data, 2);
bb4d2ac2 11311
1f6f5dba 11312 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11313 return NULL;
bb4d2ac2 11314
ab273396
AM
11315 /* Usually we'd only see verdef for defined symbols, and verneed for
11316 undefined symbols. However, symbols defined by the linker in
11317 .dynbss for variables copied from a shared library in order to
11318 avoid text relocations are defined yet have verneed. We could
11319 use a heuristic to detect the special case, for example, check
11320 for verneed first on symbols defined in SHT_NOBITS sections, but
11321 it is simpler and more reliable to just look for both verdef and
11322 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11323
ab273396
AM
11324 if (psym->st_shndx != SHN_UNDEF
11325 && vers_data != 0x8001
11326 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
11327 {
11328 Elf_Internal_Verdef ivd;
11329 Elf_Internal_Verdaux ivda;
11330 Elf_External_Verdaux evda;
11331 unsigned long off;
bb4d2ac2 11332
dda8d76d 11333 off = offset_from_vma (filedata,
ab273396
AM
11334 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
11335 sizeof (Elf_External_Verdef));
11336
11337 do
bb4d2ac2 11338 {
ab273396
AM
11339 Elf_External_Verdef evd;
11340
dda8d76d 11341 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11342 _("version def")) == NULL)
11343 {
11344 ivd.vd_ndx = 0;
11345 ivd.vd_aux = 0;
11346 ivd.vd_next = 0;
1f6f5dba 11347 ivd.vd_flags = 0;
ab273396
AM
11348 }
11349 else
bb4d2ac2 11350 {
ab273396
AM
11351 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11352 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11353 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 11354 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 11355 }
bb4d2ac2 11356
ab273396
AM
11357 off += ivd.vd_next;
11358 }
11359 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11360
ab273396
AM
11361 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11362 {
1f6f5dba
L
11363 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
11364 return NULL;
11365
ab273396
AM
11366 off -= ivd.vd_next;
11367 off += ivd.vd_aux;
bb4d2ac2 11368
dda8d76d 11369 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
11370 _("version def aux")) != NULL)
11371 {
11372 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 11373
ab273396
AM
11374 if (psym->st_name != ivda.vda_name)
11375 {
11376 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
11377 ? symbol_hidden : symbol_public);
11378 return (ivda.vda_name < strtab_size
11379 ? strtab + ivda.vda_name : _("<corrupt>"));
11380 }
11381 }
11382 }
11383 }
bb4d2ac2 11384
ab273396
AM
11385 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
11386 {
11387 Elf_External_Verneed evn;
11388 Elf_Internal_Verneed ivn;
11389 Elf_Internal_Vernaux ivna;
bb4d2ac2 11390
dda8d76d 11391 offset = offset_from_vma (filedata,
ab273396
AM
11392 version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
11393 sizeof evn);
11394 do
11395 {
11396 unsigned long vna_off;
bb4d2ac2 11397
dda8d76d 11398 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
11399 _("version need")) == NULL)
11400 {
11401 ivna.vna_next = 0;
11402 ivna.vna_other = 0;
11403 ivna.vna_name = 0;
11404 break;
11405 }
bb4d2ac2 11406
ab273396
AM
11407 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11408 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 11409
ab273396 11410 vna_off = offset + ivn.vn_aux;
bb4d2ac2 11411
ab273396
AM
11412 do
11413 {
11414 Elf_External_Vernaux evna;
bb4d2ac2 11415
dda8d76d 11416 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 11417 _("version need aux (3)")) == NULL)
bb4d2ac2 11418 {
ab273396
AM
11419 ivna.vna_next = 0;
11420 ivna.vna_other = 0;
11421 ivna.vna_name = 0;
bb4d2ac2 11422 }
bb4d2ac2 11423 else
bb4d2ac2 11424 {
ab273396
AM
11425 ivna.vna_other = BYTE_GET (evna.vna_other);
11426 ivna.vna_next = BYTE_GET (evna.vna_next);
11427 ivna.vna_name = BYTE_GET (evna.vna_name);
11428 }
bb4d2ac2 11429
ab273396
AM
11430 vna_off += ivna.vna_next;
11431 }
11432 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 11433
ab273396
AM
11434 if (ivna.vna_other == vers_data)
11435 break;
bb4d2ac2 11436
ab273396
AM
11437 offset += ivn.vn_next;
11438 }
11439 while (ivn.vn_next != 0);
bb4d2ac2 11440
ab273396
AM
11441 if (ivna.vna_other == vers_data)
11442 {
11443 *sym_info = symbol_undefined;
11444 *vna_other = ivna.vna_other;
11445 return (ivna.vna_name < strtab_size
11446 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2
L
11447 }
11448 }
ab273396 11449 return NULL;
bb4d2ac2
L
11450}
11451
e3c8793a 11452/* Dump the symbol table. */
32ec8896 11453static bfd_boolean
dda8d76d 11454process_symbol_table (Filedata * filedata)
252b5132 11455{
2cf0635d 11456 Elf_Internal_Shdr * section;
8b73c356
NC
11457 bfd_size_type nbuckets = 0;
11458 bfd_size_type nchains = 0;
2cf0635d
NC
11459 bfd_vma * buckets = NULL;
11460 bfd_vma * chains = NULL;
fdc90cb4 11461 bfd_vma ngnubuckets = 0;
2cf0635d
NC
11462 bfd_vma * gnubuckets = NULL;
11463 bfd_vma * gnuchains = NULL;
6bd1a22c 11464 bfd_vma gnusymidx = 0;
071436c6 11465 bfd_size_type ngnuchains = 0;
252b5132 11466
2c610e4b 11467 if (!do_syms && !do_dyn_syms && !do_histogram)
32ec8896 11468 return TRUE;
252b5132 11469
6bd1a22c
L
11470 if (dynamic_info[DT_HASH]
11471 && (do_histogram
2c610e4b
L
11472 || (do_using_dynamic
11473 && !do_dyn_syms
11474 && dynamic_strings != NULL)))
252b5132 11475 {
66543521
AM
11476 unsigned char nb[8];
11477 unsigned char nc[8];
8b73c356 11478 unsigned int hash_ent_size = 4;
66543521 11479
dda8d76d
NC
11480 if ((filedata->file_header.e_machine == EM_ALPHA
11481 || filedata->file_header.e_machine == EM_S390
11482 || filedata->file_header.e_machine == EM_S390_OLD)
11483 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
66543521
AM
11484 hash_ent_size = 8;
11485
dda8d76d 11486 if (fseek (filedata->handle,
fb52b2f4 11487 (archive_file_offset
dda8d76d 11488 + offset_from_vma (filedata, dynamic_info[DT_HASH],
fb52b2f4 11489 sizeof nb + sizeof nc)),
d93f0186 11490 SEEK_SET))
252b5132 11491 {
591a748a 11492 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11493 goto no_hash;
252b5132
RH
11494 }
11495
dda8d76d 11496 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11497 {
11498 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11499 goto no_hash;
252b5132
RH
11500 }
11501
dda8d76d 11502 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11503 {
11504 error (_("Failed to read in number of chains\n"));
d3a44ec6 11505 goto no_hash;
252b5132
RH
11506 }
11507
66543521
AM
11508 nbuckets = byte_get (nb, hash_ent_size);
11509 nchains = byte_get (nc, hash_ent_size);
252b5132 11510
dda8d76d
NC
11511 buckets = get_dynamic_data (filedata, nbuckets, hash_ent_size);
11512 chains = get_dynamic_data (filedata, nchains, hash_ent_size);
252b5132 11513
d3a44ec6 11514 no_hash:
252b5132 11515 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
11516 {
11517 if (do_using_dynamic)
32ec8896 11518 return FALSE;
d3a44ec6
JJ
11519 free (buckets);
11520 free (chains);
11521 buckets = NULL;
11522 chains = NULL;
11523 nbuckets = 0;
11524 nchains = 0;
11525 }
252b5132
RH
11526 }
11527
6bd1a22c
L
11528 if (dynamic_info_DT_GNU_HASH
11529 && (do_histogram
2c610e4b
L
11530 || (do_using_dynamic
11531 && !do_dyn_syms
11532 && dynamic_strings != NULL)))
252b5132 11533 {
6bd1a22c
L
11534 unsigned char nb[16];
11535 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11536 bfd_vma buckets_vma;
11537
dda8d76d 11538 if (fseek (filedata->handle,
6bd1a22c 11539 (archive_file_offset
dda8d76d 11540 + offset_from_vma (filedata, dynamic_info_DT_GNU_HASH,
6bd1a22c
L
11541 sizeof nb)),
11542 SEEK_SET))
11543 {
11544 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11545 goto no_gnu_hash;
6bd1a22c 11546 }
252b5132 11547
dda8d76d 11548 if (fread (nb, 16, 1, filedata->handle) != 1)
6bd1a22c
L
11549 {
11550 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11551 goto no_gnu_hash;
6bd1a22c
L
11552 }
11553
11554 ngnubuckets = byte_get (nb, 4);
11555 gnusymidx = byte_get (nb + 4, 4);
11556 bitmaskwords = byte_get (nb + 8, 4);
11557 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 11558 if (is_32bit_elf)
6bd1a22c 11559 buckets_vma += bitmaskwords * 4;
f7a99963 11560 else
6bd1a22c 11561 buckets_vma += bitmaskwords * 8;
252b5132 11562
dda8d76d 11563 if (fseek (filedata->handle,
6bd1a22c 11564 (archive_file_offset
dda8d76d 11565 + offset_from_vma (filedata, buckets_vma, 4)),
6bd1a22c 11566 SEEK_SET))
252b5132 11567 {
6bd1a22c 11568 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11569 goto no_gnu_hash;
6bd1a22c
L
11570 }
11571
dda8d76d 11572 gnubuckets = get_dynamic_data (filedata, ngnubuckets, 4);
252b5132 11573
6bd1a22c 11574 if (gnubuckets == NULL)
d3a44ec6 11575 goto no_gnu_hash;
6bd1a22c
L
11576
11577 for (i = 0; i < ngnubuckets; i++)
11578 if (gnubuckets[i] != 0)
11579 {
11580 if (gnubuckets[i] < gnusymidx)
32ec8896 11581 return FALSE;
6bd1a22c
L
11582
11583 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
11584 maxchain = gnubuckets[i];
11585 }
11586
11587 if (maxchain == 0xffffffff)
d3a44ec6 11588 goto no_gnu_hash;
6bd1a22c
L
11589
11590 maxchain -= gnusymidx;
11591
dda8d76d 11592 if (fseek (filedata->handle,
6bd1a22c 11593 (archive_file_offset
dda8d76d 11594 + offset_from_vma (filedata, buckets_vma
6bd1a22c
L
11595 + 4 * (ngnubuckets + maxchain), 4)),
11596 SEEK_SET))
11597 {
11598 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11599 goto no_gnu_hash;
6bd1a22c
L
11600 }
11601
11602 do
11603 {
dda8d76d 11604 if (fread (nb, 4, 1, filedata->handle) != 1)
252b5132 11605 {
6bd1a22c 11606 error (_("Failed to determine last chain length\n"));
d3a44ec6 11607 goto no_gnu_hash;
6bd1a22c 11608 }
252b5132 11609
6bd1a22c 11610 if (maxchain + 1 == 0)
d3a44ec6 11611 goto no_gnu_hash;
252b5132 11612
6bd1a22c
L
11613 ++maxchain;
11614 }
11615 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 11616
dda8d76d 11617 if (fseek (filedata->handle,
6bd1a22c 11618 (archive_file_offset
dda8d76d 11619 + offset_from_vma (filedata, buckets_vma + 4 * ngnubuckets, 4)),
6bd1a22c
L
11620 SEEK_SET))
11621 {
11622 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11623 goto no_gnu_hash;
6bd1a22c
L
11624 }
11625
dda8d76d 11626 gnuchains = get_dynamic_data (filedata, maxchain, 4);
071436c6 11627 ngnuchains = maxchain;
6bd1a22c 11628
d3a44ec6 11629 no_gnu_hash:
6bd1a22c 11630 if (gnuchains == NULL)
d3a44ec6
JJ
11631 {
11632 free (gnubuckets);
d3a44ec6
JJ
11633 gnubuckets = NULL;
11634 ngnubuckets = 0;
f64fddf1 11635 if (do_using_dynamic)
32ec8896 11636 return FALSE;
d3a44ec6 11637 }
6bd1a22c
L
11638 }
11639
11640 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
11641 && do_syms
11642 && do_using_dynamic
3102e897
NC
11643 && dynamic_strings != NULL
11644 && dynamic_symbols != NULL)
6bd1a22c
L
11645 {
11646 unsigned long hn;
11647
11648 if (dynamic_info[DT_HASH])
11649 {
11650 bfd_vma si;
6bd6a03d 11651 char *visited;
6bd1a22c
L
11652
11653 printf (_("\nSymbol table for image:\n"));
11654 if (is_32bit_elf)
11655 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11656 else
11657 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11658
6bd6a03d
AM
11659 visited = xcmalloc (nchains, 1);
11660 memset (visited, 0, nchains);
6bd1a22c
L
11661 for (hn = 0; hn < nbuckets; hn++)
11662 {
6bd6a03d
AM
11663 for (si = buckets[hn]; si > 0; si = chains[si])
11664 {
dda8d76d 11665 print_dynamic_symbol (filedata, si, hn);
6bd6a03d
AM
11666 if (si >= nchains || visited[si])
11667 {
11668 error (_("histogram chain is corrupt\n"));
11669 break;
11670 }
11671 visited[si] = 1;
11672 }
252b5132 11673 }
6bd6a03d 11674 free (visited);
252b5132 11675 }
6bd1a22c
L
11676
11677 if (dynamic_info_DT_GNU_HASH)
11678 {
11679 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
11680 if (is_32bit_elf)
11681 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11682 else
11683 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11684
11685 for (hn = 0; hn < ngnubuckets; ++hn)
11686 if (gnubuckets[hn] != 0)
11687 {
11688 bfd_vma si = gnubuckets[hn];
11689 bfd_vma off = si - gnusymidx;
11690
11691 do
11692 {
dda8d76d 11693 print_dynamic_symbol (filedata, si, hn);
6bd1a22c
L
11694 si++;
11695 }
071436c6 11696 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
11697 }
11698 }
252b5132 11699 }
8b73c356 11700 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 11701 && filedata->section_headers != NULL)
252b5132 11702 {
b34976b6 11703 unsigned int i;
252b5132 11704
dda8d76d
NC
11705 for (i = 0, section = filedata->section_headers;
11706 i < filedata->file_header.e_shnum;
252b5132
RH
11707 i++, section++)
11708 {
b34976b6 11709 unsigned int si;
2cf0635d 11710 char * strtab = NULL;
c256ffe7 11711 unsigned long int strtab_size = 0;
2cf0635d
NC
11712 Elf_Internal_Sym * symtab;
11713 Elf_Internal_Sym * psym;
ba5cdace 11714 unsigned long num_syms;
252b5132 11715
2c610e4b
L
11716 if ((section->sh_type != SHT_SYMTAB
11717 && section->sh_type != SHT_DYNSYM)
11718 || (!do_syms
11719 && section->sh_type == SHT_SYMTAB))
252b5132
RH
11720 continue;
11721
dd24e3da
NC
11722 if (section->sh_entsize == 0)
11723 {
11724 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 11725 printable_section_name (filedata, section));
dd24e3da
NC
11726 continue;
11727 }
11728
d3a49aa8
AM
11729 num_syms = section->sh_size / section->sh_entsize;
11730 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
11731 "\nSymbol table '%s' contains %lu entries:\n",
11732 num_syms),
dda8d76d 11733 printable_section_name (filedata, section),
d3a49aa8 11734 num_syms);
dd24e3da 11735
f7a99963 11736 if (is_32bit_elf)
ca47b30c 11737 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 11738 else
ca47b30c 11739 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 11740
dda8d76d 11741 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
11742 if (symtab == NULL)
11743 continue;
11744
dda8d76d 11745 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 11746 {
dda8d76d
NC
11747 strtab = filedata->string_table;
11748 strtab_size = filedata->string_table_length;
c256ffe7 11749 }
dda8d76d 11750 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 11751 {
2cf0635d 11752 Elf_Internal_Shdr * string_sec;
252b5132 11753
dda8d76d 11754 string_sec = filedata->section_headers + section->sh_link;
252b5132 11755
dda8d76d 11756 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
11757 1, string_sec->sh_size,
11758 _("string table"));
c256ffe7 11759 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
11760 }
11761
ba5cdace 11762 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 11763 {
bb4d2ac2
L
11764 const char *version_string;
11765 enum versioned_symbol_info sym_info;
11766 unsigned short vna_other;
11767
5e220199 11768 printf ("%6d: ", si);
f7a99963
NC
11769 print_vma (psym->st_value, LONG_HEX);
11770 putchar (' ');
11771 print_vma (psym->st_size, DEC_5);
dda8d76d
NC
11772 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11773 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
11774 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11775 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11776 else
11777 {
11778 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11779
11780 printf (" %-7s", get_symbol_visibility (vis));
11781 /* Check to see if any other bits in the st_other field are set.
11782 Note - displaying this information disrupts the layout of the
11783 table being generated, but for the moment this case is very rare. */
11784 if (psym->st_other ^ vis)
dda8d76d 11785 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1 11786 }
dda8d76d 11787 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
c256ffe7 11788 print_symbol (25, psym->st_name < strtab_size
2b692964 11789 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 11790
bb4d2ac2 11791 version_string
dda8d76d 11792 = get_symbol_version_string (filedata,
bb4d2ac2
L
11793 section->sh_type == SHT_DYNSYM,
11794 strtab, strtab_size, si,
11795 psym, &sym_info, &vna_other);
11796 if (version_string)
252b5132 11797 {
bb4d2ac2
L
11798 if (sym_info == symbol_undefined)
11799 printf ("@%s (%d)", version_string, vna_other);
11800 else
11801 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
11802 version_string);
252b5132
RH
11803 }
11804
11805 putchar ('\n');
52c3c391
NC
11806
11807 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
dd905818
NC
11808 && si >= section->sh_info
11809 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
dda8d76d 11810 && filedata->file_header.e_machine != EM_MIPS
dd905818
NC
11811 /* Solaris binaries have been found to violate this requirement as
11812 well. Not sure if this is a bug or an ABI requirement. */
dda8d76d 11813 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
52c3c391 11814 warn (_("local symbol %u found at index >= %s's sh_info value of %u\n"),
dda8d76d 11815 si, printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11816 }
11817
11818 free (symtab);
dda8d76d 11819 if (strtab != filedata->string_table)
252b5132
RH
11820 free (strtab);
11821 }
11822 }
11823 else if (do_syms)
11824 printf
11825 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
11826
11827 if (do_histogram && buckets != NULL)
11828 {
2cf0635d
NC
11829 unsigned long * lengths;
11830 unsigned long * counts;
66543521
AM
11831 unsigned long hn;
11832 bfd_vma si;
11833 unsigned long maxlength = 0;
11834 unsigned long nzero_counts = 0;
11835 unsigned long nsyms = 0;
6bd6a03d 11836 char *visited;
252b5132 11837
d3a49aa8
AM
11838 printf (ngettext ("\nHistogram for bucket list length "
11839 "(total of %lu bucket):\n",
11840 "\nHistogram for bucket list length "
11841 "(total of %lu buckets):\n",
11842 (unsigned long) nbuckets),
66543521 11843 (unsigned long) nbuckets);
252b5132 11844
3f5e193b 11845 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
11846 if (lengths == NULL)
11847 {
8b73c356 11848 error (_("Out of memory allocating space for histogram buckets\n"));
32ec8896 11849 return FALSE;
252b5132 11850 }
6bd6a03d
AM
11851 visited = xcmalloc (nchains, 1);
11852 memset (visited, 0, nchains);
8b73c356
NC
11853
11854 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
11855 for (hn = 0; hn < nbuckets; ++hn)
11856 {
6bd6a03d 11857 for (si = buckets[hn]; si > 0; si = chains[si])
252b5132 11858 {
b34976b6 11859 ++nsyms;
252b5132 11860 if (maxlength < ++lengths[hn])
b34976b6 11861 ++maxlength;
6bd6a03d
AM
11862 if (si >= nchains || visited[si])
11863 {
11864 error (_("histogram chain is corrupt\n"));
11865 break;
11866 }
11867 visited[si] = 1;
252b5132
RH
11868 }
11869 }
6bd6a03d 11870 free (visited);
252b5132 11871
3f5e193b 11872 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
11873 if (counts == NULL)
11874 {
b2e951ec 11875 free (lengths);
8b73c356 11876 error (_("Out of memory allocating space for histogram counts\n"));
32ec8896 11877 return FALSE;
252b5132
RH
11878 }
11879
11880 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 11881 ++counts[lengths[hn]];
252b5132 11882
103f02d3 11883 if (nbuckets > 0)
252b5132 11884 {
66543521
AM
11885 unsigned long i;
11886 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 11887 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 11888 for (i = 1; i <= maxlength; ++i)
103f02d3 11889 {
66543521
AM
11890 nzero_counts += counts[i] * i;
11891 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11892 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
11893 (nzero_counts * 100.0) / nsyms);
11894 }
252b5132
RH
11895 }
11896
11897 free (counts);
11898 free (lengths);
11899 }
11900
11901 if (buckets != NULL)
11902 {
11903 free (buckets);
11904 free (chains);
11905 }
11906
d3a44ec6 11907 if (do_histogram && gnubuckets != NULL)
fdc90cb4 11908 {
2cf0635d
NC
11909 unsigned long * lengths;
11910 unsigned long * counts;
fdc90cb4
JJ
11911 unsigned long hn;
11912 unsigned long maxlength = 0;
11913 unsigned long nzero_counts = 0;
11914 unsigned long nsyms = 0;
fdc90cb4 11915
d3a49aa8
AM
11916 printf (ngettext ("\nHistogram for `.gnu.hash' bucket list length "
11917 "(total of %lu bucket):\n",
11918 "\nHistogram for `.gnu.hash' bucket list length "
11919 "(total of %lu buckets):\n",
11920 (unsigned long) ngnubuckets),
8b73c356
NC
11921 (unsigned long) ngnubuckets);
11922
3f5e193b 11923 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
11924 if (lengths == NULL)
11925 {
8b73c356 11926 error (_("Out of memory allocating space for gnu histogram buckets\n"));
32ec8896 11927 return FALSE;
fdc90cb4
JJ
11928 }
11929
fdc90cb4
JJ
11930 printf (_(" Length Number %% of total Coverage\n"));
11931
11932 for (hn = 0; hn < ngnubuckets; ++hn)
11933 if (gnubuckets[hn] != 0)
11934 {
11935 bfd_vma off, length = 1;
11936
6bd1a22c 11937 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
11938 /* PR 17531 file: 010-77222-0.004. */
11939 off < ngnuchains && (gnuchains[off] & 1) == 0;
11940 ++off)
fdc90cb4
JJ
11941 ++length;
11942 lengths[hn] = length;
11943 if (length > maxlength)
11944 maxlength = length;
11945 nsyms += length;
11946 }
11947
3f5e193b 11948 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
11949 if (counts == NULL)
11950 {
b2e951ec 11951 free (lengths);
8b73c356 11952 error (_("Out of memory allocating space for gnu histogram counts\n"));
32ec8896 11953 return FALSE;
fdc90cb4
JJ
11954 }
11955
11956 for (hn = 0; hn < ngnubuckets; ++hn)
11957 ++counts[lengths[hn]];
11958
11959 if (ngnubuckets > 0)
11960 {
11961 unsigned long j;
11962 printf (" 0 %-10lu (%5.1f%%)\n",
11963 counts[0], (counts[0] * 100.0) / ngnubuckets);
11964 for (j = 1; j <= maxlength; ++j)
11965 {
11966 nzero_counts += counts[j] * j;
11967 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11968 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
11969 (nzero_counts * 100.0) / nsyms);
11970 }
11971 }
11972
11973 free (counts);
11974 free (lengths);
11975 free (gnubuckets);
11976 free (gnuchains);
11977 }
11978
32ec8896 11979 return TRUE;
252b5132
RH
11980}
11981
32ec8896 11982static bfd_boolean
dda8d76d 11983process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 11984{
b4c96d0d 11985 unsigned int i;
252b5132
RH
11986
11987 if (dynamic_syminfo == NULL
11988 || !do_dynamic)
11989 /* No syminfo, this is ok. */
32ec8896 11990 return TRUE;
252b5132
RH
11991
11992 /* There better should be a dynamic symbol section. */
11993 if (dynamic_symbols == NULL || dynamic_strings == NULL)
32ec8896 11994 return FALSE;
252b5132
RH
11995
11996 if (dynamic_addr)
d3a49aa8
AM
11997 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
11998 "contains %d entry:\n",
11999 "\nDynamic info segment at offset 0x%lx "
12000 "contains %d entries:\n",
12001 dynamic_syminfo_nent),
252b5132
RH
12002 dynamic_syminfo_offset, dynamic_syminfo_nent);
12003
12004 printf (_(" Num: Name BoundTo Flags\n"));
12005 for (i = 0; i < dynamic_syminfo_nent; ++i)
12006 {
12007 unsigned short int flags = dynamic_syminfo[i].si_flags;
12008
31104126 12009 printf ("%4d: ", i);
4082ef84
NC
12010 if (i >= num_dynamic_syms)
12011 printf (_("<corrupt index>"));
12012 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
12013 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
12014 else
2b692964 12015 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 12016 putchar (' ');
252b5132
RH
12017
12018 switch (dynamic_syminfo[i].si_boundto)
12019 {
12020 case SYMINFO_BT_SELF:
12021 fputs ("SELF ", stdout);
12022 break;
12023 case SYMINFO_BT_PARENT:
12024 fputs ("PARENT ", stdout);
12025 break;
12026 default:
12027 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
12028 && dynamic_syminfo[i].si_boundto < dynamic_nent
12029 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12030 {
d79b3d50 12031 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12032 putchar (' ' );
12033 }
252b5132
RH
12034 else
12035 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
12036 break;
12037 }
12038
12039 if (flags & SYMINFO_FLG_DIRECT)
12040 printf (" DIRECT");
12041 if (flags & SYMINFO_FLG_PASSTHRU)
12042 printf (" PASSTHRU");
12043 if (flags & SYMINFO_FLG_COPY)
12044 printf (" COPY");
12045 if (flags & SYMINFO_FLG_LAZYLOAD)
12046 printf (" LAZYLOAD");
12047
12048 puts ("");
12049 }
12050
32ec8896 12051 return TRUE;
252b5132
RH
12052}
12053
b32e566b
NC
12054#define IN_RANGE(START,END,ADDR,OFF) \
12055 (((ADDR) >= (START)) && ((ADDR) + (OFF) < (END)))
12056
cf13d699
NC
12057/* Check to see if the given reloc needs to be handled in a target specific
12058 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12059 FALSE.
12060
12061 If called with reloc == NULL, then this is a signal that reloc processing
12062 for the current section has finished, and any saved state should be
12063 discarded. */
09c11c86 12064
cf13d699 12065static bfd_boolean
dda8d76d
NC
12066target_specific_reloc_handling (Filedata * filedata,
12067 Elf_Internal_Rela * reloc,
12068 unsigned char * start,
12069 unsigned char * end,
12070 Elf_Internal_Sym * symtab,
12071 unsigned long num_syms)
252b5132 12072{
f84ce13b
NC
12073 unsigned int reloc_type = 0;
12074 unsigned long sym_index = 0;
12075
12076 if (reloc)
12077 {
dda8d76d 12078 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12079 sym_index = get_reloc_symindex (reloc->r_info);
12080 }
252b5132 12081
dda8d76d 12082 switch (filedata->file_header.e_machine)
252b5132 12083 {
13761a11
NC
12084 case EM_MSP430:
12085 case EM_MSP430_OLD:
12086 {
12087 static Elf_Internal_Sym * saved_sym = NULL;
12088
f84ce13b
NC
12089 if (reloc == NULL)
12090 {
12091 saved_sym = NULL;
12092 return TRUE;
12093 }
12094
13761a11
NC
12095 switch (reloc_type)
12096 {
12097 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12098 if (uses_msp430x_relocs (filedata))
13761a11 12099 break;
1a0670f3 12100 /* Fall through. */
13761a11 12101 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12102 /* PR 21139. */
12103 if (sym_index >= num_syms)
12104 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12105 sym_index);
12106 else
12107 saved_sym = symtab + sym_index;
13761a11
NC
12108 return TRUE;
12109
12110 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12111 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12112 goto handle_sym_diff;
0b4362b0 12113
13761a11
NC
12114 case 5: /* R_MSP430_16_BYTE */
12115 case 9: /* R_MSP430_8 */
dda8d76d 12116 if (uses_msp430x_relocs (filedata))
13761a11
NC
12117 break;
12118 goto handle_sym_diff;
12119
12120 case 2: /* R_MSP430_ABS16 */
12121 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12122 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12123 break;
12124 goto handle_sym_diff;
0b4362b0 12125
13761a11
NC
12126 handle_sym_diff:
12127 if (saved_sym != NULL)
12128 {
03f7786e 12129 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12130 bfd_vma value;
12131
f84ce13b
NC
12132 if (sym_index >= num_syms)
12133 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12134 sym_index);
03f7786e 12135 else
f84ce13b
NC
12136 {
12137 value = reloc->r_addend + (symtab[sym_index].st_value
12138 - saved_sym->st_value);
12139
b32e566b 12140 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12141 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12142 else
12143 /* PR 21137 */
12144 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12145 (long) reloc->r_offset);
f84ce13b 12146 }
13761a11
NC
12147
12148 saved_sym = NULL;
12149 return TRUE;
12150 }
12151 break;
12152
12153 default:
12154 if (saved_sym != NULL)
071436c6 12155 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12156 break;
12157 }
12158 break;
12159 }
12160
cf13d699
NC
12161 case EM_MN10300:
12162 case EM_CYGNUS_MN10300:
12163 {
12164 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12165
f84ce13b
NC
12166 if (reloc == NULL)
12167 {
12168 saved_sym = NULL;
12169 return TRUE;
12170 }
12171
cf13d699
NC
12172 switch (reloc_type)
12173 {
12174 case 34: /* R_MN10300_ALIGN */
12175 return TRUE;
12176 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12177 if (sym_index >= num_syms)
12178 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12179 sym_index);
12180 else
12181 saved_sym = symtab + sym_index;
cf13d699 12182 return TRUE;
f84ce13b 12183
cf13d699
NC
12184 case 1: /* R_MN10300_32 */
12185 case 2: /* R_MN10300_16 */
12186 if (saved_sym != NULL)
12187 {
03f7786e 12188 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12189 bfd_vma value;
252b5132 12190
f84ce13b
NC
12191 if (sym_index >= num_syms)
12192 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12193 sym_index);
03f7786e 12194 else
f84ce13b
NC
12195 {
12196 value = reloc->r_addend + (symtab[sym_index].st_value
12197 - saved_sym->st_value);
12198
b32e566b 12199 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12200 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12201 else
12202 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12203 (long) reloc->r_offset);
f84ce13b 12204 }
252b5132 12205
cf13d699
NC
12206 saved_sym = NULL;
12207 return TRUE;
12208 }
12209 break;
12210 default:
12211 if (saved_sym != NULL)
071436c6 12212 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12213 break;
12214 }
12215 break;
12216 }
6ff71e76
NC
12217
12218 case EM_RL78:
12219 {
12220 static bfd_vma saved_sym1 = 0;
12221 static bfd_vma saved_sym2 = 0;
12222 static bfd_vma value;
12223
f84ce13b
NC
12224 if (reloc == NULL)
12225 {
12226 saved_sym1 = saved_sym2 = 0;
12227 return TRUE;
12228 }
12229
6ff71e76
NC
12230 switch (reloc_type)
12231 {
12232 case 0x80: /* R_RL78_SYM. */
12233 saved_sym1 = saved_sym2;
f84ce13b
NC
12234 if (sym_index >= num_syms)
12235 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12236 sym_index);
12237 else
12238 {
12239 saved_sym2 = symtab[sym_index].st_value;
12240 saved_sym2 += reloc->r_addend;
12241 }
6ff71e76
NC
12242 return TRUE;
12243
12244 case 0x83: /* R_RL78_OPsub. */
12245 value = saved_sym1 - saved_sym2;
12246 saved_sym2 = saved_sym1 = 0;
12247 return TRUE;
12248 break;
12249
12250 case 0x41: /* R_RL78_ABS32. */
b32e566b 12251 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12252 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12253 else
12254 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12255 (long) reloc->r_offset);
6ff71e76
NC
12256 value = 0;
12257 return TRUE;
12258
12259 case 0x43: /* R_RL78_ABS16. */
b32e566b 12260 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12261 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12262 else
12263 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12264 (long) reloc->r_offset);
6ff71e76
NC
12265 value = 0;
12266 return TRUE;
12267
12268 default:
12269 break;
12270 }
12271 break;
12272 }
252b5132
RH
12273 }
12274
cf13d699 12275 return FALSE;
252b5132
RH
12276}
12277
aca88567
NC
12278/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12279 DWARF debug sections. This is a target specific test. Note - we do not
12280 go through the whole including-target-headers-multiple-times route, (as
12281 we have already done with <elf/h8.h>) because this would become very
12282 messy and even then this function would have to contain target specific
12283 information (the names of the relocs instead of their numeric values).
12284 FIXME: This is not the correct way to solve this problem. The proper way
12285 is to have target specific reloc sizing and typing functions created by
12286 the reloc-macros.h header, in the same way that it already creates the
12287 reloc naming functions. */
12288
12289static bfd_boolean
dda8d76d 12290is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12291{
d347c9df 12292 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12293 switch (filedata->file_header.e_machine)
aca88567 12294 {
41e92641 12295 case EM_386:
22abe556 12296 case EM_IAMCU:
41e92641 12297 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12298 case EM_68K:
12299 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12300 case EM_860:
12301 return reloc_type == 1; /* R_860_32. */
12302 case EM_960:
12303 return reloc_type == 2; /* R_960_32. */
a06ea964 12304 case EM_AARCH64:
9282b95a
JW
12305 return (reloc_type == 258
12306 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
d347c9df
PS
12307 case EM_ADAPTEVA_EPIPHANY:
12308 return reloc_type == 3;
aca88567 12309 case EM_ALPHA:
137b6b5f 12310 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12311 case EM_ARC:
12312 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12313 case EM_ARC_COMPACT:
12314 case EM_ARC_COMPACT2:
12315 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12316 case EM_ARM:
12317 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12318 case EM_AVR_OLD:
aca88567
NC
12319 case EM_AVR:
12320 return reloc_type == 1;
12321 case EM_BLACKFIN:
12322 return reloc_type == 0x12; /* R_byte4_data. */
12323 case EM_CRIS:
12324 return reloc_type == 3; /* R_CRIS_32. */
12325 case EM_CR16:
12326 return reloc_type == 3; /* R_CR16_NUM32. */
12327 case EM_CRX:
12328 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
12329 case EM_CSKY:
12330 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
12331 case EM_CYGNUS_FRV:
12332 return reloc_type == 1;
41e92641
NC
12333 case EM_CYGNUS_D10V:
12334 case EM_D10V:
12335 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12336 case EM_CYGNUS_D30V:
12337 case EM_D30V:
12338 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12339 case EM_DLX:
12340 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12341 case EM_CYGNUS_FR30:
12342 case EM_FR30:
12343 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12344 case EM_FT32:
12345 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12346 case EM_H8S:
12347 case EM_H8_300:
12348 case EM_H8_300H:
12349 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12350 case EM_IA_64:
262cdac7
AM
12351 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12352 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12353 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12354 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12355 case EM_IP2K_OLD:
12356 case EM_IP2K:
12357 return reloc_type == 2; /* R_IP2K_32. */
12358 case EM_IQ2000:
12359 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12360 case EM_LATTICEMICO32:
12361 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12362 case EM_M32C_OLD:
aca88567
NC
12363 case EM_M32C:
12364 return reloc_type == 3; /* R_M32C_32. */
12365 case EM_M32R:
12366 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12367 case EM_68HC11:
12368 case EM_68HC12:
12369 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824
JD
12370 case EM_S12Z:
12371 return reloc_type == 6; /* R_S12Z_EXT32. */
aca88567
NC
12372 case EM_MCORE:
12373 return reloc_type == 1; /* R_MCORE_ADDR32. */
12374 case EM_CYGNUS_MEP:
12375 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12376 case EM_METAG:
12377 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12378 case EM_MICROBLAZE:
12379 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12380 case EM_MIPS:
12381 return reloc_type == 2; /* R_MIPS_32. */
12382 case EM_MMIX:
12383 return reloc_type == 4; /* R_MMIX_32. */
12384 case EM_CYGNUS_MN10200:
12385 case EM_MN10200:
12386 return reloc_type == 1; /* R_MN10200_32. */
12387 case EM_CYGNUS_MN10300:
12388 case EM_MN10300:
12389 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12390 case EM_MOXIE:
12391 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12392 case EM_MSP430_OLD:
12393 case EM_MSP430:
13761a11 12394 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12395 case EM_MT:
12396 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12397 case EM_NDS32:
12398 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12399 case EM_ALTERA_NIOS2:
36591ba1 12400 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12401 case EM_NIOS32:
12402 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12403 case EM_OR1K:
12404 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12405 case EM_PARISC:
0df8ad28
NC
12406 return (reloc_type == 1 /* R_PARISC_DIR32. */
12407 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12408 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12409 case EM_PJ:
12410 case EM_PJ_OLD:
12411 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12412 case EM_PPC64:
12413 return reloc_type == 1; /* R_PPC64_ADDR32. */
12414 case EM_PPC:
12415 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12416 case EM_TI_PRU:
12417 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12418 case EM_RISCV:
12419 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12420 case EM_RL78:
12421 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12422 case EM_RX:
12423 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12424 case EM_S370:
12425 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12426 case EM_S390_OLD:
12427 case EM_S390:
12428 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12429 case EM_SCORE:
12430 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12431 case EM_SH:
12432 return reloc_type == 1; /* R_SH_DIR32. */
12433 case EM_SPARC32PLUS:
12434 case EM_SPARCV9:
12435 case EM_SPARC:
12436 return reloc_type == 3 /* R_SPARC_32. */
12437 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12438 case EM_SPU:
12439 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12440 case EM_TI_C6000:
12441 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12442 case EM_TILEGX:
12443 return reloc_type == 2; /* R_TILEGX_32. */
12444 case EM_TILEPRO:
12445 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12446 case EM_CYGNUS_V850:
12447 case EM_V850:
12448 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12449 case EM_V800:
12450 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12451 case EM_VAX:
12452 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12453 case EM_VISIUM:
12454 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12455 case EM_WEBASSEMBLY:
12456 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12457 case EM_X86_64:
8a9036a4 12458 case EM_L1OM:
7a9068fe 12459 case EM_K1OM:
aca88567 12460 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12461 case EM_XC16X:
12462 case EM_C166:
12463 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12464 case EM_XGATE:
12465 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12466 case EM_XSTORMY16:
12467 return reloc_type == 1; /* R_XSTROMY16_32. */
12468 case EM_XTENSA_OLD:
12469 case EM_XTENSA:
12470 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 12471 default:
bee0ee85
NC
12472 {
12473 static unsigned int prev_warn = 0;
12474
12475 /* Avoid repeating the same warning multiple times. */
dda8d76d 12476 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12477 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12478 filedata->file_header.e_machine);
12479 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12480 return FALSE;
12481 }
aca88567
NC
12482 }
12483}
12484
12485/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12486 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12487
12488static bfd_boolean
dda8d76d 12489is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12490{
dda8d76d 12491 switch (filedata->file_header.e_machine)
d347c9df 12492 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12493 {
41e92641 12494 case EM_386:
22abe556 12495 case EM_IAMCU:
3e0873ac 12496 return reloc_type == 2; /* R_386_PC32. */
aca88567 12497 case EM_68K:
3e0873ac 12498 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12499 case EM_AARCH64:
12500 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12501 case EM_ADAPTEVA_EPIPHANY:
12502 return reloc_type == 6;
aca88567
NC
12503 case EM_ALPHA:
12504 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12505 case EM_ARC_COMPACT:
12506 case EM_ARC_COMPACT2:
12507 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12508 case EM_ARM:
3e0873ac 12509 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12510 case EM_AVR_OLD:
12511 case EM_AVR:
12512 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12513 case EM_MICROBLAZE:
12514 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12515 case EM_OR1K:
12516 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 12517 case EM_PARISC:
85acf597 12518 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
12519 case EM_PPC:
12520 return reloc_type == 26; /* R_PPC_REL32. */
12521 case EM_PPC64:
3e0873ac 12522 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
12523 case EM_S390_OLD:
12524 case EM_S390:
3e0873ac 12525 return reloc_type == 5; /* R_390_PC32. */
aca88567 12526 case EM_SH:
3e0873ac 12527 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
12528 case EM_SPARC32PLUS:
12529 case EM_SPARCV9:
12530 case EM_SPARC:
3e0873ac 12531 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
12532 case EM_SPU:
12533 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
12534 case EM_TILEGX:
12535 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
12536 case EM_TILEPRO:
12537 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
12538 case EM_VISIUM:
12539 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 12540 case EM_X86_64:
8a9036a4 12541 case EM_L1OM:
7a9068fe 12542 case EM_K1OM:
3e0873ac 12543 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
12544 case EM_XTENSA_OLD:
12545 case EM_XTENSA:
12546 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
12547 default:
12548 /* Do not abort or issue an error message here. Not all targets use
12549 pc-relative 32-bit relocs in their DWARF debug information and we
12550 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
12551 more helpful warning message will be generated by apply_relocations
12552 anyway, so just return. */
aca88567
NC
12553 return FALSE;
12554 }
12555}
12556
12557/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12558 a 64-bit absolute RELA relocation used in DWARF debug sections. */
12559
12560static bfd_boolean
dda8d76d 12561is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12562{
dda8d76d 12563 switch (filedata->file_header.e_machine)
aca88567 12564 {
a06ea964
NC
12565 case EM_AARCH64:
12566 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
12567 case EM_ALPHA:
12568 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 12569 case EM_IA_64:
262cdac7
AM
12570 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
12571 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
12572 case EM_PARISC:
12573 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
12574 case EM_PPC64:
12575 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
12576 case EM_RISCV:
12577 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
12578 case EM_SPARC32PLUS:
12579 case EM_SPARCV9:
12580 case EM_SPARC:
714da62f
NC
12581 return reloc_type == 32 /* R_SPARC_64. */
12582 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 12583 case EM_X86_64:
8a9036a4 12584 case EM_L1OM:
7a9068fe 12585 case EM_K1OM:
aca88567 12586 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
12587 case EM_S390_OLD:
12588 case EM_S390:
aa137e4d
NC
12589 return reloc_type == 22; /* R_S390_64. */
12590 case EM_TILEGX:
12591 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 12592 case EM_MIPS:
aa137e4d 12593 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
12594 default:
12595 return FALSE;
12596 }
12597}
12598
85acf597
RH
12599/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
12600 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
12601
12602static bfd_boolean
dda8d76d 12603is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 12604{
dda8d76d 12605 switch (filedata->file_header.e_machine)
85acf597 12606 {
a06ea964
NC
12607 case EM_AARCH64:
12608 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 12609 case EM_ALPHA:
aa137e4d 12610 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 12611 case EM_IA_64:
262cdac7
AM
12612 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
12613 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 12614 case EM_PARISC:
aa137e4d 12615 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 12616 case EM_PPC64:
aa137e4d 12617 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
12618 case EM_SPARC32PLUS:
12619 case EM_SPARCV9:
12620 case EM_SPARC:
aa137e4d 12621 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 12622 case EM_X86_64:
8a9036a4 12623 case EM_L1OM:
7a9068fe 12624 case EM_K1OM:
aa137e4d 12625 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
12626 case EM_S390_OLD:
12627 case EM_S390:
aa137e4d
NC
12628 return reloc_type == 23; /* R_S390_PC64. */
12629 case EM_TILEGX:
12630 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
12631 default:
12632 return FALSE;
12633 }
12634}
12635
4dc3c23d
AM
12636/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12637 a 24-bit absolute RELA relocation used in DWARF debug sections. */
12638
12639static bfd_boolean
dda8d76d 12640is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 12641{
dda8d76d 12642 switch (filedata->file_header.e_machine)
4dc3c23d
AM
12643 {
12644 case EM_CYGNUS_MN10200:
12645 case EM_MN10200:
12646 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
12647 case EM_FT32:
12648 return reloc_type == 5; /* R_FT32_20. */
4dc3c23d
AM
12649 default:
12650 return FALSE;
12651 }
12652}
12653
aca88567
NC
12654/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12655 a 16-bit absolute RELA relocation used in DWARF debug sections. */
12656
12657static bfd_boolean
dda8d76d 12658is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 12659{
d347c9df 12660 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12661 switch (filedata->file_header.e_machine)
4b78141a 12662 {
886a2506
NC
12663 case EM_ARC:
12664 case EM_ARC_COMPACT:
12665 case EM_ARC_COMPACT2:
12666 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
12667 case EM_ADAPTEVA_EPIPHANY:
12668 return reloc_type == 5;
aca88567
NC
12669 case EM_AVR_OLD:
12670 case EM_AVR:
12671 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
12672 case EM_CYGNUS_D10V:
12673 case EM_D10V:
12674 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
12675 case EM_FT32:
12676 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
12677 case EM_H8S:
12678 case EM_H8_300:
12679 case EM_H8_300H:
aca88567
NC
12680 return reloc_type == R_H8_DIR16;
12681 case EM_IP2K_OLD:
12682 case EM_IP2K:
12683 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 12684 case EM_M32C_OLD:
f4236fe4
DD
12685 case EM_M32C:
12686 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
12687 case EM_CYGNUS_MN10200:
12688 case EM_MN10200:
12689 return reloc_type == 2; /* R_MN10200_16. */
12690 case EM_CYGNUS_MN10300:
12691 case EM_MN10300:
12692 return reloc_type == 2; /* R_MN10300_16. */
aca88567 12693 case EM_MSP430:
dda8d76d 12694 if (uses_msp430x_relocs (filedata))
13761a11 12695 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 12696 /* Fall through. */
78c8d46c 12697 case EM_MSP430_OLD:
aca88567 12698 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
12699 case EM_NDS32:
12700 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 12701 case EM_ALTERA_NIOS2:
36591ba1 12702 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
12703 case EM_NIOS32:
12704 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
12705 case EM_OR1K:
12706 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
12707 case EM_RISCV:
12708 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
12709 case EM_TI_PRU:
12710 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
12711 case EM_TI_C6000:
12712 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
12713 case EM_VISIUM:
12714 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
12715 case EM_XC16X:
12716 case EM_C166:
12717 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
12718 case EM_XGATE:
12719 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 12720 default:
aca88567 12721 return FALSE;
4b78141a
NC
12722 }
12723}
12724
39e07931
AS
12725/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12726 a 8-bit absolute RELA relocation used in DWARF debug sections. */
12727
12728static bfd_boolean
12729is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
12730{
12731 switch (filedata->file_header.e_machine)
12732 {
12733 case EM_RISCV:
12734 return reloc_type == 54; /* R_RISCV_SET8. */
12735 default:
12736 return FALSE;
12737 }
12738}
12739
12740/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12741 a 6-bit absolute RELA relocation used in DWARF debug sections. */
12742
12743static bfd_boolean
12744is_6bit_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 == 53; /* R_RISCV_SET6. */
12750 default:
12751 return FALSE;
12752 }
12753}
12754
03336641
JW
12755/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12756 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
12757
12758static bfd_boolean
12759is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12760{
12761 /* Please keep this table alpha-sorted for ease of visual lookup. */
12762 switch (filedata->file_header.e_machine)
12763 {
12764 case EM_RISCV:
12765 return reloc_type == 35; /* R_RISCV_ADD32. */
12766 default:
12767 return FALSE;
12768 }
12769}
12770
12771/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12772 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
12773
12774static bfd_boolean
12775is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12776{
12777 /* Please keep this table alpha-sorted for ease of visual lookup. */
12778 switch (filedata->file_header.e_machine)
12779 {
12780 case EM_RISCV:
12781 return reloc_type == 39; /* R_RISCV_SUB32. */
12782 default:
12783 return FALSE;
12784 }
12785}
12786
12787/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12788 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
12789
12790static bfd_boolean
12791is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12792{
12793 /* Please keep this table alpha-sorted for ease of visual lookup. */
12794 switch (filedata->file_header.e_machine)
12795 {
12796 case EM_RISCV:
12797 return reloc_type == 36; /* R_RISCV_ADD64. */
12798 default:
12799 return FALSE;
12800 }
12801}
12802
12803/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12804 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
12805
12806static bfd_boolean
12807is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12808{
12809 /* Please keep this table alpha-sorted for ease of visual lookup. */
12810 switch (filedata->file_header.e_machine)
12811 {
12812 case EM_RISCV:
12813 return reloc_type == 40; /* R_RISCV_SUB64. */
12814 default:
12815 return FALSE;
12816 }
12817}
12818
12819/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12820 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
12821
12822static bfd_boolean
12823is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12824{
12825 /* Please keep this table alpha-sorted for ease of visual lookup. */
12826 switch (filedata->file_header.e_machine)
12827 {
12828 case EM_RISCV:
12829 return reloc_type == 34; /* R_RISCV_ADD16. */
12830 default:
12831 return FALSE;
12832 }
12833}
12834
12835/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12836 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
12837
12838static bfd_boolean
12839is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12840{
12841 /* Please keep this table alpha-sorted for ease of visual lookup. */
12842 switch (filedata->file_header.e_machine)
12843 {
12844 case EM_RISCV:
12845 return reloc_type == 38; /* R_RISCV_SUB16. */
12846 default:
12847 return FALSE;
12848 }
12849}
12850
12851/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12852 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
12853
12854static bfd_boolean
12855is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12856{
12857 /* Please keep this table alpha-sorted for ease of visual lookup. */
12858 switch (filedata->file_header.e_machine)
12859 {
12860 case EM_RISCV:
12861 return reloc_type == 33; /* R_RISCV_ADD8. */
12862 default:
12863 return FALSE;
12864 }
12865}
12866
12867/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12868 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
12869
12870static bfd_boolean
12871is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12872{
12873 /* Please keep this table alpha-sorted for ease of visual lookup. */
12874 switch (filedata->file_header.e_machine)
12875 {
12876 case EM_RISCV:
12877 return reloc_type == 37; /* R_RISCV_SUB8. */
12878 default:
12879 return FALSE;
12880 }
12881}
12882
39e07931
AS
12883/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12884 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
12885
12886static bfd_boolean
12887is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12888{
12889 switch (filedata->file_header.e_machine)
12890 {
12891 case EM_RISCV:
12892 return reloc_type == 52; /* R_RISCV_SUB6. */
12893 default:
12894 return FALSE;
12895 }
12896}
12897
2a7b2e88
JK
12898/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
12899 relocation entries (possibly formerly used for SHT_GROUP sections). */
12900
12901static bfd_boolean
dda8d76d 12902is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 12903{
dda8d76d 12904 switch (filedata->file_header.e_machine)
2a7b2e88 12905 {
cb8f3167 12906 case EM_386: /* R_386_NONE. */
d347c9df 12907 case EM_68K: /* R_68K_NONE. */
cfb8c092 12908 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
12909 case EM_ALPHA: /* R_ALPHA_NONE. */
12910 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 12911 case EM_ARC: /* R_ARC_NONE. */
886a2506 12912 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 12913 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 12914 case EM_ARM: /* R_ARM_NONE. */
d347c9df 12915 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 12916 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
12917 case EM_FT32: /* R_FT32_NONE. */
12918 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 12919 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
12920 case EM_L1OM: /* R_X86_64_NONE. */
12921 case EM_M32R: /* R_M32R_NONE. */
12922 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 12923 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 12924 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
12925 case EM_NIOS32: /* R_NIOS_NONE. */
12926 case EM_OR1K: /* R_OR1K_NONE. */
12927 case EM_PARISC: /* R_PARISC_NONE. */
12928 case EM_PPC64: /* R_PPC64_NONE. */
12929 case EM_PPC: /* R_PPC_NONE. */
e23eba97 12930 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
12931 case EM_S390: /* R_390_NONE. */
12932 case EM_S390_OLD:
12933 case EM_SH: /* R_SH_NONE. */
12934 case EM_SPARC32PLUS:
12935 case EM_SPARC: /* R_SPARC_NONE. */
12936 case EM_SPARCV9:
aa137e4d
NC
12937 case EM_TILEGX: /* R_TILEGX_NONE. */
12938 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
12939 case EM_TI_C6000:/* R_C6000_NONE. */
12940 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 12941 case EM_XC16X:
f96bd6c2 12942 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 12943 return reloc_type == 0;
d347c9df 12944
a06ea964
NC
12945 case EM_AARCH64:
12946 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
12947 case EM_AVR_OLD:
12948 case EM_AVR:
12949 return (reloc_type == 0 /* R_AVR_NONE. */
12950 || reloc_type == 30 /* R_AVR_DIFF8. */
12951 || reloc_type == 31 /* R_AVR_DIFF16. */
12952 || reloc_type == 32 /* R_AVR_DIFF32. */);
12953 case EM_METAG:
12954 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
12955 case EM_NDS32:
12956 return (reloc_type == 0 /* R_XTENSA_NONE. */
12957 || reloc_type == 204 /* R_NDS32_DIFF8. */
12958 || reloc_type == 205 /* R_NDS32_DIFF16. */
12959 || reloc_type == 206 /* R_NDS32_DIFF32. */
12960 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
12961 case EM_TI_PRU:
12962 return (reloc_type == 0 /* R_PRU_NONE. */
12963 || reloc_type == 65 /* R_PRU_DIFF8. */
12964 || reloc_type == 66 /* R_PRU_DIFF16. */
12965 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
12966 case EM_XTENSA_OLD:
12967 case EM_XTENSA:
4dc3c23d
AM
12968 return (reloc_type == 0 /* R_XTENSA_NONE. */
12969 || reloc_type == 17 /* R_XTENSA_DIFF8. */
12970 || reloc_type == 18 /* R_XTENSA_DIFF16. */
12971 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
12972 }
12973 return FALSE;
12974}
12975
d1c4b12b
NC
12976/* Returns TRUE if there is a relocation against
12977 section NAME at OFFSET bytes. */
12978
12979bfd_boolean
12980reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
12981{
12982 Elf_Internal_Rela * relocs;
12983 Elf_Internal_Rela * rp;
12984
12985 if (dsec == NULL || dsec->reloc_info == NULL)
12986 return FALSE;
12987
12988 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
12989
12990 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
12991 if (rp->r_offset == offset)
12992 return TRUE;
12993
12994 return FALSE;
12995}
12996
cf13d699 12997/* Apply relocations to a section.
32ec8896
NC
12998 Returns TRUE upon success, FALSE otherwise.
12999 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13000 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13001 will be set to the number of relocs loaded.
13002
cf13d699 13003 Note: So far support has been added only for those relocations
32ec8896
NC
13004 which can be found in debug sections. FIXME: Add support for
13005 more relocations ? */
1b315056 13006
32ec8896 13007static bfd_boolean
dda8d76d 13008apply_relocations (Filedata * filedata,
d1c4b12b
NC
13009 const Elf_Internal_Shdr * section,
13010 unsigned char * start,
13011 bfd_size_type size,
1449284b 13012 void ** relocs_return,
d1c4b12b 13013 unsigned long * num_relocs_return)
1b315056 13014{
cf13d699 13015 Elf_Internal_Shdr * relsec;
0d2a7a93 13016 unsigned char * end = start + size;
32ec8896 13017 bfd_boolean res = TRUE;
cb8f3167 13018
d1c4b12b
NC
13019 if (relocs_return != NULL)
13020 {
13021 * (Elf_Internal_Rela **) relocs_return = NULL;
13022 * num_relocs_return = 0;
13023 }
13024
dda8d76d 13025 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13026 /* No relocs to apply. */
13027 return TRUE;
1b315056 13028
cf13d699 13029 /* Find the reloc section associated with the section. */
dda8d76d
NC
13030 for (relsec = filedata->section_headers;
13031 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13032 ++relsec)
252b5132 13033 {
41e92641
NC
13034 bfd_boolean is_rela;
13035 unsigned long num_relocs;
2cf0635d
NC
13036 Elf_Internal_Rela * relocs;
13037 Elf_Internal_Rela * rp;
13038 Elf_Internal_Shdr * symsec;
13039 Elf_Internal_Sym * symtab;
ba5cdace 13040 unsigned long num_syms;
2cf0635d 13041 Elf_Internal_Sym * sym;
252b5132 13042
41e92641 13043 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13044 || relsec->sh_info >= filedata->file_header.e_shnum
13045 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13046 || relsec->sh_size == 0
dda8d76d 13047 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13048 continue;
428409d5 13049
41e92641
NC
13050 is_rela = relsec->sh_type == SHT_RELA;
13051
13052 if (is_rela)
13053 {
dda8d76d 13054 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13055 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13056 return FALSE;
41e92641
NC
13057 }
13058 else
13059 {
dda8d76d 13060 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13061 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13062 return FALSE;
41e92641
NC
13063 }
13064
13065 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13066 if (filedata->file_header.e_machine == EM_SH)
41e92641 13067 is_rela = FALSE;
428409d5 13068
dda8d76d 13069 symsec = filedata->section_headers + relsec->sh_link;
1449284b
NC
13070 if (symsec->sh_type != SHT_SYMTAB
13071 && symsec->sh_type != SHT_DYNSYM)
32ec8896 13072 return FALSE;
dda8d76d 13073 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13074
41e92641 13075 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13076 {
41e92641
NC
13077 bfd_vma addend;
13078 unsigned int reloc_type;
13079 unsigned int reloc_size;
03336641
JW
13080 bfd_boolean reloc_inplace = FALSE;
13081 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13082 unsigned char * rloc;
ba5cdace 13083 unsigned long sym_index;
4b78141a 13084
dda8d76d 13085 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13086
dda8d76d 13087 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13088 continue;
dda8d76d 13089 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13090 continue;
dda8d76d
NC
13091 else if (is_32bit_abs_reloc (filedata, reloc_type)
13092 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13093 reloc_size = 4;
dda8d76d
NC
13094 else if (is_64bit_abs_reloc (filedata, reloc_type)
13095 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13096 reloc_size = 8;
dda8d76d 13097 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13098 reloc_size = 3;
dda8d76d 13099 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13100 reloc_size = 2;
39e07931
AS
13101 else if (is_8bit_abs_reloc (filedata, reloc_type)
13102 || is_6bit_abs_reloc (filedata, reloc_type))
13103 reloc_size = 1;
03336641
JW
13104 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13105 reloc_type))
13106 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13107 {
13108 reloc_size = 4;
13109 reloc_inplace = TRUE;
13110 }
13111 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13112 reloc_type))
13113 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13114 {
13115 reloc_size = 8;
13116 reloc_inplace = TRUE;
13117 }
13118 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13119 reloc_type))
13120 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13121 {
13122 reloc_size = 2;
13123 reloc_inplace = TRUE;
13124 }
13125 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13126 reloc_type))
13127 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13128 {
13129 reloc_size = 1;
13130 reloc_inplace = TRUE;
13131 }
39e07931
AS
13132 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13133 reloc_type)))
13134 {
13135 reloc_size = 1;
13136 reloc_inplace = TRUE;
13137 }
aca88567 13138 else
4b78141a 13139 {
bee0ee85 13140 static unsigned int prev_reloc = 0;
dda8d76d 13141
bee0ee85
NC
13142 if (reloc_type != prev_reloc)
13143 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13144 reloc_type, printable_section_name (filedata, section));
bee0ee85 13145 prev_reloc = reloc_type;
32ec8896 13146 res = FALSE;
4b78141a
NC
13147 continue;
13148 }
103f02d3 13149
91d6fa6a 13150 rloc = start + rp->r_offset;
c8da6823 13151 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
13152 {
13153 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13154 (unsigned long) rp->r_offset,
dda8d76d 13155 printable_section_name (filedata, section));
32ec8896 13156 res = FALSE;
700dd8b7
L
13157 continue;
13158 }
103f02d3 13159
ba5cdace
NC
13160 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13161 if (sym_index >= num_syms)
13162 {
13163 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13164 sym_index, printable_section_name (filedata, section));
32ec8896 13165 res = FALSE;
ba5cdace
NC
13166 continue;
13167 }
13168 sym = symtab + sym_index;
41e92641
NC
13169
13170 /* If the reloc has a symbol associated with it,
55f25fc3
L
13171 make sure that it is of an appropriate type.
13172
13173 Relocations against symbols without type can happen.
13174 Gcc -feliminate-dwarf2-dups may generate symbols
13175 without type for debug info.
13176
13177 Icc generates relocations against function symbols
13178 instead of local labels.
13179
13180 Relocations against object symbols can happen, eg when
13181 referencing a global array. For an example of this see
13182 the _clz.o binary in libgcc.a. */
aca88567 13183 if (sym != symtab
b8871f35 13184 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13185 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13186 {
d3a49aa8 13187 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13188 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13189 printable_section_name (filedata, relsec),
d3a49aa8 13190 (long int)(rp - relocs));
32ec8896 13191 res = FALSE;
aca88567 13192 continue;
5b18a4bc 13193 }
252b5132 13194
4dc3c23d
AM
13195 addend = 0;
13196 if (is_rela)
13197 addend += rp->r_addend;
c47320c3
AM
13198 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13199 partial_inplace. */
4dc3c23d 13200 if (!is_rela
dda8d76d 13201 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13202 && reloc_type == 1)
dda8d76d
NC
13203 || ((filedata->file_header.e_machine == EM_PJ
13204 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13205 && reloc_type == 1)
dda8d76d
NC
13206 || ((filedata->file_header.e_machine == EM_D30V
13207 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13208 && reloc_type == 12)
13209 || reloc_inplace)
39e07931
AS
13210 {
13211 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
13212 addend += byte_get (rloc, reloc_size) & 0x3f;
13213 else
13214 addend += byte_get (rloc, reloc_size);
13215 }
cb8f3167 13216
dda8d76d
NC
13217 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13218 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13219 {
13220 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13221 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13222 addend -= 8;
91d6fa6a 13223 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13224 reloc_size);
13225 }
39e07931
AS
13226 else if (is_6bit_abs_reloc (filedata, reloc_type)
13227 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
13228 {
13229 if (reloc_subtract)
13230 addend -= sym->st_value;
13231 else
13232 addend += sym->st_value;
13233 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
13234 byte_put (rloc, addend, reloc_size);
13235 }
03336641
JW
13236 else if (reloc_subtract)
13237 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13238 else
91d6fa6a 13239 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13240 }
252b5132 13241
5b18a4bc 13242 free (symtab);
f84ce13b
NC
13243 /* Let the target specific reloc processing code know that
13244 we have finished with these relocs. */
dda8d76d 13245 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13246
13247 if (relocs_return)
13248 {
13249 * (Elf_Internal_Rela **) relocs_return = relocs;
13250 * num_relocs_return = num_relocs;
13251 }
13252 else
13253 free (relocs);
13254
5b18a4bc
NC
13255 break;
13256 }
32ec8896
NC
13257
13258 return res;
5b18a4bc 13259}
103f02d3 13260
cf13d699 13261#ifdef SUPPORT_DISASSEMBLY
32ec8896 13262static bfd_boolean
dda8d76d 13263disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13264{
dda8d76d 13265 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13266
74e1a04b 13267 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13268
32ec8896 13269 return TRUE;
cf13d699
NC
13270}
13271#endif
13272
13273/* Reads in the contents of SECTION from FILE, returning a pointer
13274 to a malloc'ed buffer or NULL if something went wrong. */
13275
13276static char *
dda8d76d 13277get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13278{
dda8d76d 13279 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13280
13281 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13282 {
c6b78c96 13283 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13284 printable_section_name (filedata, section));
cf13d699
NC
13285 return NULL;
13286 }
13287
dda8d76d 13288 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13289 _("section contents"));
cf13d699
NC
13290}
13291
0e602686
NC
13292/* Uncompresses a section that was compressed using zlib, in place. */
13293
13294static bfd_boolean
dda8d76d
NC
13295uncompress_section_contents (unsigned char ** buffer,
13296 dwarf_size_type uncompressed_size,
13297 dwarf_size_type * size)
0e602686
NC
13298{
13299 dwarf_size_type compressed_size = *size;
13300 unsigned char * compressed_buffer = *buffer;
13301 unsigned char * uncompressed_buffer;
13302 z_stream strm;
13303 int rc;
13304
13305 /* It is possible the section consists of several compressed
13306 buffers concatenated together, so we uncompress in a loop. */
13307 /* PR 18313: The state field in the z_stream structure is supposed
13308 to be invisible to the user (ie us), but some compilers will
13309 still complain about it being used without initialisation. So
13310 we first zero the entire z_stream structure and then set the fields
13311 that we need. */
13312 memset (& strm, 0, sizeof strm);
13313 strm.avail_in = compressed_size;
13314 strm.next_in = (Bytef *) compressed_buffer;
13315 strm.avail_out = uncompressed_size;
13316 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13317
13318 rc = inflateInit (& strm);
13319 while (strm.avail_in > 0)
13320 {
13321 if (rc != Z_OK)
13322 goto fail;
13323 strm.next_out = ((Bytef *) uncompressed_buffer
13324 + (uncompressed_size - strm.avail_out));
13325 rc = inflate (&strm, Z_FINISH);
13326 if (rc != Z_STREAM_END)
13327 goto fail;
13328 rc = inflateReset (& strm);
13329 }
13330 rc = inflateEnd (& strm);
13331 if (rc != Z_OK
13332 || strm.avail_out != 0)
13333 goto fail;
13334
13335 *buffer = uncompressed_buffer;
13336 *size = uncompressed_size;
13337 return TRUE;
13338
13339 fail:
13340 free (uncompressed_buffer);
13341 /* Indicate decompression failure. */
13342 *buffer = NULL;
13343 return FALSE;
13344}
dd24e3da 13345
32ec8896 13346static bfd_boolean
dda8d76d 13347dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13348{
0e602686
NC
13349 Elf_Internal_Shdr * relsec;
13350 bfd_size_type num_bytes;
fd8008d8
L
13351 unsigned char * data;
13352 unsigned char * end;
13353 unsigned char * real_start;
13354 unsigned char * start;
0e602686 13355 bfd_boolean some_strings_shown;
cf13d699 13356
dda8d76d 13357 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13358 if (start == NULL)
c6b78c96
NC
13359 /* PR 21820: Do not fail if the section was empty. */
13360 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13361
0e602686 13362 num_bytes = section->sh_size;
cf13d699 13363
dda8d76d 13364 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13365
0e602686
NC
13366 if (decompress_dumps)
13367 {
13368 dwarf_size_type new_size = num_bytes;
13369 dwarf_size_type uncompressed_size = 0;
13370
13371 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13372 {
13373 Elf_Internal_Chdr chdr;
13374 unsigned int compression_header_size
ebdf1ebf
NC
13375 = get_compression_header (& chdr, (unsigned char *) start,
13376 num_bytes);
0e602686 13377
813dabb9 13378 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13379 {
813dabb9 13380 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13381 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13382 return FALSE;
813dabb9
L
13383 }
13384 else if (chdr.ch_addralign != section->sh_addralign)
13385 {
13386 warn (_("compressed section '%s' is corrupted\n"),
dda8d76d 13387 printable_section_name (filedata, section));
32ec8896 13388 return FALSE;
0e602686 13389 }
813dabb9
L
13390 uncompressed_size = chdr.ch_size;
13391 start += compression_header_size;
13392 new_size -= compression_header_size;
0e602686
NC
13393 }
13394 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13395 {
13396 /* Read the zlib header. In this case, it should be "ZLIB"
13397 followed by the uncompressed section size, 8 bytes in
13398 big-endian order. */
13399 uncompressed_size = start[4]; uncompressed_size <<= 8;
13400 uncompressed_size += start[5]; uncompressed_size <<= 8;
13401 uncompressed_size += start[6]; uncompressed_size <<= 8;
13402 uncompressed_size += start[7]; uncompressed_size <<= 8;
13403 uncompressed_size += start[8]; uncompressed_size <<= 8;
13404 uncompressed_size += start[9]; uncompressed_size <<= 8;
13405 uncompressed_size += start[10]; uncompressed_size <<= 8;
13406 uncompressed_size += start[11];
13407 start += 12;
13408 new_size -= 12;
13409 }
13410
1835f746
NC
13411 if (uncompressed_size)
13412 {
13413 if (uncompress_section_contents (& start,
13414 uncompressed_size, & new_size))
13415 num_bytes = new_size;
13416 else
13417 {
13418 error (_("Unable to decompress section %s\n"),
dda8d76d 13419 printable_section_name (filedata, section));
32ec8896 13420 return FALSE;
1835f746
NC
13421 }
13422 }
bc303e5d
NC
13423 else
13424 start = real_start;
0e602686 13425 }
fd8008d8 13426
cf13d699
NC
13427 /* If the section being dumped has relocations against it the user might
13428 be expecting these relocations to have been applied. Check for this
13429 case and issue a warning message in order to avoid confusion.
13430 FIXME: Maybe we ought to have an option that dumps a section with
13431 relocs applied ? */
dda8d76d
NC
13432 for (relsec = filedata->section_headers;
13433 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13434 ++relsec)
13435 {
13436 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13437 || relsec->sh_info >= filedata->file_header.e_shnum
13438 || filedata->section_headers + relsec->sh_info != section
cf13d699 13439 || relsec->sh_size == 0
dda8d76d 13440 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13441 continue;
13442
13443 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13444 break;
13445 }
13446
cf13d699
NC
13447 data = start;
13448 end = start + num_bytes;
13449 some_strings_shown = FALSE;
13450
13451 while (data < end)
13452 {
13453 while (!ISPRINT (* data))
13454 if (++ data >= end)
13455 break;
13456
13457 if (data < end)
13458 {
071436c6
NC
13459 size_t maxlen = end - data;
13460
cf13d699 13461#ifndef __MSVCRT__
c975cc98
NC
13462 /* PR 11128: Use two separate invocations in order to work
13463 around bugs in the Solaris 8 implementation of printf. */
13464 printf (" [%6tx] ", data - start);
cf13d699 13465#else
071436c6 13466 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 13467#endif
4082ef84
NC
13468 if (maxlen > 0)
13469 {
fd8008d8 13470 print_symbol ((int) maxlen, (const char *) data);
4082ef84 13471 putchar ('\n');
fd8008d8 13472 data += strnlen ((const char *) data, maxlen);
4082ef84
NC
13473 }
13474 else
13475 {
13476 printf (_("<corrupt>\n"));
13477 data = end;
13478 }
cf13d699
NC
13479 some_strings_shown = TRUE;
13480 }
13481 }
13482
13483 if (! some_strings_shown)
13484 printf (_(" No strings found in this section."));
13485
0e602686 13486 free (real_start);
cf13d699
NC
13487
13488 putchar ('\n');
32ec8896 13489 return TRUE;
cf13d699
NC
13490}
13491
32ec8896 13492static bfd_boolean
dda8d76d
NC
13493dump_section_as_bytes (Elf_Internal_Shdr * section,
13494 Filedata * filedata,
13495 bfd_boolean relocate)
cf13d699
NC
13496{
13497 Elf_Internal_Shdr * relsec;
0e602686
NC
13498 bfd_size_type bytes;
13499 bfd_size_type section_size;
13500 bfd_vma addr;
13501 unsigned char * data;
13502 unsigned char * real_start;
13503 unsigned char * start;
13504
dda8d76d 13505 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13506 if (start == NULL)
c6b78c96
NC
13507 /* PR 21820: Do not fail if the section was empty. */
13508 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 13509
0e602686 13510 section_size = section->sh_size;
cf13d699 13511
dda8d76d 13512 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13513
0e602686
NC
13514 if (decompress_dumps)
13515 {
13516 dwarf_size_type new_size = section_size;
13517 dwarf_size_type uncompressed_size = 0;
13518
13519 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13520 {
13521 Elf_Internal_Chdr chdr;
13522 unsigned int compression_header_size
ebdf1ebf 13523 = get_compression_header (& chdr, start, section_size);
0e602686 13524
813dabb9 13525 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13526 {
813dabb9 13527 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13528 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13529 return FALSE;
0e602686 13530 }
813dabb9
L
13531 else if (chdr.ch_addralign != section->sh_addralign)
13532 {
13533 warn (_("compressed section '%s' is corrupted\n"),
dda8d76d 13534 printable_section_name (filedata, section));
32ec8896 13535 return FALSE;
813dabb9
L
13536 }
13537 uncompressed_size = chdr.ch_size;
13538 start += compression_header_size;
13539 new_size -= compression_header_size;
0e602686
NC
13540 }
13541 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13542 {
13543 /* Read the zlib header. In this case, it should be "ZLIB"
13544 followed by the uncompressed section size, 8 bytes in
13545 big-endian order. */
13546 uncompressed_size = start[4]; uncompressed_size <<= 8;
13547 uncompressed_size += start[5]; uncompressed_size <<= 8;
13548 uncompressed_size += start[6]; uncompressed_size <<= 8;
13549 uncompressed_size += start[7]; uncompressed_size <<= 8;
13550 uncompressed_size += start[8]; uncompressed_size <<= 8;
13551 uncompressed_size += start[9]; uncompressed_size <<= 8;
13552 uncompressed_size += start[10]; uncompressed_size <<= 8;
13553 uncompressed_size += start[11];
13554 start += 12;
13555 new_size -= 12;
13556 }
13557
f055032e
NC
13558 if (uncompressed_size)
13559 {
13560 if (uncompress_section_contents (& start, uncompressed_size,
13561 & new_size))
bc303e5d
NC
13562 {
13563 section_size = new_size;
13564 }
f055032e
NC
13565 else
13566 {
13567 error (_("Unable to decompress section %s\n"),
dda8d76d 13568 printable_section_name (filedata, section));
bc303e5d 13569 /* FIXME: Print the section anyway ? */
32ec8896 13570 return FALSE;
f055032e
NC
13571 }
13572 }
bc303e5d
NC
13573 else
13574 start = real_start;
0e602686 13575 }
14ae95f2 13576
cf13d699
NC
13577 if (relocate)
13578 {
dda8d76d 13579 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
32ec8896 13580 return FALSE;
cf13d699
NC
13581 }
13582 else
13583 {
13584 /* If the section being dumped has relocations against it the user might
13585 be expecting these relocations to have been applied. Check for this
13586 case and issue a warning message in order to avoid confusion.
13587 FIXME: Maybe we ought to have an option that dumps a section with
13588 relocs applied ? */
dda8d76d
NC
13589 for (relsec = filedata->section_headers;
13590 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13591 ++relsec)
13592 {
13593 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13594 || relsec->sh_info >= filedata->file_header.e_shnum
13595 || filedata->section_headers + relsec->sh_info != section
cf13d699 13596 || relsec->sh_size == 0
dda8d76d 13597 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13598 continue;
13599
13600 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13601 break;
13602 }
13603 }
13604
13605 addr = section->sh_addr;
0e602686 13606 bytes = section_size;
cf13d699
NC
13607 data = start;
13608
13609 while (bytes)
13610 {
13611 int j;
13612 int k;
13613 int lbytes;
13614
13615 lbytes = (bytes > 16 ? 16 : bytes);
13616
13617 printf (" 0x%8.8lx ", (unsigned long) addr);
13618
13619 for (j = 0; j < 16; j++)
13620 {
13621 if (j < lbytes)
13622 printf ("%2.2x", data[j]);
13623 else
13624 printf (" ");
13625
13626 if ((j & 3) == 3)
13627 printf (" ");
13628 }
13629
13630 for (j = 0; j < lbytes; j++)
13631 {
13632 k = data[j];
13633 if (k >= ' ' && k < 0x7f)
13634 printf ("%c", k);
13635 else
13636 printf (".");
13637 }
13638
13639 putchar ('\n');
13640
13641 data += lbytes;
13642 addr += lbytes;
13643 bytes -= lbytes;
13644 }
13645
0e602686 13646 free (real_start);
cf13d699
NC
13647
13648 putchar ('\n');
32ec8896 13649 return TRUE;
cf13d699
NC
13650}
13651
32ec8896 13652static bfd_boolean
dda8d76d
NC
13653load_specific_debug_section (enum dwarf_section_display_enum debug,
13654 const Elf_Internal_Shdr * sec,
13655 void * data)
1007acb3 13656{
2cf0635d 13657 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 13658 char buf [64];
dda8d76d
NC
13659 Filedata * filedata = (Filedata *) data;
13660
19e6b90e 13661 if (section->start != NULL)
dda8d76d
NC
13662 {
13663 /* If it is already loaded, do nothing. */
13664 if (streq (section->filename, filedata->file_name))
13665 return TRUE;
13666 free (section->start);
13667 }
1007acb3 13668
19e6b90e
L
13669 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
13670 section->address = sec->sh_addr;
06614111 13671 section->user_data = NULL;
dda8d76d
NC
13672 section->filename = filedata->file_name;
13673 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
13674 sec->sh_offset, 1,
13675 sec->sh_size, buf);
59245841
NC
13676 if (section->start == NULL)
13677 section->size = 0;
13678 else
13679 {
77115a4a
L
13680 unsigned char *start = section->start;
13681 dwarf_size_type size = sec->sh_size;
dab394de 13682 dwarf_size_type uncompressed_size = 0;
77115a4a
L
13683
13684 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
13685 {
13686 Elf_Internal_Chdr chdr;
d8024a91
NC
13687 unsigned int compression_header_size;
13688
f53be977
L
13689 if (size < (is_32bit_elf
13690 ? sizeof (Elf32_External_Chdr)
13691 : sizeof (Elf64_External_Chdr)))
d8024a91
NC
13692 {
13693 warn (_("compressed section %s is too small to contain a compression header"),
13694 section->name);
32ec8896 13695 return FALSE;
d8024a91
NC
13696 }
13697
ebdf1ebf 13698 compression_header_size = get_compression_header (&chdr, start, size);
d8024a91 13699
813dabb9
L
13700 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
13701 {
13702 warn (_("section '%s' has unsupported compress type: %d\n"),
13703 section->name, chdr.ch_type);
32ec8896 13704 return FALSE;
813dabb9
L
13705 }
13706 else if (chdr.ch_addralign != sec->sh_addralign)
13707 {
13708 warn (_("compressed section '%s' is corrupted\n"),
13709 section->name);
32ec8896 13710 return FALSE;
813dabb9 13711 }
dab394de 13712 uncompressed_size = chdr.ch_size;
77115a4a
L
13713 start += compression_header_size;
13714 size -= compression_header_size;
13715 }
dab394de
L
13716 else if (size > 12 && streq ((char *) start, "ZLIB"))
13717 {
13718 /* Read the zlib header. In this case, it should be "ZLIB"
13719 followed by the uncompressed section size, 8 bytes in
13720 big-endian order. */
13721 uncompressed_size = start[4]; uncompressed_size <<= 8;
13722 uncompressed_size += start[5]; uncompressed_size <<= 8;
13723 uncompressed_size += start[6]; uncompressed_size <<= 8;
13724 uncompressed_size += start[7]; uncompressed_size <<= 8;
13725 uncompressed_size += start[8]; uncompressed_size <<= 8;
13726 uncompressed_size += start[9]; uncompressed_size <<= 8;
13727 uncompressed_size += start[10]; uncompressed_size <<= 8;
13728 uncompressed_size += start[11];
13729 start += 12;
13730 size -= 12;
13731 }
13732
1835f746 13733 if (uncompressed_size)
77115a4a 13734 {
1835f746
NC
13735 if (uncompress_section_contents (&start, uncompressed_size,
13736 &size))
13737 {
13738 /* Free the compressed buffer, update the section buffer
13739 and the section size if uncompress is successful. */
13740 free (section->start);
13741 section->start = start;
13742 }
13743 else
13744 {
13745 error (_("Unable to decompress section %s\n"),
dda8d76d 13746 printable_section_name (filedata, sec));
32ec8896 13747 return FALSE;
1835f746 13748 }
77115a4a 13749 }
bc303e5d 13750
77115a4a 13751 section->size = size;
59245841 13752 }
4a114e3e 13753
1b315056 13754 if (section->start == NULL)
32ec8896 13755 return FALSE;
1b315056 13756
19e6b90e 13757 if (debug_displays [debug].relocate)
32ec8896 13758 {
dda8d76d 13759 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
13760 & section->reloc_info, & section->num_relocs))
13761 return FALSE;
13762 }
d1c4b12b
NC
13763 else
13764 {
13765 section->reloc_info = NULL;
13766 section->num_relocs = 0;
13767 }
1007acb3 13768
32ec8896 13769 return TRUE;
1007acb3
L
13770}
13771
657d0d47
CC
13772/* If this is not NULL, load_debug_section will only look for sections
13773 within the list of sections given here. */
32ec8896 13774static unsigned int * section_subset = NULL;
657d0d47 13775
32ec8896 13776bfd_boolean
dda8d76d 13777load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 13778{
2cf0635d
NC
13779 struct dwarf_section * section = &debug_displays [debug].section;
13780 Elf_Internal_Shdr * sec;
dda8d76d
NC
13781 Filedata * filedata = (Filedata *) data;
13782
f425ec66
NC
13783 /* Without section headers we cannot find any sections. */
13784 if (filedata->section_headers == NULL)
13785 return FALSE;
13786
9c1ce108
AM
13787 if (filedata->string_table == NULL
13788 && filedata->file_header.e_shstrndx != SHN_UNDEF
13789 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
13790 {
13791 Elf_Internal_Shdr * strs;
13792
13793 /* Read in the string table, so that we have section names to scan. */
13794 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
13795
4dff97b2 13796 if (strs != NULL && strs->sh_size != 0)
dda8d76d 13797 {
9c1ce108
AM
13798 filedata->string_table
13799 = (char *) get_data (NULL, filedata, strs->sh_offset,
13800 1, strs->sh_size, _("string table"));
dda8d76d 13801
9c1ce108
AM
13802 filedata->string_table_length
13803 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
13804 }
13805 }
d966045b
DJ
13806
13807 /* Locate the debug section. */
dda8d76d 13808 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
13809 if (sec != NULL)
13810 section->name = section->uncompressed_name;
13811 else
13812 {
dda8d76d 13813 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
13814 if (sec != NULL)
13815 section->name = section->compressed_name;
13816 }
13817 if (sec == NULL)
32ec8896 13818 return FALSE;
d966045b 13819
657d0d47
CC
13820 /* If we're loading from a subset of sections, and we've loaded
13821 a section matching this name before, it's likely that it's a
13822 different one. */
13823 if (section_subset != NULL)
13824 free_debug_section (debug);
13825
dda8d76d 13826 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
13827}
13828
19e6b90e
L
13829void
13830free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 13831{
2cf0635d 13832 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 13833
19e6b90e
L
13834 if (section->start == NULL)
13835 return;
1007acb3 13836
19e6b90e
L
13837 free ((char *) section->start);
13838 section->start = NULL;
13839 section->address = 0;
13840 section->size = 0;
1007acb3
L
13841}
13842
32ec8896 13843static bfd_boolean
dda8d76d 13844display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 13845{
2cf0635d 13846 char * name = SECTION_NAME (section);
dda8d76d 13847 const char * print_name = printable_section_name (filedata, section);
19e6b90e 13848 bfd_size_type length;
32ec8896 13849 bfd_boolean result = TRUE;
3f5e193b 13850 int i;
1007acb3 13851
19e6b90e
L
13852 length = section->sh_size;
13853 if (length == 0)
1007acb3 13854 {
74e1a04b 13855 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 13856 return TRUE;
1007acb3 13857 }
5dff79d8
NC
13858 if (section->sh_type == SHT_NOBITS)
13859 {
13860 /* There is no point in dumping the contents of a debugging section
13861 which has the NOBITS type - the bits in the file will be random.
13862 This can happen when a file containing a .eh_frame section is
13863 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
13864 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
13865 print_name);
32ec8896 13866 return FALSE;
5dff79d8 13867 }
1007acb3 13868
0112cd26 13869 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 13870 name = ".debug_info";
1007acb3 13871
19e6b90e
L
13872 /* See if we know how to display the contents of this section. */
13873 for (i = 0; i < max; i++)
d85bf2ba
NC
13874 {
13875 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
13876 struct dwarf_section_display * display = debug_displays + i;
13877 struct dwarf_section * sec = & display->section;
d966045b 13878
d85bf2ba
NC
13879 if (streq (sec->uncompressed_name, name)
13880 || (id == line && const_strneq (name, ".debug_line."))
13881 || streq (sec->compressed_name, name))
13882 {
13883 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 13884
d85bf2ba
NC
13885 if (secondary)
13886 free_debug_section (id);
dda8d76d 13887
d85bf2ba
NC
13888 if (i == line && const_strneq (name, ".debug_line."))
13889 sec->name = name;
13890 else if (streq (sec->uncompressed_name, name))
13891 sec->name = sec->uncompressed_name;
13892 else
13893 sec->name = sec->compressed_name;
657d0d47 13894
d85bf2ba
NC
13895 if (load_specific_debug_section (id, section, filedata))
13896 {
13897 /* If this debug section is part of a CU/TU set in a .dwp file,
13898 restrict load_debug_section to the sections in that set. */
13899 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 13900
d85bf2ba 13901 result &= display->display (sec, filedata);
657d0d47 13902
d85bf2ba 13903 section_subset = NULL;
1007acb3 13904
d85bf2ba
NC
13905 if (secondary || (id != info && id != abbrev))
13906 free_debug_section (id);
13907 }
13908 break;
13909 }
13910 }
1007acb3 13911
19e6b90e 13912 if (i == max)
1007acb3 13913 {
74e1a04b 13914 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 13915 result = FALSE;
1007acb3
L
13916 }
13917
19e6b90e 13918 return result;
5b18a4bc 13919}
103f02d3 13920
aef1f6d0
DJ
13921/* Set DUMP_SECTS for all sections where dumps were requested
13922 based on section name. */
13923
13924static void
dda8d76d 13925initialise_dumps_byname (Filedata * filedata)
aef1f6d0 13926{
2cf0635d 13927 struct dump_list_entry * cur;
aef1f6d0
DJ
13928
13929 for (cur = dump_sects_byname; cur; cur = cur->next)
13930 {
13931 unsigned int i;
32ec8896 13932 bfd_boolean any = FALSE;
aef1f6d0 13933
dda8d76d
NC
13934 for (i = 0; i < filedata->file_header.e_shnum; i++)
13935 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 13936 {
dda8d76d 13937 request_dump_bynumber (filedata, i, cur->type);
32ec8896 13938 any = TRUE;
aef1f6d0
DJ
13939 }
13940
13941 if (!any)
13942 warn (_("Section '%s' was not dumped because it does not exist!\n"),
13943 cur->name);
13944 }
13945}
13946
32ec8896 13947static bfd_boolean
dda8d76d 13948process_section_contents (Filedata * filedata)
5b18a4bc 13949{
2cf0635d 13950 Elf_Internal_Shdr * section;
19e6b90e 13951 unsigned int i;
32ec8896 13952 bfd_boolean res = TRUE;
103f02d3 13953
19e6b90e 13954 if (! do_dump)
32ec8896 13955 return TRUE;
103f02d3 13956
dda8d76d 13957 initialise_dumps_byname (filedata);
aef1f6d0 13958
dda8d76d
NC
13959 for (i = 0, section = filedata->section_headers;
13960 i < filedata->file_header.e_shnum && i < filedata->num_dump_sects;
19e6b90e
L
13961 i++, section++)
13962 {
dda8d76d
NC
13963 dump_type dump = filedata->dump_sects[i];
13964
19e6b90e 13965#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
13966 if (dump & DISASS_DUMP)
13967 {
13968 if (! disassemble_section (section, filedata))
13969 res = FALSE;
13970 }
19e6b90e 13971#endif
dda8d76d 13972 if (dump & HEX_DUMP)
32ec8896 13973 {
dda8d76d 13974 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
13975 res = FALSE;
13976 }
103f02d3 13977
dda8d76d 13978 if (dump & RELOC_DUMP)
32ec8896 13979 {
dda8d76d 13980 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
13981 res = FALSE;
13982 }
09c11c86 13983
dda8d76d 13984 if (dump & STRING_DUMP)
32ec8896 13985 {
dda8d76d 13986 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
13987 res = FALSE;
13988 }
cf13d699 13989
dda8d76d 13990 if (dump & DEBUG_DUMP)
32ec8896 13991 {
dda8d76d 13992 if (! display_debug_section (i, section, filedata))
32ec8896
NC
13993 res = FALSE;
13994 }
5b18a4bc 13995 }
103f02d3 13996
19e6b90e
L
13997 /* Check to see if the user requested a
13998 dump of a section that does not exist. */
dda8d76d 13999 while (i < filedata->num_dump_sects)
0ee3043f 14000 {
dda8d76d 14001 if (filedata->dump_sects[i])
32ec8896
NC
14002 {
14003 warn (_("Section %d was not dumped because it does not exist!\n"), i);
14004 res = FALSE;
14005 }
0ee3043f
NC
14006 i++;
14007 }
32ec8896
NC
14008
14009 return res;
5b18a4bc 14010}
103f02d3 14011
5b18a4bc 14012static void
19e6b90e 14013process_mips_fpe_exception (int mask)
5b18a4bc 14014{
19e6b90e
L
14015 if (mask)
14016 {
32ec8896
NC
14017 bfd_boolean first = TRUE;
14018
19e6b90e 14019 if (mask & OEX_FPU_INEX)
32ec8896 14020 fputs ("INEX", stdout), first = FALSE;
19e6b90e 14021 if (mask & OEX_FPU_UFLO)
32ec8896 14022 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14023 if (mask & OEX_FPU_OFLO)
32ec8896 14024 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14025 if (mask & OEX_FPU_DIV0)
32ec8896 14026 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
14027 if (mask & OEX_FPU_INVAL)
14028 printf ("%sINVAL", first ? "" : "|");
14029 }
5b18a4bc 14030 else
19e6b90e 14031 fputs ("0", stdout);
5b18a4bc 14032}
103f02d3 14033
f6f0e17b
NC
14034/* Display's the value of TAG at location P. If TAG is
14035 greater than 0 it is assumed to be an unknown tag, and
14036 a message is printed to this effect. Otherwise it is
14037 assumed that a message has already been printed.
14038
14039 If the bottom bit of TAG is set it assumed to have a
14040 string value, otherwise it is assumed to have an integer
14041 value.
14042
14043 Returns an updated P pointing to the first unread byte
14044 beyond the end of TAG's value.
14045
14046 Reads at or beyond END will not be made. */
14047
14048static unsigned char *
60abdbed 14049display_tag_value (signed int tag,
f6f0e17b
NC
14050 unsigned char * p,
14051 const unsigned char * const end)
14052{
14053 unsigned long val;
14054
14055 if (tag > 0)
14056 printf (" Tag_unknown_%d: ", tag);
14057
14058 if (p >= end)
14059 {
4082ef84 14060 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
14061 }
14062 else if (tag & 1)
14063 {
071436c6
NC
14064 /* PR 17531 file: 027-19978-0.004. */
14065 size_t maxlen = (end - p) - 1;
14066
14067 putchar ('"');
4082ef84
NC
14068 if (maxlen > 0)
14069 {
14070 print_symbol ((int) maxlen, (const char *) p);
14071 p += strnlen ((char *) p, maxlen) + 1;
14072 }
14073 else
14074 {
14075 printf (_("<corrupt string tag>"));
14076 p = (unsigned char *) end;
14077 }
071436c6 14078 printf ("\"\n");
f6f0e17b
NC
14079 }
14080 else
14081 {
14082 unsigned int len;
14083
14084 val = read_uleb128 (p, &len, end);
14085 p += len;
14086 printf ("%ld (0x%lx)\n", val, val);
14087 }
14088
4082ef84 14089 assert (p <= end);
f6f0e17b
NC
14090 return p;
14091}
14092
53a346d8
CZ
14093/* ARC ABI attributes section. */
14094
14095static unsigned char *
14096display_arc_attribute (unsigned char * p,
14097 const unsigned char * const end)
14098{
14099 unsigned int tag;
14100 unsigned int len;
14101 unsigned int val;
14102
14103 tag = read_uleb128 (p, &len, end);
14104 p += len;
14105
14106 switch (tag)
14107 {
14108 case Tag_ARC_PCS_config:
14109 val = read_uleb128 (p, &len, end);
14110 p += len;
14111 printf (" Tag_ARC_PCS_config: ");
14112 switch (val)
14113 {
14114 case 0:
14115 printf (_("Absent/Non standard\n"));
14116 break;
14117 case 1:
14118 printf (_("Bare metal/mwdt\n"));
14119 break;
14120 case 2:
14121 printf (_("Bare metal/newlib\n"));
14122 break;
14123 case 3:
14124 printf (_("Linux/uclibc\n"));
14125 break;
14126 case 4:
14127 printf (_("Linux/glibc\n"));
14128 break;
14129 default:
14130 printf (_("Unknown\n"));
14131 break;
14132 }
14133 break;
14134
14135 case Tag_ARC_CPU_base:
14136 val = read_uleb128 (p, &len, end);
14137 p += len;
14138 printf (" Tag_ARC_CPU_base: ");
14139 switch (val)
14140 {
14141 default:
14142 case TAG_CPU_NONE:
14143 printf (_("Absent\n"));
14144 break;
14145 case TAG_CPU_ARC6xx:
14146 printf ("ARC6xx\n");
14147 break;
14148 case TAG_CPU_ARC7xx:
14149 printf ("ARC7xx\n");
14150 break;
14151 case TAG_CPU_ARCEM:
14152 printf ("ARCEM\n");
14153 break;
14154 case TAG_CPU_ARCHS:
14155 printf ("ARCHS\n");
14156 break;
14157 }
14158 break;
14159
14160 case Tag_ARC_CPU_variation:
14161 val = read_uleb128 (p, &len, end);
14162 p += len;
14163 printf (" Tag_ARC_CPU_variation: ");
14164 switch (val)
14165 {
14166 default:
14167 if (val > 0 && val < 16)
53a346d8 14168 printf ("Core%d\n", val);
d8cbc93b
JL
14169 else
14170 printf ("Unknown\n");
14171 break;
14172
53a346d8
CZ
14173 case 0:
14174 printf (_("Absent\n"));
14175 break;
14176 }
14177 break;
14178
14179 case Tag_ARC_CPU_name:
14180 printf (" Tag_ARC_CPU_name: ");
14181 p = display_tag_value (-1, p, end);
14182 break;
14183
14184 case Tag_ARC_ABI_rf16:
14185 val = read_uleb128 (p, &len, end);
14186 p += len;
14187 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
14188 break;
14189
14190 case Tag_ARC_ABI_osver:
14191 val = read_uleb128 (p, &len, end);
14192 p += len;
14193 printf (" Tag_ARC_ABI_osver: v%d\n", val);
14194 break;
14195
14196 case Tag_ARC_ABI_pic:
14197 case Tag_ARC_ABI_sda:
14198 val = read_uleb128 (p, &len, end);
14199 p += len;
14200 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
14201 : " Tag_ARC_ABI_pic: ");
14202 switch (val)
14203 {
14204 case 0:
14205 printf (_("Absent\n"));
14206 break;
14207 case 1:
14208 printf ("MWDT\n");
14209 break;
14210 case 2:
14211 printf ("GNU\n");
14212 break;
14213 default:
14214 printf (_("Unknown\n"));
14215 break;
14216 }
14217 break;
14218
14219 case Tag_ARC_ABI_tls:
14220 val = read_uleb128 (p, &len, end);
14221 p += len;
14222 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
14223 break;
14224
14225 case Tag_ARC_ABI_enumsize:
14226 val = read_uleb128 (p, &len, end);
14227 p += len;
14228 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
14229 _("smallest"));
14230 break;
14231
14232 case Tag_ARC_ABI_exceptions:
14233 val = read_uleb128 (p, &len, end);
14234 p += len;
14235 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
14236 : _("default"));
14237 break;
14238
14239 case Tag_ARC_ABI_double_size:
14240 val = read_uleb128 (p, &len, end);
14241 p += len;
14242 printf (" Tag_ARC_ABI_double_size: %d\n", val);
14243 break;
14244
14245 case Tag_ARC_ISA_config:
14246 printf (" Tag_ARC_ISA_config: ");
14247 p = display_tag_value (-1, p, end);
14248 break;
14249
14250 case Tag_ARC_ISA_apex:
14251 printf (" Tag_ARC_ISA_apex: ");
14252 p = display_tag_value (-1, p, end);
14253 break;
14254
14255 case Tag_ARC_ISA_mpy_option:
14256 val = read_uleb128 (p, &len, end);
14257 p += len;
14258 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
14259 break;
14260
db1e1b45 14261 case Tag_ARC_ATR_version:
14262 val = read_uleb128 (p, &len, end);
14263 p += len;
14264 printf (" Tag_ARC_ATR_version: %d\n", val);
14265 break;
14266
53a346d8
CZ
14267 default:
14268 return display_tag_value (tag & 1, p, end);
14269 }
14270
14271 return p;
14272}
14273
11c1ff18
PB
14274/* ARM EABI attributes section. */
14275typedef struct
14276{
70e99720 14277 unsigned int tag;
2cf0635d 14278 const char * name;
11c1ff18 14279 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 14280 unsigned int type;
2cf0635d 14281 const char ** table;
11c1ff18
PB
14282} arm_attr_public_tag;
14283
2cf0635d 14284static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 14285 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 14286 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
ff8646ee 14287 "v8-M.mainline"};
2cf0635d
NC
14288static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
14289static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 14290 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 14291static const char * arm_attr_tag_FP_arch[] =
bca38921 14292 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 14293 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 14294static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 14295static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
14296 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
14297 "NEON for ARMv8.1"};
2cf0635d 14298static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
14299 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
14300 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 14301static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 14302 {"V6", "SB", "TLS", "Unused"};
2cf0635d 14303static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 14304 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 14305static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 14306 {"Absolute", "PC-relative", "None"};
2cf0635d 14307static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 14308 {"None", "direct", "GOT-indirect"};
2cf0635d 14309static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 14310 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
14311static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
14312static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 14313 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
14314static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
14315static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
14316static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 14317 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 14318static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 14319 {"Unused", "small", "int", "forced to int"};
2cf0635d 14320static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 14321 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 14322static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 14323 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 14324static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 14325 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 14326static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
14327 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14328 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 14329static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
14330 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14331 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 14332static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 14333static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 14334 {"Not Allowed", "Allowed"};
2cf0635d 14335static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 14336 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
14337static const char * arm_attr_tag_DSP_extension[] =
14338 {"Follow architecture", "Allowed"};
dd24e3da 14339static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
14340 {"Not Allowed", "Allowed"};
14341static const char * arm_attr_tag_DIV_use[] =
dd24e3da 14342 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 14343 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
14344static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
14345static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 14346 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 14347 "TrustZone and Virtualization Extensions"};
dd24e3da 14348static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 14349 {"Not Allowed", "Allowed"};
11c1ff18
PB
14350
14351#define LOOKUP(id, name) \
14352 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 14353static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
14354{
14355 {4, "CPU_raw_name", 1, NULL},
14356 {5, "CPU_name", 1, NULL},
14357 LOOKUP(6, CPU_arch),
14358 {7, "CPU_arch_profile", 0, NULL},
14359 LOOKUP(8, ARM_ISA_use),
14360 LOOKUP(9, THUMB_ISA_use),
75375b3e 14361 LOOKUP(10, FP_arch),
11c1ff18 14362 LOOKUP(11, WMMX_arch),
f5f53991
AS
14363 LOOKUP(12, Advanced_SIMD_arch),
14364 LOOKUP(13, PCS_config),
11c1ff18
PB
14365 LOOKUP(14, ABI_PCS_R9_use),
14366 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 14367 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
14368 LOOKUP(17, ABI_PCS_GOT_use),
14369 LOOKUP(18, ABI_PCS_wchar_t),
14370 LOOKUP(19, ABI_FP_rounding),
14371 LOOKUP(20, ABI_FP_denormal),
14372 LOOKUP(21, ABI_FP_exceptions),
14373 LOOKUP(22, ABI_FP_user_exceptions),
14374 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
14375 {24, "ABI_align_needed", 0, NULL},
14376 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
14377 LOOKUP(26, ABI_enum_size),
14378 LOOKUP(27, ABI_HardFP_use),
14379 LOOKUP(28, ABI_VFP_args),
14380 LOOKUP(29, ABI_WMMX_args),
14381 LOOKUP(30, ABI_optimization_goals),
14382 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 14383 {32, "compatibility", 0, NULL},
f5f53991 14384 LOOKUP(34, CPU_unaligned_access),
75375b3e 14385 LOOKUP(36, FP_HP_extension),
8e79c3df 14386 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
14387 LOOKUP(42, MPextension_use),
14388 LOOKUP(44, DIV_use),
15afaa63 14389 LOOKUP(46, DSP_extension),
f5f53991
AS
14390 {64, "nodefaults", 0, NULL},
14391 {65, "also_compatible_with", 0, NULL},
14392 LOOKUP(66, T2EE_use),
14393 {67, "conformance", 1, NULL},
14394 LOOKUP(68, Virtualization_use),
cd21e546 14395 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
14396};
14397#undef LOOKUP
14398
11c1ff18 14399static unsigned char *
f6f0e17b
NC
14400display_arm_attribute (unsigned char * p,
14401 const unsigned char * const end)
11c1ff18 14402{
70e99720 14403 unsigned int tag;
11c1ff18 14404 unsigned int len;
70e99720 14405 unsigned int val;
2cf0635d 14406 arm_attr_public_tag * attr;
11c1ff18 14407 unsigned i;
70e99720 14408 unsigned int type;
11c1ff18 14409
f6f0e17b 14410 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
14411 p += len;
14412 attr = NULL;
2cf0635d 14413 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
14414 {
14415 if (arm_attr_public_tags[i].tag == tag)
14416 {
14417 attr = &arm_attr_public_tags[i];
14418 break;
14419 }
14420 }
14421
14422 if (attr)
14423 {
14424 printf (" Tag_%s: ", attr->name);
14425 switch (attr->type)
14426 {
14427 case 0:
14428 switch (tag)
14429 {
14430 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 14431 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14432 p += len;
14433 switch (val)
14434 {
2b692964
NC
14435 case 0: printf (_("None\n")); break;
14436 case 'A': printf (_("Application\n")); break;
14437 case 'R': printf (_("Realtime\n")); break;
14438 case 'M': printf (_("Microcontroller\n")); break;
14439 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
14440 default: printf ("??? (%d)\n", val); break;
14441 }
14442 break;
14443
75375b3e 14444 case 24: /* Tag_align_needed. */
f6f0e17b 14445 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14446 p += len;
14447 switch (val)
14448 {
2b692964
NC
14449 case 0: printf (_("None\n")); break;
14450 case 1: printf (_("8-byte\n")); break;
14451 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
14452 case 3: printf ("??? 3\n"); break;
14453 default:
14454 if (val <= 12)
dd24e3da 14455 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14456 1 << val);
14457 else
14458 printf ("??? (%d)\n", val);
14459 break;
14460 }
14461 break;
14462
14463 case 25: /* Tag_align_preserved. */
f6f0e17b 14464 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14465 p += len;
14466 switch (val)
14467 {
2b692964
NC
14468 case 0: printf (_("None\n")); break;
14469 case 1: printf (_("8-byte, except leaf SP\n")); break;
14470 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
14471 case 3: printf ("??? 3\n"); break;
14472 default:
14473 if (val <= 12)
dd24e3da 14474 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14475 1 << val);
14476 else
14477 printf ("??? (%d)\n", val);
14478 break;
14479 }
14480 break;
14481
11c1ff18 14482 case 32: /* Tag_compatibility. */
071436c6 14483 {
071436c6
NC
14484 val = read_uleb128 (p, &len, end);
14485 p += len;
071436c6 14486 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
14487 if (p < end - 1)
14488 {
14489 size_t maxlen = (end - p) - 1;
14490
14491 print_symbol ((int) maxlen, (const char *) p);
14492 p += strnlen ((char *) p, maxlen) + 1;
14493 }
14494 else
14495 {
14496 printf (_("<corrupt>"));
14497 p = (unsigned char *) end;
14498 }
071436c6 14499 putchar ('\n');
071436c6 14500 }
11c1ff18
PB
14501 break;
14502
f5f53991 14503 case 64: /* Tag_nodefaults. */
541a3cbd
NC
14504 /* PR 17531: file: 001-505008-0.01. */
14505 if (p < end)
14506 p++;
2b692964 14507 printf (_("True\n"));
f5f53991
AS
14508 break;
14509
14510 case 65: /* Tag_also_compatible_with. */
f6f0e17b 14511 val = read_uleb128 (p, &len, end);
f5f53991
AS
14512 p += len;
14513 if (val == 6 /* Tag_CPU_arch. */)
14514 {
f6f0e17b 14515 val = read_uleb128 (p, &len, end);
f5f53991 14516 p += len;
071436c6 14517 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
14518 printf ("??? (%d)\n", val);
14519 else
14520 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
14521 }
14522 else
14523 printf ("???\n");
071436c6
NC
14524 while (p < end && *(p++) != '\0' /* NUL terminator. */)
14525 ;
f5f53991
AS
14526 break;
14527
11c1ff18 14528 default:
bee0ee85
NC
14529 printf (_("<unknown: %d>\n"), tag);
14530 break;
11c1ff18
PB
14531 }
14532 return p;
14533
14534 case 1:
f6f0e17b 14535 return display_tag_value (-1, p, end);
11c1ff18 14536 case 2:
f6f0e17b 14537 return display_tag_value (0, p, end);
11c1ff18
PB
14538
14539 default:
14540 assert (attr->type & 0x80);
f6f0e17b 14541 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14542 p += len;
14543 type = attr->type & 0x7f;
14544 if (val >= type)
14545 printf ("??? (%d)\n", val);
14546 else
14547 printf ("%s\n", attr->table[val]);
14548 return p;
14549 }
14550 }
11c1ff18 14551
f6f0e17b 14552 return display_tag_value (tag, p, end);
11c1ff18
PB
14553}
14554
104d59d1 14555static unsigned char *
60bca95a 14556display_gnu_attribute (unsigned char * p,
60abdbed 14557 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 14558 const unsigned char * const end)
104d59d1
JM
14559{
14560 int tag;
14561 unsigned int len;
60abdbed 14562 unsigned int val;
104d59d1 14563
f6f0e17b 14564 tag = read_uleb128 (p, &len, end);
104d59d1
JM
14565 p += len;
14566
14567 /* Tag_compatibility is the only generic GNU attribute defined at
14568 present. */
14569 if (tag == 32)
14570 {
f6f0e17b 14571 val = read_uleb128 (p, &len, end);
104d59d1 14572 p += len;
071436c6
NC
14573
14574 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
14575 if (p == end)
14576 {
071436c6 14577 printf (_("<corrupt>\n"));
f6f0e17b
NC
14578 warn (_("corrupt vendor attribute\n"));
14579 }
14580 else
14581 {
4082ef84
NC
14582 if (p < end - 1)
14583 {
14584 size_t maxlen = (end - p) - 1;
071436c6 14585
4082ef84
NC
14586 print_symbol ((int) maxlen, (const char *) p);
14587 p += strnlen ((char *) p, maxlen) + 1;
14588 }
14589 else
14590 {
14591 printf (_("<corrupt>"));
14592 p = (unsigned char *) end;
14593 }
071436c6 14594 putchar ('\n');
f6f0e17b 14595 }
104d59d1
JM
14596 return p;
14597 }
14598
14599 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 14600 return display_proc_gnu_attribute (p, tag, end);
104d59d1 14601
f6f0e17b 14602 return display_tag_value (tag, p, end);
104d59d1
JM
14603}
14604
34c8bcba 14605static unsigned char *
f6f0e17b 14606display_power_gnu_attribute (unsigned char * p,
60abdbed 14607 unsigned int tag,
f6f0e17b 14608 const unsigned char * const end)
34c8bcba 14609{
34c8bcba 14610 unsigned int len;
005d79fd 14611 unsigned int val;
34c8bcba
JM
14612
14613 if (tag == Tag_GNU_Power_ABI_FP)
14614 {
f6f0e17b 14615 val = read_uleb128 (p, &len, end);
34c8bcba
JM
14616 p += len;
14617 printf (" Tag_GNU_Power_ABI_FP: ");
005d79fd
AM
14618 if (len == 0)
14619 {
14620 printf (_("<corrupt>\n"));
14621 return p;
14622 }
60bca95a 14623
005d79fd
AM
14624 if (val > 15)
14625 printf ("(%#x), ", val);
14626
14627 switch (val & 3)
34c8bcba
JM
14628 {
14629 case 0:
005d79fd 14630 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
14631 break;
14632 case 1:
005d79fd 14633 printf (_("hard float, "));
34c8bcba
JM
14634 break;
14635 case 2:
005d79fd 14636 printf (_("soft float, "));
34c8bcba 14637 break;
3c7b9897 14638 case 3:
005d79fd 14639 printf (_("single-precision hard float, "));
3c7b9897 14640 break;
005d79fd
AM
14641 }
14642
14643 switch (val & 0xC)
14644 {
14645 case 0:
14646 printf (_("unspecified long double\n"));
14647 break;
14648 case 4:
14649 printf (_("128-bit IBM long double\n"));
14650 break;
14651 case 8:
14652 printf (_("64-bit long double\n"));
14653 break;
14654 case 12:
14655 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
14656 break;
14657 }
14658 return p;
005d79fd 14659 }
34c8bcba 14660
c6e65352
DJ
14661 if (tag == Tag_GNU_Power_ABI_Vector)
14662 {
f6f0e17b 14663 val = read_uleb128 (p, &len, end);
c6e65352
DJ
14664 p += len;
14665 printf (" Tag_GNU_Power_ABI_Vector: ");
005d79fd
AM
14666 if (len == 0)
14667 {
14668 printf (_("<corrupt>\n"));
14669 return p;
14670 }
14671
14672 if (val > 3)
14673 printf ("(%#x), ", val);
14674
14675 switch (val & 3)
c6e65352
DJ
14676 {
14677 case 0:
005d79fd 14678 printf (_("unspecified\n"));
c6e65352
DJ
14679 break;
14680 case 1:
005d79fd 14681 printf (_("generic\n"));
c6e65352
DJ
14682 break;
14683 case 2:
14684 printf ("AltiVec\n");
14685 break;
14686 case 3:
14687 printf ("SPE\n");
14688 break;
c6e65352
DJ
14689 }
14690 return p;
005d79fd 14691 }
c6e65352 14692
f82e0623
NF
14693 if (tag == Tag_GNU_Power_ABI_Struct_Return)
14694 {
005d79fd
AM
14695 val = read_uleb128 (p, &len, end);
14696 p += len;
14697 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
14698 if (len == 0)
f6f0e17b 14699 {
005d79fd 14700 printf (_("<corrupt>\n"));
f6f0e17b
NC
14701 return p;
14702 }
0b4362b0 14703
005d79fd
AM
14704 if (val > 2)
14705 printf ("(%#x), ", val);
14706
14707 switch (val & 3)
14708 {
14709 case 0:
14710 printf (_("unspecified\n"));
14711 break;
14712 case 1:
14713 printf ("r3/r4\n");
14714 break;
14715 case 2:
14716 printf (_("memory\n"));
14717 break;
14718 case 3:
14719 printf ("???\n");
14720 break;
14721 }
f82e0623
NF
14722 return p;
14723 }
14724
f6f0e17b 14725 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
14726}
14727
643f7afb
AK
14728static unsigned char *
14729display_s390_gnu_attribute (unsigned char * p,
60abdbed 14730 unsigned int tag,
643f7afb
AK
14731 const unsigned char * const end)
14732{
14733 unsigned int len;
14734 int val;
14735
14736 if (tag == Tag_GNU_S390_ABI_Vector)
14737 {
14738 val = read_uleb128 (p, &len, end);
14739 p += len;
14740 printf (" Tag_GNU_S390_ABI_Vector: ");
14741
14742 switch (val)
14743 {
14744 case 0:
14745 printf (_("any\n"));
14746 break;
14747 case 1:
14748 printf (_("software\n"));
14749 break;
14750 case 2:
14751 printf (_("hardware\n"));
14752 break;
14753 default:
14754 printf ("??? (%d)\n", val);
14755 break;
14756 }
14757 return p;
14758 }
14759
14760 return display_tag_value (tag & 1, p, end);
14761}
14762
9e8c70f9 14763static void
60abdbed 14764display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
14765{
14766 if (mask)
14767 {
32ec8896 14768 bfd_boolean first = TRUE;
071436c6 14769
9e8c70f9 14770 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 14771 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 14772 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 14773 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 14774 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 14775 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 14776 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 14777 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 14778 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 14779 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 14780 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 14781 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 14782 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 14783 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 14784 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 14785 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 14786 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 14787 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 14788 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 14789 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 14790 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 14791 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 14792 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 14793 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 14794 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 14795 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 14796 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 14797 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 14798 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 14799 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 14800 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 14801 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
14802 }
14803 else
071436c6
NC
14804 fputc ('0', stdout);
14805 fputc ('\n', stdout);
9e8c70f9
DM
14806}
14807
3d68f91c 14808static void
60abdbed 14809display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
14810{
14811 if (mask)
14812 {
32ec8896 14813 bfd_boolean first = TRUE;
071436c6 14814
3d68f91c 14815 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 14816 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 14817 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 14818 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 14819 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 14820 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 14821 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 14822 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 14823 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 14824 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 14825 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 14826 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 14827 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 14828 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 14829 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 14830 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 14831 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 14832 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 14833 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 14834 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 14835 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 14836 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
14837 }
14838 else
071436c6
NC
14839 fputc ('0', stdout);
14840 fputc ('\n', stdout);
3d68f91c
JM
14841}
14842
9e8c70f9 14843static unsigned char *
f6f0e17b 14844display_sparc_gnu_attribute (unsigned char * p,
60abdbed 14845 unsigned int tag,
f6f0e17b 14846 const unsigned char * const end)
9e8c70f9 14847{
3d68f91c
JM
14848 unsigned int len;
14849 int val;
14850
9e8c70f9
DM
14851 if (tag == Tag_GNU_Sparc_HWCAPS)
14852 {
f6f0e17b 14853 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
14854 p += len;
14855 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
14856 display_sparc_hwcaps (val);
14857 return p;
3d68f91c
JM
14858 }
14859 if (tag == Tag_GNU_Sparc_HWCAPS2)
14860 {
14861 val = read_uleb128 (p, &len, end);
14862 p += len;
14863 printf (" Tag_GNU_Sparc_HWCAPS2: ");
14864 display_sparc_hwcaps2 (val);
14865 return p;
14866 }
9e8c70f9 14867
f6f0e17b 14868 return display_tag_value (tag, p, end);
9e8c70f9
DM
14869}
14870
351cdf24 14871static void
32ec8896 14872print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
14873{
14874 switch (val)
14875 {
14876 case Val_GNU_MIPS_ABI_FP_ANY:
14877 printf (_("Hard or soft float\n"));
14878 break;
14879 case Val_GNU_MIPS_ABI_FP_DOUBLE:
14880 printf (_("Hard float (double precision)\n"));
14881 break;
14882 case Val_GNU_MIPS_ABI_FP_SINGLE:
14883 printf (_("Hard float (single precision)\n"));
14884 break;
14885 case Val_GNU_MIPS_ABI_FP_SOFT:
14886 printf (_("Soft float\n"));
14887 break;
14888 case Val_GNU_MIPS_ABI_FP_OLD_64:
14889 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
14890 break;
14891 case Val_GNU_MIPS_ABI_FP_XX:
14892 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
14893 break;
14894 case Val_GNU_MIPS_ABI_FP_64:
14895 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
14896 break;
14897 case Val_GNU_MIPS_ABI_FP_64A:
14898 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
14899 break;
3350cc01
CM
14900 case Val_GNU_MIPS_ABI_FP_NAN2008:
14901 printf (_("NaN 2008 compatibility\n"));
14902 break;
351cdf24
MF
14903 default:
14904 printf ("??? (%d)\n", val);
14905 break;
14906 }
14907}
14908
2cf19d5c 14909static unsigned char *
f6f0e17b 14910display_mips_gnu_attribute (unsigned char * p,
60abdbed 14911 unsigned int tag,
f6f0e17b 14912 const unsigned char * const end)
2cf19d5c 14913{
2cf19d5c
JM
14914 if (tag == Tag_GNU_MIPS_ABI_FP)
14915 {
f6f0e17b 14916 unsigned int len;
32ec8896 14917 unsigned int val;
f6f0e17b
NC
14918
14919 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
14920 p += len;
14921 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 14922
351cdf24
MF
14923 print_mips_fp_abi_value (val);
14924
2cf19d5c
JM
14925 return p;
14926 }
14927
a9f58168
CF
14928 if (tag == Tag_GNU_MIPS_ABI_MSA)
14929 {
14930 unsigned int len;
32ec8896 14931 unsigned int val;
a9f58168
CF
14932
14933 val = read_uleb128 (p, &len, end);
14934 p += len;
14935 printf (" Tag_GNU_MIPS_ABI_MSA: ");
14936
14937 switch (val)
14938 {
14939 case Val_GNU_MIPS_ABI_MSA_ANY:
14940 printf (_("Any MSA or not\n"));
14941 break;
14942 case Val_GNU_MIPS_ABI_MSA_128:
14943 printf (_("128-bit MSA\n"));
14944 break;
14945 default:
14946 printf ("??? (%d)\n", val);
14947 break;
14948 }
14949 return p;
14950 }
14951
f6f0e17b 14952 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
14953}
14954
59e6276b 14955static unsigned char *
f6f0e17b
NC
14956display_tic6x_attribute (unsigned char * p,
14957 const unsigned char * const end)
59e6276b 14958{
60abdbed 14959 unsigned int tag;
59e6276b
JM
14960 unsigned int len;
14961 int val;
14962
f6f0e17b 14963 tag = read_uleb128 (p, &len, end);
59e6276b
JM
14964 p += len;
14965
14966 switch (tag)
14967 {
75fa6dc1 14968 case Tag_ISA:
f6f0e17b 14969 val = read_uleb128 (p, &len, end);
59e6276b 14970 p += len;
75fa6dc1 14971 printf (" Tag_ISA: ");
59e6276b
JM
14972
14973 switch (val)
14974 {
75fa6dc1 14975 case C6XABI_Tag_ISA_none:
59e6276b
JM
14976 printf (_("None\n"));
14977 break;
75fa6dc1 14978 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
14979 printf ("C62x\n");
14980 break;
75fa6dc1 14981 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
14982 printf ("C67x\n");
14983 break;
75fa6dc1 14984 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
14985 printf ("C67x+\n");
14986 break;
75fa6dc1 14987 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
14988 printf ("C64x\n");
14989 break;
75fa6dc1 14990 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
14991 printf ("C64x+\n");
14992 break;
75fa6dc1 14993 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
14994 printf ("C674x\n");
14995 break;
14996 default:
14997 printf ("??? (%d)\n", val);
14998 break;
14999 }
15000 return p;
15001
87779176 15002 case Tag_ABI_wchar_t:
f6f0e17b 15003 val = read_uleb128 (p, &len, end);
87779176
JM
15004 p += len;
15005 printf (" Tag_ABI_wchar_t: ");
15006 switch (val)
15007 {
15008 case 0:
15009 printf (_("Not used\n"));
15010 break;
15011 case 1:
15012 printf (_("2 bytes\n"));
15013 break;
15014 case 2:
15015 printf (_("4 bytes\n"));
15016 break;
15017 default:
15018 printf ("??? (%d)\n", val);
15019 break;
15020 }
15021 return p;
15022
15023 case Tag_ABI_stack_align_needed:
f6f0e17b 15024 val = read_uleb128 (p, &len, end);
87779176
JM
15025 p += len;
15026 printf (" Tag_ABI_stack_align_needed: ");
15027 switch (val)
15028 {
15029 case 0:
15030 printf (_("8-byte\n"));
15031 break;
15032 case 1:
15033 printf (_("16-byte\n"));
15034 break;
15035 default:
15036 printf ("??? (%d)\n", val);
15037 break;
15038 }
15039 return p;
15040
15041 case Tag_ABI_stack_align_preserved:
f6f0e17b 15042 val = read_uleb128 (p, &len, end);
87779176
JM
15043 p += len;
15044 printf (" Tag_ABI_stack_align_preserved: ");
15045 switch (val)
15046 {
15047 case 0:
15048 printf (_("8-byte\n"));
15049 break;
15050 case 1:
15051 printf (_("16-byte\n"));
15052 break;
15053 default:
15054 printf ("??? (%d)\n", val);
15055 break;
15056 }
15057 return p;
15058
b5593623 15059 case Tag_ABI_DSBT:
f6f0e17b 15060 val = read_uleb128 (p, &len, end);
b5593623
JM
15061 p += len;
15062 printf (" Tag_ABI_DSBT: ");
15063 switch (val)
15064 {
15065 case 0:
15066 printf (_("DSBT addressing not used\n"));
15067 break;
15068 case 1:
15069 printf (_("DSBT addressing used\n"));
15070 break;
15071 default:
15072 printf ("??? (%d)\n", val);
15073 break;
15074 }
15075 return p;
15076
87779176 15077 case Tag_ABI_PID:
f6f0e17b 15078 val = read_uleb128 (p, &len, end);
87779176
JM
15079 p += len;
15080 printf (" Tag_ABI_PID: ");
15081 switch (val)
15082 {
15083 case 0:
15084 printf (_("Data addressing position-dependent\n"));
15085 break;
15086 case 1:
15087 printf (_("Data addressing position-independent, GOT near DP\n"));
15088 break;
15089 case 2:
15090 printf (_("Data addressing position-independent, GOT far from DP\n"));
15091 break;
15092 default:
15093 printf ("??? (%d)\n", val);
15094 break;
15095 }
15096 return p;
15097
15098 case Tag_ABI_PIC:
f6f0e17b 15099 val = read_uleb128 (p, &len, end);
87779176
JM
15100 p += len;
15101 printf (" Tag_ABI_PIC: ");
15102 switch (val)
15103 {
15104 case 0:
15105 printf (_("Code addressing position-dependent\n"));
15106 break;
15107 case 1:
15108 printf (_("Code addressing position-independent\n"));
15109 break;
15110 default:
15111 printf ("??? (%d)\n", val);
15112 break;
15113 }
15114 return p;
15115
15116 case Tag_ABI_array_object_alignment:
f6f0e17b 15117 val = read_uleb128 (p, &len, end);
87779176
JM
15118 p += len;
15119 printf (" Tag_ABI_array_object_alignment: ");
15120 switch (val)
15121 {
15122 case 0:
15123 printf (_("8-byte\n"));
15124 break;
15125 case 1:
15126 printf (_("4-byte\n"));
15127 break;
15128 case 2:
15129 printf (_("16-byte\n"));
15130 break;
15131 default:
15132 printf ("??? (%d)\n", val);
15133 break;
15134 }
15135 return p;
15136
15137 case Tag_ABI_array_object_align_expected:
f6f0e17b 15138 val = read_uleb128 (p, &len, end);
87779176
JM
15139 p += len;
15140 printf (" Tag_ABI_array_object_align_expected: ");
15141 switch (val)
15142 {
15143 case 0:
15144 printf (_("8-byte\n"));
15145 break;
15146 case 1:
15147 printf (_("4-byte\n"));
15148 break;
15149 case 2:
15150 printf (_("16-byte\n"));
15151 break;
15152 default:
15153 printf ("??? (%d)\n", val);
15154 break;
15155 }
15156 return p;
15157
3cbd1c06 15158 case Tag_ABI_compatibility:
071436c6 15159 {
071436c6
NC
15160 val = read_uleb128 (p, &len, end);
15161 p += len;
15162 printf (" Tag_ABI_compatibility: ");
071436c6 15163 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15164 if (p < end - 1)
15165 {
15166 size_t maxlen = (end - p) - 1;
15167
15168 print_symbol ((int) maxlen, (const char *) p);
15169 p += strnlen ((char *) p, maxlen) + 1;
15170 }
15171 else
15172 {
15173 printf (_("<corrupt>"));
15174 p = (unsigned char *) end;
15175 }
071436c6 15176 putchar ('\n');
071436c6
NC
15177 return p;
15178 }
87779176
JM
15179
15180 case Tag_ABI_conformance:
071436c6 15181 {
4082ef84
NC
15182 printf (" Tag_ABI_conformance: \"");
15183 if (p < end - 1)
15184 {
15185 size_t maxlen = (end - p) - 1;
071436c6 15186
4082ef84
NC
15187 print_symbol ((int) maxlen, (const char *) p);
15188 p += strnlen ((char *) p, maxlen) + 1;
15189 }
15190 else
15191 {
15192 printf (_("<corrupt>"));
15193 p = (unsigned char *) end;
15194 }
071436c6 15195 printf ("\"\n");
071436c6
NC
15196 return p;
15197 }
59e6276b
JM
15198 }
15199
f6f0e17b
NC
15200 return display_tag_value (tag, p, end);
15201}
59e6276b 15202
f6f0e17b 15203static void
60abdbed 15204display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
15205{
15206 unsigned long addr = 0;
15207 size_t bytes = end - p;
15208
e0a31db1 15209 assert (end > p);
f6f0e17b 15210 while (bytes)
87779176 15211 {
f6f0e17b
NC
15212 int j;
15213 int k;
15214 int lbytes = (bytes > 16 ? 16 : bytes);
15215
15216 printf (" 0x%8.8lx ", addr);
15217
15218 for (j = 0; j < 16; j++)
15219 {
15220 if (j < lbytes)
15221 printf ("%2.2x", p[j]);
15222 else
15223 printf (" ");
15224
15225 if ((j & 3) == 3)
15226 printf (" ");
15227 }
15228
15229 for (j = 0; j < lbytes; j++)
15230 {
15231 k = p[j];
15232 if (k >= ' ' && k < 0x7f)
15233 printf ("%c", k);
15234 else
15235 printf (".");
15236 }
15237
15238 putchar ('\n');
15239
15240 p += lbytes;
15241 bytes -= lbytes;
15242 addr += lbytes;
87779176 15243 }
59e6276b 15244
f6f0e17b 15245 putchar ('\n');
59e6276b
JM
15246}
15247
13761a11
NC
15248static unsigned char *
15249display_msp430x_attribute (unsigned char * p,
15250 const unsigned char * const end)
15251{
15252 unsigned int len;
60abdbed
NC
15253 unsigned int val;
15254 unsigned int tag;
13761a11
NC
15255
15256 tag = read_uleb128 (p, & len, end);
15257 p += len;
0b4362b0 15258
13761a11
NC
15259 switch (tag)
15260 {
15261 case OFBA_MSPABI_Tag_ISA:
15262 val = read_uleb128 (p, &len, end);
15263 p += len;
15264 printf (" Tag_ISA: ");
15265 switch (val)
15266 {
15267 case 0: printf (_("None\n")); break;
15268 case 1: printf (_("MSP430\n")); break;
15269 case 2: printf (_("MSP430X\n")); break;
15270 default: printf ("??? (%d)\n", val); break;
15271 }
15272 break;
15273
15274 case OFBA_MSPABI_Tag_Code_Model:
15275 val = read_uleb128 (p, &len, end);
15276 p += len;
15277 printf (" Tag_Code_Model: ");
15278 switch (val)
15279 {
15280 case 0: printf (_("None\n")); break;
15281 case 1: printf (_("Small\n")); break;
15282 case 2: printf (_("Large\n")); break;
15283 default: printf ("??? (%d)\n", val); break;
15284 }
15285 break;
15286
15287 case OFBA_MSPABI_Tag_Data_Model:
15288 val = read_uleb128 (p, &len, end);
15289 p += len;
15290 printf (" Tag_Data_Model: ");
15291 switch (val)
15292 {
15293 case 0: printf (_("None\n")); break;
15294 case 1: printf (_("Small\n")); break;
15295 case 2: printf (_("Large\n")); break;
15296 case 3: printf (_("Restricted Large\n")); break;
15297 default: printf ("??? (%d)\n", val); break;
15298 }
15299 break;
15300
15301 default:
15302 printf (_(" <unknown tag %d>: "), tag);
15303
15304 if (tag & 1)
15305 {
071436c6 15306 putchar ('"');
4082ef84
NC
15307 if (p < end - 1)
15308 {
15309 size_t maxlen = (end - p) - 1;
15310
15311 print_symbol ((int) maxlen, (const char *) p);
15312 p += strnlen ((char *) p, maxlen) + 1;
15313 }
15314 else
15315 {
15316 printf (_("<corrupt>"));
15317 p = (unsigned char *) end;
15318 }
071436c6 15319 printf ("\"\n");
13761a11
NC
15320 }
15321 else
15322 {
15323 val = read_uleb128 (p, &len, end);
15324 p += len;
15325 printf ("%d (0x%x)\n", val, val);
15326 }
15327 break;
15328 }
15329
4082ef84 15330 assert (p <= end);
13761a11
NC
15331 return p;
15332}
15333
32ec8896 15334static bfd_boolean
dda8d76d 15335process_attributes (Filedata * filedata,
60bca95a 15336 const char * public_name,
104d59d1 15337 unsigned int proc_type,
f6f0e17b 15338 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 15339 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 15340{
2cf0635d 15341 Elf_Internal_Shdr * sect;
11c1ff18 15342 unsigned i;
32ec8896 15343 bfd_boolean res = TRUE;
11c1ff18
PB
15344
15345 /* Find the section header so that we get the size. */
dda8d76d
NC
15346 for (i = 0, sect = filedata->section_headers;
15347 i < filedata->file_header.e_shnum;
11c1ff18
PB
15348 i++, sect++)
15349 {
071436c6
NC
15350 unsigned char * contents;
15351 unsigned char * p;
15352
104d59d1 15353 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
15354 continue;
15355
dda8d76d 15356 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 15357 sect->sh_size, _("attributes"));
60bca95a 15358 if (contents == NULL)
32ec8896
NC
15359 {
15360 res = FALSE;
15361 continue;
15362 }
60bca95a 15363
11c1ff18 15364 p = contents;
60abdbed
NC
15365 /* The first character is the version of the attributes.
15366 Currently only version 1, (aka 'A') is recognised here. */
15367 if (*p != 'A')
32ec8896
NC
15368 {
15369 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
15370 res = FALSE;
15371 }
60abdbed 15372 else
11c1ff18 15373 {
071436c6
NC
15374 bfd_vma section_len;
15375
15376 section_len = sect->sh_size - 1;
11c1ff18 15377 p++;
60bca95a 15378
071436c6 15379 while (section_len > 0)
11c1ff18 15380 {
071436c6 15381 bfd_vma attr_len;
e9847026 15382 unsigned int namelen;
11c1ff18 15383 bfd_boolean public_section;
104d59d1 15384 bfd_boolean gnu_section;
11c1ff18 15385
071436c6 15386 if (section_len <= 4)
e0a31db1
NC
15387 {
15388 error (_("Tag section ends prematurely\n"));
32ec8896 15389 res = FALSE;
e0a31db1
NC
15390 break;
15391 }
071436c6 15392 attr_len = byte_get (p, 4);
11c1ff18 15393 p += 4;
60bca95a 15394
071436c6 15395 if (attr_len > section_len)
11c1ff18 15396 {
071436c6
NC
15397 error (_("Bad attribute length (%u > %u)\n"),
15398 (unsigned) attr_len, (unsigned) section_len);
15399 attr_len = section_len;
32ec8896 15400 res = FALSE;
11c1ff18 15401 }
74e1a04b 15402 /* PR 17531: file: 001-101425-0.004 */
071436c6 15403 else if (attr_len < 5)
74e1a04b 15404 {
071436c6 15405 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 15406 res = FALSE;
74e1a04b
NC
15407 break;
15408 }
e9847026 15409
071436c6
NC
15410 section_len -= attr_len;
15411 attr_len -= 4;
15412
15413 namelen = strnlen ((char *) p, attr_len) + 1;
15414 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
15415 {
15416 error (_("Corrupt attribute section name\n"));
32ec8896 15417 res = FALSE;
e9847026
NC
15418 break;
15419 }
15420
071436c6
NC
15421 printf (_("Attribute Section: "));
15422 print_symbol (INT_MAX, (const char *) p);
15423 putchar ('\n');
60bca95a
NC
15424
15425 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
15426 public_section = TRUE;
15427 else
15428 public_section = FALSE;
60bca95a
NC
15429
15430 if (streq ((char *) p, "gnu"))
104d59d1
JM
15431 gnu_section = TRUE;
15432 else
15433 gnu_section = FALSE;
60bca95a 15434
11c1ff18 15435 p += namelen;
071436c6 15436 attr_len -= namelen;
e0a31db1 15437
071436c6 15438 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 15439 {
e0a31db1 15440 int tag;
11c1ff18
PB
15441 int val;
15442 bfd_vma size;
071436c6 15443 unsigned char * end;
60bca95a 15444
e0a31db1 15445 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 15446 if (attr_len < 6)
e0a31db1
NC
15447 {
15448 error (_("Unused bytes at end of section\n"));
32ec8896 15449 res = FALSE;
e0a31db1
NC
15450 section_len = 0;
15451 break;
15452 }
15453
15454 tag = *(p++);
11c1ff18 15455 size = byte_get (p, 4);
071436c6 15456 if (size > attr_len)
11c1ff18 15457 {
e9847026 15458 error (_("Bad subsection length (%u > %u)\n"),
071436c6 15459 (unsigned) size, (unsigned) attr_len);
32ec8896 15460 res = FALSE;
071436c6 15461 size = attr_len;
11c1ff18 15462 }
e0a31db1
NC
15463 /* PR binutils/17531: Safe handling of corrupt files. */
15464 if (size < 6)
15465 {
15466 error (_("Bad subsection length (%u < 6)\n"),
15467 (unsigned) size);
32ec8896 15468 res = FALSE;
e0a31db1
NC
15469 section_len = 0;
15470 break;
15471 }
60bca95a 15472
071436c6 15473 attr_len -= size;
11c1ff18 15474 end = p + size - 1;
071436c6 15475 assert (end <= contents + sect->sh_size);
11c1ff18 15476 p += 4;
60bca95a 15477
11c1ff18
PB
15478 switch (tag)
15479 {
15480 case 1:
2b692964 15481 printf (_("File Attributes\n"));
11c1ff18
PB
15482 break;
15483 case 2:
2b692964 15484 printf (_("Section Attributes:"));
11c1ff18
PB
15485 goto do_numlist;
15486 case 3:
2b692964 15487 printf (_("Symbol Attributes:"));
1a0670f3 15488 /* Fall through. */
11c1ff18
PB
15489 do_numlist:
15490 for (;;)
15491 {
91d6fa6a 15492 unsigned int j;
60bca95a 15493
f6f0e17b 15494 val = read_uleb128 (p, &j, end);
91d6fa6a 15495 p += j;
11c1ff18
PB
15496 if (val == 0)
15497 break;
15498 printf (" %d", val);
15499 }
15500 printf ("\n");
15501 break;
15502 default:
2b692964 15503 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
15504 public_section = FALSE;
15505 break;
15506 }
60bca95a 15507
071436c6 15508 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
15509 {
15510 while (p < end)
f6f0e17b 15511 p = display_pub_attribute (p, end);
60abdbed 15512 assert (p == end);
104d59d1 15513 }
071436c6 15514 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
15515 {
15516 while (p < end)
15517 p = display_gnu_attribute (p,
f6f0e17b
NC
15518 display_proc_gnu_attribute,
15519 end);
60abdbed 15520 assert (p == end);
11c1ff18 15521 }
071436c6 15522 else if (p < end)
11c1ff18 15523 {
071436c6 15524 printf (_(" Unknown attribute:\n"));
f6f0e17b 15525 display_raw_attribute (p, end);
11c1ff18
PB
15526 p = end;
15527 }
071436c6
NC
15528 else
15529 attr_len = 0;
11c1ff18
PB
15530 }
15531 }
15532 }
d70c5fc7 15533
60bca95a 15534 free (contents);
11c1ff18 15535 }
32ec8896
NC
15536
15537 return res;
11c1ff18
PB
15538}
15539
ccb4c951
RS
15540/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
15541 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
15542 and return the VMA of the next entry, or -1 if there was a problem.
15543 Does not read from DATA_END or beyond. */
ccb4c951
RS
15544
15545static bfd_vma
82b1b41b
NC
15546print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
15547 unsigned char * data_end)
ccb4c951
RS
15548{
15549 printf (" ");
15550 print_vma (addr, LONG_HEX);
15551 printf (" ");
15552 if (addr < pltgot + 0xfff0)
15553 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
15554 else
15555 printf ("%10s", "");
15556 printf (" ");
15557 if (data == NULL)
2b692964 15558 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
15559 else
15560 {
15561 bfd_vma entry;
82b1b41b 15562 unsigned char * from = data + addr - pltgot;
ccb4c951 15563
82b1b41b
NC
15564 if (from + (is_32bit_elf ? 4 : 8) > data_end)
15565 {
15566 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
15567 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
15568 return (bfd_vma) -1;
15569 }
15570 else
15571 {
15572 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15573 print_vma (entry, LONG_HEX);
15574 }
ccb4c951
RS
15575 }
15576 return addr + (is_32bit_elf ? 4 : 8);
15577}
15578
861fb55a
DJ
15579/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
15580 PLTGOT. Print the Address and Initial fields of an entry at VMA
15581 ADDR and return the VMA of the next entry. */
15582
15583static bfd_vma
2cf0635d 15584print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
15585{
15586 printf (" ");
15587 print_vma (addr, LONG_HEX);
15588 printf (" ");
15589 if (data == NULL)
2b692964 15590 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
15591 else
15592 {
15593 bfd_vma entry;
15594
15595 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15596 print_vma (entry, LONG_HEX);
15597 }
15598 return addr + (is_32bit_elf ? 4 : 8);
15599}
15600
351cdf24
MF
15601static void
15602print_mips_ases (unsigned int mask)
15603{
15604 if (mask & AFL_ASE_DSP)
15605 fputs ("\n\tDSP ASE", stdout);
15606 if (mask & AFL_ASE_DSPR2)
15607 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
15608 if (mask & AFL_ASE_DSPR3)
15609 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
15610 if (mask & AFL_ASE_EVA)
15611 fputs ("\n\tEnhanced VA Scheme", stdout);
15612 if (mask & AFL_ASE_MCU)
15613 fputs ("\n\tMCU (MicroController) ASE", stdout);
15614 if (mask & AFL_ASE_MDMX)
15615 fputs ("\n\tMDMX ASE", stdout);
15616 if (mask & AFL_ASE_MIPS3D)
15617 fputs ("\n\tMIPS-3D ASE", stdout);
15618 if (mask & AFL_ASE_MT)
15619 fputs ("\n\tMT ASE", stdout);
15620 if (mask & AFL_ASE_SMARTMIPS)
15621 fputs ("\n\tSmartMIPS ASE", stdout);
15622 if (mask & AFL_ASE_VIRT)
15623 fputs ("\n\tVZ ASE", stdout);
15624 if (mask & AFL_ASE_MSA)
15625 fputs ("\n\tMSA ASE", stdout);
15626 if (mask & AFL_ASE_MIPS16)
15627 fputs ("\n\tMIPS16 ASE", stdout);
15628 if (mask & AFL_ASE_MICROMIPS)
15629 fputs ("\n\tMICROMIPS ASE", stdout);
15630 if (mask & AFL_ASE_XPA)
15631 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
15632 if (mask & AFL_ASE_MIPS16E2)
15633 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
15634 if (mask & AFL_ASE_CRC)
15635 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
15636 if (mask & AFL_ASE_GINV)
15637 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
15638 if (mask & AFL_ASE_LOONGSON_MMI)
15639 fputs ("\n\tLoongson MMI ASE", stdout);
351cdf24
MF
15640 if (mask == 0)
15641 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
15642 else if ((mask & ~AFL_ASE_MASK) != 0)
15643 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
15644}
15645
15646static void
15647print_mips_isa_ext (unsigned int isa_ext)
15648{
15649 switch (isa_ext)
15650 {
15651 case 0:
15652 fputs (_("None"), stdout);
15653 break;
15654 case AFL_EXT_XLR:
15655 fputs ("RMI XLR", stdout);
15656 break;
2c629856
N
15657 case AFL_EXT_OCTEON3:
15658 fputs ("Cavium Networks Octeon3", stdout);
15659 break;
351cdf24
MF
15660 case AFL_EXT_OCTEON2:
15661 fputs ("Cavium Networks Octeon2", stdout);
15662 break;
15663 case AFL_EXT_OCTEONP:
15664 fputs ("Cavium Networks OcteonP", stdout);
15665 break;
15666 case AFL_EXT_LOONGSON_3A:
15667 fputs ("Loongson 3A", stdout);
15668 break;
15669 case AFL_EXT_OCTEON:
15670 fputs ("Cavium Networks Octeon", stdout);
15671 break;
15672 case AFL_EXT_5900:
15673 fputs ("Toshiba R5900", stdout);
15674 break;
15675 case AFL_EXT_4650:
15676 fputs ("MIPS R4650", stdout);
15677 break;
15678 case AFL_EXT_4010:
15679 fputs ("LSI R4010", stdout);
15680 break;
15681 case AFL_EXT_4100:
15682 fputs ("NEC VR4100", stdout);
15683 break;
15684 case AFL_EXT_3900:
15685 fputs ("Toshiba R3900", stdout);
15686 break;
15687 case AFL_EXT_10000:
15688 fputs ("MIPS R10000", stdout);
15689 break;
15690 case AFL_EXT_SB1:
15691 fputs ("Broadcom SB-1", stdout);
15692 break;
15693 case AFL_EXT_4111:
15694 fputs ("NEC VR4111/VR4181", stdout);
15695 break;
15696 case AFL_EXT_4120:
15697 fputs ("NEC VR4120", stdout);
15698 break;
15699 case AFL_EXT_5400:
15700 fputs ("NEC VR5400", stdout);
15701 break;
15702 case AFL_EXT_5500:
15703 fputs ("NEC VR5500", stdout);
15704 break;
15705 case AFL_EXT_LOONGSON_2E:
15706 fputs ("ST Microelectronics Loongson 2E", stdout);
15707 break;
15708 case AFL_EXT_LOONGSON_2F:
15709 fputs ("ST Microelectronics Loongson 2F", stdout);
15710 break;
38bf472a
MR
15711 case AFL_EXT_INTERAPTIV_MR2:
15712 fputs ("Imagination interAptiv MR2", stdout);
15713 break;
351cdf24 15714 default:
00ac7aa0 15715 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
15716 }
15717}
15718
32ec8896 15719static signed int
351cdf24
MF
15720get_mips_reg_size (int reg_size)
15721{
15722 return (reg_size == AFL_REG_NONE) ? 0
15723 : (reg_size == AFL_REG_32) ? 32
15724 : (reg_size == AFL_REG_64) ? 64
15725 : (reg_size == AFL_REG_128) ? 128
15726 : -1;
15727}
15728
32ec8896 15729static bfd_boolean
dda8d76d 15730process_mips_specific (Filedata * filedata)
5b18a4bc 15731{
2cf0635d 15732 Elf_Internal_Dyn * entry;
351cdf24 15733 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
15734 size_t liblist_offset = 0;
15735 size_t liblistno = 0;
15736 size_t conflictsno = 0;
15737 size_t options_offset = 0;
15738 size_t conflicts_offset = 0;
861fb55a
DJ
15739 size_t pltrelsz = 0;
15740 size_t pltrel = 0;
ccb4c951 15741 bfd_vma pltgot = 0;
861fb55a
DJ
15742 bfd_vma mips_pltgot = 0;
15743 bfd_vma jmprel = 0;
ccb4c951
RS
15744 bfd_vma local_gotno = 0;
15745 bfd_vma gotsym = 0;
15746 bfd_vma symtabno = 0;
32ec8896 15747 bfd_boolean res = TRUE;
103f02d3 15748
dda8d76d 15749 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
15750 display_mips_gnu_attribute))
15751 res = FALSE;
2cf19d5c 15752
dda8d76d 15753 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
15754
15755 if (sect != NULL)
15756 {
15757 Elf_External_ABIFlags_v0 *abiflags_ext;
15758 Elf_Internal_ABIFlags_v0 abiflags_in;
15759
15760 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
15761 {
15762 error (_("Corrupt MIPS ABI Flags section.\n"));
15763 res = FALSE;
15764 }
351cdf24
MF
15765 else
15766 {
dda8d76d 15767 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
15768 sect->sh_size, _("MIPS ABI Flags section"));
15769 if (abiflags_ext)
15770 {
15771 abiflags_in.version = BYTE_GET (abiflags_ext->version);
15772 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
15773 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
15774 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
15775 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
15776 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
15777 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
15778 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
15779 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
15780 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
15781 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
15782
15783 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
15784 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
15785 if (abiflags_in.isa_rev > 1)
15786 printf ("r%d", abiflags_in.isa_rev);
15787 printf ("\nGPR size: %d",
15788 get_mips_reg_size (abiflags_in.gpr_size));
15789 printf ("\nCPR1 size: %d",
15790 get_mips_reg_size (abiflags_in.cpr1_size));
15791 printf ("\nCPR2 size: %d",
15792 get_mips_reg_size (abiflags_in.cpr2_size));
15793 fputs ("\nFP ABI: ", stdout);
15794 print_mips_fp_abi_value (abiflags_in.fp_abi);
15795 fputs ("ISA Extension: ", stdout);
15796 print_mips_isa_ext (abiflags_in.isa_ext);
15797 fputs ("\nASEs:", stdout);
15798 print_mips_ases (abiflags_in.ases);
15799 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
15800 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
15801 fputc ('\n', stdout);
15802 free (abiflags_ext);
15803 }
15804 }
15805 }
15806
19e6b90e
L
15807 /* We have a lot of special sections. Thanks SGI! */
15808 if (dynamic_section == NULL)
bbdd9a68
MR
15809 {
15810 /* No dynamic information available. See if there is static GOT. */
dda8d76d 15811 sect = find_section (filedata, ".got");
bbdd9a68
MR
15812 if (sect != NULL)
15813 {
15814 unsigned char *data_end;
15815 unsigned char *data;
15816 bfd_vma ent, end;
15817 int addr_size;
15818
15819 pltgot = sect->sh_addr;
15820
15821 ent = pltgot;
15822 addr_size = (is_32bit_elf ? 4 : 8);
15823 end = pltgot + sect->sh_size;
15824
dda8d76d 15825 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
15826 end - pltgot, 1,
15827 _("Global Offset Table data"));
15828 /* PR 12855: Null data is handled gracefully throughout. */
15829 data_end = data + (end - pltgot);
15830
15831 printf (_("\nStatic GOT:\n"));
15832 printf (_(" Canonical gp value: "));
15833 print_vma (ent + 0x7ff0, LONG_HEX);
15834 printf ("\n\n");
15835
15836 /* In a dynamic binary GOT[0] is reserved for the dynamic
15837 loader to store the lazy resolver pointer, however in
15838 a static binary it may well have been omitted and GOT
15839 reduced to a table of addresses.
15840 PR 21344: Check for the entry being fully available
15841 before fetching it. */
15842 if (data
15843 && data + ent - pltgot + addr_size <= data_end
15844 && byte_get (data + ent - pltgot, addr_size) == 0)
15845 {
15846 printf (_(" Reserved entries:\n"));
15847 printf (_(" %*s %10s %*s\n"),
15848 addr_size * 2, _("Address"), _("Access"),
15849 addr_size * 2, _("Value"));
15850 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15851 printf ("\n");
15852 if (ent == (bfd_vma) -1)
15853 goto sgot_print_fail;
15854
15855 /* Check for the MSB of GOT[1] being set, identifying a
15856 GNU object. This entry will be used by some runtime
15857 loaders, to store the module pointer. Otherwise this
15858 is an ordinary local entry.
15859 PR 21344: Check for the entry being fully available
15860 before fetching it. */
15861 if (data
15862 && data + ent - pltgot + addr_size <= data_end
15863 && (byte_get (data + ent - pltgot, addr_size)
15864 >> (addr_size * 8 - 1)) != 0)
15865 {
15866 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15867 printf ("\n");
15868 if (ent == (bfd_vma) -1)
15869 goto sgot_print_fail;
15870 }
15871 printf ("\n");
15872 }
15873
f17e9d8a 15874 if (data != NULL && ent < end)
bbdd9a68
MR
15875 {
15876 printf (_(" Local entries:\n"));
15877 printf (" %*s %10s %*s\n",
15878 addr_size * 2, _("Address"), _("Access"),
15879 addr_size * 2, _("Value"));
15880 while (ent < end)
15881 {
15882 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15883 printf ("\n");
15884 if (ent == (bfd_vma) -1)
15885 goto sgot_print_fail;
15886 }
15887 printf ("\n");
15888 }
15889
15890 sgot_print_fail:
15891 if (data)
15892 free (data);
15893 }
15894 return res;
15895 }
252b5132 15896
071436c6
NC
15897 for (entry = dynamic_section;
15898 /* PR 17531 file: 012-50589-0.004. */
15899 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
15900 ++entry)
252b5132
RH
15901 switch (entry->d_tag)
15902 {
15903 case DT_MIPS_LIBLIST:
d93f0186 15904 liblist_offset
dda8d76d 15905 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 15906 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
15907 break;
15908 case DT_MIPS_LIBLISTNO:
15909 liblistno = entry->d_un.d_val;
15910 break;
15911 case DT_MIPS_OPTIONS:
dda8d76d 15912 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
15913 break;
15914 case DT_MIPS_CONFLICT:
d93f0186 15915 conflicts_offset
dda8d76d 15916 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 15917 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
15918 break;
15919 case DT_MIPS_CONFLICTNO:
15920 conflictsno = entry->d_un.d_val;
15921 break;
ccb4c951 15922 case DT_PLTGOT:
861fb55a
DJ
15923 pltgot = entry->d_un.d_ptr;
15924 break;
ccb4c951
RS
15925 case DT_MIPS_LOCAL_GOTNO:
15926 local_gotno = entry->d_un.d_val;
15927 break;
15928 case DT_MIPS_GOTSYM:
15929 gotsym = entry->d_un.d_val;
15930 break;
15931 case DT_MIPS_SYMTABNO:
15932 symtabno = entry->d_un.d_val;
15933 break;
861fb55a
DJ
15934 case DT_MIPS_PLTGOT:
15935 mips_pltgot = entry->d_un.d_ptr;
15936 break;
15937 case DT_PLTREL:
15938 pltrel = entry->d_un.d_val;
15939 break;
15940 case DT_PLTRELSZ:
15941 pltrelsz = entry->d_un.d_val;
15942 break;
15943 case DT_JMPREL:
15944 jmprel = entry->d_un.d_ptr;
15945 break;
252b5132
RH
15946 default:
15947 break;
15948 }
15949
15950 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
15951 {
2cf0635d 15952 Elf32_External_Lib * elib;
252b5132
RH
15953 size_t cnt;
15954
dda8d76d 15955 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
3f5e193b
NC
15956 liblistno,
15957 sizeof (Elf32_External_Lib),
9cf03b7e 15958 _("liblist section data"));
a6e9f9df 15959 if (elib)
252b5132 15960 {
d3a49aa8
AM
15961 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
15962 "\nSection '.liblist' contains %lu entries:\n",
15963 (unsigned long) liblistno),
a6e9f9df 15964 (unsigned long) liblistno);
2b692964 15965 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
15966 stdout);
15967
15968 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 15969 {
a6e9f9df 15970 Elf32_Lib liblist;
91d6fa6a 15971 time_t atime;
d5b07ef4 15972 char timebuf[128];
2cf0635d 15973 struct tm * tmp;
a6e9f9df
AM
15974
15975 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 15976 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
15977 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
15978 liblist.l_version = BYTE_GET (elib[cnt].l_version);
15979 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
15980
91d6fa6a 15981 tmp = gmtime (&atime);
e9e44622
JJ
15982 snprintf (timebuf, sizeof (timebuf),
15983 "%04u-%02u-%02uT%02u:%02u:%02u",
15984 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
15985 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 15986
31104126 15987 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
15988 if (VALID_DYNAMIC_NAME (liblist.l_name))
15989 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
15990 else
2b692964 15991 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
15992 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
15993 liblist.l_version);
a6e9f9df
AM
15994
15995 if (liblist.l_flags == 0)
2b692964 15996 puts (_(" NONE"));
a6e9f9df
AM
15997 else
15998 {
15999 static const struct
252b5132 16000 {
2cf0635d 16001 const char * name;
a6e9f9df 16002 int bit;
252b5132 16003 }
a6e9f9df
AM
16004 l_flags_vals[] =
16005 {
16006 { " EXACT_MATCH", LL_EXACT_MATCH },
16007 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
16008 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
16009 { " EXPORTS", LL_EXPORTS },
16010 { " DELAY_LOAD", LL_DELAY_LOAD },
16011 { " DELTA", LL_DELTA }
16012 };
16013 int flags = liblist.l_flags;
16014 size_t fcnt;
16015
60bca95a 16016 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
16017 if ((flags & l_flags_vals[fcnt].bit) != 0)
16018 {
16019 fputs (l_flags_vals[fcnt].name, stdout);
16020 flags ^= l_flags_vals[fcnt].bit;
16021 }
16022 if (flags != 0)
16023 printf (" %#x", (unsigned int) flags);
252b5132 16024
a6e9f9df
AM
16025 puts ("");
16026 }
252b5132 16027 }
252b5132 16028
a6e9f9df
AM
16029 free (elib);
16030 }
32ec8896
NC
16031 else
16032 res = FALSE;
252b5132
RH
16033 }
16034
16035 if (options_offset != 0)
16036 {
2cf0635d 16037 Elf_External_Options * eopt;
2cf0635d
NC
16038 Elf_Internal_Options * iopt;
16039 Elf_Internal_Options * option;
252b5132
RH
16040 size_t offset;
16041 int cnt;
dda8d76d 16042 sect = filedata->section_headers;
252b5132
RH
16043
16044 /* Find the section header so that we get the size. */
dda8d76d 16045 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 16046 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
16047 if (sect == NULL)
16048 {
16049 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 16050 return FALSE;
071436c6 16051 }
252b5132 16052
dda8d76d 16053 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 16054 sect->sh_size, _("options"));
a6e9f9df 16055 if (eopt)
252b5132 16056 {
3f5e193b
NC
16057 iopt = (Elf_Internal_Options *)
16058 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
16059 if (iopt == NULL)
16060 {
fb324ee9 16061 error (_("Out of memory allocating space for MIPS options\n"));
32ec8896 16062 return FALSE;
a6e9f9df 16063 }
76da6bbe 16064
a6e9f9df
AM
16065 offset = cnt = 0;
16066 option = iopt;
252b5132 16067
82b1b41b 16068 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 16069 {
2cf0635d 16070 Elf_External_Options * eoption;
252b5132 16071
a6e9f9df 16072 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 16073
a6e9f9df
AM
16074 option->kind = BYTE_GET (eoption->kind);
16075 option->size = BYTE_GET (eoption->size);
16076 option->section = BYTE_GET (eoption->section);
16077 option->info = BYTE_GET (eoption->info);
76da6bbe 16078
82b1b41b
NC
16079 /* PR 17531: file: ffa0fa3b. */
16080 if (option->size < sizeof (* eopt)
16081 || offset + option->size > sect->sh_size)
16082 {
55325047 16083 error (_("Invalid size (%u) for MIPS option\n"), option->size);
32ec8896 16084 return FALSE;
82b1b41b 16085 }
a6e9f9df 16086 offset += option->size;
14ae95f2 16087
a6e9f9df
AM
16088 ++option;
16089 ++cnt;
16090 }
252b5132 16091
d3a49aa8
AM
16092 printf (ngettext ("\nSection '%s' contains %d entry:\n",
16093 "\nSection '%s' contains %d entries:\n",
16094 cnt),
dda8d76d 16095 printable_section_name (filedata, sect), cnt);
76da6bbe 16096
a6e9f9df 16097 option = iopt;
82b1b41b 16098 offset = 0;
252b5132 16099
a6e9f9df 16100 while (cnt-- > 0)
252b5132 16101 {
a6e9f9df
AM
16102 size_t len;
16103
16104 switch (option->kind)
252b5132 16105 {
a6e9f9df
AM
16106 case ODK_NULL:
16107 /* This shouldn't happen. */
16108 printf (" NULL %d %lx", option->section, option->info);
16109 break;
16110 case ODK_REGINFO:
16111 printf (" REGINFO ");
dda8d76d 16112 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df
AM
16113 {
16114 /* 32bit form. */
2cf0635d 16115 Elf32_External_RegInfo * ereg;
b34976b6 16116 Elf32_RegInfo reginfo;
a6e9f9df
AM
16117
16118 ereg = (Elf32_External_RegInfo *) (option + 1);
16119 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
16120 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
16121 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16122 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16123 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
16124 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
16125
16126 printf ("GPR %08lx GP 0x%lx\n",
16127 reginfo.ri_gprmask,
16128 (unsigned long) reginfo.ri_gp_value);
16129 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
16130 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
16131 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
16132 }
16133 else
16134 {
16135 /* 64 bit form. */
2cf0635d 16136 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
16137 Elf64_Internal_RegInfo reginfo;
16138
16139 ereg = (Elf64_External_RegInfo *) (option + 1);
16140 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
16141 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
16142 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16143 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16144 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 16145 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
16146
16147 printf ("GPR %08lx GP 0x",
16148 reginfo.ri_gprmask);
16149 printf_vma (reginfo.ri_gp_value);
16150 printf ("\n");
16151
16152 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
16153 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
16154 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
16155 }
16156 ++option;
16157 continue;
16158 case ODK_EXCEPTIONS:
16159 fputs (" EXCEPTIONS fpe_min(", stdout);
16160 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
16161 fputs (") fpe_max(", stdout);
16162 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
16163 fputs (")", stdout);
16164
16165 if (option->info & OEX_PAGE0)
16166 fputs (" PAGE0", stdout);
16167 if (option->info & OEX_SMM)
16168 fputs (" SMM", stdout);
16169 if (option->info & OEX_FPDBUG)
16170 fputs (" FPDBUG", stdout);
16171 if (option->info & OEX_DISMISS)
16172 fputs (" DISMISS", stdout);
16173 break;
16174 case ODK_PAD:
16175 fputs (" PAD ", stdout);
16176 if (option->info & OPAD_PREFIX)
16177 fputs (" PREFIX", stdout);
16178 if (option->info & OPAD_POSTFIX)
16179 fputs (" POSTFIX", stdout);
16180 if (option->info & OPAD_SYMBOL)
16181 fputs (" SYMBOL", stdout);
16182 break;
16183 case ODK_HWPATCH:
16184 fputs (" HWPATCH ", stdout);
16185 if (option->info & OHW_R4KEOP)
16186 fputs (" R4KEOP", stdout);
16187 if (option->info & OHW_R8KPFETCH)
16188 fputs (" R8KPFETCH", stdout);
16189 if (option->info & OHW_R5KEOP)
16190 fputs (" R5KEOP", stdout);
16191 if (option->info & OHW_R5KCVTL)
16192 fputs (" R5KCVTL", stdout);
16193 break;
16194 case ODK_FILL:
16195 fputs (" FILL ", stdout);
16196 /* XXX Print content of info word? */
16197 break;
16198 case ODK_TAGS:
16199 fputs (" TAGS ", stdout);
16200 /* XXX Print content of info word? */
16201 break;
16202 case ODK_HWAND:
16203 fputs (" HWAND ", stdout);
16204 if (option->info & OHWA0_R4KEOP_CHECKED)
16205 fputs (" R4KEOP_CHECKED", stdout);
16206 if (option->info & OHWA0_R4KEOP_CLEAN)
16207 fputs (" R4KEOP_CLEAN", stdout);
16208 break;
16209 case ODK_HWOR:
16210 fputs (" HWOR ", stdout);
16211 if (option->info & OHWA0_R4KEOP_CHECKED)
16212 fputs (" R4KEOP_CHECKED", stdout);
16213 if (option->info & OHWA0_R4KEOP_CLEAN)
16214 fputs (" R4KEOP_CLEAN", stdout);
16215 break;
16216 case ODK_GP_GROUP:
16217 printf (" GP_GROUP %#06lx self-contained %#06lx",
16218 option->info & OGP_GROUP,
16219 (option->info & OGP_SELF) >> 16);
16220 break;
16221 case ODK_IDENT:
16222 printf (" IDENT %#06lx self-contained %#06lx",
16223 option->info & OGP_GROUP,
16224 (option->info & OGP_SELF) >> 16);
16225 break;
16226 default:
16227 /* This shouldn't happen. */
16228 printf (" %3d ??? %d %lx",
16229 option->kind, option->section, option->info);
16230 break;
252b5132 16231 }
a6e9f9df 16232
2cf0635d 16233 len = sizeof (* eopt);
a6e9f9df 16234 while (len < option->size)
82b1b41b 16235 {
7e27a9d5 16236 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 16237
82b1b41b
NC
16238 if (ISPRINT (datum))
16239 printf ("%c", datum);
16240 else
16241 printf ("\\%03o", datum);
16242 len ++;
16243 }
a6e9f9df 16244 fputs ("\n", stdout);
82b1b41b
NC
16245
16246 offset += option->size;
252b5132 16247 ++option;
252b5132
RH
16248 }
16249
a6e9f9df 16250 free (eopt);
252b5132 16251 }
32ec8896
NC
16252 else
16253 res = FALSE;
252b5132
RH
16254 }
16255
16256 if (conflicts_offset != 0 && conflictsno != 0)
16257 {
2cf0635d 16258 Elf32_Conflict * iconf;
252b5132
RH
16259 size_t cnt;
16260
16261 if (dynamic_symbols == NULL)
16262 {
591a748a 16263 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 16264 return FALSE;
252b5132
RH
16265 }
16266
7296a62a
NC
16267 /* PR 21345 - print a slightly more helpful error message
16268 if we are sure that the cmalloc will fail. */
dda8d76d 16269 if (conflictsno * sizeof (* iconf) > filedata->file_size)
7296a62a
NC
16270 {
16271 error (_("Overlarge number of conflicts detected: %lx\n"),
16272 (long) conflictsno);
16273 return FALSE;
16274 }
16275
3f5e193b 16276 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
16277 if (iconf == NULL)
16278 {
8b73c356 16279 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 16280 return FALSE;
252b5132
RH
16281 }
16282
9ea033b2 16283 if (is_32bit_elf)
252b5132 16284 {
2cf0635d 16285 Elf32_External_Conflict * econf32;
a6e9f9df 16286
3f5e193b 16287 econf32 = (Elf32_External_Conflict *)
dda8d76d 16288 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16289 sizeof (* econf32), _("conflict"));
a6e9f9df 16290 if (!econf32)
32ec8896 16291 return FALSE;
252b5132
RH
16292
16293 for (cnt = 0; cnt < conflictsno; ++cnt)
16294 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
16295
16296 free (econf32);
252b5132
RH
16297 }
16298 else
16299 {
2cf0635d 16300 Elf64_External_Conflict * econf64;
a6e9f9df 16301
3f5e193b 16302 econf64 = (Elf64_External_Conflict *)
dda8d76d 16303 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16304 sizeof (* econf64), _("conflict"));
a6e9f9df 16305 if (!econf64)
32ec8896 16306 return FALSE;
252b5132
RH
16307
16308 for (cnt = 0; cnt < conflictsno; ++cnt)
16309 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
16310
16311 free (econf64);
252b5132
RH
16312 }
16313
d3a49aa8
AM
16314 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
16315 "\nSection '.conflict' contains %lu entries:\n",
16316 (unsigned long) conflictsno),
c7e7ca54 16317 (unsigned long) conflictsno);
252b5132
RH
16318 puts (_(" Num: Index Value Name"));
16319
16320 for (cnt = 0; cnt < conflictsno; ++cnt)
16321 {
b34976b6 16322 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
16323
16324 if (iconf[cnt] >= num_dynamic_syms)
16325 printf (_("<corrupt symbol index>"));
d79b3d50 16326 else
e0a31db1
NC
16327 {
16328 Elf_Internal_Sym * psym;
16329
16330 psym = & dynamic_symbols[iconf[cnt]];
16331 print_vma (psym->st_value, FULL_HEX);
16332 putchar (' ');
16333 if (VALID_DYNAMIC_NAME (psym->st_name))
16334 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
16335 else
16336 printf (_("<corrupt: %14ld>"), psym->st_name);
16337 }
31104126 16338 putchar ('\n');
252b5132
RH
16339 }
16340
252b5132
RH
16341 free (iconf);
16342 }
16343
ccb4c951
RS
16344 if (pltgot != 0 && local_gotno != 0)
16345 {
91d6fa6a 16346 bfd_vma ent, local_end, global_end;
bbeee7ea 16347 size_t i, offset;
2cf0635d 16348 unsigned char * data;
82b1b41b 16349 unsigned char * data_end;
bbeee7ea 16350 int addr_size;
ccb4c951 16351
91d6fa6a 16352 ent = pltgot;
ccb4c951
RS
16353 addr_size = (is_32bit_elf ? 4 : 8);
16354 local_end = pltgot + local_gotno * addr_size;
ccb4c951 16355
74e1a04b
NC
16356 /* PR binutils/17533 file: 012-111227-0.004 */
16357 if (symtabno < gotsym)
16358 {
16359 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 16360 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 16361 return FALSE;
74e1a04b 16362 }
82b1b41b 16363
74e1a04b 16364 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
16365 /* PR 17531: file: 54c91a34. */
16366 if (global_end < local_end)
16367 {
16368 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 16369 return FALSE;
82b1b41b 16370 }
948f632f 16371
dda8d76d
NC
16372 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
16373 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
16374 global_end - pltgot, 1,
16375 _("Global Offset Table data"));
919383ac 16376 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 16377 data_end = data + (global_end - pltgot);
59245841 16378
ccb4c951
RS
16379 printf (_("\nPrimary GOT:\n"));
16380 printf (_(" Canonical gp value: "));
16381 print_vma (pltgot + 0x7ff0, LONG_HEX);
16382 printf ("\n\n");
16383
16384 printf (_(" Reserved entries:\n"));
16385 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
16386 addr_size * 2, _("Address"), _("Access"),
16387 addr_size * 2, _("Initial"));
82b1b41b 16388 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 16389 printf (_(" Lazy resolver\n"));
82b1b41b
NC
16390 if (ent == (bfd_vma) -1)
16391 goto got_print_fail;
75ec1fdb 16392
c4ab9505
MR
16393 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
16394 This entry will be used by some runtime loaders, to store the
16395 module pointer. Otherwise this is an ordinary local entry.
16396 PR 21344: Check for the entry being fully available before
16397 fetching it. */
16398 if (data
16399 && data + ent - pltgot + addr_size <= data_end
16400 && (byte_get (data + ent - pltgot, addr_size)
16401 >> (addr_size * 8 - 1)) != 0)
16402 {
16403 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16404 printf (_(" Module pointer (GNU extension)\n"));
16405 if (ent == (bfd_vma) -1)
16406 goto got_print_fail;
ccb4c951
RS
16407 }
16408 printf ("\n");
16409
f17e9d8a 16410 if (data != NULL && ent < local_end)
ccb4c951
RS
16411 {
16412 printf (_(" Local entries:\n"));
cc5914eb 16413 printf (" %*s %10s %*s\n",
2b692964
NC
16414 addr_size * 2, _("Address"), _("Access"),
16415 addr_size * 2, _("Initial"));
91d6fa6a 16416 while (ent < local_end)
ccb4c951 16417 {
82b1b41b 16418 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16419 printf ("\n");
82b1b41b
NC
16420 if (ent == (bfd_vma) -1)
16421 goto got_print_fail;
ccb4c951
RS
16422 }
16423 printf ("\n");
16424 }
16425
f17e9d8a 16426 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
16427 {
16428 int sym_width;
16429
16430 printf (_(" Global entries:\n"));
cc5914eb 16431 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
16432 addr_size * 2, _("Address"),
16433 _("Access"),
2b692964 16434 addr_size * 2, _("Initial"),
9cf03b7e
NC
16435 addr_size * 2, _("Sym.Val."),
16436 _("Type"),
16437 /* Note for translators: "Ndx" = abbreviated form of "Index". */
16438 _("Ndx"), _("Name"));
0b4362b0 16439
ccb4c951 16440 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 16441
ccb4c951
RS
16442 for (i = gotsym; i < symtabno; i++)
16443 {
82b1b41b 16444 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16445 printf (" ");
e0a31db1
NC
16446
16447 if (dynamic_symbols == NULL)
16448 printf (_("<no dynamic symbols>"));
16449 else if (i < num_dynamic_syms)
16450 {
16451 Elf_Internal_Sym * psym = dynamic_symbols + i;
16452
16453 print_vma (psym->st_value, LONG_HEX);
16454 printf (" %-7s %3s ",
dda8d76d
NC
16455 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16456 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16457
16458 if (VALID_DYNAMIC_NAME (psym->st_name))
16459 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16460 else
16461 printf (_("<corrupt: %14ld>"), psym->st_name);
16462 }
ccb4c951 16463 else
7fc5ac57
JBG
16464 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
16465 (unsigned long) i);
e0a31db1 16466
ccb4c951 16467 printf ("\n");
82b1b41b
NC
16468 if (ent == (bfd_vma) -1)
16469 break;
ccb4c951
RS
16470 }
16471 printf ("\n");
16472 }
16473
82b1b41b 16474 got_print_fail:
ccb4c951
RS
16475 if (data)
16476 free (data);
16477 }
16478
861fb55a
DJ
16479 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
16480 {
91d6fa6a 16481 bfd_vma ent, end;
861fb55a
DJ
16482 size_t offset, rel_offset;
16483 unsigned long count, i;
2cf0635d 16484 unsigned char * data;
861fb55a 16485 int addr_size, sym_width;
2cf0635d 16486 Elf_Internal_Rela * rels;
861fb55a 16487
dda8d76d 16488 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
16489 if (pltrel == DT_RELA)
16490 {
dda8d76d 16491 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16492 return FALSE;
861fb55a
DJ
16493 }
16494 else
16495 {
dda8d76d 16496 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16497 return FALSE;
861fb55a
DJ
16498 }
16499
91d6fa6a 16500 ent = mips_pltgot;
861fb55a
DJ
16501 addr_size = (is_32bit_elf ? 4 : 8);
16502 end = mips_pltgot + (2 + count) * addr_size;
16503
dda8d76d
NC
16504 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
16505 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 16506 1, _("Procedure Linkage Table data"));
59245841 16507 if (data == NULL)
32ec8896 16508 return FALSE;
59245841 16509
9cf03b7e 16510 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
16511 printf (_(" Reserved entries:\n"));
16512 printf (_(" %*s %*s Purpose\n"),
2b692964 16513 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 16514 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16515 printf (_(" PLT lazy resolver\n"));
91d6fa6a 16516 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16517 printf (_(" Module pointer\n"));
861fb55a
DJ
16518 printf ("\n");
16519
16520 printf (_(" Entries:\n"));
cc5914eb 16521 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
16522 addr_size * 2, _("Address"),
16523 addr_size * 2, _("Initial"),
16524 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
16525 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
16526 for (i = 0; i < count; i++)
16527 {
df97ab2a 16528 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 16529
91d6fa6a 16530 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 16531 printf (" ");
e0a31db1 16532
df97ab2a
MF
16533 if (idx >= num_dynamic_syms)
16534 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 16535 else
e0a31db1 16536 {
df97ab2a 16537 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
16538
16539 print_vma (psym->st_value, LONG_HEX);
16540 printf (" %-7s %3s ",
dda8d76d
NC
16541 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16542 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16543 if (VALID_DYNAMIC_NAME (psym->st_name))
16544 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16545 else
16546 printf (_("<corrupt: %14ld>"), psym->st_name);
16547 }
861fb55a
DJ
16548 printf ("\n");
16549 }
16550 printf ("\n");
16551
16552 if (data)
16553 free (data);
16554 free (rels);
16555 }
16556
32ec8896 16557 return res;
252b5132
RH
16558}
16559
32ec8896 16560static bfd_boolean
dda8d76d 16561process_nds32_specific (Filedata * filedata)
35c08157
KLC
16562{
16563 Elf_Internal_Shdr *sect = NULL;
16564
dda8d76d 16565 sect = find_section (filedata, ".nds32_e_flags");
35c08157
KLC
16566 if (sect != NULL)
16567 {
16568 unsigned int *flag;
16569
16570 printf ("\nNDS32 elf flags section:\n");
dda8d76d 16571 flag = get_data (NULL, filedata, sect->sh_offset, 1,
35c08157
KLC
16572 sect->sh_size, _("NDS32 elf flags section"));
16573
32ec8896
NC
16574 if (! flag)
16575 return FALSE;
16576
35c08157
KLC
16577 switch ((*flag) & 0x3)
16578 {
16579 case 0:
16580 printf ("(VEC_SIZE):\tNo entry.\n");
16581 break;
16582 case 1:
16583 printf ("(VEC_SIZE):\t4 bytes\n");
16584 break;
16585 case 2:
16586 printf ("(VEC_SIZE):\t16 bytes\n");
16587 break;
16588 case 3:
16589 printf ("(VEC_SIZE):\treserved\n");
16590 break;
16591 }
16592 }
16593
16594 return TRUE;
16595}
16596
32ec8896 16597static bfd_boolean
dda8d76d 16598process_gnu_liblist (Filedata * filedata)
047b2264 16599{
2cf0635d
NC
16600 Elf_Internal_Shdr * section;
16601 Elf_Internal_Shdr * string_sec;
16602 Elf32_External_Lib * elib;
16603 char * strtab;
c256ffe7 16604 size_t strtab_size;
047b2264 16605 size_t cnt;
d3a49aa8 16606 unsigned long num_liblist;
047b2264 16607 unsigned i;
32ec8896 16608 bfd_boolean res = TRUE;
047b2264
JJ
16609
16610 if (! do_arch)
32ec8896 16611 return TRUE;
047b2264 16612
dda8d76d
NC
16613 for (i = 0, section = filedata->section_headers;
16614 i < filedata->file_header.e_shnum;
b34976b6 16615 i++, section++)
047b2264
JJ
16616 {
16617 switch (section->sh_type)
16618 {
16619 case SHT_GNU_LIBLIST:
dda8d76d 16620 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
16621 break;
16622
3f5e193b 16623 elib = (Elf32_External_Lib *)
dda8d76d 16624 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 16625 _("liblist section data"));
047b2264
JJ
16626
16627 if (elib == NULL)
32ec8896
NC
16628 {
16629 res = FALSE;
16630 break;
16631 }
047b2264 16632
dda8d76d
NC
16633 string_sec = filedata->section_headers + section->sh_link;
16634 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
16635 string_sec->sh_size,
16636 _("liblist string table"));
047b2264
JJ
16637 if (strtab == NULL
16638 || section->sh_entsize != sizeof (Elf32_External_Lib))
16639 {
16640 free (elib);
2842702f 16641 free (strtab);
32ec8896 16642 res = FALSE;
047b2264
JJ
16643 break;
16644 }
59245841 16645 strtab_size = string_sec->sh_size;
047b2264 16646
d3a49aa8
AM
16647 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
16648 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
16649 "\nLibrary list section '%s' contains %lu entries:\n",
16650 num_liblist),
dda8d76d 16651 printable_section_name (filedata, section),
d3a49aa8 16652 num_liblist);
047b2264 16653
2b692964 16654 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
16655
16656 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
16657 ++cnt)
16658 {
16659 Elf32_Lib liblist;
91d6fa6a 16660 time_t atime;
d5b07ef4 16661 char timebuf[128];
2cf0635d 16662 struct tm * tmp;
047b2264
JJ
16663
16664 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16665 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
16666 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16667 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16668 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16669
91d6fa6a 16670 tmp = gmtime (&atime);
e9e44622
JJ
16671 snprintf (timebuf, sizeof (timebuf),
16672 "%04u-%02u-%02uT%02u:%02u:%02u",
16673 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16674 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
16675
16676 printf ("%3lu: ", (unsigned long) cnt);
16677 if (do_wide)
c256ffe7 16678 printf ("%-20s", liblist.l_name < strtab_size
2b692964 16679 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 16680 else
c256ffe7 16681 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 16682 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
16683 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
16684 liblist.l_version, liblist.l_flags);
16685 }
16686
16687 free (elib);
2842702f 16688 free (strtab);
047b2264
JJ
16689 }
16690 }
16691
32ec8896 16692 return res;
047b2264
JJ
16693}
16694
9437c45b 16695static const char *
dda8d76d 16696get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
16697{
16698 static char buff[64];
103f02d3 16699
dda8d76d 16700 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
16701 switch (e_type)
16702 {
57346661 16703 case NT_AUXV:
1ec5cd37 16704 return _("NT_AUXV (auxiliary vector)");
57346661 16705 case NT_PRSTATUS:
1ec5cd37 16706 return _("NT_PRSTATUS (prstatus structure)");
57346661 16707 case NT_FPREGSET:
1ec5cd37 16708 return _("NT_FPREGSET (floating point registers)");
57346661 16709 case NT_PRPSINFO:
1ec5cd37 16710 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 16711 case NT_TASKSTRUCT:
1ec5cd37 16712 return _("NT_TASKSTRUCT (task structure)");
57346661 16713 case NT_PRXFPREG:
1ec5cd37 16714 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
16715 case NT_PPC_VMX:
16716 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
16717 case NT_PPC_VSX:
16718 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
16719 case NT_PPC_TAR:
16720 return _("NT_PPC_TAR (ppc TAR register)");
16721 case NT_PPC_PPR:
16722 return _("NT_PPC_PPR (ppc PPR register)");
16723 case NT_PPC_DSCR:
16724 return _("NT_PPC_DSCR (ppc DSCR register)");
16725 case NT_PPC_EBB:
16726 return _("NT_PPC_EBB (ppc EBB registers)");
16727 case NT_PPC_PMU:
16728 return _("NT_PPC_PMU (ppc PMU registers)");
16729 case NT_PPC_TM_CGPR:
16730 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
16731 case NT_PPC_TM_CFPR:
16732 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
16733 case NT_PPC_TM_CVMX:
16734 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
16735 case NT_PPC_TM_CVSX:
3fd21718 16736 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
16737 case NT_PPC_TM_SPR:
16738 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
16739 case NT_PPC_TM_CTAR:
16740 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
16741 case NT_PPC_TM_CPPR:
16742 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
16743 case NT_PPC_TM_CDSCR:
16744 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
16745 case NT_386_TLS:
16746 return _("NT_386_TLS (x86 TLS information)");
16747 case NT_386_IOPERM:
16748 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
16749 case NT_X86_XSTATE:
16750 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
16751 case NT_S390_HIGH_GPRS:
16752 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
16753 case NT_S390_TIMER:
16754 return _("NT_S390_TIMER (s390 timer register)");
16755 case NT_S390_TODCMP:
16756 return _("NT_S390_TODCMP (s390 TOD comparator register)");
16757 case NT_S390_TODPREG:
16758 return _("NT_S390_TODPREG (s390 TOD programmable register)");
16759 case NT_S390_CTRS:
16760 return _("NT_S390_CTRS (s390 control registers)");
16761 case NT_S390_PREFIX:
16762 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
16763 case NT_S390_LAST_BREAK:
16764 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
16765 case NT_S390_SYSTEM_CALL:
16766 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
16767 case NT_S390_TDB:
16768 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
16769 case NT_S390_VXRS_LOW:
16770 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
16771 case NT_S390_VXRS_HIGH:
16772 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
16773 case NT_S390_GS_CB:
16774 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
16775 case NT_S390_GS_BC:
16776 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
16777 case NT_ARM_VFP:
16778 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
16779 case NT_ARM_TLS:
16780 return _("NT_ARM_TLS (AArch TLS registers)");
16781 case NT_ARM_HW_BREAK:
16782 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
16783 case NT_ARM_HW_WATCH:
16784 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 16785 case NT_PSTATUS:
1ec5cd37 16786 return _("NT_PSTATUS (pstatus structure)");
57346661 16787 case NT_FPREGS:
1ec5cd37 16788 return _("NT_FPREGS (floating point registers)");
57346661 16789 case NT_PSINFO:
1ec5cd37 16790 return _("NT_PSINFO (psinfo structure)");
57346661 16791 case NT_LWPSTATUS:
1ec5cd37 16792 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 16793 case NT_LWPSINFO:
1ec5cd37 16794 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 16795 case NT_WIN32PSTATUS:
1ec5cd37 16796 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
16797 case NT_SIGINFO:
16798 return _("NT_SIGINFO (siginfo_t data)");
16799 case NT_FILE:
16800 return _("NT_FILE (mapped files)");
1ec5cd37
NC
16801 default:
16802 break;
16803 }
16804 else
16805 switch (e_type)
16806 {
16807 case NT_VERSION:
16808 return _("NT_VERSION (version)");
16809 case NT_ARCH:
16810 return _("NT_ARCH (architecture)");
9ef920e9 16811 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 16812 return _("OPEN");
9ef920e9 16813 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 16814 return _("func");
1ec5cd37
NC
16815 default:
16816 break;
16817 }
16818
e9e44622 16819 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 16820 return buff;
779fe533
NC
16821}
16822
32ec8896 16823static bfd_boolean
9ece1fa9
TT
16824print_core_note (Elf_Internal_Note *pnote)
16825{
16826 unsigned int addr_size = is_32bit_elf ? 4 : 8;
16827 bfd_vma count, page_size;
16828 unsigned char *descdata, *filenames, *descend;
16829
16830 if (pnote->type != NT_FILE)
04ac15ab
AS
16831 {
16832 if (do_wide)
16833 printf ("\n");
16834 return TRUE;
16835 }
9ece1fa9
TT
16836
16837#ifndef BFD64
16838 if (!is_32bit_elf)
16839 {
16840 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
16841 /* Still "successful". */
32ec8896 16842 return TRUE;
9ece1fa9
TT
16843 }
16844#endif
16845
16846 if (pnote->descsz < 2 * addr_size)
16847 {
32ec8896
NC
16848 error (_(" Malformed note - too short for header\n"));
16849 return FALSE;
9ece1fa9
TT
16850 }
16851
16852 descdata = (unsigned char *) pnote->descdata;
16853 descend = descdata + pnote->descsz;
16854
16855 if (descdata[pnote->descsz - 1] != '\0')
16856 {
32ec8896
NC
16857 error (_(" Malformed note - does not end with \\0\n"));
16858 return FALSE;
9ece1fa9
TT
16859 }
16860
16861 count = byte_get (descdata, addr_size);
16862 descdata += addr_size;
16863
16864 page_size = byte_get (descdata, addr_size);
16865 descdata += addr_size;
16866
5396a86e
AM
16867 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
16868 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 16869 {
32ec8896
NC
16870 error (_(" Malformed note - too short for supplied file count\n"));
16871 return FALSE;
9ece1fa9
TT
16872 }
16873
16874 printf (_(" Page size: "));
16875 print_vma (page_size, DEC);
16876 printf ("\n");
16877
16878 printf (_(" %*s%*s%*s\n"),
16879 (int) (2 + 2 * addr_size), _("Start"),
16880 (int) (4 + 2 * addr_size), _("End"),
16881 (int) (4 + 2 * addr_size), _("Page Offset"));
16882 filenames = descdata + count * 3 * addr_size;
595712bb 16883 while (count-- > 0)
9ece1fa9
TT
16884 {
16885 bfd_vma start, end, file_ofs;
16886
16887 if (filenames == descend)
16888 {
32ec8896
NC
16889 error (_(" Malformed note - filenames end too early\n"));
16890 return FALSE;
9ece1fa9
TT
16891 }
16892
16893 start = byte_get (descdata, addr_size);
16894 descdata += addr_size;
16895 end = byte_get (descdata, addr_size);
16896 descdata += addr_size;
16897 file_ofs = byte_get (descdata, addr_size);
16898 descdata += addr_size;
16899
16900 printf (" ");
16901 print_vma (start, FULL_HEX);
16902 printf (" ");
16903 print_vma (end, FULL_HEX);
16904 printf (" ");
16905 print_vma (file_ofs, FULL_HEX);
16906 printf ("\n %s\n", filenames);
16907
16908 filenames += 1 + strlen ((char *) filenames);
16909 }
16910
32ec8896 16911 return TRUE;
9ece1fa9
TT
16912}
16913
1118d252
RM
16914static const char *
16915get_gnu_elf_note_type (unsigned e_type)
16916{
1449284b 16917 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
16918 switch (e_type)
16919 {
16920 case NT_GNU_ABI_TAG:
16921 return _("NT_GNU_ABI_TAG (ABI version tag)");
16922 case NT_GNU_HWCAP:
16923 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
16924 case NT_GNU_BUILD_ID:
16925 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
16926 case NT_GNU_GOLD_VERSION:
16927 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
16928 case NT_GNU_PROPERTY_TYPE_0:
16929 return _("NT_GNU_PROPERTY_TYPE_0");
16930 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
16931 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
16932 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
16933 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 16934 default:
1449284b
NC
16935 {
16936 static char buff[64];
1118d252 16937
1449284b
NC
16938 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
16939 return buff;
16940 }
16941 }
1118d252
RM
16942}
16943
9ef920e9 16944static void
1fc87489 16945decode_x86_isa (unsigned int bitmask)
9ef920e9
NC
16946{
16947 while (bitmask)
16948 {
1fc87489 16949 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
16950
16951 bitmask &= ~ bit;
16952 switch (bit)
16953 {
16954 case GNU_PROPERTY_X86_ISA_1_486: printf ("i486"); break;
16955 case GNU_PROPERTY_X86_ISA_1_586: printf ("586"); break;
16956 case GNU_PROPERTY_X86_ISA_1_686: printf ("686"); break;
16957 case GNU_PROPERTY_X86_ISA_1_SSE: printf ("SSE"); break;
16958 case GNU_PROPERTY_X86_ISA_1_SSE2: printf ("SSE2"); break;
16959 case GNU_PROPERTY_X86_ISA_1_SSE3: printf ("SSE3"); break;
16960 case GNU_PROPERTY_X86_ISA_1_SSSE3: printf ("SSSE3"); break;
16961 case GNU_PROPERTY_X86_ISA_1_SSE4_1: printf ("SSE4_1"); break;
16962 case GNU_PROPERTY_X86_ISA_1_SSE4_2: printf ("SSE4_2"); break;
16963 case GNU_PROPERTY_X86_ISA_1_AVX: printf ("AVX"); break;
16964 case GNU_PROPERTY_X86_ISA_1_AVX2: printf ("AVX2"); break;
16965 case GNU_PROPERTY_X86_ISA_1_AVX512F: printf ("AVX512F"); break;
16966 case GNU_PROPERTY_X86_ISA_1_AVX512CD: printf ("AVX512CD"); break;
16967 case GNU_PROPERTY_X86_ISA_1_AVX512ER: printf ("AVX512ER"); break;
16968 case GNU_PROPERTY_X86_ISA_1_AVX512PF: printf ("AVX512PF"); break;
16969 case GNU_PROPERTY_X86_ISA_1_AVX512VL: printf ("AVX512VL"); break;
16970 case GNU_PROPERTY_X86_ISA_1_AVX512DQ: printf ("AVX512DQ"); break;
16971 case GNU_PROPERTY_X86_ISA_1_AVX512BW: printf ("AVX512BW"); break;
1fc87489 16972 default: printf (_("<unknown: %x>"), bit); break;
9ef920e9
NC
16973 }
16974 if (bitmask)
16975 printf (", ");
16976 }
16977}
16978
ee2fdd6f
L
16979static void
16980decode_x86_feature (unsigned int type, unsigned int bitmask)
16981{
16982 while (bitmask)
16983 {
16984 unsigned int bit = bitmask & (- bitmask);
16985
16986 bitmask &= ~ bit;
16987 switch (bit)
16988 {
16989 case GNU_PROPERTY_X86_FEATURE_1_IBT:
16990 switch (type)
16991 {
16992 case GNU_PROPERTY_X86_FEATURE_1_AND:
16993 printf ("IBT");
16994 break;
16995 default:
16996 /* This should never happen. */
16997 abort ();
16998 }
16999 break;
48580982
L
17000 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
17001 switch (type)
17002 {
17003 case GNU_PROPERTY_X86_FEATURE_1_AND:
17004 printf ("SHSTK");
17005 break;
17006 default:
17007 /* This should never happen. */
17008 abort ();
17009 }
17010 break;
ee2fdd6f
L
17011 default:
17012 printf (_("<unknown: %x>"), bit);
17013 break;
17014 }
17015 if (bitmask)
17016 printf (", ");
17017 }
17018}
17019
9ef920e9 17020static void
dda8d76d 17021print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
17022{
17023 unsigned char * ptr = (unsigned char *) pnote->descdata;
17024 unsigned char * ptr_end = ptr + pnote->descsz;
17025 unsigned int size = is_32bit_elf ? 4 : 8;
17026
17027 printf (_(" Properties: "));
17028
1fc87489 17029 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
17030 {
17031 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
17032 return;
17033 }
17034
6ab2c4ed 17035 while (ptr < ptr_end)
9ef920e9 17036 {
1fc87489 17037 unsigned int j;
6ab2c4ed
MC
17038 unsigned int type;
17039 unsigned int datasz;
17040
17041 if ((size_t) (ptr_end - ptr) < 8)
17042 {
17043 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
17044 break;
17045 }
17046
17047 type = byte_get (ptr, 4);
17048 datasz = byte_get (ptr + 4, 4);
9ef920e9 17049
1fc87489 17050 ptr += 8;
9ef920e9 17051
6ab2c4ed 17052 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 17053 {
1fc87489
L
17054 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
17055 type, datasz);
9ef920e9 17056 break;
1fc87489 17057 }
9ef920e9 17058
1fc87489
L
17059 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
17060 {
dda8d76d
NC
17061 if (filedata->file_header.e_machine == EM_X86_64
17062 || filedata->file_header.e_machine == EM_IAMCU
17063 || filedata->file_header.e_machine == EM_386)
1fc87489
L
17064 {
17065 switch (type)
17066 {
17067 case GNU_PROPERTY_X86_ISA_1_USED:
17068 printf ("x86 ISA used: ");
17069 if (datasz != 4)
17070 printf (_("<corrupt length: %#x> "), datasz);
17071 else
17072 decode_x86_isa (byte_get (ptr, 4));
17073 goto next;
9ef920e9 17074
1fc87489
L
17075 case GNU_PROPERTY_X86_ISA_1_NEEDED:
17076 printf ("x86 ISA needed: ");
17077 if (datasz != 4)
17078 printf (_("<corrupt length: %#x> "), datasz);
17079 else
17080 decode_x86_isa (byte_get (ptr, 4));
17081 goto next;
9ef920e9 17082
ee2fdd6f
L
17083 case GNU_PROPERTY_X86_FEATURE_1_AND:
17084 printf ("x86 feature: ");
17085 if (datasz != 4)
17086 printf (_("<corrupt length: %#x> "), datasz);
17087 else
17088 decode_x86_feature (type, byte_get (ptr, 4));
17089 goto next;
17090
1fc87489
L
17091 default:
17092 break;
17093 }
17094 }
17095 }
17096 else
17097 {
17098 switch (type)
9ef920e9 17099 {
1fc87489
L
17100 case GNU_PROPERTY_STACK_SIZE:
17101 printf (_("stack size: "));
17102 if (datasz != size)
17103 printf (_("<corrupt length: %#x> "), datasz);
17104 else
17105 printf ("%#lx", (unsigned long) byte_get (ptr, size));
17106 goto next;
17107
17108 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
17109 printf ("no copy on protected ");
17110 if (datasz)
17111 printf (_("<corrupt length: %#x> "), datasz);
17112 goto next;
17113
17114 default:
9ef920e9
NC
17115 break;
17116 }
9ef920e9
NC
17117 }
17118
1fc87489
L
17119 if (type < GNU_PROPERTY_LOPROC)
17120 printf (_("<unknown type %#x data: "), type);
17121 else if (type < GNU_PROPERTY_LOUSER)
17122 printf (_("<procesor-specific type %#x data: "), type);
17123 else
17124 printf (_("<application-specific type %#x data: "), type);
17125 for (j = 0; j < datasz; ++j)
17126 printf ("%02x ", ptr[j] & 0xff);
17127 printf (">");
17128
17129next:
9ef920e9 17130 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
17131 if (ptr == ptr_end)
17132 break;
1fc87489 17133
6ab2c4ed
MC
17134 if (do_wide)
17135 printf (", ");
17136 else
17137 printf ("\n\t");
9ef920e9
NC
17138 }
17139
17140 printf ("\n");
17141}
17142
32ec8896 17143static bfd_boolean
dda8d76d 17144print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 17145{
1449284b 17146 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
17147 switch (pnote->type)
17148 {
17149 case NT_GNU_BUILD_ID:
17150 {
17151 unsigned long i;
17152
17153 printf (_(" Build ID: "));
17154 for (i = 0; i < pnote->descsz; ++i)
17155 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 17156 printf ("\n");
664f90a3
TT
17157 }
17158 break;
17159
17160 case NT_GNU_ABI_TAG:
17161 {
17162 unsigned long os, major, minor, subminor;
17163 const char *osname;
17164
3102e897
NC
17165 /* PR 17531: file: 030-599401-0.004. */
17166 if (pnote->descsz < 16)
17167 {
17168 printf (_(" <corrupt GNU_ABI_TAG>\n"));
17169 break;
17170 }
17171
664f90a3
TT
17172 os = byte_get ((unsigned char *) pnote->descdata, 4);
17173 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17174 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
17175 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
17176
17177 switch (os)
17178 {
17179 case GNU_ABI_TAG_LINUX:
17180 osname = "Linux";
17181 break;
17182 case GNU_ABI_TAG_HURD:
17183 osname = "Hurd";
17184 break;
17185 case GNU_ABI_TAG_SOLARIS:
17186 osname = "Solaris";
17187 break;
17188 case GNU_ABI_TAG_FREEBSD:
17189 osname = "FreeBSD";
17190 break;
17191 case GNU_ABI_TAG_NETBSD:
17192 osname = "NetBSD";
17193 break;
14ae95f2
RM
17194 case GNU_ABI_TAG_SYLLABLE:
17195 osname = "Syllable";
17196 break;
17197 case GNU_ABI_TAG_NACL:
17198 osname = "NaCl";
17199 break;
664f90a3
TT
17200 default:
17201 osname = "Unknown";
17202 break;
17203 }
17204
17205 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
17206 major, minor, subminor);
17207 }
17208 break;
926c5385
CC
17209
17210 case NT_GNU_GOLD_VERSION:
17211 {
17212 unsigned long i;
17213
17214 printf (_(" Version: "));
17215 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
17216 printf ("%c", pnote->descdata[i]);
17217 printf ("\n");
17218 }
17219 break;
1449284b
NC
17220
17221 case NT_GNU_HWCAP:
17222 {
17223 unsigned long num_entries, mask;
17224
17225 /* Hardware capabilities information. Word 0 is the number of entries.
17226 Word 1 is a bitmask of enabled entries. The rest of the descriptor
17227 is a series of entries, where each entry is a single byte followed
17228 by a nul terminated string. The byte gives the bit number to test
17229 if enabled in the bitmask. */
17230 printf (_(" Hardware Capabilities: "));
17231 if (pnote->descsz < 8)
17232 {
32ec8896
NC
17233 error (_("<corrupt GNU_HWCAP>\n"));
17234 return FALSE;
1449284b
NC
17235 }
17236 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
17237 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17238 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
17239 /* FIXME: Add code to display the entries... */
17240 }
17241 break;
17242
9ef920e9 17243 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 17244 print_gnu_property_note (filedata, pnote);
9ef920e9
NC
17245 break;
17246
1449284b
NC
17247 default:
17248 /* Handle unrecognised types. An error message should have already been
17249 created by get_gnu_elf_note_type(), so all that we need to do is to
17250 display the data. */
17251 {
17252 unsigned long i;
17253
17254 printf (_(" Description data: "));
17255 for (i = 0; i < pnote->descsz; ++i)
17256 printf ("%02x ", pnote->descdata[i] & 0xff);
17257 printf ("\n");
17258 }
17259 break;
664f90a3
TT
17260 }
17261
32ec8896 17262 return TRUE;
664f90a3
TT
17263}
17264
685080f2
NC
17265static const char *
17266get_v850_elf_note_type (enum v850_notes n_type)
17267{
17268 static char buff[64];
17269
17270 switch (n_type)
17271 {
17272 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
17273 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
17274 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
17275 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
17276 case V850_NOTE_CACHE_INFO: return _("Use of cache");
17277 case V850_NOTE_MMU_INFO: return _("Use of MMU");
17278 default:
17279 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
17280 return buff;
17281 }
17282}
17283
32ec8896 17284static bfd_boolean
685080f2
NC
17285print_v850_note (Elf_Internal_Note * pnote)
17286{
17287 unsigned int val;
17288
17289 if (pnote->descsz != 4)
32ec8896
NC
17290 return FALSE;
17291
685080f2
NC
17292 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
17293
17294 if (val == 0)
17295 {
17296 printf (_("not set\n"));
32ec8896 17297 return TRUE;
685080f2
NC
17298 }
17299
17300 switch (pnote->type)
17301 {
17302 case V850_NOTE_ALIGNMENT:
17303 switch (val)
17304 {
32ec8896
NC
17305 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
17306 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
17307 }
17308 break;
14ae95f2 17309
685080f2
NC
17310 case V850_NOTE_DATA_SIZE:
17311 switch (val)
17312 {
32ec8896
NC
17313 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
17314 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
17315 }
17316 break;
14ae95f2 17317
685080f2
NC
17318 case V850_NOTE_FPU_INFO:
17319 switch (val)
17320 {
32ec8896
NC
17321 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
17322 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
17323 }
17324 break;
14ae95f2 17325
685080f2
NC
17326 case V850_NOTE_MMU_INFO:
17327 case V850_NOTE_CACHE_INFO:
17328 case V850_NOTE_SIMD_INFO:
17329 if (val == EF_RH850_SIMD)
17330 {
17331 printf (_("yes\n"));
32ec8896 17332 return TRUE;
685080f2
NC
17333 }
17334 break;
17335
17336 default:
17337 /* An 'unknown note type' message will already have been displayed. */
17338 break;
17339 }
17340
17341 printf (_("unknown value: %x\n"), val);
32ec8896 17342 return FALSE;
685080f2
NC
17343}
17344
32ec8896 17345static bfd_boolean
c6056a74
SF
17346process_netbsd_elf_note (Elf_Internal_Note * pnote)
17347{
17348 unsigned int version;
17349
17350 switch (pnote->type)
17351 {
17352 case NT_NETBSD_IDENT:
17353 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
17354 if ((version / 10000) % 100)
17355 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
17356 version, version / 100000000, (version / 1000000) % 100,
17357 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 17358 'A' + (version / 10000) % 26);
c6056a74
SF
17359 else
17360 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
17361 version, version / 100000000, (version / 1000000) % 100,
15f205b1 17362 (version / 100) % 100);
32ec8896 17363 return TRUE;
c6056a74
SF
17364
17365 case NT_NETBSD_MARCH:
17366 printf (" NetBSD\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
17367 pnote->descdata);
32ec8896 17368 return TRUE;
c6056a74
SF
17369
17370 default:
32ec8896
NC
17371 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n", pnote->descsz,
17372 pnote->type);
17373 return FALSE;
c6056a74 17374 }
c6056a74
SF
17375}
17376
f4ddf30f 17377static const char *
dda8d76d 17378get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 17379{
f4ddf30f
JB
17380 switch (e_type)
17381 {
17382 case NT_FREEBSD_THRMISC:
17383 return _("NT_THRMISC (thrmisc structure)");
17384 case NT_FREEBSD_PROCSTAT_PROC:
17385 return _("NT_PROCSTAT_PROC (proc data)");
17386 case NT_FREEBSD_PROCSTAT_FILES:
17387 return _("NT_PROCSTAT_FILES (files data)");
17388 case NT_FREEBSD_PROCSTAT_VMMAP:
17389 return _("NT_PROCSTAT_VMMAP (vmmap data)");
17390 case NT_FREEBSD_PROCSTAT_GROUPS:
17391 return _("NT_PROCSTAT_GROUPS (groups data)");
17392 case NT_FREEBSD_PROCSTAT_UMASK:
17393 return _("NT_PROCSTAT_UMASK (umask data)");
17394 case NT_FREEBSD_PROCSTAT_RLIMIT:
17395 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
17396 case NT_FREEBSD_PROCSTAT_OSREL:
17397 return _("NT_PROCSTAT_OSREL (osreldate data)");
17398 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
17399 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
17400 case NT_FREEBSD_PROCSTAT_AUXV:
17401 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
17402 case NT_FREEBSD_PTLWPINFO:
17403 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 17404 }
dda8d76d 17405 return get_note_type (filedata, e_type);
f4ddf30f
JB
17406}
17407
9437c45b 17408static const char *
dda8d76d 17409get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
17410{
17411 static char buff[64];
17412
b4db1224 17413 if (e_type == NT_NETBSDCORE_PROCINFO)
dda8d76d 17414 return _("NetBSD procinfo structure");
9437c45b
JT
17415
17416 /* As of Jan 2002 there are no other machine-independent notes
17417 defined for NetBSD core files. If the note type is less
17418 than the start of the machine-dependent note types, we don't
17419 understand it. */
17420
b4db1224 17421 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 17422 {
e9e44622 17423 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
17424 return buff;
17425 }
17426
dda8d76d 17427 switch (filedata->file_header.e_machine)
9437c45b
JT
17428 {
17429 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
17430 and PT_GETFPREGS == mach+2. */
17431
17432 case EM_OLD_ALPHA:
17433 case EM_ALPHA:
17434 case EM_SPARC:
17435 case EM_SPARC32PLUS:
17436 case EM_SPARCV9:
17437 switch (e_type)
17438 {
2b692964 17439 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 17440 return _("PT_GETREGS (reg structure)");
2b692964 17441 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 17442 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17443 default:
17444 break;
17445 }
17446 break;
17447
17448 /* On all other arch's, PT_GETREGS == mach+1 and
17449 PT_GETFPREGS == mach+3. */
17450 default:
17451 switch (e_type)
17452 {
2b692964 17453 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 17454 return _("PT_GETREGS (reg structure)");
2b692964 17455 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 17456 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17457 default:
17458 break;
17459 }
17460 }
17461
9cf03b7e 17462 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 17463 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
17464 return buff;
17465}
17466
70616151
TT
17467static const char *
17468get_stapsdt_note_type (unsigned e_type)
17469{
17470 static char buff[64];
17471
17472 switch (e_type)
17473 {
17474 case NT_STAPSDT:
17475 return _("NT_STAPSDT (SystemTap probe descriptors)");
17476
17477 default:
17478 break;
17479 }
17480
17481 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17482 return buff;
17483}
17484
32ec8896 17485static bfd_boolean
c6a9fc58
TT
17486print_stapsdt_note (Elf_Internal_Note *pnote)
17487{
17488 int addr_size = is_32bit_elf ? 4 : 8;
17489 char *data = pnote->descdata;
17490 char *data_end = pnote->descdata + pnote->descsz;
17491 bfd_vma pc, base_addr, semaphore;
17492 char *provider, *probe, *arg_fmt;
17493
17494 pc = byte_get ((unsigned char *) data, addr_size);
17495 data += addr_size;
17496 base_addr = byte_get ((unsigned char *) data, addr_size);
17497 data += addr_size;
17498 semaphore = byte_get ((unsigned char *) data, addr_size);
17499 data += addr_size;
17500
17501 provider = data;
17502 data += strlen (data) + 1;
17503 probe = data;
17504 data += strlen (data) + 1;
17505 arg_fmt = data;
17506 data += strlen (data) + 1;
17507
17508 printf (_(" Provider: %s\n"), provider);
17509 printf (_(" Name: %s\n"), probe);
17510 printf (_(" Location: "));
17511 print_vma (pc, FULL_HEX);
17512 printf (_(", Base: "));
17513 print_vma (base_addr, FULL_HEX);
17514 printf (_(", Semaphore: "));
17515 print_vma (semaphore, FULL_HEX);
9cf03b7e 17516 printf ("\n");
c6a9fc58
TT
17517 printf (_(" Arguments: %s\n"), arg_fmt);
17518
17519 return data == data_end;
17520}
17521
00e98fc7
TG
17522static const char *
17523get_ia64_vms_note_type (unsigned e_type)
17524{
17525 static char buff[64];
17526
17527 switch (e_type)
17528 {
17529 case NT_VMS_MHD:
17530 return _("NT_VMS_MHD (module header)");
17531 case NT_VMS_LNM:
17532 return _("NT_VMS_LNM (language name)");
17533 case NT_VMS_SRC:
17534 return _("NT_VMS_SRC (source files)");
17535 case NT_VMS_TITLE:
9cf03b7e 17536 return "NT_VMS_TITLE";
00e98fc7
TG
17537 case NT_VMS_EIDC:
17538 return _("NT_VMS_EIDC (consistency check)");
17539 case NT_VMS_FPMODE:
17540 return _("NT_VMS_FPMODE (FP mode)");
17541 case NT_VMS_LINKTIME:
9cf03b7e 17542 return "NT_VMS_LINKTIME";
00e98fc7
TG
17543 case NT_VMS_IMGNAM:
17544 return _("NT_VMS_IMGNAM (image name)");
17545 case NT_VMS_IMGID:
17546 return _("NT_VMS_IMGID (image id)");
17547 case NT_VMS_LINKID:
17548 return _("NT_VMS_LINKID (link id)");
17549 case NT_VMS_IMGBID:
17550 return _("NT_VMS_IMGBID (build id)");
17551 case NT_VMS_GSTNAM:
17552 return _("NT_VMS_GSTNAM (sym table name)");
17553 case NT_VMS_ORIG_DYN:
9cf03b7e 17554 return "NT_VMS_ORIG_DYN";
00e98fc7 17555 case NT_VMS_PATCHTIME:
9cf03b7e 17556 return "NT_VMS_PATCHTIME";
00e98fc7
TG
17557 default:
17558 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17559 return buff;
17560 }
17561}
17562
32ec8896 17563static bfd_boolean
00e98fc7
TG
17564print_ia64_vms_note (Elf_Internal_Note * pnote)
17565{
17566 switch (pnote->type)
17567 {
17568 case NT_VMS_MHD:
17569 if (pnote->descsz > 36)
17570 {
17571 size_t l = strlen (pnote->descdata + 34);
17572 printf (_(" Creation date : %.17s\n"), pnote->descdata);
17573 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
17574 printf (_(" Module name : %s\n"), pnote->descdata + 34);
17575 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
17576 }
17577 else
17578 printf (_(" Invalid size\n"));
17579 break;
17580 case NT_VMS_LNM:
17581 printf (_(" Language: %s\n"), pnote->descdata);
17582 break;
17583#ifdef BFD64
17584 case NT_VMS_FPMODE:
9cf03b7e 17585 printf (_(" Floating Point mode: "));
4a5cb34f 17586 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 17587 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
17588 break;
17589 case NT_VMS_LINKTIME:
17590 printf (_(" Link time: "));
17591 print_vms_time
17592 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
17593 printf ("\n");
17594 break;
17595 case NT_VMS_PATCHTIME:
17596 printf (_(" Patch time: "));
17597 print_vms_time
17598 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
17599 printf ("\n");
17600 break;
17601 case NT_VMS_ORIG_DYN:
17602 printf (_(" Major id: %u, minor id: %u\n"),
17603 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
17604 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 17605 printf (_(" Last modified : "));
00e98fc7
TG
17606 print_vms_time
17607 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 17608 printf (_("\n Link flags : "));
4a5cb34f 17609 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 17610 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 17611 printf (_(" Header flags: 0x%08x\n"),
948f632f 17612 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
00e98fc7
TG
17613 printf (_(" Image id : %s\n"), pnote->descdata + 32);
17614 break;
17615#endif
17616 case NT_VMS_IMGNAM:
17617 printf (_(" Image name: %s\n"), pnote->descdata);
17618 break;
17619 case NT_VMS_GSTNAM:
17620 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
17621 break;
17622 case NT_VMS_IMGID:
17623 printf (_(" Image id: %s\n"), pnote->descdata);
17624 break;
17625 case NT_VMS_LINKID:
17626 printf (_(" Linker id: %s\n"), pnote->descdata);
17627 break;
17628 default:
32ec8896 17629 return FALSE;
00e98fc7 17630 }
32ec8896 17631 return TRUE;
00e98fc7
TG
17632}
17633
6f156d7a
NC
17634/* Find the symbol associated with a build attribute that is attached
17635 to address OFFSET. If PNAME is non-NULL then store the name of
17636 the symbol (if found) in the provided pointer, Returns NULL if a
17637 symbol could not be found. */
c799a79d 17638
6f156d7a
NC
17639static Elf_Internal_Sym *
17640get_symbol_for_build_attribute (Filedata * filedata,
17641 unsigned long offset,
17642 bfd_boolean is_open_attr,
17643 const char ** pname)
9ef920e9 17644{
dda8d76d 17645 static Filedata * saved_filedata = NULL;
c799a79d
NC
17646 static char * strtab;
17647 static unsigned long strtablen;
17648 static Elf_Internal_Sym * symtab;
17649 static unsigned long nsyms;
7296a62a
NC
17650 Elf_Internal_Sym * saved_sym = NULL;
17651 Elf_Internal_Sym * sym;
9ef920e9 17652
dda8d76d
NC
17653 if (filedata->section_headers != NULL
17654 && (saved_filedata == NULL || filedata != saved_filedata))
9ef920e9 17655 {
c799a79d 17656 Elf_Internal_Shdr * symsec;
9ef920e9 17657
c799a79d 17658 /* Load the symbol and string sections. */
dda8d76d
NC
17659 for (symsec = filedata->section_headers;
17660 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 17661 symsec ++)
9ef920e9 17662 {
c799a79d 17663 if (symsec->sh_type == SHT_SYMTAB)
9ef920e9 17664 {
dda8d76d 17665 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
9ef920e9 17666
dda8d76d 17667 if (symsec->sh_link < filedata->file_header.e_shnum)
c799a79d 17668 {
dda8d76d 17669 Elf_Internal_Shdr * strtab_sec = filedata->section_headers + symsec->sh_link;
c799a79d 17670
dda8d76d 17671 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
c799a79d
NC
17672 1, strtab_sec->sh_size,
17673 _("string table"));
17674 strtablen = strtab != NULL ? strtab_sec->sh_size : 0;
17675 }
9ef920e9
NC
17676 }
17677 }
dda8d76d 17678 saved_filedata = filedata;
9ef920e9
NC
17679 }
17680
c799a79d 17681 if (symtab == NULL || strtab == NULL)
6f156d7a 17682 return NULL;
9ef920e9 17683
c799a79d
NC
17684 /* Find a symbol whose value matches offset. */
17685 for (sym = symtab; sym < symtab + nsyms; sym ++)
17686 if (sym->st_value == offset)
17687 {
17688 if (sym->st_name >= strtablen)
17689 /* Huh ? This should not happen. */
17690 continue;
9ef920e9 17691
c799a79d
NC
17692 if (strtab[sym->st_name] == 0)
17693 continue;
9ef920e9 17694
8fd75781
NC
17695 /* The AArch64 and ARM architectures define mapping symbols
17696 (eg $d, $x, $t) which we want to ignore. */
17697 if (strtab[sym->st_name] == '$'
17698 && strtab[sym->st_name + 1] != 0
17699 && strtab[sym->st_name + 2] == 0)
17700 continue;
17701
c799a79d
NC
17702 if (is_open_attr)
17703 {
17704 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
17705 and FILE or OBJECT symbols over NOTYPE symbols. We skip
17706 FUNC symbols entirely. */
17707 switch (ELF_ST_TYPE (sym->st_info))
17708 {
c799a79d 17709 case STT_OBJECT:
6f156d7a 17710 case STT_FILE:
c799a79d 17711 saved_sym = sym;
6f156d7a
NC
17712 if (sym->st_size)
17713 {
17714 /* If the symbol has a size associated
17715 with it then we can stop searching. */
17716 sym = symtab + nsyms;
17717 }
c799a79d 17718 continue;
9ef920e9 17719
c799a79d
NC
17720 case STT_FUNC:
17721 /* Ignore function symbols. */
17722 continue;
17723
17724 default:
17725 break;
17726 }
17727
17728 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 17729 {
c799a79d
NC
17730 case STB_GLOBAL:
17731 if (saved_sym == NULL
17732 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
17733 saved_sym = sym;
17734 break;
c871dade 17735
c799a79d
NC
17736 case STB_LOCAL:
17737 if (saved_sym == NULL)
17738 saved_sym = sym;
17739 break;
17740
17741 default:
9ef920e9
NC
17742 break;
17743 }
17744 }
c799a79d
NC
17745 else
17746 {
17747 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
17748 continue;
17749
17750 saved_sym = sym;
17751 break;
17752 }
17753 }
17754
6f156d7a
NC
17755 if (saved_sym && pname)
17756 * pname = strtab + saved_sym->st_name;
17757
17758 return saved_sym;
c799a79d
NC
17759}
17760
d20e98ab
NC
17761/* Returns true iff addr1 and addr2 are in the same section. */
17762
17763static bfd_boolean
17764same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
17765{
17766 Elf_Internal_Shdr * a1;
17767 Elf_Internal_Shdr * a2;
17768
17769 a1 = find_section_by_address (filedata, addr1);
17770 a2 = find_section_by_address (filedata, addr2);
17771
17772 return a1 == a2 && a1 != NULL;
17773}
17774
c799a79d 17775static bfd_boolean
dda8d76d
NC
17776print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
17777 Filedata * filedata)
c799a79d 17778{
6f156d7a
NC
17779 static unsigned long global_offset = 0;
17780 static unsigned long global_end = 0;
17781 static unsigned long func_offset = 0;
17782 static unsigned long func_end = 0;
c871dade 17783
6f156d7a
NC
17784 Elf_Internal_Sym * sym;
17785 const char * name;
17786 unsigned long start;
17787 unsigned long end;
17788 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
17789
17790 switch (pnote->descsz)
c799a79d 17791 {
6f156d7a
NC
17792 case 0:
17793 /* A zero-length description means that the range of
17794 the previous note of the same type should be used. */
c799a79d 17795 if (is_open_attr)
c871dade 17796 {
6f156d7a
NC
17797 if (global_end > global_offset)
17798 printf (_(" Applies to region from %#lx to %#lx\n"),
17799 global_offset, global_end);
17800 else
17801 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
17802 }
17803 else
17804 {
6f156d7a
NC
17805 if (func_end > func_offset)
17806 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
17807 else
17808 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 17809 }
6f156d7a 17810 return TRUE;
9ef920e9 17811
6f156d7a
NC
17812 case 4:
17813 start = byte_get ((unsigned char *) pnote->descdata, 4);
17814 end = 0;
17815 break;
17816
17817 case 8:
17818 if (is_32bit_elf)
17819 {
17820 /* FIXME: We should check that version 3+ notes are being used here... */
17821 start = byte_get ((unsigned char *) pnote->descdata, 4);
17822 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17823 }
17824 else
17825 {
17826 start = byte_get ((unsigned char *) pnote->descdata, 8);
17827 end = 0;
17828 }
17829 break;
17830
17831 case 16:
17832 start = byte_get ((unsigned char *) pnote->descdata, 8);
17833 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
17834 break;
17835
17836 default:
c799a79d
NC
17837 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
17838 printf (_(" <invalid descsz>"));
17839 return FALSE;
17840 }
17841
6f156d7a
NC
17842 name = NULL;
17843 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
17844 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
17845 in order to avoid them being confused with the start address of the
17846 first function in the file... */
17847 if (sym == NULL && is_open_attr)
17848 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
17849 & name);
6f156d7a
NC
17850
17851 if (end == 0 && sym != NULL && sym->st_size > 0)
17852 end = start + sym->st_size;
c799a79d
NC
17853
17854 if (is_open_attr)
17855 {
d20e98ab
NC
17856 /* FIXME: Need to properly allow for section alignment.
17857 16 is just the alignment used on x86_64. */
17858 if (global_end > 0
17859 && start > BFD_ALIGN (global_end, 16)
17860 /* Build notes are not guaranteed to be organised in order of
17861 increasing address, but we should find the all of the notes
17862 for one section in the same place. */
17863 && same_section (filedata, start, global_end))
6f156d7a
NC
17864 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
17865 global_end + 1, start - 1);
17866
17867 printf (_(" Applies to region from %#lx"), start);
17868 global_offset = start;
17869
17870 if (end)
17871 {
17872 printf (_(" to %#lx"), end);
17873 global_end = end;
17874 }
c799a79d
NC
17875 }
17876 else
17877 {
6f156d7a
NC
17878 printf (_(" Applies to region from %#lx"), start);
17879 func_offset = start;
17880
17881 if (end)
17882 {
17883 printf (_(" to %#lx"), end);
17884 func_end = end;
17885 }
c799a79d
NC
17886 }
17887
6f156d7a
NC
17888 if (sym && name)
17889 printf (_(" (%s)"), name);
17890
17891 printf ("\n");
17892 return TRUE;
9ef920e9
NC
17893}
17894
17895static bfd_boolean
17896print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
17897{
1d15e434
NC
17898 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
17899 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
17900 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
17901 char name_type;
17902 char name_attribute;
1d15e434 17903 const char * expected_types;
9ef920e9
NC
17904 const char * name = pnote->namedata;
17905 const char * text;
88305e1b 17906 signed int left;
9ef920e9
NC
17907
17908 if (name == NULL || pnote->namesz < 2)
17909 {
17910 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 17911 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
17912 return FALSE;
17913 }
17914
6f156d7a
NC
17915 if (do_wide)
17916 left = 28;
17917 else
17918 left = 20;
88305e1b
NC
17919
17920 /* Version 2 of the spec adds a "GA" prefix to the name field. */
17921 if (name[0] == 'G' && name[1] == 'A')
17922 {
6f156d7a
NC
17923 if (pnote->namesz < 4)
17924 {
17925 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
17926 print_symbol (-20, _(" <corrupt name>"));
17927 return FALSE;
17928 }
17929
88305e1b
NC
17930 printf ("GA");
17931 name += 2;
17932 left -= 2;
17933 }
17934
9ef920e9
NC
17935 switch ((name_type = * name))
17936 {
17937 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
17938 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
17939 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
17940 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
17941 printf ("%c", * name);
88305e1b 17942 left --;
9ef920e9
NC
17943 break;
17944 default:
17945 error (_("unrecognised attribute type in name field: %d\n"), name_type);
17946 print_symbol (-20, _("<unknown name type>"));
17947 return FALSE;
17948 }
17949
9ef920e9
NC
17950 ++ name;
17951 text = NULL;
17952
17953 switch ((name_attribute = * name))
17954 {
17955 case GNU_BUILD_ATTRIBUTE_VERSION:
17956 text = _("<version>");
1d15e434 17957 expected_types = string_expected;
9ef920e9
NC
17958 ++ name;
17959 break;
17960 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
17961 text = _("<stack prot>");
75d7d298 17962 expected_types = "!+*";
9ef920e9
NC
17963 ++ name;
17964 break;
17965 case GNU_BUILD_ATTRIBUTE_RELRO:
17966 text = _("<relro>");
1d15e434 17967 expected_types = bool_expected;
9ef920e9
NC
17968 ++ name;
17969 break;
17970 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
17971 text = _("<stack size>");
1d15e434 17972 expected_types = number_expected;
9ef920e9
NC
17973 ++ name;
17974 break;
17975 case GNU_BUILD_ATTRIBUTE_TOOL:
17976 text = _("<tool>");
1d15e434 17977 expected_types = string_expected;
9ef920e9
NC
17978 ++ name;
17979 break;
17980 case GNU_BUILD_ATTRIBUTE_ABI:
17981 text = _("<ABI>");
17982 expected_types = "$*";
17983 ++ name;
17984 break;
17985 case GNU_BUILD_ATTRIBUTE_PIC:
17986 text = _("<PIC>");
1d15e434 17987 expected_types = number_expected;
9ef920e9
NC
17988 ++ name;
17989 break;
a8be5506
NC
17990 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
17991 text = _("<short enum>");
1d15e434 17992 expected_types = bool_expected;
a8be5506
NC
17993 ++ name;
17994 break;
9ef920e9
NC
17995 default:
17996 if (ISPRINT (* name))
17997 {
17998 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
17999
18000 if (len > left && ! do_wide)
18001 len = left;
75d7d298 18002 printf ("%.*s:", len, name);
9ef920e9 18003 left -= len;
0dd6ae21 18004 name += len;
9ef920e9
NC
18005 }
18006 else
18007 {
3e6b6445 18008 static char tmpbuf [128];
88305e1b 18009
3e6b6445
NC
18010 error (_("unrecognised byte in name field: %d\n"), * name);
18011 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
18012 text = tmpbuf;
18013 name ++;
9ef920e9
NC
18014 }
18015 expected_types = "*$!+";
18016 break;
18017 }
18018
18019 if (text)
88305e1b 18020 left -= printf ("%s", text);
9ef920e9
NC
18021
18022 if (strchr (expected_types, name_type) == NULL)
75d7d298 18023 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
18024
18025 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
18026 {
18027 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
18028 (unsigned long) pnote->namesz,
18029 (long) (name - pnote->namedata));
18030 return FALSE;
18031 }
18032
18033 if (left < 1 && ! do_wide)
18034 return TRUE;
18035
18036 switch (name_type)
18037 {
18038 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
18039 {
b06b2c92 18040 unsigned int bytes;
ddef72cd
NC
18041 unsigned long long val = 0;
18042 unsigned int shift = 0;
18043 char * decoded = NULL;
18044
b06b2c92
NC
18045 bytes = pnote->namesz - (name - pnote->namedata);
18046 if (bytes > 0)
18047 /* The -1 is because the name field is always 0 terminated, and we
18048 want to be able to ensure that the shift in the while loop below
18049 will not overflow. */
18050 -- bytes;
18051
ddef72cd
NC
18052 if (bytes > sizeof (val))
18053 {
3e6b6445
NC
18054 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
18055 bytes);
18056 bytes = sizeof (val);
ddef72cd 18057 }
3e6b6445
NC
18058 /* We do not bother to warn if bytes == 0 as this can
18059 happen with some early versions of the gcc plugin. */
9ef920e9
NC
18060
18061 while (bytes --)
18062 {
79a964dc
NC
18063 unsigned long byte = (* name ++) & 0xff;
18064
18065 val |= byte << shift;
9ef920e9
NC
18066 shift += 8;
18067 }
18068
75d7d298 18069 switch (name_attribute)
9ef920e9 18070 {
75d7d298 18071 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
18072 switch (val)
18073 {
75d7d298
NC
18074 case 0: decoded = "static"; break;
18075 case 1: decoded = "pic"; break;
18076 case 2: decoded = "PIC"; break;
18077 case 3: decoded = "pie"; break;
18078 case 4: decoded = "PIE"; break;
18079 default: break;
9ef920e9 18080 }
75d7d298
NC
18081 break;
18082 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
18083 switch (val)
9ef920e9 18084 {
75d7d298
NC
18085 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
18086 case 0: decoded = "off"; break;
18087 case 1: decoded = "on"; break;
18088 case 2: decoded = "all"; break;
18089 case 3: decoded = "strong"; break;
18090 case 4: decoded = "explicit"; break;
18091 default: break;
9ef920e9 18092 }
75d7d298
NC
18093 break;
18094 default:
18095 break;
9ef920e9
NC
18096 }
18097
75d7d298 18098 if (decoded != NULL)
3e6b6445
NC
18099 {
18100 print_symbol (-left, decoded);
18101 left = 0;
18102 }
18103 else if (val == 0)
18104 {
18105 printf ("0x0");
18106 left -= 3;
18107 }
9ef920e9 18108 else
75d7d298
NC
18109 {
18110 if (do_wide)
ddef72cd 18111 left -= printf ("0x%llx", val);
75d7d298 18112 else
ddef72cd 18113 left -= printf ("0x%-.*llx", left, val);
75d7d298 18114 }
9ef920e9
NC
18115 }
18116 break;
18117 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
18118 left -= print_symbol (- left, name);
18119 break;
18120 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
18121 left -= print_symbol (- left, "true");
18122 break;
18123 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
18124 left -= print_symbol (- left, "false");
18125 break;
18126 }
18127
18128 if (do_wide && left > 0)
18129 printf ("%-*s", left, " ");
18130
18131 return TRUE;
18132}
18133
6d118b09
NC
18134/* Note that by the ELF standard, the name field is already null byte
18135 terminated, and namesz includes the terminating null byte.
18136 I.E. the value of namesz for the name "FSF" is 4.
18137
e3c8793a 18138 If the value of namesz is zero, there is no name present. */
9ef920e9 18139
32ec8896 18140static bfd_boolean
9ef920e9 18141process_note (Elf_Internal_Note * pnote,
dda8d76d 18142 Filedata * filedata)
779fe533 18143{
2cf0635d
NC
18144 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
18145 const char * nt;
9437c45b
JT
18146
18147 if (pnote->namesz == 0)
1ec5cd37
NC
18148 /* If there is no note name, then use the default set of
18149 note type strings. */
dda8d76d 18150 nt = get_note_type (filedata, pnote->type);
1ec5cd37 18151
1118d252
RM
18152 else if (const_strneq (pnote->namedata, "GNU"))
18153 /* GNU-specific object file notes. */
18154 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
18155
18156 else if (const_strneq (pnote->namedata, "FreeBSD"))
18157 /* FreeBSD-specific core file notes. */
dda8d76d 18158 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 18159
0112cd26 18160 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 18161 /* NetBSD-specific core file notes. */
dda8d76d 18162 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 18163
c6056a74
SF
18164 else if (const_strneq (pnote->namedata, "NetBSD"))
18165 /* NetBSD-specific core file notes. */
18166 return process_netbsd_elf_note (pnote);
18167
b15fa79e
AM
18168 else if (strneq (pnote->namedata, "SPU/", 4))
18169 {
18170 /* SPU-specific core file notes. */
18171 nt = pnote->namedata + 4;
18172 name = "SPU";
18173 }
18174
00e98fc7
TG
18175 else if (const_strneq (pnote->namedata, "IPF/VMS"))
18176 /* VMS/ia64-specific file notes. */
18177 nt = get_ia64_vms_note_type (pnote->type);
18178
70616151
TT
18179 else if (const_strneq (pnote->namedata, "stapsdt"))
18180 nt = get_stapsdt_note_type (pnote->type);
18181
9437c45b 18182 else
1ec5cd37
NC
18183 /* Don't recognize this note name; just use the default set of
18184 note type strings. */
dda8d76d 18185 nt = get_note_type (filedata, pnote->type);
9437c45b 18186
1449284b 18187 printf (" ");
9ef920e9 18188
483767a3
AM
18189 if (((const_strneq (pnote->namedata, "GA")
18190 && strchr ("*$!+", pnote->namedata[2]) != NULL)
18191 || strchr ("*$!+", pnote->namedata[0]) != NULL)
18192 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
18193 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
18194 print_gnu_build_attribute_name (pnote);
18195 else
18196 print_symbol (-20, name);
18197
18198 if (do_wide)
18199 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
18200 else
18201 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
18202
18203 if (const_strneq (pnote->namedata, "IPF/VMS"))
18204 return print_ia64_vms_note (pnote);
664f90a3 18205 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 18206 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
18207 else if (const_strneq (pnote->namedata, "stapsdt"))
18208 return print_stapsdt_note (pnote);
9ece1fa9
TT
18209 else if (const_strneq (pnote->namedata, "CORE"))
18210 return print_core_note (pnote);
483767a3
AM
18211 else if (((const_strneq (pnote->namedata, "GA")
18212 && strchr ("*$!+", pnote->namedata[2]) != NULL)
18213 || strchr ("*$!+", pnote->namedata[0]) != NULL)
18214 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
18215 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 18216 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 18217
9ef920e9 18218 if (pnote->descsz)
1449284b
NC
18219 {
18220 unsigned long i;
18221
18222 printf (_(" description data: "));
18223 for (i = 0; i < pnote->descsz; i++)
18224 printf ("%02x ", pnote->descdata[i]);
04ac15ab
AS
18225 if (!do_wide)
18226 printf ("\n");
1449284b
NC
18227 }
18228
9ef920e9
NC
18229 if (do_wide)
18230 printf ("\n");
18231
32ec8896 18232 return TRUE;
1449284b 18233}
6d118b09 18234
32ec8896 18235static bfd_boolean
dda8d76d
NC
18236process_notes_at (Filedata * filedata,
18237 Elf_Internal_Shdr * section,
18238 bfd_vma offset,
82ed9683
L
18239 bfd_vma length,
18240 bfd_vma align)
779fe533 18241{
2cf0635d
NC
18242 Elf_External_Note * pnotes;
18243 Elf_External_Note * external;
4dff97b2
NC
18244 char * end;
18245 bfd_boolean res = TRUE;
103f02d3 18246
779fe533 18247 if (length <= 0)
32ec8896 18248 return FALSE;
103f02d3 18249
1449284b
NC
18250 if (section)
18251 {
dda8d76d 18252 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 18253 if (pnotes)
32ec8896 18254 {
dda8d76d 18255 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
32ec8896
NC
18256 return FALSE;
18257 }
1449284b
NC
18258 }
18259 else
82ed9683 18260 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 18261 _("notes"));
4dff97b2 18262
dd24e3da 18263 if (pnotes == NULL)
32ec8896 18264 return FALSE;
779fe533 18265
103f02d3 18266 external = pnotes;
103f02d3 18267
1449284b 18268 if (section)
dda8d76d 18269 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
18270 else
18271 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
18272 (unsigned long) offset, (unsigned long) length);
18273
82ed9683
L
18274 /* NB: Some note sections may have alignment value of 0 or 1. gABI
18275 specifies that notes should be aligned to 4 bytes in 32-bit
18276 objects and to 8 bytes in 64-bit objects. As a Linux extension,
18277 we also support 4 byte alignment in 64-bit objects. If section
18278 alignment is less than 4, we treate alignment as 4 bytes. */
18279 if (align < 4)
18280 align = 4;
18281 else if (align != 4 && align != 8)
18282 {
18283 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
18284 (long) align);
18285 return FALSE;
18286 }
18287
2aee03ae 18288 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 18289
c8071705
NC
18290 end = (char *) pnotes + length;
18291 while ((char *) external < end)
779fe533 18292 {
b34976b6 18293 Elf_Internal_Note inote;
15b42fb0 18294 size_t min_notesz;
4dff97b2 18295 char * next;
2cf0635d 18296 char * temp = NULL;
c8071705 18297 size_t data_remaining = end - (char *) external;
6d118b09 18298
dda8d76d 18299 if (!is_ia64_vms (filedata))
15b42fb0 18300 {
9dd3a467
NC
18301 /* PR binutils/15191
18302 Make sure that there is enough data to read. */
15b42fb0
AM
18303 min_notesz = offsetof (Elf_External_Note, name);
18304 if (data_remaining < min_notesz)
9dd3a467 18305 {
d3a49aa8
AM
18306 warn (ngettext ("Corrupt note: only %ld byte remains, "
18307 "not enough for a full note\n",
18308 "Corrupt note: only %ld bytes remain, "
18309 "not enough for a full note\n",
18310 data_remaining),
18311 (long) data_remaining);
9dd3a467
NC
18312 break;
18313 }
5396a86e
AM
18314 data_remaining -= min_notesz;
18315
15b42fb0
AM
18316 inote.type = BYTE_GET (external->type);
18317 inote.namesz = BYTE_GET (external->namesz);
18318 inote.namedata = external->name;
18319 inote.descsz = BYTE_GET (external->descsz);
276da9b3 18320 inote.descdata = ((char *) external
4dff97b2 18321 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 18322 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 18323 next = ((char *) external
4dff97b2 18324 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 18325 }
00e98fc7 18326 else
15b42fb0
AM
18327 {
18328 Elf64_External_VMS_Note *vms_external;
00e98fc7 18329
9dd3a467
NC
18330 /* PR binutils/15191
18331 Make sure that there is enough data to read. */
15b42fb0
AM
18332 min_notesz = offsetof (Elf64_External_VMS_Note, name);
18333 if (data_remaining < min_notesz)
9dd3a467 18334 {
d3a49aa8
AM
18335 warn (ngettext ("Corrupt note: only %ld byte remains, "
18336 "not enough for a full note\n",
18337 "Corrupt note: only %ld bytes remain, "
18338 "not enough for a full note\n",
18339 data_remaining),
18340 (long) data_remaining);
9dd3a467
NC
18341 break;
18342 }
5396a86e 18343 data_remaining -= min_notesz;
3e55a963 18344
15b42fb0
AM
18345 vms_external = (Elf64_External_VMS_Note *) external;
18346 inote.type = BYTE_GET (vms_external->type);
18347 inote.namesz = BYTE_GET (vms_external->namesz);
18348 inote.namedata = vms_external->name;
18349 inote.descsz = BYTE_GET (vms_external->descsz);
18350 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
18351 inote.descpos = offset + (inote.descdata - (char *) pnotes);
18352 next = inote.descdata + align_power (inote.descsz, 3);
18353 }
18354
5396a86e
AM
18355 /* PR 17531: file: 3443835e. */
18356 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
18357 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
18358 || (size_t) (inote.descdata - inote.namedata) > data_remaining
18359 || (size_t) (next - inote.descdata) < inote.descsz
18360 || ((size_t) (next - inote.descdata)
18361 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 18362 {
15b42fb0 18363 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 18364 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
18365 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
18366 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
18367 break;
18368 }
18369
15b42fb0 18370 external = (Elf_External_Note *) next;
dd24e3da 18371
6d118b09
NC
18372 /* Verify that name is null terminated. It appears that at least
18373 one version of Linux (RedHat 6.0) generates corefiles that don't
18374 comply with the ELF spec by failing to include the null byte in
18375 namesz. */
8b971f9f 18376 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 18377 {
5396a86e 18378 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 18379 {
5396a86e
AM
18380 temp = (char *) malloc (inote.namesz + 1);
18381 if (temp == NULL)
18382 {
18383 error (_("Out of memory allocating space for inote name\n"));
18384 res = FALSE;
18385 break;
18386 }
76da6bbe 18387
5396a86e
AM
18388 memcpy (temp, inote.namedata, inote.namesz);
18389 inote.namedata = temp;
18390 }
18391 inote.namedata[inote.namesz] = 0;
6d118b09
NC
18392 }
18393
dda8d76d 18394 if (! process_note (& inote, filedata))
6b4bf3bc 18395 res = FALSE;
103f02d3 18396
6d118b09
NC
18397 if (temp != NULL)
18398 {
18399 free (temp);
18400 temp = NULL;
18401 }
779fe533
NC
18402 }
18403
18404 free (pnotes);
103f02d3 18405
779fe533
NC
18406 return res;
18407}
18408
32ec8896 18409static bfd_boolean
dda8d76d 18410process_corefile_note_segments (Filedata * filedata)
779fe533 18411{
2cf0635d 18412 Elf_Internal_Phdr * segment;
b34976b6 18413 unsigned int i;
32ec8896 18414 bfd_boolean res = TRUE;
103f02d3 18415
dda8d76d 18416 if (! get_program_headers (filedata))
6b4bf3bc 18417 return TRUE;
103f02d3 18418
dda8d76d
NC
18419 for (i = 0, segment = filedata->program_headers;
18420 i < filedata->file_header.e_phnum;
b34976b6 18421 i++, segment++)
779fe533
NC
18422 {
18423 if (segment->p_type == PT_NOTE)
dda8d76d 18424 if (! process_notes_at (filedata, NULL,
32ec8896 18425 (bfd_vma) segment->p_offset,
82ed9683
L
18426 (bfd_vma) segment->p_filesz,
18427 (bfd_vma) segment->p_align))
32ec8896 18428 res = FALSE;
779fe533 18429 }
103f02d3 18430
779fe533
NC
18431 return res;
18432}
18433
32ec8896 18434static bfd_boolean
dda8d76d 18435process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
18436{
18437 Elf_External_Note * pnotes;
18438 Elf_External_Note * external;
c8071705 18439 char * end;
32ec8896 18440 bfd_boolean res = TRUE;
685080f2
NC
18441
18442 if (length <= 0)
32ec8896 18443 return FALSE;
685080f2 18444
dda8d76d 18445 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
18446 _("v850 notes"));
18447 if (pnotes == NULL)
32ec8896 18448 return FALSE;
685080f2
NC
18449
18450 external = pnotes;
c8071705 18451 end = (char*) pnotes + length;
685080f2
NC
18452
18453 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
18454 (unsigned long) offset, (unsigned long) length);
18455
c8071705 18456 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
18457 {
18458 Elf_External_Note * next;
18459 Elf_Internal_Note inote;
18460
18461 inote.type = BYTE_GET (external->type);
18462 inote.namesz = BYTE_GET (external->namesz);
18463 inote.namedata = external->name;
18464 inote.descsz = BYTE_GET (external->descsz);
18465 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
18466 inote.descpos = offset + (inote.descdata - (char *) pnotes);
18467
c8071705
NC
18468 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
18469 {
18470 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
18471 inote.descdata = inote.namedata;
18472 inote.namesz = 0;
18473 }
18474
685080f2
NC
18475 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
18476
c8071705 18477 if ( ((char *) next > end)
685080f2
NC
18478 || ((char *) next < (char *) pnotes))
18479 {
18480 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
18481 (unsigned long) ((char *) external - (char *) pnotes));
18482 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
18483 inote.type, inote.namesz, inote.descsz);
18484 break;
18485 }
18486
18487 external = next;
18488
18489 /* Prevent out-of-bounds indexing. */
c8071705 18490 if ( inote.namedata + inote.namesz > end
685080f2
NC
18491 || inote.namedata + inote.namesz < inote.namedata)
18492 {
18493 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
18494 (unsigned long) ((char *) external - (char *) pnotes));
18495 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
18496 inote.type, inote.namesz, inote.descsz);
18497 break;
18498 }
18499
18500 printf (" %s: ", get_v850_elf_note_type (inote.type));
18501
18502 if (! print_v850_note (& inote))
18503 {
32ec8896 18504 res = FALSE;
685080f2
NC
18505 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
18506 inote.namesz, inote.descsz);
18507 }
18508 }
18509
18510 free (pnotes);
18511
18512 return res;
18513}
18514
32ec8896 18515static bfd_boolean
dda8d76d 18516process_note_sections (Filedata * filedata)
1ec5cd37 18517{
2cf0635d 18518 Elf_Internal_Shdr * section;
1ec5cd37 18519 unsigned long i;
32ec8896
NC
18520 unsigned int n = 0;
18521 bfd_boolean res = TRUE;
1ec5cd37 18522
dda8d76d
NC
18523 for (i = 0, section = filedata->section_headers;
18524 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 18525 i++, section++)
685080f2
NC
18526 {
18527 if (section->sh_type == SHT_NOTE)
18528 {
dda8d76d 18529 if (! process_notes_at (filedata, section,
32ec8896 18530 (bfd_vma) section->sh_offset,
82ed9683
L
18531 (bfd_vma) section->sh_size,
18532 (bfd_vma) section->sh_addralign))
32ec8896 18533 res = FALSE;
685080f2
NC
18534 n++;
18535 }
18536
dda8d76d
NC
18537 if (( filedata->file_header.e_machine == EM_V800
18538 || filedata->file_header.e_machine == EM_V850
18539 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
18540 && section->sh_type == SHT_RENESAS_INFO)
18541 {
dda8d76d 18542 if (! process_v850_notes (filedata,
32ec8896
NC
18543 (bfd_vma) section->sh_offset,
18544 (bfd_vma) section->sh_size))
18545 res = FALSE;
685080f2
NC
18546 n++;
18547 }
18548 }
df565f32
NC
18549
18550 if (n == 0)
18551 /* Try processing NOTE segments instead. */
dda8d76d 18552 return process_corefile_note_segments (filedata);
1ec5cd37
NC
18553
18554 return res;
18555}
18556
32ec8896 18557static bfd_boolean
dda8d76d 18558process_notes (Filedata * filedata)
779fe533
NC
18559{
18560 /* If we have not been asked to display the notes then do nothing. */
18561 if (! do_notes)
32ec8896 18562 return TRUE;
103f02d3 18563
dda8d76d
NC
18564 if (filedata->file_header.e_type != ET_CORE)
18565 return process_note_sections (filedata);
103f02d3 18566
779fe533 18567 /* No program headers means no NOTE segment. */
dda8d76d
NC
18568 if (filedata->file_header.e_phnum > 0)
18569 return process_corefile_note_segments (filedata);
779fe533 18570
1ec5cd37 18571 printf (_("No note segments present in the core file.\n"));
32ec8896 18572 return TRUE;
779fe533
NC
18573}
18574
60abdbed
NC
18575static unsigned char *
18576display_public_gnu_attributes (unsigned char * start,
18577 const unsigned char * const end)
18578{
18579 printf (_(" Unknown GNU attribute: %s\n"), start);
18580
18581 start += strnlen ((char *) start, end - start);
18582 display_raw_attribute (start, end);
18583
18584 return (unsigned char *) end;
18585}
18586
18587static unsigned char *
18588display_generic_attribute (unsigned char * start,
18589 unsigned int tag,
18590 const unsigned char * const end)
18591{
18592 if (tag == 0)
18593 return (unsigned char *) end;
18594
18595 return display_tag_value (tag, start, end);
18596}
18597
32ec8896 18598static bfd_boolean
dda8d76d 18599process_arch_specific (Filedata * filedata)
252b5132 18600{
a952a375 18601 if (! do_arch)
32ec8896 18602 return TRUE;
a952a375 18603
dda8d76d 18604 switch (filedata->file_header.e_machine)
252b5132 18605 {
53a346d8
CZ
18606 case EM_ARC:
18607 case EM_ARC_COMPACT:
18608 case EM_ARC_COMPACT2:
dda8d76d 18609 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
18610 display_arc_attribute,
18611 display_generic_attribute);
11c1ff18 18612 case EM_ARM:
dda8d76d 18613 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
18614 display_arm_attribute,
18615 display_generic_attribute);
18616
252b5132 18617 case EM_MIPS:
4fe85591 18618 case EM_MIPS_RS3_LE:
dda8d76d 18619 return process_mips_specific (filedata);
60abdbed
NC
18620
18621 case EM_MSP430:
dda8d76d
NC
18622 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
18623 display_msp430x_attribute,
18624 display_generic_attribute);
60abdbed 18625
35c08157 18626 case EM_NDS32:
dda8d76d 18627 return process_nds32_specific (filedata);
60abdbed 18628
34c8bcba 18629 case EM_PPC:
b82317dd 18630 case EM_PPC64:
dda8d76d 18631 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18632 display_power_gnu_attribute);
18633
643f7afb
AK
18634 case EM_S390:
18635 case EM_S390_OLD:
dda8d76d 18636 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18637 display_s390_gnu_attribute);
18638
9e8c70f9
DM
18639 case EM_SPARC:
18640 case EM_SPARC32PLUS:
18641 case EM_SPARCV9:
dda8d76d 18642 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18643 display_sparc_gnu_attribute);
18644
59e6276b 18645 case EM_TI_C6000:
dda8d76d 18646 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
18647 display_tic6x_attribute,
18648 display_generic_attribute);
18649
252b5132 18650 default:
dda8d76d 18651 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
18652 display_public_gnu_attributes,
18653 display_generic_attribute);
252b5132 18654 }
252b5132
RH
18655}
18656
32ec8896 18657static bfd_boolean
dda8d76d 18658get_file_header (Filedata * filedata)
252b5132 18659{
9ea033b2 18660 /* Read in the identity array. */
dda8d76d 18661 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18662 return FALSE;
252b5132 18663
9ea033b2 18664 /* Determine how to read the rest of the header. */
dda8d76d 18665 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 18666 {
1a0670f3
AM
18667 default:
18668 case ELFDATANONE:
adab8cdc
AO
18669 case ELFDATA2LSB:
18670 byte_get = byte_get_little_endian;
18671 byte_put = byte_put_little_endian;
18672 break;
18673 case ELFDATA2MSB:
18674 byte_get = byte_get_big_endian;
18675 byte_put = byte_put_big_endian;
18676 break;
9ea033b2
NC
18677 }
18678
18679 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 18680 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
18681
18682 /* Read in the rest of the header. */
18683 if (is_32bit_elf)
18684 {
18685 Elf32_External_Ehdr ehdr32;
252b5132 18686
dda8d76d 18687 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18688 return FALSE;
103f02d3 18689
dda8d76d
NC
18690 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
18691 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
18692 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
18693 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
18694 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
18695 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
18696 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
18697 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
18698 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
18699 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
18700 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
18701 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
18702 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 18703 }
252b5132 18704 else
9ea033b2
NC
18705 {
18706 Elf64_External_Ehdr ehdr64;
a952a375
NC
18707
18708 /* If we have been compiled with sizeof (bfd_vma) == 4, then
18709 we will not be able to cope with the 64bit data found in
18710 64 ELF files. Detect this now and abort before we start
50c2245b 18711 overwriting things. */
a952a375
NC
18712 if (sizeof (bfd_vma) < 8)
18713 {
e3c8793a
NC
18714 error (_("This instance of readelf has been built without support for a\n\
1871564 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 18716 return FALSE;
a952a375 18717 }
103f02d3 18718
dda8d76d 18719 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18720 return FALSE;
103f02d3 18721
dda8d76d
NC
18722 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
18723 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
18724 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
18725 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
18726 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
18727 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
18728 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
18729 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
18730 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
18731 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
18732 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
18733 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
18734 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 18735 }
252b5132 18736
dda8d76d 18737 if (filedata->file_header.e_shoff)
7ece0d85
JJ
18738 {
18739 /* There may be some extensions in the first section header. Don't
18740 bomb if we can't read it. */
18741 if (is_32bit_elf)
dda8d76d 18742 get_32bit_section_headers (filedata, TRUE);
7ece0d85 18743 else
dda8d76d 18744 get_64bit_section_headers (filedata, TRUE);
7ece0d85 18745 }
560f3c1c 18746
32ec8896 18747 return TRUE;
252b5132
RH
18748}
18749
dda8d76d
NC
18750static void
18751close_file (Filedata * filedata)
18752{
18753 if (filedata)
18754 {
18755 if (filedata->handle)
18756 fclose (filedata->handle);
18757 free (filedata);
18758 }
18759}
18760
18761void
18762close_debug_file (void * data)
18763{
18764 close_file ((Filedata *) data);
18765}
18766
18767static Filedata *
18768open_file (const char * pathname)
18769{
18770 struct stat statbuf;
18771 Filedata * filedata = NULL;
18772
18773 if (stat (pathname, & statbuf) < 0
18774 || ! S_ISREG (statbuf.st_mode))
18775 goto fail;
18776
18777 filedata = calloc (1, sizeof * filedata);
18778 if (filedata == NULL)
18779 goto fail;
18780
18781 filedata->handle = fopen (pathname, "rb");
18782 if (filedata->handle == NULL)
18783 goto fail;
18784
18785 filedata->file_size = (bfd_size_type) statbuf.st_size;
18786 filedata->file_name = pathname;
18787
18788 if (! get_file_header (filedata))
18789 goto fail;
18790
18791 if (filedata->file_header.e_shoff)
18792 {
18793 bfd_boolean res;
18794
18795 /* Read the section headers again, this time for real. */
18796 if (is_32bit_elf)
18797 res = get_32bit_section_headers (filedata, FALSE);
18798 else
18799 res = get_64bit_section_headers (filedata, FALSE);
18800
18801 if (!res)
18802 goto fail;
18803 }
18804
18805 return filedata;
18806
18807 fail:
18808 if (filedata)
18809 {
18810 if (filedata->handle)
18811 fclose (filedata->handle);
18812 free (filedata);
18813 }
18814 return NULL;
18815}
18816
18817void *
18818open_debug_file (const char * pathname)
18819{
18820 return open_file (pathname);
18821}
18822
fb52b2f4
NC
18823/* Process one ELF object file according to the command line options.
18824 This file may actually be stored in an archive. The file is
32ec8896
NC
18825 positioned at the start of the ELF object. Returns TRUE if no
18826 problems were encountered, FALSE otherwise. */
fb52b2f4 18827
32ec8896 18828static bfd_boolean
dda8d76d 18829process_object (Filedata * filedata)
252b5132 18830{
dda8d76d 18831 Filedata * separates;
252b5132 18832 unsigned int i;
32ec8896 18833 bfd_boolean res = TRUE;
252b5132 18834
dda8d76d 18835 if (! get_file_header (filedata))
252b5132 18836 {
dda8d76d 18837 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 18838 return FALSE;
252b5132
RH
18839 }
18840
18841 /* Initialise per file variables. */
60bca95a 18842 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
18843 version_info[i] = 0;
18844
60bca95a 18845 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 18846 dynamic_info[i] = 0;
5115b233 18847 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
18848
18849 /* Process the file. */
18850 if (show_name)
dda8d76d 18851 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 18852
18bd398b
NC
18853 /* Initialise the dump_sects array from the cmdline_dump_sects array.
18854 Note we do this even if cmdline_dump_sects is empty because we
18855 must make sure that the dump_sets array is zeroed out before each
18856 object file is processed. */
dda8d76d
NC
18857 if (filedata->num_dump_sects > cmdline.num_dump_sects)
18858 memset (filedata->dump_sects, 0, filedata->num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 18859
dda8d76d 18860 if (cmdline.num_dump_sects > 0)
18bd398b 18861 {
dda8d76d 18862 if (filedata->num_dump_sects == 0)
18bd398b 18863 /* A sneaky way of allocating the dump_sects array. */
dda8d76d 18864 request_dump_bynumber (filedata, cmdline.num_dump_sects, 0);
18bd398b 18865
dda8d76d
NC
18866 assert (filedata->num_dump_sects >= cmdline.num_dump_sects);
18867 memcpy (filedata->dump_sects, cmdline.dump_sects,
18868 cmdline.num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 18869 }
d70c5fc7 18870
dda8d76d 18871 if (! process_file_header (filedata))
32ec8896 18872 return FALSE;
252b5132 18873
dda8d76d 18874 if (! process_section_headers (filedata))
2f62977e 18875 {
32ec8896
NC
18876 /* Without loaded section headers we cannot process lots of things. */
18877 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 18878
2f62977e 18879 if (! do_using_dynamic)
32ec8896 18880 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 18881 }
252b5132 18882
dda8d76d 18883 if (! process_section_groups (filedata))
32ec8896
NC
18884 /* Without loaded section groups we cannot process unwind. */
18885 do_unwind = FALSE;
d1f5c6e3 18886
dda8d76d
NC
18887 if (process_program_headers (filedata))
18888 process_dynamic_section (filedata);
32ec8896
NC
18889 else
18890 res = FALSE;
252b5132 18891
dda8d76d 18892 if (! process_relocs (filedata))
32ec8896 18893 res = FALSE;
252b5132 18894
dda8d76d 18895 if (! process_unwind (filedata))
32ec8896 18896 res = FALSE;
4d6ed7c8 18897
dda8d76d 18898 if (! process_symbol_table (filedata))
32ec8896 18899 res = FALSE;
252b5132 18900
dda8d76d 18901 if (! process_syminfo (filedata))
32ec8896 18902 res = FALSE;
252b5132 18903
dda8d76d 18904 if (! process_version_sections (filedata))
32ec8896 18905 res = FALSE;
252b5132 18906
82ed9683
L
18907 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
18908 separates = load_separate_debug_file (filedata, filedata->file_name);
18909 else
18910 separates = NULL;
dda8d76d
NC
18911
18912 if (! process_section_contents (filedata))
32ec8896 18913 res = FALSE;
f5842774 18914
dda8d76d
NC
18915 if (separates)
18916 {
18917 if (! process_section_headers (separates))
18918 res = FALSE;
18919 else if (! process_section_contents (separates))
18920 res = FALSE;
18921 }
18922
18923 if (! process_notes (filedata))
32ec8896 18924 res = FALSE;
103f02d3 18925
dda8d76d 18926 if (! process_gnu_liblist (filedata))
32ec8896 18927 res = FALSE;
047b2264 18928
dda8d76d 18929 if (! process_arch_specific (filedata))
32ec8896 18930 res = FALSE;
252b5132 18931
dda8d76d
NC
18932 free (filedata->program_headers);
18933 filedata->program_headers = NULL;
d93f0186 18934
dda8d76d
NC
18935 free (filedata->section_headers);
18936 filedata->section_headers = NULL;
252b5132 18937
dda8d76d
NC
18938 free (filedata->string_table);
18939 filedata->string_table = NULL;
18940 filedata->string_table_length = 0;
252b5132
RH
18941
18942 if (dynamic_strings)
18943 {
18944 free (dynamic_strings);
18945 dynamic_strings = NULL;
d79b3d50 18946 dynamic_strings_length = 0;
252b5132
RH
18947 }
18948
18949 if (dynamic_symbols)
18950 {
18951 free (dynamic_symbols);
18952 dynamic_symbols = NULL;
19936277 18953 num_dynamic_syms = 0;
252b5132
RH
18954 }
18955
18956 if (dynamic_syminfo)
18957 {
18958 free (dynamic_syminfo);
18959 dynamic_syminfo = NULL;
18960 }
ff78d6d6 18961
293c573e
MR
18962 if (dynamic_section)
18963 {
18964 free (dynamic_section);
18965 dynamic_section = NULL;
18966 }
18967
e4b17d5c
L
18968 if (section_headers_groups)
18969 {
18970 free (section_headers_groups);
18971 section_headers_groups = NULL;
18972 }
18973
18974 if (section_groups)
18975 {
2cf0635d
NC
18976 struct group_list * g;
18977 struct group_list * next;
e4b17d5c
L
18978
18979 for (i = 0; i < group_count; i++)
18980 {
18981 for (g = section_groups [i].root; g != NULL; g = next)
18982 {
18983 next = g->next;
18984 free (g);
18985 }
18986 }
18987
18988 free (section_groups);
18989 section_groups = NULL;
18990 }
18991
19e6b90e 18992 free_debug_memory ();
18bd398b 18993
32ec8896 18994 return res;
252b5132
RH
18995}
18996
2cf0635d 18997/* Process an ELF archive.
32ec8896
NC
18998 On entry the file is positioned just after the ARMAG string.
18999 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 19000
32ec8896 19001static bfd_boolean
dda8d76d 19002process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
19003{
19004 struct archive_info arch;
19005 struct archive_info nested_arch;
19006 size_t got;
32ec8896 19007 bfd_boolean ret = TRUE;
2cf0635d 19008
32ec8896 19009 show_name = TRUE;
2cf0635d
NC
19010
19011 /* The ARCH structure is used to hold information about this archive. */
19012 arch.file_name = NULL;
19013 arch.file = NULL;
19014 arch.index_array = NULL;
19015 arch.sym_table = NULL;
19016 arch.longnames = NULL;
19017
19018 /* The NESTED_ARCH structure is used as a single-item cache of information
19019 about a nested archive (when members of a thin archive reside within
19020 another regular archive file). */
19021 nested_arch.file_name = NULL;
19022 nested_arch.file = NULL;
19023 nested_arch.index_array = NULL;
19024 nested_arch.sym_table = NULL;
19025 nested_arch.longnames = NULL;
19026
dda8d76d
NC
19027 if (setup_archive (&arch, filedata->file_name, filedata->handle,
19028 is_thin_archive, do_archive_index) != 0)
2cf0635d 19029 {
32ec8896 19030 ret = FALSE;
2cf0635d 19031 goto out;
4145f1d5 19032 }
fb52b2f4 19033
4145f1d5
NC
19034 if (do_archive_index)
19035 {
2cf0635d 19036 if (arch.sym_table == NULL)
dda8d76d 19037 error (_("%s: unable to dump the index as none was found\n"), filedata->file_name);
4145f1d5
NC
19038 else
19039 {
591f7597 19040 unsigned long i, l;
4145f1d5
NC
19041 unsigned long current_pos;
19042
591f7597 19043 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
dda8d76d
NC
19044 filedata->file_name, (unsigned long) arch.index_num, arch.sym_size);
19045
19046 current_pos = ftell (filedata->handle);
4145f1d5 19047
2cf0635d 19048 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 19049 {
2cf0635d
NC
19050 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
19051 {
19052 char * member_name;
4145f1d5 19053
2cf0635d
NC
19054 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
19055
19056 if (member_name != NULL)
19057 {
19058 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
19059
19060 if (qualified_name != NULL)
19061 {
c2a7d3f5
NC
19062 printf (_("Contents of binary %s at offset "), qualified_name);
19063 (void) print_vma (arch.index_array[i], PREFIX_HEX);
19064 putchar ('\n');
2cf0635d
NC
19065 free (qualified_name);
19066 }
4145f1d5
NC
19067 }
19068 }
2cf0635d
NC
19069
19070 if (l >= arch.sym_size)
4145f1d5
NC
19071 {
19072 error (_("%s: end of the symbol table reached before the end of the index\n"),
dda8d76d 19073 filedata->file_name);
32ec8896 19074 ret = FALSE;
cb8f3167 19075 break;
4145f1d5 19076 }
591f7597
NC
19077 /* PR 17531: file: 0b6630b2. */
19078 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
19079 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
19080 }
19081
67ce483b 19082 if (arch.uses_64bit_indices)
c2a7d3f5
NC
19083 l = (l + 7) & ~ 7;
19084 else
19085 l += l & 1;
19086
2cf0635d 19087 if (l < arch.sym_size)
32ec8896 19088 {
d3a49aa8
AM
19089 error (ngettext ("%s: %ld byte remains in the symbol table, "
19090 "but without corresponding entries in "
19091 "the index table\n",
19092 "%s: %ld bytes remain in the symbol table, "
19093 "but without corresponding entries in "
19094 "the index table\n",
19095 arch.sym_size - l),
dda8d76d 19096 filedata->file_name, arch.sym_size - l);
32ec8896
NC
19097 ret = FALSE;
19098 }
4145f1d5 19099
dda8d76d 19100 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 19101 {
dda8d76d
NC
19102 error (_("%s: failed to seek back to start of object files in the archive\n"),
19103 filedata->file_name);
32ec8896 19104 ret = FALSE;
2cf0635d 19105 goto out;
4145f1d5 19106 }
fb52b2f4 19107 }
4145f1d5
NC
19108
19109 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
19110 && !do_segments && !do_header && !do_dump && !do_version
19111 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 19112 && !do_section_groups && !do_dyn_syms)
2cf0635d 19113 {
32ec8896 19114 ret = TRUE; /* Archive index only. */
2cf0635d
NC
19115 goto out;
19116 }
fb52b2f4
NC
19117 }
19118
fb52b2f4
NC
19119 while (1)
19120 {
2cf0635d
NC
19121 char * name;
19122 size_t namelen;
19123 char * qualified_name;
19124
19125 /* Read the next archive header. */
dda8d76d 19126 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
2cf0635d 19127 {
dda8d76d 19128 error (_("%s: failed to seek to next archive header\n"), filedata->file_name);
32ec8896 19129 return FALSE;
2cf0635d 19130 }
dda8d76d 19131 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d
NC
19132 if (got != sizeof arch.arhdr)
19133 {
19134 if (got == 0)
19135 break;
dda8d76d 19136 error (_("%s: failed to read archive header\n"), filedata->file_name);
32ec8896 19137 ret = FALSE;
2cf0635d
NC
19138 break;
19139 }
19140 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
19141 {
19142 error (_("%s: did not find a valid archive header\n"), arch.file_name);
32ec8896 19143 ret = FALSE;
2cf0635d
NC
19144 break;
19145 }
19146
19147 arch.next_arhdr_offset += sizeof arch.arhdr;
19148
19149 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
19150 if (archive_file_size & 01)
19151 ++archive_file_size;
19152
19153 name = get_archive_member_name (&arch, &nested_arch);
19154 if (name == NULL)
fb52b2f4 19155 {
dda8d76d 19156 error (_("%s: bad archive file name\n"), filedata->file_name);
32ec8896 19157 ret = FALSE;
d989285c 19158 break;
fb52b2f4 19159 }
2cf0635d 19160 namelen = strlen (name);
fb52b2f4 19161
2cf0635d
NC
19162 qualified_name = make_qualified_name (&arch, &nested_arch, name);
19163 if (qualified_name == NULL)
fb52b2f4 19164 {
dda8d76d 19165 error (_("%s: bad archive file name\n"), filedata->file_name);
32ec8896 19166 ret = FALSE;
d989285c 19167 break;
fb52b2f4
NC
19168 }
19169
2cf0635d
NC
19170 if (is_thin_archive && arch.nested_member_origin == 0)
19171 {
19172 /* This is a proxy for an external member of a thin archive. */
dda8d76d
NC
19173 Filedata * member_filedata;
19174 char * member_file_name = adjust_relative_path
19175 (filedata->file_name, name, namelen);
32ec8896 19176
2cf0635d
NC
19177 if (member_file_name == NULL)
19178 {
32ec8896 19179 ret = FALSE;
2cf0635d
NC
19180 break;
19181 }
19182
dda8d76d
NC
19183 member_filedata = open_file (member_file_name);
19184 if (member_filedata == NULL)
2cf0635d
NC
19185 {
19186 error (_("Input file '%s' is not readable.\n"), member_file_name);
19187 free (member_file_name);
32ec8896 19188 ret = FALSE;
2cf0635d
NC
19189 break;
19190 }
19191
19192 archive_file_offset = arch.nested_member_origin;
dda8d76d 19193 member_filedata->file_name = qualified_name;
2cf0635d 19194
dda8d76d 19195 if (! process_object (member_filedata))
32ec8896 19196 ret = FALSE;
2cf0635d 19197
dda8d76d 19198 close_file (member_filedata);
2cf0635d
NC
19199 free (member_file_name);
19200 }
19201 else if (is_thin_archive)
19202 {
eb02c04d
PK
19203 Filedata thin_filedata;
19204
19205 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 19206
a043396b
NC
19207 /* PR 15140: Allow for corrupt thin archives. */
19208 if (nested_arch.file == NULL)
19209 {
19210 error (_("%s: contains corrupt thin archive: %s\n"),
dda8d76d 19211 filedata->file_name, name);
32ec8896 19212 ret = FALSE;
a043396b
NC
19213 break;
19214 }
19215
2cf0635d
NC
19216 /* This is a proxy for a member of a nested archive. */
19217 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
19218
19219 /* The nested archive file will have been opened and setup by
19220 get_archive_member_name. */
19221 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
19222 {
19223 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
32ec8896 19224 ret = FALSE;
2cf0635d
NC
19225 break;
19226 }
19227
dda8d76d
NC
19228 thin_filedata.handle = nested_arch.file;
19229 thin_filedata.file_name = qualified_name;
19230
19231 if (! process_object (& thin_filedata))
32ec8896 19232 ret = FALSE;
2cf0635d
NC
19233 }
19234 else
19235 {
19236 archive_file_offset = arch.next_arhdr_offset;
19237 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 19238
6a6196fc 19239 filedata->file_name = qualified_name;
dda8d76d 19240 if (! process_object (filedata))
32ec8896 19241 ret = FALSE;
2cf0635d 19242 }
fb52b2f4 19243
dda8d76d 19244 if (filedata->dump_sects != NULL)
2b52916e 19245 {
dda8d76d
NC
19246 free (filedata->dump_sects);
19247 filedata->dump_sects = NULL;
19248 filedata->num_dump_sects = 0;
2b52916e
L
19249 }
19250
2cf0635d 19251 free (qualified_name);
fb52b2f4
NC
19252 }
19253
4145f1d5 19254 out:
2cf0635d
NC
19255 if (nested_arch.file != NULL)
19256 fclose (nested_arch.file);
19257 release_archive (&nested_arch);
19258 release_archive (&arch);
fb52b2f4 19259
d989285c 19260 return ret;
fb52b2f4
NC
19261}
19262
32ec8896 19263static bfd_boolean
2cf0635d 19264process_file (char * file_name)
fb52b2f4 19265{
dda8d76d 19266 Filedata * filedata = NULL;
fb52b2f4
NC
19267 struct stat statbuf;
19268 char armag[SARMAG];
32ec8896 19269 bfd_boolean ret = TRUE;
fb52b2f4
NC
19270
19271 if (stat (file_name, &statbuf) < 0)
19272 {
f24ddbdd
NC
19273 if (errno == ENOENT)
19274 error (_("'%s': No such file\n"), file_name);
19275 else
19276 error (_("Could not locate '%s'. System error message: %s\n"),
19277 file_name, strerror (errno));
32ec8896 19278 return FALSE;
f24ddbdd
NC
19279 }
19280
19281 if (! S_ISREG (statbuf.st_mode))
19282 {
19283 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 19284 return FALSE;
fb52b2f4
NC
19285 }
19286
dda8d76d
NC
19287 filedata = calloc (1, sizeof * filedata);
19288 if (filedata == NULL)
19289 {
19290 error (_("Out of memory allocating file data structure\n"));
19291 return FALSE;
19292 }
19293
19294 filedata->file_name = file_name;
19295 filedata->handle = fopen (file_name, "rb");
19296 if (filedata->handle == NULL)
fb52b2f4 19297 {
f24ddbdd 19298 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 19299 free (filedata);
32ec8896 19300 return FALSE;
fb52b2f4
NC
19301 }
19302
dda8d76d 19303 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 19304 {
4145f1d5 19305 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
19306 fclose (filedata->handle);
19307 free (filedata);
32ec8896 19308 return FALSE;
fb52b2f4
NC
19309 }
19310
dda8d76d 19311 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 19312
fb52b2f4 19313 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 19314 {
dda8d76d 19315 if (! process_archive (filedata, FALSE))
32ec8896
NC
19316 ret = FALSE;
19317 }
2cf0635d 19318 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 19319 {
dda8d76d 19320 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
19321 ret = FALSE;
19322 }
fb52b2f4
NC
19323 else
19324 {
4145f1d5
NC
19325 if (do_archive_index)
19326 error (_("File %s is not an archive so its index cannot be displayed.\n"),
19327 file_name);
19328
dda8d76d 19329 rewind (filedata->handle);
fb52b2f4 19330 archive_file_size = archive_file_offset = 0;
32ec8896 19331
dda8d76d 19332 if (! process_object (filedata))
32ec8896 19333 ret = FALSE;
fb52b2f4
NC
19334 }
19335
dda8d76d
NC
19336 fclose (filedata->handle);
19337 free (filedata);
32ec8896 19338
fb52b2f4
NC
19339 return ret;
19340}
19341
252b5132
RH
19342#ifdef SUPPORT_DISASSEMBLY
19343/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 19344 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 19345 symbols. */
252b5132
RH
19346
19347void
2cf0635d 19348print_address (unsigned int addr, FILE * outfile)
252b5132
RH
19349{
19350 fprintf (outfile,"0x%8.8x", addr);
19351}
19352
e3c8793a 19353/* Needed by the i386 disassembler. */
dda8d76d 19354
252b5132
RH
19355void
19356db_task_printsym (unsigned int addr)
19357{
19358 print_address (addr, stderr);
19359}
19360#endif
19361
19362int
2cf0635d 19363main (int argc, char ** argv)
252b5132 19364{
ff78d6d6
L
19365 int err;
19366
252b5132
RH
19367#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
19368 setlocale (LC_MESSAGES, "");
3882b010
L
19369#endif
19370#if defined (HAVE_SETLOCALE)
19371 setlocale (LC_CTYPE, "");
252b5132
RH
19372#endif
19373 bindtextdomain (PACKAGE, LOCALEDIR);
19374 textdomain (PACKAGE);
19375
869b9d07
MM
19376 expandargv (&argc, &argv);
19377
dda8d76d
NC
19378 cmdline.file_name = "<cmdline>";
19379 parse_args (& cmdline, argc, argv);
59f14fc0 19380
18bd398b 19381 if (optind < (argc - 1))
32ec8896 19382 show_name = TRUE;
5656ba2c
L
19383 else if (optind >= argc)
19384 {
19385 warn (_("Nothing to do.\n"));
19386 usage (stderr);
19387 }
18bd398b 19388
32ec8896 19389 err = FALSE;
252b5132 19390 while (optind < argc)
32ec8896
NC
19391 if (! process_file (argv[optind++]))
19392 err = TRUE;
252b5132 19393
dda8d76d
NC
19394 if (cmdline.dump_sects != NULL)
19395 free (cmdline.dump_sects);
252b5132 19396
32ec8896 19397 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 19398}