]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
gdb: Remove support for SH-5/SH64
[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"
252b5132
RH
101#include "elf/d10v.h"
102#include "elf/d30v.h"
d172d4ba 103#include "elf/dlx.h"
cfb8c092 104#include "elf/epiphany.h"
252b5132 105#include "elf/fr30.h"
5c70f934 106#include "elf/frv.h"
3f8107ab 107#include "elf/ft32.h"
3b16e843
NC
108#include "elf/h8.h"
109#include "elf/hppa.h"
110#include "elf/i386.h"
3b16e843 111#include "elf/ia64.h"
1e4cf259 112#include "elf/ip2k.h"
84e94c90 113#include "elf/lm32.h"
1c0d3aa6 114#include "elf/iq2000.h"
49f58d10 115#include "elf/m32c.h"
3b16e843
NC
116#include "elf/m32r.h"
117#include "elf/m68k.h"
75751cd9 118#include "elf/m68hc11.h"
252b5132 119#include "elf/mcore.h"
15ab5209 120#include "elf/mep.h"
a3c62988 121#include "elf/metag.h"
7ba29e2a 122#include "elf/microblaze.h"
3b16e843 123#include "elf/mips.h"
3c3bdf30 124#include "elf/mmix.h"
3b16e843
NC
125#include "elf/mn10200.h"
126#include "elf/mn10300.h"
5506d11a 127#include "elf/moxie.h"
4970f871 128#include "elf/mt.h"
2469cfa2 129#include "elf/msp430.h"
35c08157 130#include "elf/nds32.h"
13761a11 131#include "elf/nios2.h"
73589c9d 132#include "elf/or1k.h"
7d466069 133#include "elf/pj.h"
3b16e843 134#include "elf/ppc.h"
c833c019 135#include "elf/ppc64.h"
2b100bb5 136#include "elf/pru.h"
03336641 137#include "elf/riscv.h"
99c513f6 138#include "elf/rl78.h"
c7927a3c 139#include "elf/rx.h"
a85d7ed0 140#include "elf/s390.h"
1c0d3aa6 141#include "elf/score.h"
3b16e843
NC
142#include "elf/sh.h"
143#include "elf/sparc.h"
e9f53129 144#include "elf/spu.h"
40b36596 145#include "elf/tic6x.h"
aa137e4d
NC
146#include "elf/tilegx.h"
147#include "elf/tilepro.h"
3b16e843 148#include "elf/v850.h"
179d3252 149#include "elf/vax.h"
619ed720 150#include "elf/visium.h"
f96bd6c2 151#include "elf/wasm32.h"
3b16e843 152#include "elf/x86-64.h"
c29aca4a 153#include "elf/xc16x.h"
f6c1a2d5 154#include "elf/xgate.h"
93fbbb04 155#include "elf/xstormy16.h"
88da6820 156#include "elf/xtensa.h"
252b5132 157
252b5132 158#include "getopt.h"
566b0d53 159#include "libiberty.h"
09c11c86 160#include "safe-ctype.h"
2cf0635d 161#include "filenames.h"
252b5132 162
15b42fb0
AM
163#ifndef offsetof
164#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
165#endif
166
6a40cf0c
NC
167typedef struct elf_section_list
168{
dda8d76d
NC
169 Elf_Internal_Shdr * hdr;
170 struct elf_section_list * next;
6a40cf0c
NC
171} elf_section_list;
172
dda8d76d
NC
173/* Flag bits indicating particular types of dump. */
174#define HEX_DUMP (1 << 0) /* The -x command line switch. */
175#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
176#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
177#define STRING_DUMP (1 << 3) /* The -p command line switch. */
178#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
179
180typedef unsigned char dump_type;
181
182/* A linked list of the section names for which dumps were requested. */
183struct dump_list_entry
184{
185 char * name;
186 dump_type type;
187 struct dump_list_entry * next;
188};
189
190typedef struct filedata
191{
192 const char * file_name;
193 FILE * handle;
194 bfd_size_type file_size;
195 Elf_Internal_Ehdr file_header;
196 Elf_Internal_Shdr * section_headers;
197 Elf_Internal_Phdr * program_headers;
198 char * string_table;
199 unsigned long string_table_length;
200 /* A dynamic array of flags indicating for which sections a dump of
201 some kind has been requested. It is reset on a per-object file
202 basis and then initialised from the cmdline_dump_sects array,
203 the results of interpreting the -w switch, and the
204 dump_sects_byname list. */
205 dump_type * dump_sects;
206 unsigned int num_dump_sects;
207} Filedata;
208
2cf0635d 209char * program_name = "readelf";
dda8d76d 210
c9c1d674 211static unsigned long archive_file_offset;
85b1c36d
BE
212static unsigned long archive_file_size;
213static unsigned long dynamic_addr;
214static bfd_size_type dynamic_size;
8b73c356 215static size_t dynamic_nent;
2cf0635d 216static char * dynamic_strings;
85b1c36d 217static unsigned long dynamic_strings_length;
85b1c36d 218static unsigned long num_dynamic_syms;
2cf0635d
NC
219static Elf_Internal_Sym * dynamic_symbols;
220static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
221static unsigned long dynamic_syminfo_offset;
222static unsigned int dynamic_syminfo_nent;
f8eae8b2 223static char program_interpreter[PATH_MAX];
bb8a0291 224static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 225static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d 226static bfd_vma version_info[16];
2cf0635d 227static Elf_Internal_Dyn * dynamic_section;
6a40cf0c 228static elf_section_list * symtab_shndx_list;
32ec8896
NC
229static bfd_boolean show_name = FALSE;
230static bfd_boolean do_dynamic = FALSE;
231static bfd_boolean do_syms = FALSE;
232static bfd_boolean do_dyn_syms = FALSE;
233static bfd_boolean do_reloc = FALSE;
234static bfd_boolean do_sections = FALSE;
235static bfd_boolean do_section_groups = FALSE;
236static bfd_boolean do_section_details = FALSE;
237static bfd_boolean do_segments = FALSE;
238static bfd_boolean do_unwind = FALSE;
239static bfd_boolean do_using_dynamic = FALSE;
240static bfd_boolean do_header = FALSE;
241static bfd_boolean do_dump = FALSE;
242static bfd_boolean do_version = FALSE;
243static bfd_boolean do_histogram = FALSE;
244static bfd_boolean do_debugging = FALSE;
245static bfd_boolean do_arch = FALSE;
246static bfd_boolean do_notes = FALSE;
247static bfd_boolean do_archive_index = FALSE;
248static bfd_boolean is_32bit_elf = FALSE;
249static bfd_boolean decompress_dumps = FALSE;
252b5132 250
e4b17d5c
L
251struct group_list
252{
dda8d76d
NC
253 struct group_list * next;
254 unsigned int section_index;
e4b17d5c
L
255};
256
257struct group
258{
dda8d76d
NC
259 struct group_list * root;
260 unsigned int group_index;
e4b17d5c
L
261};
262
dda8d76d
NC
263static size_t group_count;
264static struct group * section_groups;
265static struct group ** section_headers_groups;
aef1f6d0 266
09c11c86
NC
267/* A dynamic array of flags indicating for which sections a dump
268 has been requested via command line switches. */
dda8d76d 269static Filedata cmdline;
252b5132 270
dda8d76d 271static struct dump_list_entry * dump_sects_byname;
252b5132 272
c256ffe7 273/* How to print a vma value. */
843dd992
NC
274typedef enum print_mode
275{
276 HEX,
277 DEC,
278 DEC_5,
279 UNSIGNED,
280 PREFIX_HEX,
281 FULL_HEX,
282 LONG_HEX
283}
284print_mode;
285
bb4d2ac2
L
286/* Versioned symbol info. */
287enum versioned_symbol_info
288{
289 symbol_undefined,
290 symbol_hidden,
291 symbol_public
292};
293
32ec8896 294static const char * get_symbol_version_string
dda8d76d 295 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 296 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 297
9c19a809
NC
298#define UNKNOWN -1
299
2b692964
NC
300#define SECTION_NAME(X) \
301 ((X) == NULL ? _("<none>") \
dda8d76d
NC
302 : filedata->string_table == NULL ? _("<no-strings>") \
303 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
304 : filedata->string_table + (X)->sh_name))
252b5132 305
ee42cf8c 306#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 307
ba5cdace
NC
308#define GET_ELF_SYMBOLS(file, section, sym_count) \
309 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
310 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 311
d79b3d50
NC
312#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
313/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
314 already been called and verified that the string exists. */
315#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 316
61865e30
NC
317#define REMOVE_ARCH_BITS(ADDR) \
318 do \
319 { \
dda8d76d 320 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
321 (ADDR) &= ~1; \
322 } \
323 while (0)
d79b3d50 324\f
66cfc0fd
AM
325/* Print a BFD_VMA to an internal buffer, for use in error messages.
326 BFD_FMA_FMT can't be used in translated strings. */
327
328static const char *
329bfd_vmatoa (char *fmtch, bfd_vma value)
330{
331 /* bfd_vmatoa is used more then once in a printf call for output.
332 Cycle through an array of buffers. */
333 static int buf_pos = 0;
334 static struct bfd_vmatoa_buf
335 {
336 char place[64];
337 } buf[4];
338 char *ret;
339 char fmt[32];
340
341 ret = buf[buf_pos++].place;
342 buf_pos %= ARRAY_SIZE (buf);
343
344 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
345 snprintf (ret, sizeof (buf[0].place), fmt, value);
346 return ret;
347}
348
dda8d76d
NC
349/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
350 OFFSET + the offset of the current archive member, if we are examining an
351 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
352 allocate a buffer using malloc and fill that. In either case return the
353 pointer to the start of the retrieved data or NULL if something went wrong.
354 If something does go wrong and REASON is not NULL then emit an error
355 message using REASON as part of the context. */
59245841 356
c256ffe7 357static void *
dda8d76d
NC
358get_data (void * var,
359 Filedata * filedata,
360 unsigned long offset,
361 bfd_size_type size,
362 bfd_size_type nmemb,
363 const char * reason)
a6e9f9df 364{
2cf0635d 365 void * mvar;
57028622 366 bfd_size_type amt = size * nmemb;
a6e9f9df 367
c256ffe7 368 if (size == 0 || nmemb == 0)
a6e9f9df
AM
369 return NULL;
370
57028622
NC
371 /* If the size_t type is smaller than the bfd_size_type, eg because
372 you are building a 32-bit tool on a 64-bit host, then make sure
373 that when the sizes are cast to (size_t) no information is lost. */
374 if (sizeof (size_t) < sizeof (bfd_size_type)
375 && ( (bfd_size_type) ((size_t) size) != size
376 || (bfd_size_type) ((size_t) nmemb) != nmemb))
377 {
378 if (reason)
66cfc0fd
AM
379 error (_("Size truncation prevents reading %s"
380 " elements of size %s for %s\n"),
381 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
382 return NULL;
383 }
384
385 /* Check for size overflow. */
386 if (amt < nmemb)
387 {
388 if (reason)
66cfc0fd
AM
389 error (_("Size overflow prevents reading %s"
390 " elements of size %s for %s\n"),
391 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
392 return NULL;
393 }
394
c9c1d674
EG
395 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
396 attempting to allocate memory when the read is bound to fail. */
dda8d76d
NC
397 if (amt > filedata->file_size
398 || offset + archive_file_offset + amt > filedata->file_size)
a6e9f9df 399 {
049b0c3a 400 if (reason)
66cfc0fd
AM
401 error (_("Reading %s bytes extends past end of file for %s\n"),
402 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
403 return NULL;
404 }
405
dda8d76d 406 if (fseek (filedata->handle, archive_file_offset + offset, SEEK_SET))
071436c6
NC
407 {
408 if (reason)
c9c1d674 409 error (_("Unable to seek to 0x%lx for %s\n"),
ed754a13 410 archive_file_offset + offset, reason);
071436c6
NC
411 return NULL;
412 }
413
a6e9f9df
AM
414 mvar = var;
415 if (mvar == NULL)
416 {
c256ffe7 417 /* Check for overflow. */
57028622 418 if (nmemb < (~(bfd_size_type) 0 - 1) / size)
c256ffe7 419 /* + 1 so that we can '\0' terminate invalid string table sections. */
57028622 420 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
421
422 if (mvar == NULL)
423 {
049b0c3a 424 if (reason)
66cfc0fd
AM
425 error (_("Out of memory allocating %s bytes for %s\n"),
426 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
427 return NULL;
428 }
c256ffe7 429
c9c1d674 430 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
431 }
432
dda8d76d 433 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 434 {
049b0c3a 435 if (reason)
66cfc0fd
AM
436 error (_("Unable to read in %s bytes of %s\n"),
437 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
438 if (mvar != var)
439 free (mvar);
440 return NULL;
441 }
442
443 return mvar;
444}
445
32ec8896
NC
446/* Print a VMA value in the MODE specified.
447 Returns the number of characters displayed. */
cb8f3167 448
32ec8896 449static unsigned int
14a91970 450print_vma (bfd_vma vma, print_mode mode)
66543521 451{
32ec8896 452 unsigned int nc = 0;
66543521 453
14a91970 454 switch (mode)
66543521 455 {
14a91970
AM
456 case FULL_HEX:
457 nc = printf ("0x");
1a0670f3 458 /* Fall through. */
14a91970 459 case LONG_HEX:
f7a99963 460#ifdef BFD64
14a91970 461 if (is_32bit_elf)
437c2fb7 462 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 463#endif
14a91970
AM
464 printf_vma (vma);
465 return nc + 16;
b19aac67 466
14a91970
AM
467 case DEC_5:
468 if (vma <= 99999)
469 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 470 /* Fall through. */
14a91970
AM
471 case PREFIX_HEX:
472 nc = printf ("0x");
1a0670f3 473 /* Fall through. */
14a91970
AM
474 case HEX:
475 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 476
14a91970
AM
477 case DEC:
478 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 479
14a91970
AM
480 case UNSIGNED:
481 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
482
483 default:
484 /* FIXME: Report unrecognised mode ? */
485 return 0;
f7a99963 486 }
f7a99963
NC
487}
488
7bfd842d 489/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 490 multibye characters (assuming the host environment supports them).
31104126 491
7bfd842d
NC
492 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
493
494 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
495 padding as necessary.
171191ba
NC
496
497 Returns the number of emitted characters. */
498
499static unsigned int
32ec8896 500print_symbol (signed int width, const char *symbol)
31104126 501{
171191ba 502 bfd_boolean extra_padding = FALSE;
32ec8896 503 signed int num_printed = 0;
3bfcb652 504#ifdef HAVE_MBSTATE_T
7bfd842d 505 mbstate_t state;
3bfcb652 506#endif
32ec8896 507 unsigned int width_remaining;
961c521f 508
7bfd842d 509 if (width < 0)
961c521f 510 {
88305e1b 511 /* Keep the width positive. This helps the code below. */
961c521f 512 width = - width;
171191ba 513 extra_padding = TRUE;
0b4362b0 514 }
74e1a04b 515 assert (width != 0);
961c521f 516
7bfd842d
NC
517 if (do_wide)
518 /* Set the remaining width to a very large value.
519 This simplifies the code below. */
520 width_remaining = INT_MAX;
521 else
522 width_remaining = width;
cb8f3167 523
3bfcb652 524#ifdef HAVE_MBSTATE_T
7bfd842d
NC
525 /* Initialise the multibyte conversion state. */
526 memset (& state, 0, sizeof (state));
3bfcb652 527#endif
961c521f 528
7bfd842d
NC
529 while (width_remaining)
530 {
531 size_t n;
7bfd842d 532 const char c = *symbol++;
961c521f 533
7bfd842d 534 if (c == 0)
961c521f
NC
535 break;
536
7bfd842d
NC
537 /* Do not print control characters directly as they can affect terminal
538 settings. Such characters usually appear in the names generated
539 by the assembler for local labels. */
540 if (ISCNTRL (c))
961c521f 541 {
7bfd842d 542 if (width_remaining < 2)
961c521f
NC
543 break;
544
7bfd842d
NC
545 printf ("^%c", c + 0x40);
546 width_remaining -= 2;
171191ba 547 num_printed += 2;
961c521f 548 }
7bfd842d
NC
549 else if (ISPRINT (c))
550 {
551 putchar (c);
552 width_remaining --;
553 num_printed ++;
554 }
961c521f
NC
555 else
556 {
3bfcb652
NC
557#ifdef HAVE_MBSTATE_T
558 wchar_t w;
559#endif
7bfd842d
NC
560 /* Let printf do the hard work of displaying multibyte characters. */
561 printf ("%.1s", symbol - 1);
562 width_remaining --;
563 num_printed ++;
564
3bfcb652 565#ifdef HAVE_MBSTATE_T
7bfd842d
NC
566 /* Try to find out how many bytes made up the character that was
567 just printed. Advance the symbol pointer past the bytes that
568 were displayed. */
569 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
570#else
571 n = 1;
572#endif
7bfd842d
NC
573 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
574 symbol += (n - 1);
961c521f 575 }
961c521f 576 }
171191ba 577
7bfd842d 578 if (extra_padding && num_printed < width)
171191ba
NC
579 {
580 /* Fill in the remaining spaces. */
7bfd842d
NC
581 printf ("%-*s", width - num_printed, " ");
582 num_printed = width;
171191ba
NC
583 }
584
585 return num_printed;
31104126
NC
586}
587
1449284b 588/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
589 the given section's name. Like print_symbol, except that it does not try
590 to print multibyte characters, it just interprets them as hex values. */
591
592static const char *
dda8d76d 593printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
594{
595#define MAX_PRINT_SEC_NAME_LEN 128
596 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
597 const char * name = SECTION_NAME (sec);
598 char * buf = sec_name_buf;
599 char c;
600 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
601
602 while ((c = * name ++) != 0)
603 {
604 if (ISCNTRL (c))
605 {
606 if (remaining < 2)
607 break;
948f632f 608
74e1a04b
NC
609 * buf ++ = '^';
610 * buf ++ = c + 0x40;
611 remaining -= 2;
612 }
613 else if (ISPRINT (c))
614 {
615 * buf ++ = c;
616 remaining -= 1;
617 }
618 else
619 {
620 static char hex[17] = "0123456789ABCDEF";
621
622 if (remaining < 4)
623 break;
624 * buf ++ = '<';
625 * buf ++ = hex[(c & 0xf0) >> 4];
626 * buf ++ = hex[c & 0x0f];
627 * buf ++ = '>';
628 remaining -= 4;
629 }
630
631 if (remaining == 0)
632 break;
633 }
634
635 * buf = 0;
636 return sec_name_buf;
637}
638
639static const char *
dda8d76d 640printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 641{
dda8d76d 642 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
643 return _("<corrupt>");
644
dda8d76d 645 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
646}
647
89fac5e3
RS
648/* Return a pointer to section NAME, or NULL if no such section exists. */
649
650static Elf_Internal_Shdr *
dda8d76d 651find_section (Filedata * filedata, const char * name)
89fac5e3
RS
652{
653 unsigned int i;
654
68807c3c
NC
655 if (filedata->section_headers == NULL)
656 return NULL;
dda8d76d
NC
657
658 for (i = 0; i < filedata->file_header.e_shnum; i++)
659 if (streq (SECTION_NAME (filedata->section_headers + i), name))
660 return filedata->section_headers + i;
89fac5e3
RS
661
662 return NULL;
663}
664
0b6ae522
DJ
665/* Return a pointer to a section containing ADDR, or NULL if no such
666 section exists. */
667
668static Elf_Internal_Shdr *
dda8d76d 669find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
670{
671 unsigned int i;
672
68807c3c
NC
673 if (filedata->section_headers == NULL)
674 return NULL;
675
dda8d76d 676 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 677 {
dda8d76d
NC
678 Elf_Internal_Shdr *sec = filedata->section_headers + i;
679
0b6ae522
DJ
680 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
681 return sec;
682 }
683
684 return NULL;
685}
686
071436c6 687static Elf_Internal_Shdr *
dda8d76d 688find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
689{
690 unsigned int i;
691
68807c3c
NC
692 if (filedata->section_headers == NULL)
693 return NULL;
694
dda8d76d 695 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 696 {
dda8d76d
NC
697 Elf_Internal_Shdr *sec = filedata->section_headers + i;
698
071436c6
NC
699 if (sec->sh_type == type)
700 return sec;
701 }
702
703 return NULL;
704}
705
657d0d47
CC
706/* Return a pointer to section NAME, or NULL if no such section exists,
707 restricted to the list of sections given in SET. */
708
709static Elf_Internal_Shdr *
dda8d76d 710find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
711{
712 unsigned int i;
713
68807c3c
NC
714 if (filedata->section_headers == NULL)
715 return NULL;
716
657d0d47
CC
717 if (set != NULL)
718 {
719 while ((i = *set++) > 0)
b814a36d
NC
720 {
721 /* See PR 21156 for a reproducer. */
dda8d76d 722 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
723 continue; /* FIXME: Should we issue an error message ? */
724
dda8d76d
NC
725 if (streq (SECTION_NAME (filedata->section_headers + i), name))
726 return filedata->section_headers + i;
b814a36d 727 }
657d0d47
CC
728 }
729
dda8d76d 730 return find_section (filedata, name);
657d0d47
CC
731}
732
32ec8896
NC
733/* Read an unsigned LEB128 encoded value from DATA.
734 Set *LENGTH_RETURN to the number of bytes read. */
0b6ae522 735
f6f0e17b 736static inline unsigned long
32ec8896
NC
737read_uleb128 (unsigned char * data,
738 unsigned int * length_return,
f6f0e17b 739 const unsigned char * const end)
0b6ae522 740{
f6f0e17b 741 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
742}
743
32ec8896 744/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
745 This OS has so many departures from the ELF standard that we test it at
746 many places. */
747
32ec8896 748static inline bfd_boolean
dda8d76d 749is_ia64_vms (Filedata * filedata)
28f997cf 750{
dda8d76d
NC
751 return filedata->file_header.e_machine == EM_IA_64
752 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
753}
754
bcedfee6 755/* Guess the relocation size commonly used by the specific machines. */
252b5132 756
32ec8896 757static bfd_boolean
2dc4cec1 758guess_is_rela (unsigned int e_machine)
252b5132 759{
9c19a809 760 switch (e_machine)
252b5132
RH
761 {
762 /* Targets that use REL relocations. */
252b5132 763 case EM_386:
22abe556 764 case EM_IAMCU:
e9f53129 765 case EM_ARM:
2b0337b0 766 case EM_D10V:
252b5132 767 case EM_CYGNUS_D10V:
e9f53129 768 case EM_DLX:
252b5132 769 case EM_MIPS:
4fe85591 770 case EM_MIPS_RS3_LE:
e9f53129 771 case EM_CYGNUS_M32R:
1c0d3aa6 772 case EM_SCORE:
f6c1a2d5 773 case EM_XGATE:
9c19a809 774 return FALSE;
103f02d3 775
252b5132
RH
776 /* Targets that use RELA relocations. */
777 case EM_68K:
a06ea964 778 case EM_AARCH64:
cfb8c092 779 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
780 case EM_ALPHA:
781 case EM_ALTERA_NIOS2:
886a2506
NC
782 case EM_ARC:
783 case EM_ARC_COMPACT:
784 case EM_ARC_COMPACT2:
e9f53129
AM
785 case EM_AVR:
786 case EM_AVR_OLD:
787 case EM_BLACKFIN:
60bca95a 788 case EM_CR16:
e9f53129
AM
789 case EM_CRIS:
790 case EM_CRX:
2b0337b0 791 case EM_D30V:
252b5132 792 case EM_CYGNUS_D30V:
2b0337b0 793 case EM_FR30:
3f8107ab 794 case EM_FT32:
252b5132 795 case EM_CYGNUS_FR30:
5c70f934 796 case EM_CYGNUS_FRV:
e9f53129
AM
797 case EM_H8S:
798 case EM_H8_300:
799 case EM_H8_300H:
800eeca4 800 case EM_IA_64:
1e4cf259
NC
801 case EM_IP2K:
802 case EM_IP2K_OLD:
3b36097d 803 case EM_IQ2000:
84e94c90 804 case EM_LATTICEMICO32:
ff7eeb89 805 case EM_M32C_OLD:
49f58d10 806 case EM_M32C:
e9f53129
AM
807 case EM_M32R:
808 case EM_MCORE:
15ab5209 809 case EM_CYGNUS_MEP:
a3c62988 810 case EM_METAG:
e9f53129
AM
811 case EM_MMIX:
812 case EM_MN10200:
813 case EM_CYGNUS_MN10200:
814 case EM_MN10300:
815 case EM_CYGNUS_MN10300:
5506d11a 816 case EM_MOXIE:
e9f53129
AM
817 case EM_MSP430:
818 case EM_MSP430_OLD:
d031aafb 819 case EM_MT:
35c08157 820 case EM_NDS32:
64fd6348 821 case EM_NIOS32:
73589c9d 822 case EM_OR1K:
e9f53129
AM
823 case EM_PPC64:
824 case EM_PPC:
2b100bb5 825 case EM_TI_PRU:
e23eba97 826 case EM_RISCV:
99c513f6 827 case EM_RL78:
c7927a3c 828 case EM_RX:
e9f53129
AM
829 case EM_S390:
830 case EM_S390_OLD:
831 case EM_SH:
832 case EM_SPARC:
833 case EM_SPARC32PLUS:
834 case EM_SPARCV9:
835 case EM_SPU:
40b36596 836 case EM_TI_C6000:
aa137e4d
NC
837 case EM_TILEGX:
838 case EM_TILEPRO:
708e2187 839 case EM_V800:
e9f53129
AM
840 case EM_V850:
841 case EM_CYGNUS_V850:
842 case EM_VAX:
619ed720 843 case EM_VISIUM:
e9f53129 844 case EM_X86_64:
8a9036a4 845 case EM_L1OM:
7a9068fe 846 case EM_K1OM:
e9f53129
AM
847 case EM_XSTORMY16:
848 case EM_XTENSA:
849 case EM_XTENSA_OLD:
7ba29e2a
NC
850 case EM_MICROBLAZE:
851 case EM_MICROBLAZE_OLD:
f96bd6c2 852 case EM_WEBASSEMBLY:
9c19a809 853 return TRUE;
103f02d3 854
e9f53129
AM
855 case EM_68HC05:
856 case EM_68HC08:
857 case EM_68HC11:
858 case EM_68HC16:
859 case EM_FX66:
860 case EM_ME16:
d1133906 861 case EM_MMA:
d1133906
NC
862 case EM_NCPU:
863 case EM_NDR1:
e9f53129 864 case EM_PCP:
d1133906 865 case EM_ST100:
e9f53129 866 case EM_ST19:
d1133906 867 case EM_ST7:
e9f53129
AM
868 case EM_ST9PLUS:
869 case EM_STARCORE:
d1133906 870 case EM_SVX:
e9f53129 871 case EM_TINYJ:
9c19a809
NC
872 default:
873 warn (_("Don't know about relocations on this machine architecture\n"));
874 return FALSE;
875 }
876}
252b5132 877
dda8d76d 878/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
879 Returns TRUE upon success, FALSE otherwise. If successful then a
880 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
881 and the number of relocs loaded is placed in *NRELASP. It is the caller's
882 responsibility to free the allocated buffer. */
883
884static bfd_boolean
dda8d76d
NC
885slurp_rela_relocs (Filedata * filedata,
886 unsigned long rel_offset,
887 unsigned long rel_size,
888 Elf_Internal_Rela ** relasp,
889 unsigned long * nrelasp)
9c19a809 890{
2cf0635d 891 Elf_Internal_Rela * relas;
8b73c356 892 size_t nrelas;
4d6ed7c8 893 unsigned int i;
252b5132 894
4d6ed7c8
NC
895 if (is_32bit_elf)
896 {
2cf0635d 897 Elf32_External_Rela * erelas;
103f02d3 898
dda8d76d 899 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 900 rel_size, _("32-bit relocation data"));
a6e9f9df 901 if (!erelas)
32ec8896 902 return FALSE;
252b5132 903
4d6ed7c8 904 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 905
3f5e193b
NC
906 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
907 sizeof (Elf_Internal_Rela));
103f02d3 908
4d6ed7c8
NC
909 if (relas == NULL)
910 {
c256ffe7 911 free (erelas);
591a748a 912 error (_("out of memory parsing relocs\n"));
32ec8896 913 return FALSE;
4d6ed7c8 914 }
103f02d3 915
4d6ed7c8
NC
916 for (i = 0; i < nrelas; i++)
917 {
918 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
919 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 920 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 921 }
103f02d3 922
4d6ed7c8
NC
923 free (erelas);
924 }
925 else
926 {
2cf0635d 927 Elf64_External_Rela * erelas;
103f02d3 928
dda8d76d 929 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 930 rel_size, _("64-bit relocation data"));
a6e9f9df 931 if (!erelas)
32ec8896 932 return FALSE;
4d6ed7c8
NC
933
934 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 935
3f5e193b
NC
936 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
937 sizeof (Elf_Internal_Rela));
103f02d3 938
4d6ed7c8
NC
939 if (relas == NULL)
940 {
c256ffe7 941 free (erelas);
591a748a 942 error (_("out of memory parsing relocs\n"));
32ec8896 943 return FALSE;
9c19a809 944 }
4d6ed7c8
NC
945
946 for (i = 0; i < nrelas; i++)
9c19a809 947 {
66543521
AM
948 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
949 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 950 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
951
952 /* The #ifdef BFD64 below is to prevent a compile time
953 warning. We know that if we do not have a 64 bit data
954 type that we will never execute this code anyway. */
955#ifdef BFD64
dda8d76d
NC
956 if (filedata->file_header.e_machine == EM_MIPS
957 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
958 {
959 /* In little-endian objects, r_info isn't really a
960 64-bit little-endian value: it has a 32-bit
961 little-endian symbol index followed by four
962 individual byte fields. Reorder INFO
963 accordingly. */
91d6fa6a
NC
964 bfd_vma inf = relas[i].r_info;
965 inf = (((inf & 0xffffffff) << 32)
966 | ((inf >> 56) & 0xff)
967 | ((inf >> 40) & 0xff00)
968 | ((inf >> 24) & 0xff0000)
969 | ((inf >> 8) & 0xff000000));
970 relas[i].r_info = inf;
861fb55a
DJ
971 }
972#endif /* BFD64 */
4d6ed7c8 973 }
103f02d3 974
4d6ed7c8
NC
975 free (erelas);
976 }
32ec8896 977
4d6ed7c8
NC
978 *relasp = relas;
979 *nrelasp = nrelas;
32ec8896 980 return TRUE;
4d6ed7c8 981}
103f02d3 982
dda8d76d 983/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
984 Returns TRUE upon success, FALSE otherwise. If successful then a
985 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
986 and the number of relocs loaded is placed in *NRELSP. It is the caller's
987 responsibility to free the allocated buffer. */
988
989static bfd_boolean
dda8d76d
NC
990slurp_rel_relocs (Filedata * filedata,
991 unsigned long rel_offset,
992 unsigned long rel_size,
993 Elf_Internal_Rela ** relsp,
994 unsigned long * nrelsp)
4d6ed7c8 995{
2cf0635d 996 Elf_Internal_Rela * rels;
8b73c356 997 size_t nrels;
4d6ed7c8 998 unsigned int i;
103f02d3 999
4d6ed7c8
NC
1000 if (is_32bit_elf)
1001 {
2cf0635d 1002 Elf32_External_Rel * erels;
103f02d3 1003
dda8d76d 1004 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1005 rel_size, _("32-bit relocation data"));
a6e9f9df 1006 if (!erels)
32ec8896 1007 return FALSE;
103f02d3 1008
4d6ed7c8 1009 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1010
3f5e193b 1011 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1012
4d6ed7c8
NC
1013 if (rels == NULL)
1014 {
c256ffe7 1015 free (erels);
591a748a 1016 error (_("out of memory parsing relocs\n"));
32ec8896 1017 return FALSE;
4d6ed7c8
NC
1018 }
1019
1020 for (i = 0; i < nrels; i++)
1021 {
1022 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1023 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1024 rels[i].r_addend = 0;
9ea033b2 1025 }
4d6ed7c8
NC
1026
1027 free (erels);
9c19a809
NC
1028 }
1029 else
1030 {
2cf0635d 1031 Elf64_External_Rel * erels;
9ea033b2 1032
dda8d76d 1033 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1034 rel_size, _("64-bit relocation data"));
a6e9f9df 1035 if (!erels)
32ec8896 1036 return FALSE;
103f02d3 1037
4d6ed7c8 1038 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1039
3f5e193b 1040 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1041
4d6ed7c8 1042 if (rels == NULL)
9c19a809 1043 {
c256ffe7 1044 free (erels);
591a748a 1045 error (_("out of memory parsing relocs\n"));
32ec8896 1046 return FALSE;
4d6ed7c8 1047 }
103f02d3 1048
4d6ed7c8
NC
1049 for (i = 0; i < nrels; i++)
1050 {
66543521
AM
1051 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1052 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1053 rels[i].r_addend = 0;
861fb55a
DJ
1054
1055 /* The #ifdef BFD64 below is to prevent a compile time
1056 warning. We know that if we do not have a 64 bit data
1057 type that we will never execute this code anyway. */
1058#ifdef BFD64
dda8d76d
NC
1059 if (filedata->file_header.e_machine == EM_MIPS
1060 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1061 {
1062 /* In little-endian objects, r_info isn't really a
1063 64-bit little-endian value: it has a 32-bit
1064 little-endian symbol index followed by four
1065 individual byte fields. Reorder INFO
1066 accordingly. */
91d6fa6a
NC
1067 bfd_vma inf = rels[i].r_info;
1068 inf = (((inf & 0xffffffff) << 32)
1069 | ((inf >> 56) & 0xff)
1070 | ((inf >> 40) & 0xff00)
1071 | ((inf >> 24) & 0xff0000)
1072 | ((inf >> 8) & 0xff000000));
1073 rels[i].r_info = inf;
861fb55a
DJ
1074 }
1075#endif /* BFD64 */
4d6ed7c8 1076 }
103f02d3 1077
4d6ed7c8
NC
1078 free (erels);
1079 }
32ec8896 1080
4d6ed7c8
NC
1081 *relsp = rels;
1082 *nrelsp = nrels;
32ec8896 1083 return TRUE;
4d6ed7c8 1084}
103f02d3 1085
aca88567
NC
1086/* Returns the reloc type extracted from the reloc info field. */
1087
1088static unsigned int
dda8d76d 1089get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1090{
1091 if (is_32bit_elf)
1092 return ELF32_R_TYPE (reloc_info);
1093
dda8d76d 1094 switch (filedata->file_header.e_machine)
aca88567
NC
1095 {
1096 case EM_MIPS:
1097 /* Note: We assume that reloc_info has already been adjusted for us. */
1098 return ELF64_MIPS_R_TYPE (reloc_info);
1099
1100 case EM_SPARCV9:
1101 return ELF64_R_TYPE_ID (reloc_info);
1102
1103 default:
1104 return ELF64_R_TYPE (reloc_info);
1105 }
1106}
1107
1108/* Return the symbol index extracted from the reloc info field. */
1109
1110static bfd_vma
1111get_reloc_symindex (bfd_vma reloc_info)
1112{
1113 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1114}
1115
13761a11 1116static inline bfd_boolean
dda8d76d 1117uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1118{
1119 return
dda8d76d 1120 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1121 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1122 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1123 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1124 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1125}
1126
d3ba0551
AM
1127/* Display the contents of the relocation data found at the specified
1128 offset. */
ee42cf8c 1129
32ec8896 1130static bfd_boolean
dda8d76d
NC
1131dump_relocations (Filedata * filedata,
1132 unsigned long rel_offset,
1133 unsigned long rel_size,
1134 Elf_Internal_Sym * symtab,
1135 unsigned long nsyms,
1136 char * strtab,
1137 unsigned long strtablen,
1138 int is_rela,
1139 bfd_boolean is_dynsym)
4d6ed7c8 1140{
32ec8896 1141 unsigned long i;
2cf0635d 1142 Elf_Internal_Rela * rels;
32ec8896 1143 bfd_boolean res = TRUE;
103f02d3 1144
4d6ed7c8 1145 if (is_rela == UNKNOWN)
dda8d76d 1146 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1147
4d6ed7c8
NC
1148 if (is_rela)
1149 {
dda8d76d 1150 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1151 return FALSE;
4d6ed7c8
NC
1152 }
1153 else
1154 {
dda8d76d 1155 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1156 return FALSE;
252b5132
RH
1157 }
1158
410f7a12
L
1159 if (is_32bit_elf)
1160 {
1161 if (is_rela)
2c71103e
NC
1162 {
1163 if (do_wide)
1164 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1165 else
1166 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1167 }
410f7a12 1168 else
2c71103e
NC
1169 {
1170 if (do_wide)
1171 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1172 else
1173 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1174 }
410f7a12 1175 }
252b5132 1176 else
410f7a12
L
1177 {
1178 if (is_rela)
2c71103e
NC
1179 {
1180 if (do_wide)
8beeaeb7 1181 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1182 else
1183 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1184 }
410f7a12 1185 else
2c71103e
NC
1186 {
1187 if (do_wide)
8beeaeb7 1188 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1189 else
1190 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1191 }
410f7a12 1192 }
252b5132
RH
1193
1194 for (i = 0; i < rel_size; i++)
1195 {
2cf0635d 1196 const char * rtype;
b34976b6 1197 bfd_vma offset;
91d6fa6a 1198 bfd_vma inf;
b34976b6
AM
1199 bfd_vma symtab_index;
1200 bfd_vma type;
103f02d3 1201
b34976b6 1202 offset = rels[i].r_offset;
91d6fa6a 1203 inf = rels[i].r_info;
103f02d3 1204
dda8d76d 1205 type = get_reloc_type (filedata, inf);
91d6fa6a 1206 symtab_index = get_reloc_symindex (inf);
252b5132 1207
410f7a12
L
1208 if (is_32bit_elf)
1209 {
39dbeff8
AM
1210 printf ("%8.8lx %8.8lx ",
1211 (unsigned long) offset & 0xffffffff,
91d6fa6a 1212 (unsigned long) inf & 0xffffffff);
410f7a12
L
1213 }
1214 else
1215 {
39dbeff8
AM
1216#if BFD_HOST_64BIT_LONG
1217 printf (do_wide
1218 ? "%16.16lx %16.16lx "
1219 : "%12.12lx %12.12lx ",
91d6fa6a 1220 offset, inf);
39dbeff8 1221#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1222#ifndef __MSVCRT__
39dbeff8
AM
1223 printf (do_wide
1224 ? "%16.16llx %16.16llx "
1225 : "%12.12llx %12.12llx ",
91d6fa6a 1226 offset, inf);
6e3d6dc1
NC
1227#else
1228 printf (do_wide
1229 ? "%16.16I64x %16.16I64x "
1230 : "%12.12I64x %12.12I64x ",
91d6fa6a 1231 offset, inf);
6e3d6dc1 1232#endif
39dbeff8 1233#else
2c71103e
NC
1234 printf (do_wide
1235 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1236 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1237 _bfd_int64_high (offset),
1238 _bfd_int64_low (offset),
91d6fa6a
NC
1239 _bfd_int64_high (inf),
1240 _bfd_int64_low (inf));
9ea033b2 1241#endif
410f7a12 1242 }
103f02d3 1243
dda8d76d 1244 switch (filedata->file_header.e_machine)
252b5132
RH
1245 {
1246 default:
1247 rtype = NULL;
1248 break;
1249
a06ea964
NC
1250 case EM_AARCH64:
1251 rtype = elf_aarch64_reloc_type (type);
1252 break;
1253
2b0337b0 1254 case EM_M32R:
252b5132 1255 case EM_CYGNUS_M32R:
9ea033b2 1256 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1257 break;
1258
1259 case EM_386:
22abe556 1260 case EM_IAMCU:
9ea033b2 1261 rtype = elf_i386_reloc_type (type);
252b5132
RH
1262 break;
1263
ba2685cc
AM
1264 case EM_68HC11:
1265 case EM_68HC12:
1266 rtype = elf_m68hc11_reloc_type (type);
1267 break;
75751cd9 1268
252b5132 1269 case EM_68K:
9ea033b2 1270 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1271 break;
1272
adde6300 1273 case EM_AVR:
2b0337b0 1274 case EM_AVR_OLD:
adde6300
AM
1275 rtype = elf_avr_reloc_type (type);
1276 break;
1277
9ea033b2
NC
1278 case EM_OLD_SPARCV9:
1279 case EM_SPARC32PLUS:
1280 case EM_SPARCV9:
252b5132 1281 case EM_SPARC:
9ea033b2 1282 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1283 break;
1284
e9f53129
AM
1285 case EM_SPU:
1286 rtype = elf_spu_reloc_type (type);
1287 break;
1288
708e2187
NC
1289 case EM_V800:
1290 rtype = v800_reloc_type (type);
1291 break;
2b0337b0 1292 case EM_V850:
252b5132 1293 case EM_CYGNUS_V850:
9ea033b2 1294 rtype = v850_reloc_type (type);
252b5132
RH
1295 break;
1296
2b0337b0 1297 case EM_D10V:
252b5132 1298 case EM_CYGNUS_D10V:
9ea033b2 1299 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1300 break;
1301
2b0337b0 1302 case EM_D30V:
252b5132 1303 case EM_CYGNUS_D30V:
9ea033b2 1304 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1305 break;
1306
d172d4ba
NC
1307 case EM_DLX:
1308 rtype = elf_dlx_reloc_type (type);
1309 break;
1310
252b5132 1311 case EM_SH:
9ea033b2 1312 rtype = elf_sh_reloc_type (type);
252b5132
RH
1313 break;
1314
2b0337b0 1315 case EM_MN10300:
252b5132 1316 case EM_CYGNUS_MN10300:
9ea033b2 1317 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1318 break;
1319
2b0337b0 1320 case EM_MN10200:
252b5132 1321 case EM_CYGNUS_MN10200:
9ea033b2 1322 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1323 break;
1324
2b0337b0 1325 case EM_FR30:
252b5132 1326 case EM_CYGNUS_FR30:
9ea033b2 1327 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1328 break;
1329
ba2685cc
AM
1330 case EM_CYGNUS_FRV:
1331 rtype = elf_frv_reloc_type (type);
1332 break;
5c70f934 1333
3f8107ab
AM
1334 case EM_FT32:
1335 rtype = elf_ft32_reloc_type (type);
1336 break;
1337
252b5132 1338 case EM_MCORE:
9ea033b2 1339 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1340 break;
1341
3c3bdf30
NC
1342 case EM_MMIX:
1343 rtype = elf_mmix_reloc_type (type);
1344 break;
1345
5506d11a
AM
1346 case EM_MOXIE:
1347 rtype = elf_moxie_reloc_type (type);
1348 break;
1349
2469cfa2 1350 case EM_MSP430:
dda8d76d 1351 if (uses_msp430x_relocs (filedata))
13761a11
NC
1352 {
1353 rtype = elf_msp430x_reloc_type (type);
1354 break;
1355 }
1a0670f3 1356 /* Fall through. */
2469cfa2
NC
1357 case EM_MSP430_OLD:
1358 rtype = elf_msp430_reloc_type (type);
1359 break;
1360
35c08157
KLC
1361 case EM_NDS32:
1362 rtype = elf_nds32_reloc_type (type);
1363 break;
1364
252b5132 1365 case EM_PPC:
9ea033b2 1366 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1367 break;
1368
c833c019
AM
1369 case EM_PPC64:
1370 rtype = elf_ppc64_reloc_type (type);
1371 break;
1372
252b5132 1373 case EM_MIPS:
4fe85591 1374 case EM_MIPS_RS3_LE:
9ea033b2 1375 rtype = elf_mips_reloc_type (type);
252b5132
RH
1376 break;
1377
e23eba97
NC
1378 case EM_RISCV:
1379 rtype = elf_riscv_reloc_type (type);
1380 break;
1381
252b5132 1382 case EM_ALPHA:
9ea033b2 1383 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1384 break;
1385
1386 case EM_ARM:
9ea033b2 1387 rtype = elf_arm_reloc_type (type);
252b5132
RH
1388 break;
1389
584da044 1390 case EM_ARC:
886a2506
NC
1391 case EM_ARC_COMPACT:
1392 case EM_ARC_COMPACT2:
9ea033b2 1393 rtype = elf_arc_reloc_type (type);
252b5132
RH
1394 break;
1395
1396 case EM_PARISC:
69e617ca 1397 rtype = elf_hppa_reloc_type (type);
252b5132 1398 break;
7d466069 1399
b8720f9d
JL
1400 case EM_H8_300:
1401 case EM_H8_300H:
1402 case EM_H8S:
1403 rtype = elf_h8_reloc_type (type);
1404 break;
1405
73589c9d
CS
1406 case EM_OR1K:
1407 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1408 break;
1409
7d466069 1410 case EM_PJ:
2b0337b0 1411 case EM_PJ_OLD:
7d466069
ILT
1412 rtype = elf_pj_reloc_type (type);
1413 break;
800eeca4
JW
1414 case EM_IA_64:
1415 rtype = elf_ia64_reloc_type (type);
1416 break;
1b61cf92
HPN
1417
1418 case EM_CRIS:
1419 rtype = elf_cris_reloc_type (type);
1420 break;
535c37ff 1421
bcedfee6 1422 case EM_X86_64:
8a9036a4 1423 case EM_L1OM:
7a9068fe 1424 case EM_K1OM:
bcedfee6
NC
1425 rtype = elf_x86_64_reloc_type (type);
1426 break;
a85d7ed0 1427
53c7db4b
KH
1428 case EM_S390_OLD:
1429 case EM_S390:
1430 rtype = elf_s390_reloc_type (type);
1431 break;
93fbbb04 1432
1c0d3aa6
NC
1433 case EM_SCORE:
1434 rtype = elf_score_reloc_type (type);
1435 break;
1436
93fbbb04
GK
1437 case EM_XSTORMY16:
1438 rtype = elf_xstormy16_reloc_type (type);
1439 break;
179d3252 1440
1fe1f39c
NC
1441 case EM_CRX:
1442 rtype = elf_crx_reloc_type (type);
1443 break;
1444
179d3252
JT
1445 case EM_VAX:
1446 rtype = elf_vax_reloc_type (type);
1447 break;
1e4cf259 1448
619ed720
EB
1449 case EM_VISIUM:
1450 rtype = elf_visium_reloc_type (type);
1451 break;
1452
cfb8c092
NC
1453 case EM_ADAPTEVA_EPIPHANY:
1454 rtype = elf_epiphany_reloc_type (type);
1455 break;
1456
1e4cf259
NC
1457 case EM_IP2K:
1458 case EM_IP2K_OLD:
1459 rtype = elf_ip2k_reloc_type (type);
1460 break;
3b36097d
SC
1461
1462 case EM_IQ2000:
1463 rtype = elf_iq2000_reloc_type (type);
1464 break;
88da6820
NC
1465
1466 case EM_XTENSA_OLD:
1467 case EM_XTENSA:
1468 rtype = elf_xtensa_reloc_type (type);
1469 break;
a34e3ecb 1470
84e94c90
NC
1471 case EM_LATTICEMICO32:
1472 rtype = elf_lm32_reloc_type (type);
1473 break;
1474
ff7eeb89 1475 case EM_M32C_OLD:
49f58d10
JB
1476 case EM_M32C:
1477 rtype = elf_m32c_reloc_type (type);
1478 break;
1479
d031aafb
NS
1480 case EM_MT:
1481 rtype = elf_mt_reloc_type (type);
a34e3ecb 1482 break;
1d65ded4
CM
1483
1484 case EM_BLACKFIN:
1485 rtype = elf_bfin_reloc_type (type);
1486 break;
15ab5209
DB
1487
1488 case EM_CYGNUS_MEP:
1489 rtype = elf_mep_reloc_type (type);
1490 break;
60bca95a
NC
1491
1492 case EM_CR16:
1493 rtype = elf_cr16_reloc_type (type);
1494 break;
dd24e3da 1495
7ba29e2a
NC
1496 case EM_MICROBLAZE:
1497 case EM_MICROBLAZE_OLD:
1498 rtype = elf_microblaze_reloc_type (type);
1499 break;
c7927a3c 1500
99c513f6
DD
1501 case EM_RL78:
1502 rtype = elf_rl78_reloc_type (type);
1503 break;
1504
c7927a3c
NC
1505 case EM_RX:
1506 rtype = elf_rx_reloc_type (type);
1507 break;
c29aca4a 1508
a3c62988
NC
1509 case EM_METAG:
1510 rtype = elf_metag_reloc_type (type);
1511 break;
1512
c29aca4a
NC
1513 case EM_XC16X:
1514 case EM_C166:
1515 rtype = elf_xc16x_reloc_type (type);
1516 break;
40b36596
JM
1517
1518 case EM_TI_C6000:
1519 rtype = elf_tic6x_reloc_type (type);
1520 break;
aa137e4d
NC
1521
1522 case EM_TILEGX:
1523 rtype = elf_tilegx_reloc_type (type);
1524 break;
1525
1526 case EM_TILEPRO:
1527 rtype = elf_tilepro_reloc_type (type);
1528 break;
f6c1a2d5 1529
f96bd6c2
PC
1530 case EM_WEBASSEMBLY:
1531 rtype = elf_wasm32_reloc_type (type);
1532 break;
1533
f6c1a2d5
NC
1534 case EM_XGATE:
1535 rtype = elf_xgate_reloc_type (type);
1536 break;
36591ba1
SL
1537
1538 case EM_ALTERA_NIOS2:
1539 rtype = elf_nios2_reloc_type (type);
1540 break;
2b100bb5
DD
1541
1542 case EM_TI_PRU:
1543 rtype = elf_pru_reloc_type (type);
1544 break;
252b5132
RH
1545 }
1546
1547 if (rtype == NULL)
39dbeff8 1548 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1549 else
5c144731 1550 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1551
dda8d76d 1552 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1553 && rtype != NULL
7ace3541
RH
1554 && streq (rtype, "R_ALPHA_LITUSE")
1555 && is_rela)
1556 {
1557 switch (rels[i].r_addend)
1558 {
1559 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1560 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1561 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1562 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1563 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1564 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1565 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1566 default: rtype = NULL;
1567 }
32ec8896 1568
7ace3541
RH
1569 if (rtype)
1570 printf (" (%s)", rtype);
1571 else
1572 {
1573 putchar (' ');
1574 printf (_("<unknown addend: %lx>"),
1575 (unsigned long) rels[i].r_addend);
32ec8896 1576 res = FALSE;
7ace3541
RH
1577 }
1578 }
1579 else if (symtab_index)
252b5132 1580 {
af3fc3bc 1581 if (symtab == NULL || symtab_index >= nsyms)
32ec8896
NC
1582 {
1583 error (_(" bad symbol index: %08lx in reloc"), (unsigned long) symtab_index);
1584 res = FALSE;
1585 }
af3fc3bc 1586 else
19936277 1587 {
2cf0635d 1588 Elf_Internal_Sym * psym;
bb4d2ac2
L
1589 const char * version_string;
1590 enum versioned_symbol_info sym_info;
1591 unsigned short vna_other;
19936277 1592
af3fc3bc 1593 psym = symtab + symtab_index;
103f02d3 1594
bb4d2ac2 1595 version_string
dda8d76d 1596 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1597 strtab, strtablen,
1598 symtab_index,
1599 psym,
1600 &sym_info,
1601 &vna_other);
1602
af3fc3bc 1603 printf (" ");
171191ba 1604
d8045f23
NC
1605 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1606 {
1607 const char * name;
1608 unsigned int len;
1609 unsigned int width = is_32bit_elf ? 8 : 14;
1610
1611 /* Relocations against GNU_IFUNC symbols do not use the value
1612 of the symbol as the address to relocate against. Instead
1613 they invoke the function named by the symbol and use its
1614 result as the address for relocation.
1615
1616 To indicate this to the user, do not display the value of
1617 the symbol in the "Symbols's Value" field. Instead show
1618 its name followed by () as a hint that the symbol is
1619 invoked. */
1620
1621 if (strtab == NULL
1622 || psym->st_name == 0
1623 || psym->st_name >= strtablen)
1624 name = "??";
1625 else
1626 name = strtab + psym->st_name;
1627
1628 len = print_symbol (width, name);
bb4d2ac2
L
1629 if (version_string)
1630 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1631 version_string);
d8045f23
NC
1632 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1633 }
1634 else
1635 {
1636 print_vma (psym->st_value, LONG_HEX);
171191ba 1637
d8045f23
NC
1638 printf (is_32bit_elf ? " " : " ");
1639 }
103f02d3 1640
af3fc3bc 1641 if (psym->st_name == 0)
f1ef08cb 1642 {
2cf0635d 1643 const char * sec_name = "<null>";
f1ef08cb
AM
1644 char name_buf[40];
1645
1646 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1647 {
dda8d76d
NC
1648 if (psym->st_shndx < filedata->file_header.e_shnum)
1649 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1650 else if (psym->st_shndx == SHN_ABS)
1651 sec_name = "ABS";
1652 else if (psym->st_shndx == SHN_COMMON)
1653 sec_name = "COMMON";
dda8d76d 1654 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1655 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1656 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1657 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1658 sec_name = "SCOMMON";
dda8d76d 1659 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1660 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1661 sec_name = "SUNDEF";
dda8d76d
NC
1662 else if ((filedata->file_header.e_machine == EM_X86_64
1663 || filedata->file_header.e_machine == EM_L1OM
1664 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1665 && psym->st_shndx == SHN_X86_64_LCOMMON)
1666 sec_name = "LARGE_COMMON";
dda8d76d
NC
1667 else if (filedata->file_header.e_machine == EM_IA_64
1668 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1669 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1670 sec_name = "ANSI_COM";
dda8d76d 1671 else if (is_ia64_vms (filedata)
148b93f2
NC
1672 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1673 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1674 else
1675 {
1676 sprintf (name_buf, "<section 0x%x>",
1677 (unsigned int) psym->st_shndx);
1678 sec_name = name_buf;
1679 }
1680 }
1681 print_symbol (22, sec_name);
1682 }
af3fc3bc 1683 else if (strtab == NULL)
d79b3d50 1684 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1685 else if (psym->st_name >= strtablen)
32ec8896
NC
1686 {
1687 error (_("<corrupt string table index: %3ld>"), psym->st_name);
1688 res = FALSE;
1689 }
af3fc3bc 1690 else
bb4d2ac2
L
1691 {
1692 print_symbol (22, strtab + psym->st_name);
1693 if (version_string)
1694 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1695 version_string);
1696 }
103f02d3 1697
af3fc3bc 1698 if (is_rela)
171191ba 1699 {
7360e63f 1700 bfd_vma off = rels[i].r_addend;
171191ba 1701
7360e63f 1702 if ((bfd_signed_vma) off < 0)
598aaa76 1703 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1704 else
598aaa76 1705 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1706 }
19936277 1707 }
252b5132 1708 }
1b228002 1709 else if (is_rela)
f7a99963 1710 {
7360e63f 1711 bfd_vma off = rels[i].r_addend;
e04d7088
L
1712
1713 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1714 if ((bfd_signed_vma) off < 0)
e04d7088
L
1715 printf ("-%" BFD_VMA_FMT "x", - off);
1716 else
1717 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1718 }
252b5132 1719
dda8d76d 1720 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1721 && rtype != NULL
1722 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1723 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1724
252b5132 1725 putchar ('\n');
2c71103e 1726
aca88567 1727#ifdef BFD64
dda8d76d 1728 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1729 {
91d6fa6a
NC
1730 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1731 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1732 const char * rtype2 = elf_mips_reloc_type (type2);
1733 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1734
2c71103e
NC
1735 printf (" Type2: ");
1736
1737 if (rtype2 == NULL)
39dbeff8
AM
1738 printf (_("unrecognized: %-7lx"),
1739 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1740 else
1741 printf ("%-17.17s", rtype2);
1742
18bd398b 1743 printf ("\n Type3: ");
2c71103e
NC
1744
1745 if (rtype3 == NULL)
39dbeff8
AM
1746 printf (_("unrecognized: %-7lx"),
1747 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1748 else
1749 printf ("%-17.17s", rtype3);
1750
53c7db4b 1751 putchar ('\n');
2c71103e 1752 }
aca88567 1753#endif /* BFD64 */
252b5132
RH
1754 }
1755
c8286bd1 1756 free (rels);
32ec8896
NC
1757
1758 return res;
252b5132
RH
1759}
1760
1761static const char *
d3ba0551 1762get_mips_dynamic_type (unsigned long type)
252b5132
RH
1763{
1764 switch (type)
1765 {
1766 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1767 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1768 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1769 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1770 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1771 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1772 case DT_MIPS_MSYM: return "MIPS_MSYM";
1773 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1774 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1775 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1776 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1777 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1778 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1779 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1780 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1781 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1782 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1783 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1784 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1785 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1786 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1787 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1788 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1789 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1790 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1791 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1792 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1793 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1794 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1795 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1796 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1797 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1798 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1799 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1800 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1801 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1802 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1803 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1804 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1805 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1806 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1807 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1808 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1809 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1810 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1811 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1812 default:
1813 return NULL;
1814 }
1815}
1816
9a097730 1817static const char *
d3ba0551 1818get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1819{
1820 switch (type)
1821 {
1822 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1823 default:
1824 return NULL;
1825 }
103f02d3
UD
1826}
1827
7490d522
AM
1828static const char *
1829get_ppc_dynamic_type (unsigned long type)
1830{
1831 switch (type)
1832 {
a7f2871e 1833 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1834 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1835 default:
1836 return NULL;
1837 }
1838}
1839
f1cb7e17 1840static const char *
d3ba0551 1841get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1842{
1843 switch (type)
1844 {
a7f2871e
AM
1845 case DT_PPC64_GLINK: return "PPC64_GLINK";
1846 case DT_PPC64_OPD: return "PPC64_OPD";
1847 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1848 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1849 default:
1850 return NULL;
1851 }
1852}
1853
103f02d3 1854static const char *
d3ba0551 1855get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1856{
1857 switch (type)
1858 {
1859 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1860 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1861 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1862 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1863 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1864 case DT_HP_PREINIT: return "HP_PREINIT";
1865 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1866 case DT_HP_NEEDED: return "HP_NEEDED";
1867 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1868 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1869 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1870 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1871 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1872 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1873 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1874 case DT_HP_FILTERED: return "HP_FILTERED";
1875 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1876 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1877 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1878 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1879 case DT_PLT: return "PLT";
1880 case DT_PLT_SIZE: return "PLT_SIZE";
1881 case DT_DLT: return "DLT";
1882 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1883 default:
1884 return NULL;
1885 }
1886}
9a097730 1887
ecc51f48 1888static const char *
d3ba0551 1889get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1890{
1891 switch (type)
1892 {
148b93f2
NC
1893 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1894 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1895 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1896 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1897 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1898 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1899 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1900 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1901 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1902 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1903 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1904 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1905 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1906 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1907 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1908 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1909 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1910 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1911 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1912 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1913 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1914 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1915 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1916 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1917 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1918 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1919 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1920 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1921 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1922 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1923 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1924 default:
1925 return NULL;
1926 }
1927}
1928
fd85a6a1
NC
1929static const char *
1930get_solaris_section_type (unsigned long type)
1931{
1932 switch (type)
1933 {
1934 case 0x6fffffee: return "SUNW_ancillary";
1935 case 0x6fffffef: return "SUNW_capchain";
1936 case 0x6ffffff0: return "SUNW_capinfo";
1937 case 0x6ffffff1: return "SUNW_symsort";
1938 case 0x6ffffff2: return "SUNW_tlssort";
1939 case 0x6ffffff3: return "SUNW_LDYNSYM";
1940 case 0x6ffffff4: return "SUNW_dof";
1941 case 0x6ffffff5: return "SUNW_cap";
1942 case 0x6ffffff6: return "SUNW_SIGNATURE";
1943 case 0x6ffffff7: return "SUNW_ANNOTATE";
1944 case 0x6ffffff8: return "SUNW_DEBUGSTR";
1945 case 0x6ffffff9: return "SUNW_DEBUG";
1946 case 0x6ffffffa: return "SUNW_move";
1947 case 0x6ffffffb: return "SUNW_COMDAT";
1948 case 0x6ffffffc: return "SUNW_syminfo";
1949 case 0x6ffffffd: return "SUNW_verdef";
1950 case 0x6ffffffe: return "SUNW_verneed";
1951 case 0x6fffffff: return "SUNW_versym";
1952 case 0x70000000: return "SPARC_GOTDATA";
1953 default: return NULL;
1954 }
1955}
1956
fabcb361
RH
1957static const char *
1958get_alpha_dynamic_type (unsigned long type)
1959{
1960 switch (type)
1961 {
1962 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 1963 default: return NULL;
fabcb361
RH
1964 }
1965}
1966
1c0d3aa6
NC
1967static const char *
1968get_score_dynamic_type (unsigned long type)
1969{
1970 switch (type)
1971 {
1972 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1973 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1974 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1975 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1976 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1977 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 1978 default: return NULL;
1c0d3aa6
NC
1979 }
1980}
1981
40b36596
JM
1982static const char *
1983get_tic6x_dynamic_type (unsigned long type)
1984{
1985 switch (type)
1986 {
1987 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1988 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1989 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1990 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1991 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1992 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 1993 default: return NULL;
40b36596
JM
1994 }
1995}
1c0d3aa6 1996
36591ba1
SL
1997static const char *
1998get_nios2_dynamic_type (unsigned long type)
1999{
2000 switch (type)
2001 {
2002 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2003 default: return NULL;
36591ba1
SL
2004 }
2005}
2006
fd85a6a1
NC
2007static const char *
2008get_solaris_dynamic_type (unsigned long type)
2009{
2010 switch (type)
2011 {
2012 case 0x6000000d: return "SUNW_AUXILIARY";
2013 case 0x6000000e: return "SUNW_RTLDINF";
2014 case 0x6000000f: return "SUNW_FILTER";
2015 case 0x60000010: return "SUNW_CAP";
2016 case 0x60000011: return "SUNW_SYMTAB";
2017 case 0x60000012: return "SUNW_SYMSZ";
2018 case 0x60000013: return "SUNW_SORTENT";
2019 case 0x60000014: return "SUNW_SYMSORT";
2020 case 0x60000015: return "SUNW_SYMSORTSZ";
2021 case 0x60000016: return "SUNW_TLSSORT";
2022 case 0x60000017: return "SUNW_TLSSORTSZ";
2023 case 0x60000018: return "SUNW_CAPINFO";
2024 case 0x60000019: return "SUNW_STRPAD";
2025 case 0x6000001a: return "SUNW_CAPCHAIN";
2026 case 0x6000001b: return "SUNW_LDMACH";
2027 case 0x6000001d: return "SUNW_CAPCHAINENT";
2028 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2029 case 0x60000021: return "SUNW_PARENT";
2030 case 0x60000023: return "SUNW_ASLR";
2031 case 0x60000025: return "SUNW_RELAX";
2032 case 0x60000029: return "SUNW_NXHEAP";
2033 case 0x6000002b: return "SUNW_NXSTACK";
2034
2035 case 0x70000001: return "SPARC_REGISTER";
2036 case 0x7ffffffd: return "AUXILIARY";
2037 case 0x7ffffffe: return "USED";
2038 case 0x7fffffff: return "FILTER";
2039
15f205b1 2040 default: return NULL;
fd85a6a1
NC
2041 }
2042}
2043
252b5132 2044static const char *
dda8d76d 2045get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2046{
e9e44622 2047 static char buff[64];
252b5132
RH
2048
2049 switch (type)
2050 {
2051 case DT_NULL: return "NULL";
2052 case DT_NEEDED: return "NEEDED";
2053 case DT_PLTRELSZ: return "PLTRELSZ";
2054 case DT_PLTGOT: return "PLTGOT";
2055 case DT_HASH: return "HASH";
2056 case DT_STRTAB: return "STRTAB";
2057 case DT_SYMTAB: return "SYMTAB";
2058 case DT_RELA: return "RELA";
2059 case DT_RELASZ: return "RELASZ";
2060 case DT_RELAENT: return "RELAENT";
2061 case DT_STRSZ: return "STRSZ";
2062 case DT_SYMENT: return "SYMENT";
2063 case DT_INIT: return "INIT";
2064 case DT_FINI: return "FINI";
2065 case DT_SONAME: return "SONAME";
2066 case DT_RPATH: return "RPATH";
2067 case DT_SYMBOLIC: return "SYMBOLIC";
2068 case DT_REL: return "REL";
2069 case DT_RELSZ: return "RELSZ";
2070 case DT_RELENT: return "RELENT";
2071 case DT_PLTREL: return "PLTREL";
2072 case DT_DEBUG: return "DEBUG";
2073 case DT_TEXTREL: return "TEXTREL";
2074 case DT_JMPREL: return "JMPREL";
2075 case DT_BIND_NOW: return "BIND_NOW";
2076 case DT_INIT_ARRAY: return "INIT_ARRAY";
2077 case DT_FINI_ARRAY: return "FINI_ARRAY";
2078 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2079 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2080 case DT_RUNPATH: return "RUNPATH";
2081 case DT_FLAGS: return "FLAGS";
2d0e6f43 2082
d1133906
NC
2083 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2084 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2085 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2086
05107a46 2087 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2088 case DT_PLTPADSZ: return "PLTPADSZ";
2089 case DT_MOVEENT: return "MOVEENT";
2090 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2091 case DT_FEATURE: return "FEATURE";
252b5132
RH
2092 case DT_POSFLAG_1: return "POSFLAG_1";
2093 case DT_SYMINSZ: return "SYMINSZ";
2094 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2095
252b5132 2096 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2097 case DT_CONFIG: return "CONFIG";
2098 case DT_DEPAUDIT: return "DEPAUDIT";
2099 case DT_AUDIT: return "AUDIT";
2100 case DT_PLTPAD: return "PLTPAD";
2101 case DT_MOVETAB: return "MOVETAB";
252b5132 2102 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2103
252b5132 2104 case DT_VERSYM: return "VERSYM";
103f02d3 2105
67a4f2b7
AO
2106 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2107 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2108 case DT_RELACOUNT: return "RELACOUNT";
2109 case DT_RELCOUNT: return "RELCOUNT";
2110 case DT_FLAGS_1: return "FLAGS_1";
2111 case DT_VERDEF: return "VERDEF";
2112 case DT_VERDEFNUM: return "VERDEFNUM";
2113 case DT_VERNEED: return "VERNEED";
2114 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2115
019148e4 2116 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2117 case DT_USED: return "USED";
2118 case DT_FILTER: return "FILTER";
103f02d3 2119
047b2264
JJ
2120 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2121 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2122 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2123 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2124 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2125 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2126
252b5132
RH
2127 default:
2128 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2129 {
2cf0635d 2130 const char * result;
103f02d3 2131
dda8d76d 2132 switch (filedata->file_header.e_machine)
252b5132
RH
2133 {
2134 case EM_MIPS:
4fe85591 2135 case EM_MIPS_RS3_LE:
252b5132
RH
2136 result = get_mips_dynamic_type (type);
2137 break;
9a097730
RH
2138 case EM_SPARCV9:
2139 result = get_sparc64_dynamic_type (type);
2140 break;
7490d522
AM
2141 case EM_PPC:
2142 result = get_ppc_dynamic_type (type);
2143 break;
f1cb7e17
AM
2144 case EM_PPC64:
2145 result = get_ppc64_dynamic_type (type);
2146 break;
ecc51f48
NC
2147 case EM_IA_64:
2148 result = get_ia64_dynamic_type (type);
2149 break;
fabcb361
RH
2150 case EM_ALPHA:
2151 result = get_alpha_dynamic_type (type);
2152 break;
1c0d3aa6
NC
2153 case EM_SCORE:
2154 result = get_score_dynamic_type (type);
2155 break;
40b36596
JM
2156 case EM_TI_C6000:
2157 result = get_tic6x_dynamic_type (type);
2158 break;
36591ba1
SL
2159 case EM_ALTERA_NIOS2:
2160 result = get_nios2_dynamic_type (type);
2161 break;
252b5132 2162 default:
dda8d76d 2163 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2164 result = get_solaris_dynamic_type (type);
2165 else
2166 result = NULL;
252b5132
RH
2167 break;
2168 }
2169
2170 if (result != NULL)
2171 return result;
2172
e9e44622 2173 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2174 }
eec8f817 2175 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2176 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2177 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2178 {
2cf0635d 2179 const char * result;
103f02d3 2180
dda8d76d 2181 switch (filedata->file_header.e_machine)
103f02d3
UD
2182 {
2183 case EM_PARISC:
2184 result = get_parisc_dynamic_type (type);
2185 break;
148b93f2
NC
2186 case EM_IA_64:
2187 result = get_ia64_dynamic_type (type);
2188 break;
103f02d3 2189 default:
dda8d76d 2190 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2191 result = get_solaris_dynamic_type (type);
2192 else
2193 result = NULL;
103f02d3
UD
2194 break;
2195 }
2196
2197 if (result != NULL)
2198 return result;
2199
e9e44622
JJ
2200 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2201 type);
103f02d3 2202 }
252b5132 2203 else
e9e44622 2204 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2205
252b5132
RH
2206 return buff;
2207 }
2208}
2209
2210static char *
d3ba0551 2211get_file_type (unsigned e_type)
252b5132 2212{
b34976b6 2213 static char buff[32];
252b5132
RH
2214
2215 switch (e_type)
2216 {
32ec8896
NC
2217 case ET_NONE: return _("NONE (None)");
2218 case ET_REL: return _("REL (Relocatable file)");
2219 case ET_EXEC: return _("EXEC (Executable file)");
2220 case ET_DYN: return _("DYN (Shared object file)");
2221 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2222
2223 default:
2224 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2225 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2226 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2227 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2228 else
e9e44622 2229 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2230 return buff;
2231 }
2232}
2233
2234static char *
d3ba0551 2235get_machine_name (unsigned e_machine)
252b5132 2236{
b34976b6 2237 static char buff[64]; /* XXX */
252b5132
RH
2238
2239 switch (e_machine)
2240 {
55e22ca8
NC
2241 /* Please keep this switch table sorted by increasing EM_ value. */
2242 /* 0 */
c45021f2
NC
2243 case EM_NONE: return _("None");
2244 case EM_M32: return "WE32100";
2245 case EM_SPARC: return "Sparc";
2246 case EM_386: return "Intel 80386";
2247 case EM_68K: return "MC68000";
2248 case EM_88K: return "MC88000";
22abe556 2249 case EM_IAMCU: return "Intel MCU";
fb70ec17 2250 case EM_860: return "Intel 80860";
c45021f2
NC
2251 case EM_MIPS: return "MIPS R3000";
2252 case EM_S370: return "IBM System/370";
55e22ca8 2253 /* 10 */
7036c0e1 2254 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2255 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2256 case EM_PARISC: return "HPPA";
55e22ca8 2257 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2258 case EM_SPARC32PLUS: return "Sparc v8+" ;
fb70ec17 2259 case EM_960: return "Intel 90860";
c45021f2 2260 case EM_PPC: return "PowerPC";
55e22ca8 2261 /* 20 */
285d1771 2262 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2263 case EM_S390_OLD:
2264 case EM_S390: return "IBM S/390";
2265 case EM_SPU: return "SPU";
2266 /* 30 */
2267 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2268 case EM_FR20: return "Fujitsu FR20";
2269 case EM_RH32: return "TRW RH32";
b34976b6 2270 case EM_MCORE: return "MCORE";
55e22ca8 2271 /* 40 */
7036c0e1
AJ
2272 case EM_ARM: return "ARM";
2273 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2274 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2275 case EM_SPARCV9: return "Sparc v9";
2276 case EM_TRICORE: return "Siemens Tricore";
584da044 2277 case EM_ARC: return "ARC";
c2dcd04e
NC
2278 case EM_H8_300: return "Renesas H8/300";
2279 case EM_H8_300H: return "Renesas H8/300H";
2280 case EM_H8S: return "Renesas H8S";
2281 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2282 /* 50 */
30800947 2283 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2284 case EM_MIPS_X: return "Stanford MIPS-X";
2285 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2286 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2287 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2288 case EM_PCP: return "Siemens PCP";
2289 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2290 case EM_NDR1: return "Denso NDR1 microprocesspr";
2291 case EM_STARCORE: return "Motorola Star*Core processor";
2292 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2293 /* 60 */
7036c0e1
AJ
2294 case EM_ST100: return "STMicroelectronics ST100 processor";
2295 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2296 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2297 case EM_PDSP: return "Sony DSP processor";
2298 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2299 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2300 case EM_FX66: return "Siemens FX66 microcontroller";
2301 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2302 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2303 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2304 /* 70 */
7036c0e1
AJ
2305 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2306 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2307 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2308 case EM_SVX: return "Silicon Graphics SVx";
2309 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2310 case EM_VAX: return "Digital VAX";
1b61cf92 2311 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2312 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2313 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2314 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2315 /* 80 */
b34976b6 2316 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2317 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2318 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2319 case EM_AVR_OLD:
2320 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2321 case EM_CYGNUS_FR30:
2322 case EM_FR30: return "Fujitsu FR30";
2323 case EM_CYGNUS_D10V:
2324 case EM_D10V: return "d10v";
2325 case EM_CYGNUS_D30V:
2326 case EM_D30V: return "d30v";
2327 case EM_CYGNUS_V850:
2328 case EM_V850: return "Renesas V850";
2329 case EM_CYGNUS_M32R:
2330 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2331 case EM_CYGNUS_MN10300:
2332 case EM_MN10300: return "mn10300";
2333 /* 90 */
2334 case EM_CYGNUS_MN10200:
2335 case EM_MN10200: return "mn10200";
2336 case EM_PJ: return "picoJava";
73589c9d 2337 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2338 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2339 case EM_XTENSA_OLD:
2340 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2341 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2342 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2343 case EM_NS32K: return "National Semiconductor 32000 series";
2344 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2345 case EM_SNP1K: return "Trebia SNP 1000 processor";
2346 /* 100 */
2347 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2348 case EM_IP2K_OLD:
2349 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2350 case EM_MAX: return "MAX Processor";
2351 case EM_CR: return "National Semiconductor CompactRISC";
2352 case EM_F2MC16: return "Fujitsu F2MC16";
2353 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2354 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2355 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2356 case EM_SEP: return "Sharp embedded microprocessor";
2357 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2358 /* 110 */
11636f9e
JM
2359 case EM_UNICORE: return "Unicore";
2360 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2361 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2362 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2363 case EM_CRX: return "National Semiconductor CRX microprocessor";
2364 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2365 case EM_C166:
d70c5fc7 2366 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2367 case EM_M16C: return "Renesas M16C series microprocessors";
2368 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2369 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2370 /* 120 */
2371 case EM_M32C: return "Renesas M32c";
2372 /* 130 */
11636f9e
JM
2373 case EM_TSK3000: return "Altium TSK3000 core";
2374 case EM_RS08: return "Freescale RS08 embedded processor";
2375 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2376 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2377 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2378 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2379 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2380 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2381 /* 140 */
11636f9e
JM
2382 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2383 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2384 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2385 case EM_TI_PRU: return "TI PRU I/O processor";
2386 /* 160 */
11636f9e
JM
2387 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2388 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2389 case EM_R32C: return "Renesas R32C series microprocessors";
2390 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2391 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2392 case EM_8051: return "Intel 8051 and variants";
2393 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2394 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2395 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2396 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2397 /* 170 */
11636f9e
JM
2398 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2399 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2400 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2401 case EM_RX: return "Renesas RX";
a3c62988 2402 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2403 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2404 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2405 case EM_CR16:
2406 case EM_MICROBLAZE:
2407 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2408 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2409 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2410 /* 180 */
2411 case EM_L1OM: return "Intel L1OM";
2412 case EM_K1OM: return "Intel K1OM";
2413 case EM_INTEL182: return "Intel (reserved)";
2414 case EM_AARCH64: return "AArch64";
2415 case EM_ARM184: return "ARM (reserved)";
2416 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2417 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2418 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2419 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2420 /* 190 */
11636f9e 2421 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2422 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2423 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2424 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2425 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2426 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2427 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2428 case EM_RL78: return "Renesas RL78";
6d913794 2429 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2430 case EM_78K0R: return "Renesas 78K0R";
2431 /* 200 */
6d913794 2432 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2433 case EM_BA1: return "Beyond BA1 CPU architecture";
2434 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2435 case EM_XCORE: return "XMOS xCORE processor family";
2436 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2437 /* 210 */
6d913794
NC
2438 case EM_KM32: return "KM211 KM32 32-bit processor";
2439 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2440 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2441 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2442 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2443 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2444 case EM_COGE: return "Cognitive Smart Memory Processor";
2445 case EM_COOL: return "Bluechip Systems CoolEngine";
2446 case EM_NORC: return "Nanoradio Optimized RISC";
2447 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2448 /* 220 */
15f205b1 2449 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2450 case EM_VISIUM: return "CDS VISIUMcore processor";
2451 case EM_FT32: return "FTDI Chip FT32";
2452 case EM_MOXIE: return "Moxie";
2453 case EM_AMDGPU: return "AMD GPU";
2454 case EM_RISCV: return "RISC-V";
2455 case EM_LANAI: return "Lanai 32-bit processor";
2456 case EM_BPF: return "Linux BPF";
2457
2458 /* Large numbers... */
2459 case EM_MT: return "Morpho Techologies MT processor";
2460 case EM_ALPHA: return "Alpha";
2461 case EM_WEBASSEMBLY: return "Web Assembly";
2462 case EM_DLX: return "OpenDLX";
2463 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2464 case EM_IQ2000: return "Vitesse IQ2000";
2465 case EM_M32C_OLD:
2466 case EM_NIOS32: return "Altera Nios";
2467 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2468 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2469 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2470
252b5132 2471 default:
35d9dd2f 2472 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2473 return buff;
2474 }
2475}
2476
a9522a21
AB
2477static void
2478decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2479{
2480 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2481 other compilers don't a specific architecture type in the e_flags, and
2482 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2483 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2484 architectures.
2485
2486 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2487 but also sets a specific architecture type in the e_flags field.
2488
2489 However, when decoding the flags we don't worry if we see an
2490 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2491 ARCEM architecture type. */
2492
2493 switch (e_flags & EF_ARC_MACH_MSK)
2494 {
2495 /* We only expect these to occur for EM_ARC_COMPACT2. */
2496 case EF_ARC_CPU_ARCV2EM:
2497 strcat (buf, ", ARC EM");
2498 break;
2499 case EF_ARC_CPU_ARCV2HS:
2500 strcat (buf, ", ARC HS");
2501 break;
2502
2503 /* We only expect these to occur for EM_ARC_COMPACT. */
2504 case E_ARC_MACH_ARC600:
2505 strcat (buf, ", ARC600");
2506 break;
2507 case E_ARC_MACH_ARC601:
2508 strcat (buf, ", ARC601");
2509 break;
2510 case E_ARC_MACH_ARC700:
2511 strcat (buf, ", ARC700");
2512 break;
2513
2514 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2515 new ELF with new architecture being read by an old version of
2516 readelf, or (c) An ELF built with non-GNU compiler that does not
2517 set the architecture in the e_flags. */
2518 default:
2519 if (e_machine == EM_ARC_COMPACT)
2520 strcat (buf, ", Unknown ARCompact");
2521 else
2522 strcat (buf, ", Unknown ARC");
2523 break;
2524 }
2525
2526 switch (e_flags & EF_ARC_OSABI_MSK)
2527 {
2528 case E_ARC_OSABI_ORIG:
2529 strcat (buf, ", (ABI:legacy)");
2530 break;
2531 case E_ARC_OSABI_V2:
2532 strcat (buf, ", (ABI:v2)");
2533 break;
2534 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2535 case E_ARC_OSABI_V3:
2536 strcat (buf, ", v3 no-legacy-syscalls ABI");
2537 break;
53a346d8
CZ
2538 case E_ARC_OSABI_V4:
2539 strcat (buf, ", v4 ABI");
2540 break;
a9522a21
AB
2541 default:
2542 strcat (buf, ", unrecognised ARC OSABI flag");
2543 break;
2544 }
2545}
2546
f3485b74 2547static void
d3ba0551 2548decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2549{
2550 unsigned eabi;
32ec8896 2551 bfd_boolean unknown = FALSE;
f3485b74
NC
2552
2553 eabi = EF_ARM_EABI_VERSION (e_flags);
2554 e_flags &= ~ EF_ARM_EABIMASK;
2555
2556 /* Handle "generic" ARM flags. */
2557 if (e_flags & EF_ARM_RELEXEC)
2558 {
2559 strcat (buf, ", relocatable executable");
2560 e_flags &= ~ EF_ARM_RELEXEC;
2561 }
76da6bbe 2562
f3485b74
NC
2563 /* Now handle EABI specific flags. */
2564 switch (eabi)
2565 {
2566 default:
2c71103e 2567 strcat (buf, ", <unrecognized EABI>");
f3485b74 2568 if (e_flags)
32ec8896 2569 unknown = TRUE;
f3485b74
NC
2570 break;
2571
2572 case EF_ARM_EABI_VER1:
a5bcd848 2573 strcat (buf, ", Version1 EABI");
f3485b74
NC
2574 while (e_flags)
2575 {
2576 unsigned flag;
76da6bbe 2577
f3485b74
NC
2578 /* Process flags one bit at a time. */
2579 flag = e_flags & - e_flags;
2580 e_flags &= ~ flag;
76da6bbe 2581
f3485b74
NC
2582 switch (flag)
2583 {
a5bcd848 2584 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2585 strcat (buf, ", sorted symbol tables");
2586 break;
76da6bbe 2587
f3485b74 2588 default:
32ec8896 2589 unknown = TRUE;
f3485b74
NC
2590 break;
2591 }
2592 }
2593 break;
76da6bbe 2594
a5bcd848
PB
2595 case EF_ARM_EABI_VER2:
2596 strcat (buf, ", Version2 EABI");
2597 while (e_flags)
2598 {
2599 unsigned flag;
2600
2601 /* Process flags one bit at a time. */
2602 flag = e_flags & - e_flags;
2603 e_flags &= ~ flag;
2604
2605 switch (flag)
2606 {
2607 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2608 strcat (buf, ", sorted symbol tables");
2609 break;
2610
2611 case EF_ARM_DYNSYMSUSESEGIDX:
2612 strcat (buf, ", dynamic symbols use segment index");
2613 break;
2614
2615 case EF_ARM_MAPSYMSFIRST:
2616 strcat (buf, ", mapping symbols precede others");
2617 break;
2618
2619 default:
32ec8896 2620 unknown = TRUE;
a5bcd848
PB
2621 break;
2622 }
2623 }
2624 break;
2625
d507cf36
PB
2626 case EF_ARM_EABI_VER3:
2627 strcat (buf, ", Version3 EABI");
8cb51566
PB
2628 break;
2629
2630 case EF_ARM_EABI_VER4:
2631 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2632 while (e_flags)
2633 {
2634 unsigned flag;
2635
2636 /* Process flags one bit at a time. */
2637 flag = e_flags & - e_flags;
2638 e_flags &= ~ flag;
2639
2640 switch (flag)
2641 {
2642 case EF_ARM_BE8:
2643 strcat (buf, ", BE8");
2644 break;
2645
2646 case EF_ARM_LE8:
2647 strcat (buf, ", LE8");
2648 break;
2649
2650 default:
32ec8896 2651 unknown = TRUE;
3bfcb652
NC
2652 break;
2653 }
3bfcb652
NC
2654 }
2655 break;
3a4a14e9
PB
2656
2657 case EF_ARM_EABI_VER5:
2658 strcat (buf, ", Version5 EABI");
d507cf36
PB
2659 while (e_flags)
2660 {
2661 unsigned flag;
2662
2663 /* Process flags one bit at a time. */
2664 flag = e_flags & - e_flags;
2665 e_flags &= ~ flag;
2666
2667 switch (flag)
2668 {
2669 case EF_ARM_BE8:
2670 strcat (buf, ", BE8");
2671 break;
2672
2673 case EF_ARM_LE8:
2674 strcat (buf, ", LE8");
2675 break;
2676
3bfcb652
NC
2677 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2678 strcat (buf, ", soft-float ABI");
2679 break;
2680
2681 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2682 strcat (buf, ", hard-float ABI");
2683 break;
2684
d507cf36 2685 default:
32ec8896 2686 unknown = TRUE;
d507cf36
PB
2687 break;
2688 }
2689 }
2690 break;
2691
f3485b74 2692 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2693 strcat (buf, ", GNU EABI");
f3485b74
NC
2694 while (e_flags)
2695 {
2696 unsigned flag;
76da6bbe 2697
f3485b74
NC
2698 /* Process flags one bit at a time. */
2699 flag = e_flags & - e_flags;
2700 e_flags &= ~ flag;
76da6bbe 2701
f3485b74
NC
2702 switch (flag)
2703 {
a5bcd848 2704 case EF_ARM_INTERWORK:
f3485b74
NC
2705 strcat (buf, ", interworking enabled");
2706 break;
76da6bbe 2707
a5bcd848 2708 case EF_ARM_APCS_26:
f3485b74
NC
2709 strcat (buf, ", uses APCS/26");
2710 break;
76da6bbe 2711
a5bcd848 2712 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2713 strcat (buf, ", uses APCS/float");
2714 break;
76da6bbe 2715
a5bcd848 2716 case EF_ARM_PIC:
f3485b74
NC
2717 strcat (buf, ", position independent");
2718 break;
76da6bbe 2719
a5bcd848 2720 case EF_ARM_ALIGN8:
f3485b74
NC
2721 strcat (buf, ", 8 bit structure alignment");
2722 break;
76da6bbe 2723
a5bcd848 2724 case EF_ARM_NEW_ABI:
f3485b74
NC
2725 strcat (buf, ", uses new ABI");
2726 break;
76da6bbe 2727
a5bcd848 2728 case EF_ARM_OLD_ABI:
f3485b74
NC
2729 strcat (buf, ", uses old ABI");
2730 break;
76da6bbe 2731
a5bcd848 2732 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2733 strcat (buf, ", software FP");
2734 break;
76da6bbe 2735
90e01f86
ILT
2736 case EF_ARM_VFP_FLOAT:
2737 strcat (buf, ", VFP");
2738 break;
2739
fde78edd
NC
2740 case EF_ARM_MAVERICK_FLOAT:
2741 strcat (buf, ", Maverick FP");
2742 break;
2743
f3485b74 2744 default:
32ec8896 2745 unknown = TRUE;
f3485b74
NC
2746 break;
2747 }
2748 }
2749 }
f3485b74
NC
2750
2751 if (unknown)
2b692964 2752 strcat (buf,_(", <unknown>"));
f3485b74
NC
2753}
2754
343433df
AB
2755static void
2756decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2757{
2758 --size; /* Leave space for null terminator. */
2759
2760 switch (e_flags & EF_AVR_MACH)
2761 {
2762 case E_AVR_MACH_AVR1:
2763 strncat (buf, ", avr:1", size);
2764 break;
2765 case E_AVR_MACH_AVR2:
2766 strncat (buf, ", avr:2", size);
2767 break;
2768 case E_AVR_MACH_AVR25:
2769 strncat (buf, ", avr:25", size);
2770 break;
2771 case E_AVR_MACH_AVR3:
2772 strncat (buf, ", avr:3", size);
2773 break;
2774 case E_AVR_MACH_AVR31:
2775 strncat (buf, ", avr:31", size);
2776 break;
2777 case E_AVR_MACH_AVR35:
2778 strncat (buf, ", avr:35", size);
2779 break;
2780 case E_AVR_MACH_AVR4:
2781 strncat (buf, ", avr:4", size);
2782 break;
2783 case E_AVR_MACH_AVR5:
2784 strncat (buf, ", avr:5", size);
2785 break;
2786 case E_AVR_MACH_AVR51:
2787 strncat (buf, ", avr:51", size);
2788 break;
2789 case E_AVR_MACH_AVR6:
2790 strncat (buf, ", avr:6", size);
2791 break;
2792 case E_AVR_MACH_AVRTINY:
2793 strncat (buf, ", avr:100", size);
2794 break;
2795 case E_AVR_MACH_XMEGA1:
2796 strncat (buf, ", avr:101", size);
2797 break;
2798 case E_AVR_MACH_XMEGA2:
2799 strncat (buf, ", avr:102", size);
2800 break;
2801 case E_AVR_MACH_XMEGA3:
2802 strncat (buf, ", avr:103", size);
2803 break;
2804 case E_AVR_MACH_XMEGA4:
2805 strncat (buf, ", avr:104", size);
2806 break;
2807 case E_AVR_MACH_XMEGA5:
2808 strncat (buf, ", avr:105", size);
2809 break;
2810 case E_AVR_MACH_XMEGA6:
2811 strncat (buf, ", avr:106", size);
2812 break;
2813 case E_AVR_MACH_XMEGA7:
2814 strncat (buf, ", avr:107", size);
2815 break;
2816 default:
2817 strncat (buf, ", avr:<unknown>", size);
2818 break;
2819 }
2820
2821 size -= strlen (buf);
2822 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2823 strncat (buf, ", link-relax", size);
2824}
2825
35c08157
KLC
2826static void
2827decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2828{
2829 unsigned abi;
2830 unsigned arch;
2831 unsigned config;
2832 unsigned version;
32ec8896
NC
2833 bfd_boolean has_fpu = FALSE;
2834 unsigned int r = 0;
35c08157
KLC
2835
2836 static const char *ABI_STRINGS[] =
2837 {
2838 "ABI v0", /* use r5 as return register; only used in N1213HC */
2839 "ABI v1", /* use r0 as return register */
2840 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2841 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2842 "AABI",
2843 "ABI2 FP+"
35c08157
KLC
2844 };
2845 static const char *VER_STRINGS[] =
2846 {
2847 "Andes ELF V1.3 or older",
2848 "Andes ELF V1.3.1",
2849 "Andes ELF V1.4"
2850 };
2851 static const char *ARCH_STRINGS[] =
2852 {
2853 "",
2854 "Andes Star v1.0",
2855 "Andes Star v2.0",
2856 "Andes Star v3.0",
2857 "Andes Star v3.0m"
2858 };
2859
2860 abi = EF_NDS_ABI & e_flags;
2861 arch = EF_NDS_ARCH & e_flags;
2862 config = EF_NDS_INST & e_flags;
2863 version = EF_NDS32_ELF_VERSION & e_flags;
2864
2865 memset (buf, 0, size);
2866
2867 switch (abi)
2868 {
2869 case E_NDS_ABI_V0:
2870 case E_NDS_ABI_V1:
2871 case E_NDS_ABI_V2:
2872 case E_NDS_ABI_V2FP:
2873 case E_NDS_ABI_AABI:
40c7a7cb 2874 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2875 /* In case there are holes in the array. */
2876 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2877 break;
2878
2879 default:
2880 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2881 break;
2882 }
2883
2884 switch (version)
2885 {
2886 case E_NDS32_ELF_VER_1_2:
2887 case E_NDS32_ELF_VER_1_3:
2888 case E_NDS32_ELF_VER_1_4:
2889 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2890 break;
2891
2892 default:
2893 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2894 break;
2895 }
2896
2897 if (E_NDS_ABI_V0 == abi)
2898 {
2899 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2900 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2901 if (arch == E_NDS_ARCH_STAR_V1_0)
2902 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2903 return;
2904 }
2905
2906 switch (arch)
2907 {
2908 case E_NDS_ARCH_STAR_V1_0:
2909 case E_NDS_ARCH_STAR_V2_0:
2910 case E_NDS_ARCH_STAR_V3_0:
2911 case E_NDS_ARCH_STAR_V3_M:
2912 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2913 break;
2914
2915 default:
2916 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2917 /* ARCH version determines how the e_flags are interpreted.
2918 If it is unknown, we cannot proceed. */
2919 return;
2920 }
2921
2922 /* Newer ABI; Now handle architecture specific flags. */
2923 if (arch == E_NDS_ARCH_STAR_V1_0)
2924 {
2925 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2926 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2927
2928 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2929 r += snprintf (buf + r, size -r, ", MAC");
2930
2931 if (config & E_NDS32_HAS_DIV_INST)
2932 r += snprintf (buf + r, size -r, ", DIV");
2933
2934 if (config & E_NDS32_HAS_16BIT_INST)
2935 r += snprintf (buf + r, size -r, ", 16b");
2936 }
2937 else
2938 {
2939 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2940 {
2941 if (version <= E_NDS32_ELF_VER_1_3)
2942 r += snprintf (buf + r, size -r, ", [B8]");
2943 else
2944 r += snprintf (buf + r, size -r, ", EX9");
2945 }
2946
2947 if (config & E_NDS32_HAS_MAC_DX_INST)
2948 r += snprintf (buf + r, size -r, ", MAC_DX");
2949
2950 if (config & E_NDS32_HAS_DIV_DX_INST)
2951 r += snprintf (buf + r, size -r, ", DIV_DX");
2952
2953 if (config & E_NDS32_HAS_16BIT_INST)
2954 {
2955 if (version <= E_NDS32_ELF_VER_1_3)
2956 r += snprintf (buf + r, size -r, ", 16b");
2957 else
2958 r += snprintf (buf + r, size -r, ", IFC");
2959 }
2960 }
2961
2962 if (config & E_NDS32_HAS_EXT_INST)
2963 r += snprintf (buf + r, size -r, ", PERF1");
2964
2965 if (config & E_NDS32_HAS_EXT2_INST)
2966 r += snprintf (buf + r, size -r, ", PERF2");
2967
2968 if (config & E_NDS32_HAS_FPU_INST)
2969 {
32ec8896 2970 has_fpu = TRUE;
35c08157
KLC
2971 r += snprintf (buf + r, size -r, ", FPU_SP");
2972 }
2973
2974 if (config & E_NDS32_HAS_FPU_DP_INST)
2975 {
32ec8896 2976 has_fpu = TRUE;
35c08157
KLC
2977 r += snprintf (buf + r, size -r, ", FPU_DP");
2978 }
2979
2980 if (config & E_NDS32_HAS_FPU_MAC_INST)
2981 {
32ec8896 2982 has_fpu = TRUE;
35c08157
KLC
2983 r += snprintf (buf + r, size -r, ", FPU_MAC");
2984 }
2985
2986 if (has_fpu)
2987 {
2988 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2989 {
2990 case E_NDS32_FPU_REG_8SP_4DP:
2991 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2992 break;
2993 case E_NDS32_FPU_REG_16SP_8DP:
2994 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2995 break;
2996 case E_NDS32_FPU_REG_32SP_16DP:
2997 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2998 break;
2999 case E_NDS32_FPU_REG_32SP_32DP:
3000 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3001 break;
3002 }
3003 }
3004
3005 if (config & E_NDS32_HAS_AUDIO_INST)
3006 r += snprintf (buf + r, size -r, ", AUDIO");
3007
3008 if (config & E_NDS32_HAS_STRING_INST)
3009 r += snprintf (buf + r, size -r, ", STR");
3010
3011 if (config & E_NDS32_HAS_REDUCED_REGS)
3012 r += snprintf (buf + r, size -r, ", 16REG");
3013
3014 if (config & E_NDS32_HAS_VIDEO_INST)
3015 {
3016 if (version <= E_NDS32_ELF_VER_1_3)
3017 r += snprintf (buf + r, size -r, ", VIDEO");
3018 else
3019 r += snprintf (buf + r, size -r, ", SATURATION");
3020 }
3021
3022 if (config & E_NDS32_HAS_ENCRIPT_INST)
3023 r += snprintf (buf + r, size -r, ", ENCRP");
3024
3025 if (config & E_NDS32_HAS_L2C_INST)
3026 r += snprintf (buf + r, size -r, ", L2C");
3027}
3028
252b5132 3029static char *
dda8d76d 3030get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3031{
b34976b6 3032 static char buf[1024];
252b5132
RH
3033
3034 buf[0] = '\0';
76da6bbe 3035
252b5132
RH
3036 if (e_flags)
3037 {
3038 switch (e_machine)
3039 {
3040 default:
3041 break;
3042
886a2506 3043 case EM_ARC_COMPACT2:
886a2506 3044 case EM_ARC_COMPACT:
a9522a21
AB
3045 decode_ARC_machine_flags (e_flags, e_machine, buf);
3046 break;
886a2506 3047
f3485b74
NC
3048 case EM_ARM:
3049 decode_ARM_machine_flags (e_flags, buf);
3050 break;
76da6bbe 3051
343433df
AB
3052 case EM_AVR:
3053 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3054 break;
3055
781303ce
MF
3056 case EM_BLACKFIN:
3057 if (e_flags & EF_BFIN_PIC)
3058 strcat (buf, ", PIC");
3059
3060 if (e_flags & EF_BFIN_FDPIC)
3061 strcat (buf, ", FDPIC");
3062
3063 if (e_flags & EF_BFIN_CODE_IN_L1)
3064 strcat (buf, ", code in L1");
3065
3066 if (e_flags & EF_BFIN_DATA_IN_L1)
3067 strcat (buf, ", data in L1");
3068
3069 break;
3070
ec2dfb42
AO
3071 case EM_CYGNUS_FRV:
3072 switch (e_flags & EF_FRV_CPU_MASK)
3073 {
3074 case EF_FRV_CPU_GENERIC:
3075 break;
3076
3077 default:
3078 strcat (buf, ", fr???");
3079 break;
57346661 3080
ec2dfb42
AO
3081 case EF_FRV_CPU_FR300:
3082 strcat (buf, ", fr300");
3083 break;
3084
3085 case EF_FRV_CPU_FR400:
3086 strcat (buf, ", fr400");
3087 break;
3088 case EF_FRV_CPU_FR405:
3089 strcat (buf, ", fr405");
3090 break;
3091
3092 case EF_FRV_CPU_FR450:
3093 strcat (buf, ", fr450");
3094 break;
3095
3096 case EF_FRV_CPU_FR500:
3097 strcat (buf, ", fr500");
3098 break;
3099 case EF_FRV_CPU_FR550:
3100 strcat (buf, ", fr550");
3101 break;
3102
3103 case EF_FRV_CPU_SIMPLE:
3104 strcat (buf, ", simple");
3105 break;
3106 case EF_FRV_CPU_TOMCAT:
3107 strcat (buf, ", tomcat");
3108 break;
3109 }
1c877e87 3110 break;
ec2dfb42 3111
53c7db4b 3112 case EM_68K:
425c6cb0 3113 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3114 strcat (buf, ", m68000");
425c6cb0 3115 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3116 strcat (buf, ", cpu32");
3117 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3118 strcat (buf, ", fido_a");
425c6cb0 3119 else
266abb8f 3120 {
2cf0635d
NC
3121 char const * isa = _("unknown");
3122 char const * mac = _("unknown mac");
3123 char const * additional = NULL;
0112cd26 3124
c694fd50 3125 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3126 {
c694fd50 3127 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3128 isa = "A";
3129 additional = ", nodiv";
3130 break;
c694fd50 3131 case EF_M68K_CF_ISA_A:
266abb8f
NS
3132 isa = "A";
3133 break;
c694fd50 3134 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3135 isa = "A+";
3136 break;
c694fd50 3137 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3138 isa = "B";
3139 additional = ", nousp";
3140 break;
c694fd50 3141 case EF_M68K_CF_ISA_B:
266abb8f
NS
3142 isa = "B";
3143 break;
f608cd77
NS
3144 case EF_M68K_CF_ISA_C:
3145 isa = "C";
3146 break;
3147 case EF_M68K_CF_ISA_C_NODIV:
3148 isa = "C";
3149 additional = ", nodiv";
3150 break;
266abb8f
NS
3151 }
3152 strcat (buf, ", cf, isa ");
3153 strcat (buf, isa);
0b2e31dc
NS
3154 if (additional)
3155 strcat (buf, additional);
c694fd50 3156 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3157 strcat (buf, ", float");
c694fd50 3158 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3159 {
3160 case 0:
3161 mac = NULL;
3162 break;
c694fd50 3163 case EF_M68K_CF_MAC:
266abb8f
NS
3164 mac = "mac";
3165 break;
c694fd50 3166 case EF_M68K_CF_EMAC:
266abb8f
NS
3167 mac = "emac";
3168 break;
f608cd77
NS
3169 case EF_M68K_CF_EMAC_B:
3170 mac = "emac_b";
3171 break;
266abb8f
NS
3172 }
3173 if (mac)
3174 {
3175 strcat (buf, ", ");
3176 strcat (buf, mac);
3177 }
266abb8f 3178 }
53c7db4b 3179 break;
33c63f9d 3180
153a2776
NC
3181 case EM_CYGNUS_MEP:
3182 switch (e_flags & EF_MEP_CPU_MASK)
3183 {
3184 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3185 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3186 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3187 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3188 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3189 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3190 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3191 }
3192
3193 switch (e_flags & EF_MEP_COP_MASK)
3194 {
3195 case EF_MEP_COP_NONE: break;
3196 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3197 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3198 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3199 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3200 default: strcat (buf, _("<unknown MeP copro type>")); break;
3201 }
3202
3203 if (e_flags & EF_MEP_LIBRARY)
3204 strcat (buf, ", Built for Library");
3205
3206 if (e_flags & EF_MEP_INDEX_MASK)
3207 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3208 e_flags & EF_MEP_INDEX_MASK);
3209
3210 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3211 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3212 e_flags & ~ EF_MEP_ALL_FLAGS);
3213 break;
3214
252b5132
RH
3215 case EM_PPC:
3216 if (e_flags & EF_PPC_EMB)
3217 strcat (buf, ", emb");
3218
3219 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3220 strcat (buf, _(", relocatable"));
252b5132
RH
3221
3222 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3223 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3224 break;
3225
ee67d69a
AM
3226 case EM_PPC64:
3227 if (e_flags & EF_PPC64_ABI)
3228 {
3229 char abi[] = ", abiv0";
3230
3231 abi[6] += e_flags & EF_PPC64_ABI;
3232 strcat (buf, abi);
3233 }
3234 break;
3235
708e2187
NC
3236 case EM_V800:
3237 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3238 strcat (buf, ", RH850 ABI");
0b4362b0 3239
708e2187
NC
3240 if (e_flags & EF_V800_850E3)
3241 strcat (buf, ", V3 architecture");
3242
3243 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3244 strcat (buf, ", FPU not used");
3245
3246 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3247 strcat (buf, ", regmode: COMMON");
3248
3249 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3250 strcat (buf, ", r4 not used");
3251
3252 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3253 strcat (buf, ", r30 not used");
3254
3255 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3256 strcat (buf, ", r5 not used");
3257
3258 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3259 strcat (buf, ", r2 not used");
3260
3261 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3262 {
3263 switch (e_flags & - e_flags)
3264 {
3265 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3266 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3267 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3268 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3269 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3270 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3271 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3272 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3273 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3274 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3275 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3276 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3277 default: break;
3278 }
3279 }
3280 break;
3281
2b0337b0 3282 case EM_V850:
252b5132
RH
3283 case EM_CYGNUS_V850:
3284 switch (e_flags & EF_V850_ARCH)
3285 {
78c8d46c
NC
3286 case E_V850E3V5_ARCH:
3287 strcat (buf, ", v850e3v5");
3288 break;
1cd986c5
NC
3289 case E_V850E2V3_ARCH:
3290 strcat (buf, ", v850e2v3");
3291 break;
3292 case E_V850E2_ARCH:
3293 strcat (buf, ", v850e2");
3294 break;
3295 case E_V850E1_ARCH:
3296 strcat (buf, ", v850e1");
8ad30312 3297 break;
252b5132
RH
3298 case E_V850E_ARCH:
3299 strcat (buf, ", v850e");
3300 break;
252b5132
RH
3301 case E_V850_ARCH:
3302 strcat (buf, ", v850");
3303 break;
3304 default:
2b692964 3305 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3306 break;
3307 }
3308 break;
3309
2b0337b0 3310 case EM_M32R:
252b5132
RH
3311 case EM_CYGNUS_M32R:
3312 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3313 strcat (buf, ", m32r");
252b5132
RH
3314 break;
3315
3316 case EM_MIPS:
4fe85591 3317 case EM_MIPS_RS3_LE:
252b5132
RH
3318 if (e_flags & EF_MIPS_NOREORDER)
3319 strcat (buf, ", noreorder");
3320
3321 if (e_flags & EF_MIPS_PIC)
3322 strcat (buf, ", pic");
3323
3324 if (e_flags & EF_MIPS_CPIC)
3325 strcat (buf, ", cpic");
3326
d1bdd336
TS
3327 if (e_flags & EF_MIPS_UCODE)
3328 strcat (buf, ", ugen_reserved");
3329
252b5132
RH
3330 if (e_flags & EF_MIPS_ABI2)
3331 strcat (buf, ", abi2");
3332
43521d43
TS
3333 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3334 strcat (buf, ", odk first");
3335
a5d22d2a
TS
3336 if (e_flags & EF_MIPS_32BITMODE)
3337 strcat (buf, ", 32bitmode");
3338
ba92f887
MR
3339 if (e_flags & EF_MIPS_NAN2008)
3340 strcat (buf, ", nan2008");
3341
fef1b0b3
SE
3342 if (e_flags & EF_MIPS_FP64)
3343 strcat (buf, ", fp64");
3344
156c2f8b
NC
3345 switch ((e_flags & EF_MIPS_MACH))
3346 {
3347 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3348 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3349 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3350 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3351 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3352 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3353 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3354 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3355 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3356 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3357 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3358 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3359 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 3360 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 3361 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3362 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3363 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3364 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3365 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3366 case 0:
3367 /* We simply ignore the field in this case to avoid confusion:
3368 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3369 extension. */
3370 break;
2b692964 3371 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3372 }
43521d43
TS
3373
3374 switch ((e_flags & EF_MIPS_ABI))
3375 {
3376 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3377 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3378 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3379 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3380 case 0:
3381 /* We simply ignore the field in this case to avoid confusion:
3382 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3383 This means it is likely to be an o32 file, but not for
3384 sure. */
3385 break;
2b692964 3386 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3387 }
3388
3389 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3390 strcat (buf, ", mdmx");
3391
3392 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3393 strcat (buf, ", mips16");
3394
df58fc94
RS
3395 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3396 strcat (buf, ", micromips");
3397
43521d43
TS
3398 switch ((e_flags & EF_MIPS_ARCH))
3399 {
3400 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3401 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3402 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3403 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3404 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3405 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3406 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3407 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3408 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3409 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3410 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3411 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3412 }
252b5132 3413 break;
351b4b40 3414
35c08157
KLC
3415 case EM_NDS32:
3416 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3417 break;
3418
e23eba97
NC
3419 case EM_RISCV:
3420 if (e_flags & EF_RISCV_RVC)
3421 strcat (buf, ", RVC");
2922d21d
AW
3422
3423 switch (e_flags & EF_RISCV_FLOAT_ABI)
3424 {
3425 case EF_RISCV_FLOAT_ABI_SOFT:
3426 strcat (buf, ", soft-float ABI");
3427 break;
3428
3429 case EF_RISCV_FLOAT_ABI_SINGLE:
3430 strcat (buf, ", single-float ABI");
3431 break;
3432
3433 case EF_RISCV_FLOAT_ABI_DOUBLE:
3434 strcat (buf, ", double-float ABI");
3435 break;
3436
3437 case EF_RISCV_FLOAT_ABI_QUAD:
3438 strcat (buf, ", quad-float ABI");
3439 break;
3440 }
e23eba97
NC
3441 break;
3442
ccde1100
AO
3443 case EM_SH:
3444 switch ((e_flags & EF_SH_MACH_MASK))
3445 {
3446 case EF_SH1: strcat (buf, ", sh1"); break;
3447 case EF_SH2: strcat (buf, ", sh2"); break;
3448 case EF_SH3: strcat (buf, ", sh3"); break;
3449 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3450 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3451 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3452 case EF_SH3E: strcat (buf, ", sh3e"); break;
3453 case EF_SH4: strcat (buf, ", sh4"); break;
3454 case EF_SH5: strcat (buf, ", sh5"); break;
3455 case EF_SH2E: strcat (buf, ", sh2e"); break;
3456 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3457 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3458 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3459 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3460 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3461 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3462 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3463 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3464 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3465 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3466 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3467 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3468 }
3469
cec6a5b8
MR
3470 if (e_flags & EF_SH_PIC)
3471 strcat (buf, ", pic");
3472
3473 if (e_flags & EF_SH_FDPIC)
3474 strcat (buf, ", fdpic");
ccde1100 3475 break;
948f632f 3476
73589c9d
CS
3477 case EM_OR1K:
3478 if (e_flags & EF_OR1K_NODELAY)
3479 strcat (buf, ", no delay");
3480 break;
57346661 3481
351b4b40
RH
3482 case EM_SPARCV9:
3483 if (e_flags & EF_SPARC_32PLUS)
3484 strcat (buf, ", v8+");
3485
3486 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3487 strcat (buf, ", ultrasparcI");
3488
3489 if (e_flags & EF_SPARC_SUN_US3)
3490 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3491
3492 if (e_flags & EF_SPARC_HAL_R1)
3493 strcat (buf, ", halr1");
3494
3495 if (e_flags & EF_SPARC_LEDATA)
3496 strcat (buf, ", ledata");
3497
3498 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3499 strcat (buf, ", tso");
3500
3501 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3502 strcat (buf, ", pso");
3503
3504 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3505 strcat (buf, ", rmo");
3506 break;
7d466069 3507
103f02d3
UD
3508 case EM_PARISC:
3509 switch (e_flags & EF_PARISC_ARCH)
3510 {
3511 case EFA_PARISC_1_0:
3512 strcpy (buf, ", PA-RISC 1.0");
3513 break;
3514 case EFA_PARISC_1_1:
3515 strcpy (buf, ", PA-RISC 1.1");
3516 break;
3517 case EFA_PARISC_2_0:
3518 strcpy (buf, ", PA-RISC 2.0");
3519 break;
3520 default:
3521 break;
3522 }
3523 if (e_flags & EF_PARISC_TRAPNIL)
3524 strcat (buf, ", trapnil");
3525 if (e_flags & EF_PARISC_EXT)
3526 strcat (buf, ", ext");
3527 if (e_flags & EF_PARISC_LSB)
3528 strcat (buf, ", lsb");
3529 if (e_flags & EF_PARISC_WIDE)
3530 strcat (buf, ", wide");
3531 if (e_flags & EF_PARISC_NO_KABP)
3532 strcat (buf, ", no kabp");
3533 if (e_flags & EF_PARISC_LAZYSWAP)
3534 strcat (buf, ", lazyswap");
30800947 3535 break;
76da6bbe 3536
7d466069 3537 case EM_PJ:
2b0337b0 3538 case EM_PJ_OLD:
7d466069
ILT
3539 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3540 strcat (buf, ", new calling convention");
3541
3542 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3543 strcat (buf, ", gnu calling convention");
3544 break;
4d6ed7c8
NC
3545
3546 case EM_IA_64:
3547 if ((e_flags & EF_IA_64_ABI64))
3548 strcat (buf, ", 64-bit");
3549 else
3550 strcat (buf, ", 32-bit");
3551 if ((e_flags & EF_IA_64_REDUCEDFP))
3552 strcat (buf, ", reduced fp model");
3553 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3554 strcat (buf, ", no function descriptors, constant gp");
3555 else if ((e_flags & EF_IA_64_CONS_GP))
3556 strcat (buf, ", constant gp");
3557 if ((e_flags & EF_IA_64_ABSOLUTE))
3558 strcat (buf, ", absolute");
dda8d76d 3559 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3560 {
3561 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3562 strcat (buf, ", vms_linkages");
3563 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3564 {
3565 case EF_IA_64_VMS_COMCOD_SUCCESS:
3566 break;
3567 case EF_IA_64_VMS_COMCOD_WARNING:
3568 strcat (buf, ", warning");
3569 break;
3570 case EF_IA_64_VMS_COMCOD_ERROR:
3571 strcat (buf, ", error");
3572 break;
3573 case EF_IA_64_VMS_COMCOD_ABORT:
3574 strcat (buf, ", abort");
3575 break;
3576 default:
bee0ee85
NC
3577 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3578 e_flags & EF_IA_64_VMS_COMCOD);
3579 strcat (buf, ", <unknown>");
28f997cf
TG
3580 }
3581 }
4d6ed7c8 3582 break;
179d3252
JT
3583
3584 case EM_VAX:
3585 if ((e_flags & EF_VAX_NONPIC))
3586 strcat (buf, ", non-PIC");
3587 if ((e_flags & EF_VAX_DFLOAT))
3588 strcat (buf, ", D-Float");
3589 if ((e_flags & EF_VAX_GFLOAT))
3590 strcat (buf, ", G-Float");
3591 break;
c7927a3c 3592
619ed720
EB
3593 case EM_VISIUM:
3594 if (e_flags & EF_VISIUM_ARCH_MCM)
3595 strcat (buf, ", mcm");
3596 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3597 strcat (buf, ", mcm24");
3598 if (e_flags & EF_VISIUM_ARCH_GR6)
3599 strcat (buf, ", gr6");
3600 break;
3601
4046d87a 3602 case EM_RL78:
1740ba0c
NC
3603 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3604 {
3605 case E_FLAG_RL78_ANY_CPU: break;
3606 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3607 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3608 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3609 }
856ea05c
KP
3610 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3611 strcat (buf, ", 64-bit doubles");
4046d87a 3612 break;
0b4362b0 3613
c7927a3c
NC
3614 case EM_RX:
3615 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3616 strcat (buf, ", 64-bit doubles");
3617 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3618 strcat (buf, ", dsp");
d4cb0ea0 3619 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3620 strcat (buf, ", pid");
708e2187
NC
3621 if (e_flags & E_FLAG_RX_ABI)
3622 strcat (buf, ", RX ABI");
3525236c
NC
3623 if (e_flags & E_FLAG_RX_SINSNS_SET)
3624 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3625 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3626 if (e_flags & E_FLAG_RX_V2)
3627 strcat (buf, ", V2");
d4cb0ea0 3628 break;
55786da2
AK
3629
3630 case EM_S390:
3631 if (e_flags & EF_S390_HIGH_GPRS)
3632 strcat (buf, ", highgprs");
d4cb0ea0 3633 break;
40b36596
JM
3634
3635 case EM_TI_C6000:
3636 if ((e_flags & EF_C6000_REL))
3637 strcat (buf, ", relocatable module");
d4cb0ea0 3638 break;
13761a11
NC
3639
3640 case EM_MSP430:
3641 strcat (buf, _(": architecture variant: "));
3642 switch (e_flags & EF_MSP430_MACH)
3643 {
3644 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3645 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3646 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3647 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3648 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3649 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3650 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3651 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3652 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3653 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3654 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3655 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3656 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3657 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3658 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3659 default:
3660 strcat (buf, _(": unknown")); break;
3661 }
3662
3663 if (e_flags & ~ EF_MSP430_MACH)
3664 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3665 }
3666 }
3667
3668 return buf;
3669}
3670
252b5132 3671static const char *
dda8d76d 3672get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3673{
3674 static char buff[32];
3675
3676 switch (osabi)
3677 {
3678 case ELFOSABI_NONE: return "UNIX - System V";
3679 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3680 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3681 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3682 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3683 case ELFOSABI_AIX: return "UNIX - AIX";
3684 case ELFOSABI_IRIX: return "UNIX - IRIX";
3685 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3686 case ELFOSABI_TRU64: return "UNIX - TRU64";
3687 case ELFOSABI_MODESTO: return "Novell - Modesto";
3688 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3689 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3690 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3691 case ELFOSABI_AROS: return "AROS";
11636f9e 3692 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3693 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3694 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3695 default:
40b36596 3696 if (osabi >= 64)
dda8d76d 3697 switch (filedata->file_header.e_machine)
40b36596
JM
3698 {
3699 case EM_ARM:
3700 switch (osabi)
3701 {
3702 case ELFOSABI_ARM: return "ARM";
3703 default:
3704 break;
3705 }
3706 break;
3707
3708 case EM_MSP430:
3709 case EM_MSP430_OLD:
619ed720 3710 case EM_VISIUM:
40b36596
JM
3711 switch (osabi)
3712 {
3713 case ELFOSABI_STANDALONE: return _("Standalone App");
3714 default:
3715 break;
3716 }
3717 break;
3718
3719 case EM_TI_C6000:
3720 switch (osabi)
3721 {
3722 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3723 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3724 default:
3725 break;
3726 }
3727 break;
3728
3729 default:
3730 break;
3731 }
e9e44622 3732 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3733 return buff;
3734 }
3735}
3736
a06ea964
NC
3737static const char *
3738get_aarch64_segment_type (unsigned long type)
3739{
3740 switch (type)
3741 {
32ec8896
NC
3742 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3743 default: return NULL;
a06ea964 3744 }
a06ea964
NC
3745}
3746
b294bdf8
MM
3747static const char *
3748get_arm_segment_type (unsigned long type)
3749{
3750 switch (type)
3751 {
32ec8896
NC
3752 case PT_ARM_EXIDX: return "EXIDX";
3753 default: return NULL;
b294bdf8 3754 }
b294bdf8
MM
3755}
3756
b4cbbe8f
AK
3757static const char *
3758get_s390_segment_type (unsigned long type)
3759{
3760 switch (type)
3761 {
3762 case PT_S390_PGSTE: return "S390_PGSTE";
3763 default: return NULL;
3764 }
3765}
3766
d3ba0551
AM
3767static const char *
3768get_mips_segment_type (unsigned long type)
252b5132
RH
3769{
3770 switch (type)
3771 {
32ec8896
NC
3772 case PT_MIPS_REGINFO: return "REGINFO";
3773 case PT_MIPS_RTPROC: return "RTPROC";
3774 case PT_MIPS_OPTIONS: return "OPTIONS";
3775 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3776 default: return NULL;
252b5132 3777 }
252b5132
RH
3778}
3779
103f02d3 3780static const char *
d3ba0551 3781get_parisc_segment_type (unsigned long type)
103f02d3
UD
3782{
3783 switch (type)
3784 {
3785 case PT_HP_TLS: return "HP_TLS";
3786 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3787 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3788 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3789 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3790 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3791 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3792 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3793 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3794 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3795 case PT_HP_PARALLEL: return "HP_PARALLEL";
3796 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3797 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3798 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3799 case PT_HP_STACK: return "HP_STACK";
3800 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3801 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3802 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3803 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3804 default: return NULL;
103f02d3 3805 }
103f02d3
UD
3806}
3807
4d6ed7c8 3808static const char *
d3ba0551 3809get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3810{
3811 switch (type)
3812 {
3813 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3814 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3815 case PT_HP_TLS: return "HP_TLS";
3816 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3817 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3818 case PT_IA_64_HP_STACK: return "HP_STACK";
32ec8896 3819 default: return NULL;
4d6ed7c8 3820 }
4d6ed7c8
NC
3821}
3822
40b36596
JM
3823static const char *
3824get_tic6x_segment_type (unsigned long type)
3825{
3826 switch (type)
3827 {
32ec8896
NC
3828 case PT_C6000_PHATTR: return "C6000_PHATTR";
3829 default: return NULL;
40b36596 3830 }
40b36596
JM
3831}
3832
5522f910
NC
3833static const char *
3834get_solaris_segment_type (unsigned long type)
3835{
3836 switch (type)
3837 {
3838 case 0x6464e550: return "PT_SUNW_UNWIND";
3839 case 0x6474e550: return "PT_SUNW_EH_FRAME";
3840 case 0x6ffffff7: return "PT_LOSUNW";
3841 case 0x6ffffffa: return "PT_SUNWBSS";
3842 case 0x6ffffffb: return "PT_SUNWSTACK";
3843 case 0x6ffffffc: return "PT_SUNWDTRACE";
3844 case 0x6ffffffd: return "PT_SUNWCAP";
3845 case 0x6fffffff: return "PT_HISUNW";
32ec8896 3846 default: return NULL;
5522f910
NC
3847 }
3848}
3849
252b5132 3850static const char *
dda8d76d 3851get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 3852{
b34976b6 3853 static char buff[32];
252b5132
RH
3854
3855 switch (p_type)
3856 {
b34976b6
AM
3857 case PT_NULL: return "NULL";
3858 case PT_LOAD: return "LOAD";
252b5132 3859 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3860 case PT_INTERP: return "INTERP";
3861 case PT_NOTE: return "NOTE";
3862 case PT_SHLIB: return "SHLIB";
3863 case PT_PHDR: return "PHDR";
13ae64f3 3864 case PT_TLS: return "TLS";
32ec8896 3865 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 3866 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3867 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3868
252b5132 3869 default:
a91e1603
L
3870 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
3871 {
3872 sprintf (buff, "GNU_MBIND+%#lx",
3873 p_type - PT_GNU_MBIND_LO);
3874 }
3875 else if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 3876 {
2cf0635d 3877 const char * result;
103f02d3 3878
dda8d76d 3879 switch (filedata->file_header.e_machine)
252b5132 3880 {
a06ea964
NC
3881 case EM_AARCH64:
3882 result = get_aarch64_segment_type (p_type);
3883 break;
b294bdf8
MM
3884 case EM_ARM:
3885 result = get_arm_segment_type (p_type);
3886 break;
252b5132 3887 case EM_MIPS:
4fe85591 3888 case EM_MIPS_RS3_LE:
252b5132
RH
3889 result = get_mips_segment_type (p_type);
3890 break;
103f02d3
UD
3891 case EM_PARISC:
3892 result = get_parisc_segment_type (p_type);
3893 break;
4d6ed7c8
NC
3894 case EM_IA_64:
3895 result = get_ia64_segment_type (p_type);
3896 break;
40b36596
JM
3897 case EM_TI_C6000:
3898 result = get_tic6x_segment_type (p_type);
3899 break;
b4cbbe8f
AK
3900 case EM_S390:
3901 case EM_S390_OLD:
3902 result = get_s390_segment_type (p_type);
3903 break;
252b5132
RH
3904 default:
3905 result = NULL;
3906 break;
3907 }
103f02d3 3908
252b5132
RH
3909 if (result != NULL)
3910 return result;
103f02d3 3911
1a9ccd70 3912 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
3913 }
3914 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3915 {
2cf0635d 3916 const char * result;
103f02d3 3917
dda8d76d 3918 switch (filedata->file_header.e_machine)
103f02d3
UD
3919 {
3920 case EM_PARISC:
3921 result = get_parisc_segment_type (p_type);
3922 break;
00428cca
AM
3923 case EM_IA_64:
3924 result = get_ia64_segment_type (p_type);
3925 break;
103f02d3 3926 default:
dda8d76d 3927 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5522f910
NC
3928 result = get_solaris_segment_type (p_type);
3929 else
3930 result = NULL;
103f02d3
UD
3931 break;
3932 }
3933
3934 if (result != NULL)
3935 return result;
3936
1a9ccd70 3937 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 3938 }
252b5132 3939 else
e9e44622 3940 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3941
3942 return buff;
3943 }
3944}
3945
53a346d8
CZ
3946static const char *
3947get_arc_section_type_name (unsigned int sh_type)
3948{
3949 switch (sh_type)
3950 {
3951 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
3952 default:
3953 break;
3954 }
3955 return NULL;
3956}
3957
252b5132 3958static const char *
d3ba0551 3959get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3960{
3961 switch (sh_type)
3962 {
b34976b6
AM
3963 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3964 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3965 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3966 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3967 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3968 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3969 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3970 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3971 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3972 case SHT_MIPS_RELD: return "MIPS_RELD";
3973 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3974 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3975 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3976 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3977 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3978 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3979 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3980 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3981 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3982 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3983 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3984 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3985 case SHT_MIPS_LINE: return "MIPS_LINE";
3986 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3987 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3988 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3989 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3990 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3991 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3992 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3993 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3994 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3995 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3996 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3997 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3998 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3999 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4000 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4001 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4002 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
4003 default:
4004 break;
4005 }
4006 return NULL;
4007}
4008
103f02d3 4009static const char *
d3ba0551 4010get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4011{
4012 switch (sh_type)
4013 {
4014 case SHT_PARISC_EXT: return "PARISC_EXT";
4015 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4016 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4017 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4018 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4019 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4020 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4021 default: return NULL;
103f02d3 4022 }
103f02d3
UD
4023}
4024
4d6ed7c8 4025static const char *
dda8d76d 4026get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4027{
18bd398b 4028 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4029 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4030 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4031
4d6ed7c8
NC
4032 switch (sh_type)
4033 {
148b93f2
NC
4034 case SHT_IA_64_EXT: return "IA_64_EXT";
4035 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4036 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4037 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4038 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4039 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4040 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4041 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4042 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4043 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4044 default:
4045 break;
4046 }
4047 return NULL;
4048}
4049
d2b2c203
DJ
4050static const char *
4051get_x86_64_section_type_name (unsigned int sh_type)
4052{
4053 switch (sh_type)
4054 {
4055 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4056 default: return NULL;
d2b2c203 4057 }
d2b2c203
DJ
4058}
4059
a06ea964
NC
4060static const char *
4061get_aarch64_section_type_name (unsigned int sh_type)
4062{
4063 switch (sh_type)
4064 {
32ec8896
NC
4065 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4066 default: return NULL;
a06ea964 4067 }
a06ea964
NC
4068}
4069
40a18ebd
NC
4070static const char *
4071get_arm_section_type_name (unsigned int sh_type)
4072{
4073 switch (sh_type)
4074 {
7f6fed87
NC
4075 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4076 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4077 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4078 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4079 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4080 default: return NULL;
40a18ebd 4081 }
40a18ebd
NC
4082}
4083
40b36596
JM
4084static const char *
4085get_tic6x_section_type_name (unsigned int sh_type)
4086{
4087 switch (sh_type)
4088 {
32ec8896
NC
4089 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4090 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4091 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4092 case SHT_TI_ICODE: return "TI_ICODE";
4093 case SHT_TI_XREF: return "TI_XREF";
4094 case SHT_TI_HANDLER: return "TI_HANDLER";
4095 case SHT_TI_INITINFO: return "TI_INITINFO";
4096 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4097 default: return NULL;
40b36596 4098 }
40b36596
JM
4099}
4100
13761a11
NC
4101static const char *
4102get_msp430x_section_type_name (unsigned int sh_type)
4103{
4104 switch (sh_type)
4105 {
32ec8896
NC
4106 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4107 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4108 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4109 default: return NULL;
13761a11
NC
4110 }
4111}
4112
685080f2
NC
4113static const char *
4114get_v850_section_type_name (unsigned int sh_type)
4115{
4116 switch (sh_type)
4117 {
32ec8896
NC
4118 case SHT_V850_SCOMMON: return "V850 Small Common";
4119 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4120 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4121 case SHT_RENESAS_IOP: return "RENESAS IOP";
4122 case SHT_RENESAS_INFO: return "RENESAS INFO";
4123 default: return NULL;
685080f2
NC
4124 }
4125}
4126
252b5132 4127static const char *
dda8d76d 4128get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4129{
b34976b6 4130 static char buff[32];
9fb71ee4 4131 const char * result;
252b5132
RH
4132
4133 switch (sh_type)
4134 {
4135 case SHT_NULL: return "NULL";
4136 case SHT_PROGBITS: return "PROGBITS";
4137 case SHT_SYMTAB: return "SYMTAB";
4138 case SHT_STRTAB: return "STRTAB";
4139 case SHT_RELA: return "RELA";
4140 case SHT_HASH: return "HASH";
4141 case SHT_DYNAMIC: return "DYNAMIC";
4142 case SHT_NOTE: return "NOTE";
4143 case SHT_NOBITS: return "NOBITS";
4144 case SHT_REL: return "REL";
4145 case SHT_SHLIB: return "SHLIB";
4146 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4147 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4148 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4149 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4150 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
4151 case SHT_GROUP: return "GROUP";
4152 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
4153 case SHT_GNU_verdef: return "VERDEF";
4154 case SHT_GNU_verneed: return "VERNEED";
4155 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4156 case 0x6ffffff0: return "VERSYM";
4157 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4158 case 0x7ffffffd: return "AUXILIARY";
4159 case 0x7fffffff: return "FILTER";
047b2264 4160 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4161
4162 default:
4163 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4164 {
dda8d76d 4165 switch (filedata->file_header.e_machine)
252b5132 4166 {
53a346d8
CZ
4167 case EM_ARC:
4168 case EM_ARC_COMPACT:
4169 case EM_ARC_COMPACT2:
4170 result = get_arc_section_type_name (sh_type);
4171 break;
252b5132 4172 case EM_MIPS:
4fe85591 4173 case EM_MIPS_RS3_LE:
252b5132
RH
4174 result = get_mips_section_type_name (sh_type);
4175 break;
103f02d3
UD
4176 case EM_PARISC:
4177 result = get_parisc_section_type_name (sh_type);
4178 break;
4d6ed7c8 4179 case EM_IA_64:
dda8d76d 4180 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4181 break;
d2b2c203 4182 case EM_X86_64:
8a9036a4 4183 case EM_L1OM:
7a9068fe 4184 case EM_K1OM:
d2b2c203
DJ
4185 result = get_x86_64_section_type_name (sh_type);
4186 break;
a06ea964
NC
4187 case EM_AARCH64:
4188 result = get_aarch64_section_type_name (sh_type);
4189 break;
40a18ebd
NC
4190 case EM_ARM:
4191 result = get_arm_section_type_name (sh_type);
4192 break;
40b36596
JM
4193 case EM_TI_C6000:
4194 result = get_tic6x_section_type_name (sh_type);
4195 break;
13761a11
NC
4196 case EM_MSP430:
4197 result = get_msp430x_section_type_name (sh_type);
4198 break;
685080f2
NC
4199 case EM_V800:
4200 case EM_V850:
4201 case EM_CYGNUS_V850:
4202 result = get_v850_section_type_name (sh_type);
4203 break;
252b5132
RH
4204 default:
4205 result = NULL;
4206 break;
4207 }
4208
4209 if (result != NULL)
4210 return result;
4211
9fb71ee4 4212 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4213 }
4214 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4215 {
dda8d76d 4216 switch (filedata->file_header.e_machine)
148b93f2
NC
4217 {
4218 case EM_IA_64:
dda8d76d 4219 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4220 break;
4221 default:
dda8d76d 4222 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4223 result = get_solaris_section_type (sh_type);
4224 else
1b4b80bf
NC
4225 {
4226 switch (sh_type)
4227 {
4228 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4229 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4230 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4231 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4232 default:
4233 result = NULL;
4234 break;
4235 }
4236 }
148b93f2
NC
4237 break;
4238 }
4239
4240 if (result != NULL)
4241 return result;
4242
9fb71ee4 4243 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4244 }
252b5132 4245 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4246 {
dda8d76d 4247 switch (filedata->file_header.e_machine)
685080f2
NC
4248 {
4249 case EM_V800:
4250 case EM_V850:
4251 case EM_CYGNUS_V850:
9fb71ee4 4252 result = get_v850_section_type_name (sh_type);
a9fb83be 4253 break;
685080f2 4254 default:
9fb71ee4 4255 result = NULL;
685080f2
NC
4256 break;
4257 }
4258
9fb71ee4
NC
4259 if (result != NULL)
4260 return result;
4261
4262 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4263 }
252b5132 4264 else
a7dbfd1c
NC
4265 /* This message is probably going to be displayed in a 15
4266 character wide field, so put the hex value first. */
4267 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4268
252b5132
RH
4269 return buff;
4270 }
4271}
4272
2979dc34 4273#define OPTION_DEBUG_DUMP 512
2c610e4b 4274#define OPTION_DYN_SYMS 513
fd2f0033
TT
4275#define OPTION_DWARF_DEPTH 514
4276#define OPTION_DWARF_START 515
4723351a 4277#define OPTION_DWARF_CHECK 516
2979dc34 4278
85b1c36d 4279static struct option options[] =
252b5132 4280{
b34976b6 4281 {"all", no_argument, 0, 'a'},
252b5132
RH
4282 {"file-header", no_argument, 0, 'h'},
4283 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4284 {"headers", no_argument, 0, 'e'},
4285 {"histogram", no_argument, 0, 'I'},
4286 {"segments", no_argument, 0, 'l'},
4287 {"sections", no_argument, 0, 'S'},
252b5132 4288 {"section-headers", no_argument, 0, 'S'},
f5842774 4289 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4290 {"section-details", no_argument, 0, 't'},
595cf52e 4291 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4292 {"symbols", no_argument, 0, 's'},
4293 {"syms", no_argument, 0, 's'},
2c610e4b 4294 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4295 {"relocs", no_argument, 0, 'r'},
4296 {"notes", no_argument, 0, 'n'},
4297 {"dynamic", no_argument, 0, 'd'},
a952a375 4298 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4299 {"version-info", no_argument, 0, 'V'},
4300 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4301 {"unwind", no_argument, 0, 'u'},
4145f1d5 4302 {"archive-index", no_argument, 0, 'c'},
b34976b6 4303 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4304 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4305 {"string-dump", required_argument, 0, 'p'},
0e602686 4306 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4307#ifdef SUPPORT_DISASSEMBLY
4308 {"instruction-dump", required_argument, 0, 'i'},
4309#endif
cf13d699 4310 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4311
fd2f0033
TT
4312 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4313 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4314 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4315
b34976b6
AM
4316 {"version", no_argument, 0, 'v'},
4317 {"wide", no_argument, 0, 'W'},
4318 {"help", no_argument, 0, 'H'},
4319 {0, no_argument, 0, 0}
252b5132
RH
4320};
4321
4322static void
2cf0635d 4323usage (FILE * stream)
252b5132 4324{
92f01d61
JM
4325 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4326 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4327 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4328 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4329 -h --file-header Display the ELF file header\n\
4330 -l --program-headers Display the program headers\n\
4331 --segments An alias for --program-headers\n\
4332 -S --section-headers Display the sections' header\n\
4333 --sections An alias for --section-headers\n\
f5842774 4334 -g --section-groups Display the section groups\n\
5477e8a0 4335 -t --section-details Display the section details\n\
8b53311e
NC
4336 -e --headers Equivalent to: -h -l -S\n\
4337 -s --syms Display the symbol table\n\
3f08eb35 4338 --symbols An alias for --syms\n\
2c610e4b 4339 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4340 -n --notes Display the core notes (if present)\n\
4341 -r --relocs Display the relocations (if present)\n\
4342 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4343 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4344 -V --version-info Display the version sections (if present)\n\
1b31d05e 4345 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4346 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4347 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
4348 -x --hex-dump=<number|name>\n\
4349 Dump the contents of section <number|name> as bytes\n\
4350 -p --string-dump=<number|name>\n\
4351 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4352 -R --relocated-dump=<number|name>\n\
4353 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4354 -z --decompress Decompress section before dumping it\n\
dda8d76d 4355 -w[lLiaprmfFsoRtUuTgAckK] or\n\
1ed06042 4356 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4357 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47 4358 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4359 =addr,=cu_index,=links,=follow-links]\n\
4360 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4361 fprintf (stream, _("\
4362 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4363 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4364 or deeper\n"));
252b5132 4365#ifdef SUPPORT_DISASSEMBLY
92f01d61 4366 fprintf (stream, _("\
09c11c86
NC
4367 -i --instruction-dump=<number|name>\n\
4368 Disassemble the contents of section <number|name>\n"));
252b5132 4369#endif
92f01d61 4370 fprintf (stream, _("\
8b53311e
NC
4371 -I --histogram Display histogram of bucket list lengths\n\
4372 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4373 @<file> Read options from <file>\n\
8b53311e
NC
4374 -H --help Display this information\n\
4375 -v --version Display the version number of readelf\n"));
1118d252 4376
92f01d61
JM
4377 if (REPORT_BUGS_TO[0] && stream == stdout)
4378 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4379
92f01d61 4380 exit (stream == stdout ? 0 : 1);
252b5132
RH
4381}
4382
18bd398b
NC
4383/* Record the fact that the user wants the contents of section number
4384 SECTION to be displayed using the method(s) encoded as flags bits
4385 in TYPE. Note, TYPE can be zero if we are creating the array for
4386 the first time. */
4387
252b5132 4388static void
dda8d76d 4389request_dump_bynumber (Filedata * filedata, unsigned int section, dump_type type)
252b5132 4390{
dda8d76d 4391 if (section >= filedata->num_dump_sects)
252b5132 4392 {
2cf0635d 4393 dump_type * new_dump_sects;
252b5132 4394
3f5e193b 4395 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4396 sizeof (* new_dump_sects));
252b5132
RH
4397
4398 if (new_dump_sects == NULL)
591a748a 4399 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4400 else
4401 {
dda8d76d 4402 if (filedata->dump_sects)
21b65bac
NC
4403 {
4404 /* Copy current flag settings. */
dda8d76d
NC
4405 memcpy (new_dump_sects, filedata->dump_sects,
4406 filedata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4407
dda8d76d 4408 free (filedata->dump_sects);
21b65bac 4409 }
252b5132 4410
dda8d76d
NC
4411 filedata->dump_sects = new_dump_sects;
4412 filedata->num_dump_sects = section + 1;
252b5132
RH
4413 }
4414 }
4415
dda8d76d
NC
4416 if (filedata->dump_sects)
4417 filedata->dump_sects[section] |= type;
252b5132
RH
4418}
4419
aef1f6d0
DJ
4420/* Request a dump by section name. */
4421
4422static void
2cf0635d 4423request_dump_byname (const char * section, dump_type type)
aef1f6d0 4424{
2cf0635d 4425 struct dump_list_entry * new_request;
aef1f6d0 4426
3f5e193b
NC
4427 new_request = (struct dump_list_entry *)
4428 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4429 if (!new_request)
591a748a 4430 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4431
4432 new_request->name = strdup (section);
4433 if (!new_request->name)
591a748a 4434 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4435
4436 new_request->type = type;
4437
4438 new_request->next = dump_sects_byname;
4439 dump_sects_byname = new_request;
4440}
4441
cf13d699 4442static inline void
dda8d76d 4443request_dump (Filedata * filedata, dump_type type)
cf13d699
NC
4444{
4445 int section;
4446 char * cp;
4447
4448 do_dump++;
4449 section = strtoul (optarg, & cp, 0);
4450
4451 if (! *cp && section >= 0)
dda8d76d 4452 request_dump_bynumber (filedata, section, type);
cf13d699
NC
4453 else
4454 request_dump_byname (optarg, type);
4455}
4456
252b5132 4457static void
dda8d76d 4458parse_args (Filedata * filedata, int argc, char ** argv)
252b5132
RH
4459{
4460 int c;
4461
4462 if (argc < 2)
92f01d61 4463 usage (stderr);
252b5132
RH
4464
4465 while ((c = getopt_long
0e602686 4466 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4467 {
252b5132
RH
4468 switch (c)
4469 {
4470 case 0:
4471 /* Long options. */
4472 break;
4473 case 'H':
92f01d61 4474 usage (stdout);
252b5132
RH
4475 break;
4476
4477 case 'a':
32ec8896
NC
4478 do_syms = TRUE;
4479 do_reloc = TRUE;
4480 do_unwind = TRUE;
4481 do_dynamic = TRUE;
4482 do_header = TRUE;
4483 do_sections = TRUE;
4484 do_section_groups = TRUE;
4485 do_segments = TRUE;
4486 do_version = TRUE;
4487 do_histogram = TRUE;
4488 do_arch = TRUE;
4489 do_notes = TRUE;
252b5132 4490 break;
f5842774 4491 case 'g':
32ec8896 4492 do_section_groups = TRUE;
f5842774 4493 break;
5477e8a0 4494 case 't':
595cf52e 4495 case 'N':
32ec8896
NC
4496 do_sections = TRUE;
4497 do_section_details = TRUE;
595cf52e 4498 break;
252b5132 4499 case 'e':
32ec8896
NC
4500 do_header = TRUE;
4501 do_sections = TRUE;
4502 do_segments = TRUE;
252b5132 4503 break;
a952a375 4504 case 'A':
32ec8896 4505 do_arch = TRUE;
a952a375 4506 break;
252b5132 4507 case 'D':
32ec8896 4508 do_using_dynamic = TRUE;
252b5132
RH
4509 break;
4510 case 'r':
32ec8896 4511 do_reloc = TRUE;
252b5132 4512 break;
4d6ed7c8 4513 case 'u':
32ec8896 4514 do_unwind = TRUE;
4d6ed7c8 4515 break;
252b5132 4516 case 'h':
32ec8896 4517 do_header = TRUE;
252b5132
RH
4518 break;
4519 case 'l':
32ec8896 4520 do_segments = TRUE;
252b5132
RH
4521 break;
4522 case 's':
32ec8896 4523 do_syms = TRUE;
252b5132
RH
4524 break;
4525 case 'S':
32ec8896 4526 do_sections = TRUE;
252b5132
RH
4527 break;
4528 case 'd':
32ec8896 4529 do_dynamic = TRUE;
252b5132 4530 break;
a952a375 4531 case 'I':
32ec8896 4532 do_histogram = TRUE;
a952a375 4533 break;
779fe533 4534 case 'n':
32ec8896 4535 do_notes = TRUE;
779fe533 4536 break;
4145f1d5 4537 case 'c':
32ec8896 4538 do_archive_index = TRUE;
4145f1d5 4539 break;
252b5132 4540 case 'x':
dda8d76d 4541 request_dump (filedata, HEX_DUMP);
aef1f6d0 4542 break;
09c11c86 4543 case 'p':
dda8d76d 4544 request_dump (filedata, STRING_DUMP);
cf13d699
NC
4545 break;
4546 case 'R':
dda8d76d 4547 request_dump (filedata, RELOC_DUMP);
09c11c86 4548 break;
0e602686 4549 case 'z':
32ec8896 4550 decompress_dumps = TRUE;
0e602686 4551 break;
252b5132 4552 case 'w':
32ec8896 4553 do_dump = TRUE;
252b5132 4554 if (optarg == 0)
613ff48b 4555 {
32ec8896 4556 do_debugging = TRUE;
613ff48b
CC
4557 dwarf_select_sections_all ();
4558 }
252b5132
RH
4559 else
4560 {
32ec8896 4561 do_debugging = FALSE;
4cb93e3b 4562 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4563 }
4564 break;
2979dc34 4565 case OPTION_DEBUG_DUMP:
32ec8896 4566 do_dump = TRUE;
2979dc34 4567 if (optarg == 0)
32ec8896 4568 do_debugging = TRUE;
2979dc34
JJ
4569 else
4570 {
32ec8896 4571 do_debugging = FALSE;
4cb93e3b 4572 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4573 }
4574 break;
fd2f0033
TT
4575 case OPTION_DWARF_DEPTH:
4576 {
4577 char *cp;
4578
4579 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4580 }
4581 break;
4582 case OPTION_DWARF_START:
4583 {
4584 char *cp;
4585
4586 dwarf_start_die = strtoul (optarg, & cp, 0);
4587 }
4588 break;
4723351a 4589 case OPTION_DWARF_CHECK:
32ec8896 4590 dwarf_check = TRUE;
4723351a 4591 break;
2c610e4b 4592 case OPTION_DYN_SYMS:
32ec8896 4593 do_dyn_syms = TRUE;
2c610e4b 4594 break;
252b5132
RH
4595#ifdef SUPPORT_DISASSEMBLY
4596 case 'i':
dda8d76d 4597 request_dump (filedata, DISASS_DUMP);
cf13d699 4598 break;
252b5132
RH
4599#endif
4600 case 'v':
4601 print_version (program_name);
4602 break;
4603 case 'V':
32ec8896 4604 do_version = TRUE;
252b5132 4605 break;
d974e256 4606 case 'W':
32ec8896 4607 do_wide = TRUE;
d974e256 4608 break;
252b5132 4609 default:
252b5132
RH
4610 /* xgettext:c-format */
4611 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4612 /* Fall through. */
252b5132 4613 case '?':
92f01d61 4614 usage (stderr);
252b5132
RH
4615 }
4616 }
4617
4d6ed7c8 4618 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4619 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4620 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4621 && !do_section_groups && !do_archive_index
4622 && !do_dyn_syms)
92f01d61 4623 usage (stderr);
252b5132
RH
4624}
4625
4626static const char *
d3ba0551 4627get_elf_class (unsigned int elf_class)
252b5132 4628{
b34976b6 4629 static char buff[32];
103f02d3 4630
252b5132
RH
4631 switch (elf_class)
4632 {
4633 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4634 case ELFCLASS32: return "ELF32";
4635 case ELFCLASS64: return "ELF64";
ab5e7794 4636 default:
e9e44622 4637 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4638 return buff;
252b5132
RH
4639 }
4640}
4641
4642static const char *
d3ba0551 4643get_data_encoding (unsigned int encoding)
252b5132 4644{
b34976b6 4645 static char buff[32];
103f02d3 4646
252b5132
RH
4647 switch (encoding)
4648 {
4649 case ELFDATANONE: return _("none");
33c63f9d
CM
4650 case ELFDATA2LSB: return _("2's complement, little endian");
4651 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4652 default:
e9e44622 4653 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4654 return buff;
252b5132
RH
4655 }
4656}
4657
dda8d76d 4658/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4659
32ec8896 4660static bfd_boolean
dda8d76d 4661process_file_header (Filedata * filedata)
252b5132 4662{
dda8d76d
NC
4663 Elf_Internal_Ehdr * header = & filedata->file_header;
4664
4665 if ( header->e_ident[EI_MAG0] != ELFMAG0
4666 || header->e_ident[EI_MAG1] != ELFMAG1
4667 || header->e_ident[EI_MAG2] != ELFMAG2
4668 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4669 {
4670 error
4671 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4672 return FALSE;
252b5132
RH
4673 }
4674
dda8d76d 4675 init_dwarf_regnames (header->e_machine);
2dc4cec1 4676
252b5132
RH
4677 if (do_header)
4678 {
32ec8896 4679 unsigned i;
252b5132
RH
4680
4681 printf (_("ELF Header:\n"));
4682 printf (_(" Magic: "));
b34976b6 4683 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4684 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4685 printf ("\n");
4686 printf (_(" Class: %s\n"),
dda8d76d 4687 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4688 printf (_(" Data: %s\n"),
dda8d76d 4689 get_data_encoding (header->e_ident[EI_DATA]));
252b5132 4690 printf (_(" Version: %d %s\n"),
dda8d76d
NC
4691 header->e_ident[EI_VERSION],
4692 (header->e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4693 ? "(current)"
dda8d76d 4694 : (header->e_ident[EI_VERSION] != EV_NONE
2b692964 4695 ? _("<unknown: %lx>")
789be9f7 4696 : "")));
252b5132 4697 printf (_(" OS/ABI: %s\n"),
dda8d76d 4698 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 4699 printf (_(" ABI Version: %d\n"),
dda8d76d 4700 header->e_ident[EI_ABIVERSION]);
252b5132 4701 printf (_(" Type: %s\n"),
dda8d76d 4702 get_file_type (header->e_type));
252b5132 4703 printf (_(" Machine: %s\n"),
dda8d76d 4704 get_machine_name (header->e_machine));
252b5132 4705 printf (_(" Version: 0x%lx\n"),
dda8d76d 4706 (unsigned long) header->e_version);
76da6bbe 4707
f7a99963 4708 printf (_(" Entry point address: "));
dda8d76d 4709 print_vma ((bfd_vma) header->e_entry, PREFIX_HEX);
f7a99963 4710 printf (_("\n Start of program headers: "));
dda8d76d 4711 print_vma ((bfd_vma) header->e_phoff, DEC);
f7a99963 4712 printf (_(" (bytes into file)\n Start of section headers: "));
dda8d76d 4713 print_vma ((bfd_vma) header->e_shoff, DEC);
f7a99963 4714 printf (_(" (bytes into file)\n"));
76da6bbe 4715
252b5132 4716 printf (_(" Flags: 0x%lx%s\n"),
dda8d76d
NC
4717 (unsigned long) header->e_flags,
4718 get_machine_flags (filedata, header->e_flags, header->e_machine));
252b5132 4719 printf (_(" Size of this header: %ld (bytes)\n"),
dda8d76d 4720 (long) header->e_ehsize);
252b5132 4721 printf (_(" Size of program headers: %ld (bytes)\n"),
dda8d76d 4722 (long) header->e_phentsize);
2046a35d 4723 printf (_(" Number of program headers: %ld"),
dda8d76d
NC
4724 (long) header->e_phnum);
4725 if (filedata->section_headers != NULL
4726 && header->e_phnum == PN_XNUM
4727 && filedata->section_headers[0].sh_info != 0)
4728 printf (" (%ld)", (long) filedata->section_headers[0].sh_info);
2046a35d 4729 putc ('\n', stdout);
252b5132 4730 printf (_(" Size of section headers: %ld (bytes)\n"),
dda8d76d 4731 (long) header->e_shentsize);
560f3c1c 4732 printf (_(" Number of section headers: %ld"),
dda8d76d
NC
4733 (long) header->e_shnum);
4734 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
4735 printf (" (%ld)", (long) filedata->section_headers[0].sh_size);
560f3c1c
AM
4736 putc ('\n', stdout);
4737 printf (_(" Section header string table index: %ld"),
dda8d76d
NC
4738 (long) header->e_shstrndx);
4739 if (filedata->section_headers != NULL
4740 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
4741 printf (" (%u)", filedata->section_headers[0].sh_link);
4742 else if (header->e_shstrndx != SHN_UNDEF
4743 && header->e_shstrndx >= header->e_shnum)
2b692964 4744 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4745 putc ('\n', stdout);
4746 }
4747
dda8d76d 4748 if (filedata->section_headers != NULL)
560f3c1c 4749 {
dda8d76d
NC
4750 if (header->e_phnum == PN_XNUM
4751 && filedata->section_headers[0].sh_info != 0)
4752 header->e_phnum = filedata->section_headers[0].sh_info;
4753 if (header->e_shnum == SHN_UNDEF)
4754 header->e_shnum = filedata->section_headers[0].sh_size;
4755 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
4756 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 4757 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
4758 header->e_shstrndx = SHN_UNDEF;
4759 free (filedata->section_headers);
4760 filedata->section_headers = NULL;
252b5132 4761 }
103f02d3 4762
32ec8896 4763 return TRUE;
9ea033b2
NC
4764}
4765
dda8d76d
NC
4766/* Read in the program headers from FILEDATA and store them in PHEADERS.
4767 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
4768
e0a31db1 4769static bfd_boolean
dda8d76d 4770get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4771{
2cf0635d
NC
4772 Elf32_External_Phdr * phdrs;
4773 Elf32_External_Phdr * external;
4774 Elf_Internal_Phdr * internal;
b34976b6 4775 unsigned int i;
dda8d76d
NC
4776 unsigned int size = filedata->file_header.e_phentsize;
4777 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4778
4779 /* PR binutils/17531: Cope with unexpected section header sizes. */
4780 if (size == 0 || num == 0)
4781 return FALSE;
4782 if (size < sizeof * phdrs)
4783 {
4784 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4785 return FALSE;
4786 }
4787 if (size > sizeof * phdrs)
4788 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4789
dda8d76d 4790 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
4791 size, num, _("program headers"));
4792 if (phdrs == NULL)
4793 return FALSE;
9ea033b2 4794
91d6fa6a 4795 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4796 i < filedata->file_header.e_phnum;
b34976b6 4797 i++, internal++, external++)
252b5132 4798 {
9ea033b2
NC
4799 internal->p_type = BYTE_GET (external->p_type);
4800 internal->p_offset = BYTE_GET (external->p_offset);
4801 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4802 internal->p_paddr = BYTE_GET (external->p_paddr);
4803 internal->p_filesz = BYTE_GET (external->p_filesz);
4804 internal->p_memsz = BYTE_GET (external->p_memsz);
4805 internal->p_flags = BYTE_GET (external->p_flags);
4806 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4807 }
4808
9ea033b2 4809 free (phdrs);
e0a31db1 4810 return TRUE;
252b5132
RH
4811}
4812
dda8d76d
NC
4813/* Read in the program headers from FILEDATA and store them in PHEADERS.
4814 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
4815
e0a31db1 4816static bfd_boolean
dda8d76d 4817get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4818{
2cf0635d
NC
4819 Elf64_External_Phdr * phdrs;
4820 Elf64_External_Phdr * external;
4821 Elf_Internal_Phdr * internal;
b34976b6 4822 unsigned int i;
dda8d76d
NC
4823 unsigned int size = filedata->file_header.e_phentsize;
4824 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4825
4826 /* PR binutils/17531: Cope with unexpected section header sizes. */
4827 if (size == 0 || num == 0)
4828 return FALSE;
4829 if (size < sizeof * phdrs)
4830 {
4831 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4832 return FALSE;
4833 }
4834 if (size > sizeof * phdrs)
4835 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4836
dda8d76d 4837 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 4838 size, num, _("program headers"));
a6e9f9df 4839 if (!phdrs)
e0a31db1 4840 return FALSE;
9ea033b2 4841
91d6fa6a 4842 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4843 i < filedata->file_header.e_phnum;
b34976b6 4844 i++, internal++, external++)
9ea033b2
NC
4845 {
4846 internal->p_type = BYTE_GET (external->p_type);
4847 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4848 internal->p_offset = BYTE_GET (external->p_offset);
4849 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4850 internal->p_paddr = BYTE_GET (external->p_paddr);
4851 internal->p_filesz = BYTE_GET (external->p_filesz);
4852 internal->p_memsz = BYTE_GET (external->p_memsz);
4853 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4854 }
4855
4856 free (phdrs);
e0a31db1 4857 return TRUE;
9ea033b2 4858}
252b5132 4859
32ec8896 4860/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 4861
32ec8896 4862static bfd_boolean
dda8d76d 4863get_program_headers (Filedata * filedata)
d93f0186 4864{
2cf0635d 4865 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4866
4867 /* Check cache of prior read. */
dda8d76d 4868 if (filedata->program_headers != NULL)
32ec8896 4869 return TRUE;
d93f0186 4870
82156ab7
NC
4871 /* Be kind to memory checkers by looking for
4872 e_phnum values which we know must be invalid. */
dda8d76d 4873 if (filedata->file_header.e_phnum
82156ab7 4874 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 4875 >= filedata->file_size)
82156ab7
NC
4876 {
4877 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 4878 filedata->file_header.e_phnum);
82156ab7
NC
4879 return FALSE;
4880 }
d93f0186 4881
dda8d76d 4882 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 4883 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4884 if (phdrs == NULL)
4885 {
8b73c356 4886 error (_("Out of memory reading %u program headers\n"),
dda8d76d 4887 filedata->file_header.e_phnum);
32ec8896 4888 return FALSE;
d93f0186
NC
4889 }
4890
4891 if (is_32bit_elf
dda8d76d
NC
4892 ? get_32bit_program_headers (filedata, phdrs)
4893 : get_64bit_program_headers (filedata, phdrs))
d93f0186 4894 {
dda8d76d 4895 filedata->program_headers = phdrs;
32ec8896 4896 return TRUE;
d93f0186
NC
4897 }
4898
4899 free (phdrs);
32ec8896 4900 return FALSE;
d93f0186
NC
4901}
4902
32ec8896 4903/* Returns TRUE if the program headers were loaded. */
2f62977e 4904
32ec8896 4905static bfd_boolean
dda8d76d 4906process_program_headers (Filedata * filedata)
252b5132 4907{
2cf0635d 4908 Elf_Internal_Phdr * segment;
b34976b6 4909 unsigned int i;
1a9ccd70 4910 Elf_Internal_Phdr * previous_load = NULL;
252b5132 4911
dda8d76d 4912 if (filedata->file_header.e_phnum == 0)
252b5132 4913 {
82f2dbf7 4914 /* PR binutils/12467. */
dda8d76d 4915 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
4916 {
4917 warn (_("possibly corrupt ELF header - it has a non-zero program"
4918 " header offset, but no program headers\n"));
4919 return FALSE;
4920 }
82f2dbf7 4921 else if (do_segments)
252b5132 4922 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 4923 return TRUE;
252b5132
RH
4924 }
4925
4926 if (do_segments && !do_header)
4927 {
dda8d76d
NC
4928 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
4929 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
4930 printf (ngettext ("There is %d program header, starting at offset %s\n",
4931 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
4932 filedata->file_header.e_phnum),
4933 filedata->file_header.e_phnum,
4934 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
4935 }
4936
dda8d76d 4937 if (! get_program_headers (filedata))
6b4bf3bc 4938 return TRUE;
103f02d3 4939
252b5132
RH
4940 if (do_segments)
4941 {
dda8d76d 4942 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
4943 printf (_("\nProgram Headers:\n"));
4944 else
4945 printf (_("\nProgram Headers:\n"));
76da6bbe 4946
f7a99963
NC
4947 if (is_32bit_elf)
4948 printf
4949 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4950 else if (do_wide)
4951 printf
4952 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4953 else
4954 {
4955 printf
4956 (_(" Type Offset VirtAddr PhysAddr\n"));
4957 printf
4958 (_(" FileSiz MemSiz Flags Align\n"));
4959 }
252b5132
RH
4960 }
4961
252b5132 4962 dynamic_addr = 0;
1b228002 4963 dynamic_size = 0;
252b5132 4964
dda8d76d
NC
4965 for (i = 0, segment = filedata->program_headers;
4966 i < filedata->file_header.e_phnum;
b34976b6 4967 i++, segment++)
252b5132
RH
4968 {
4969 if (do_segments)
4970 {
dda8d76d 4971 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
4972
4973 if (is_32bit_elf)
4974 {
4975 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4976 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4977 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4978 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4979 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4980 printf ("%c%c%c ",
4981 (segment->p_flags & PF_R ? 'R' : ' '),
4982 (segment->p_flags & PF_W ? 'W' : ' '),
4983 (segment->p_flags & PF_X ? 'E' : ' '));
4984 printf ("%#lx", (unsigned long) segment->p_align);
4985 }
d974e256
JJ
4986 else if (do_wide)
4987 {
4988 if ((unsigned long) segment->p_offset == segment->p_offset)
4989 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4990 else
4991 {
4992 print_vma (segment->p_offset, FULL_HEX);
4993 putchar (' ');
4994 }
4995
4996 print_vma (segment->p_vaddr, FULL_HEX);
4997 putchar (' ');
4998 print_vma (segment->p_paddr, FULL_HEX);
4999 putchar (' ');
5000
5001 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5002 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5003 else
5004 {
5005 print_vma (segment->p_filesz, FULL_HEX);
5006 putchar (' ');
5007 }
5008
5009 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5010 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5011 else
5012 {
f48e6c45 5013 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5014 }
5015
5016 printf (" %c%c%c ",
5017 (segment->p_flags & PF_R ? 'R' : ' '),
5018 (segment->p_flags & PF_W ? 'W' : ' '),
5019 (segment->p_flags & PF_X ? 'E' : ' '));
5020
5021 if ((unsigned long) segment->p_align == segment->p_align)
5022 printf ("%#lx", (unsigned long) segment->p_align);
5023 else
5024 {
5025 print_vma (segment->p_align, PREFIX_HEX);
5026 }
5027 }
f7a99963
NC
5028 else
5029 {
5030 print_vma (segment->p_offset, FULL_HEX);
5031 putchar (' ');
5032 print_vma (segment->p_vaddr, FULL_HEX);
5033 putchar (' ');
5034 print_vma (segment->p_paddr, FULL_HEX);
5035 printf ("\n ");
5036 print_vma (segment->p_filesz, FULL_HEX);
5037 putchar (' ');
5038 print_vma (segment->p_memsz, FULL_HEX);
5039 printf (" %c%c%c ",
5040 (segment->p_flags & PF_R ? 'R' : ' '),
5041 (segment->p_flags & PF_W ? 'W' : ' '),
5042 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5043 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5044 }
252b5132 5045
1a9ccd70
NC
5046 putc ('\n', stdout);
5047 }
f54498b4 5048
252b5132
RH
5049 switch (segment->p_type)
5050 {
1a9ccd70 5051 case PT_LOAD:
502d895c
NC
5052#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5053 required by the ELF standard, several programs, including the Linux
5054 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5055 if (previous_load
5056 && previous_load->p_vaddr > segment->p_vaddr)
5057 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5058#endif
1a9ccd70
NC
5059 if (segment->p_memsz < segment->p_filesz)
5060 error (_("the segment's file size is larger than its memory size\n"));
5061 previous_load = segment;
5062 break;
5063
5064 case PT_PHDR:
5065 /* PR 20815 - Verify that the program header is loaded into memory. */
5066 if (i > 0 && previous_load != NULL)
5067 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5068 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5069 {
5070 unsigned int j;
5071
dda8d76d
NC
5072 for (j = 1; j < filedata->file_header.e_phnum; j++)
5073 if (filedata->program_headers[j].p_vaddr <= segment->p_vaddr
5074 && (filedata->program_headers[j].p_vaddr
5075 + filedata->program_headers[j].p_memsz)
1a9ccd70
NC
5076 >= (segment->p_vaddr + segment->p_filesz))
5077 break;
dda8d76d 5078 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5079 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5080 }
5081 break;
5082
252b5132
RH
5083 case PT_DYNAMIC:
5084 if (dynamic_addr)
5085 error (_("more than one dynamic segment\n"));
5086
20737c13
AM
5087 /* By default, assume that the .dynamic section is the first
5088 section in the DYNAMIC segment. */
5089 dynamic_addr = segment->p_offset;
5090 dynamic_size = segment->p_filesz;
5091
b2d38a17
NC
5092 /* Try to locate the .dynamic section. If there is
5093 a section header table, we can easily locate it. */
dda8d76d 5094 if (filedata->section_headers != NULL)
b2d38a17 5095 {
2cf0635d 5096 Elf_Internal_Shdr * sec;
b2d38a17 5097
dda8d76d 5098 sec = find_section (filedata, ".dynamic");
89fac5e3 5099 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5100 {
28f997cf
TG
5101 /* A corresponding .dynamic section is expected, but on
5102 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5103 if (!is_ia64_vms (filedata))
28f997cf 5104 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5105 break;
5106 }
5107
42bb2e33 5108 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
5109 {
5110 dynamic_size = 0;
5111 break;
5112 }
42bb2e33 5113
b2d38a17
NC
5114 dynamic_addr = sec->sh_offset;
5115 dynamic_size = sec->sh_size;
5116
5117 if (dynamic_addr < segment->p_offset
5118 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
5119 warn (_("the .dynamic section is not contained"
5120 " within the dynamic segment\n"));
b2d38a17 5121 else if (dynamic_addr > segment->p_offset)
20737c13
AM
5122 warn (_("the .dynamic section is not the first section"
5123 " in the dynamic segment.\n"));
b2d38a17 5124 }
39e224f6
MW
5125
5126 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5127 segment. Check this after matching against the section headers
5128 so we don't warn on debuginfo file (which have NOBITS .dynamic
5129 sections). */
dda8d76d 5130 if (dynamic_addr + dynamic_size >= filedata->file_size)
39e224f6
MW
5131 {
5132 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
5133 dynamic_addr = dynamic_size = 0;
5134 }
252b5132
RH
5135 break;
5136
5137 case PT_INTERP:
dda8d76d 5138 if (fseek (filedata->handle, archive_file_offset + (long) segment->p_offset,
fb52b2f4 5139 SEEK_SET))
252b5132
RH
5140 error (_("Unable to find program interpreter name\n"));
5141 else
5142 {
f8eae8b2 5143 char fmt [32];
9495b2e6 5144 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5145
5146 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5147 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5148
252b5132 5149 program_interpreter[0] = 0;
dda8d76d 5150 if (fscanf (filedata->handle, fmt, program_interpreter) <= 0)
7bd7b3ef 5151 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5152
5153 if (do_segments)
f54498b4 5154 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
5155 program_interpreter);
5156 }
5157 break;
5158 }
252b5132
RH
5159 }
5160
dda8d76d
NC
5161 if (do_segments
5162 && filedata->section_headers != NULL
5163 && filedata->string_table != NULL)
252b5132
RH
5164 {
5165 printf (_("\n Section to Segment mapping:\n"));
5166 printf (_(" Segment Sections...\n"));
5167
dda8d76d 5168 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5169 {
9ad5cbcf 5170 unsigned int j;
2cf0635d 5171 Elf_Internal_Shdr * section;
252b5132 5172
dda8d76d
NC
5173 segment = filedata->program_headers + i;
5174 section = filedata->section_headers + 1;
252b5132
RH
5175
5176 printf (" %2.2d ", i);
5177
dda8d76d 5178 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5179 {
f4638467
AM
5180 if (!ELF_TBSS_SPECIAL (section, segment)
5181 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5182 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5183 }
5184
5185 putc ('\n',stdout);
5186 }
5187 }
5188
32ec8896 5189 return TRUE;
252b5132
RH
5190}
5191
5192
d93f0186
NC
5193/* Find the file offset corresponding to VMA by using the program headers. */
5194
5195static long
dda8d76d 5196offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5197{
2cf0635d 5198 Elf_Internal_Phdr * seg;
d93f0186 5199
dda8d76d 5200 if (! get_program_headers (filedata))
d93f0186
NC
5201 {
5202 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5203 return (long) vma;
5204 }
5205
dda8d76d
NC
5206 for (seg = filedata->program_headers;
5207 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5208 ++seg)
5209 {
5210 if (seg->p_type != PT_LOAD)
5211 continue;
5212
5213 if (vma >= (seg->p_vaddr & -seg->p_align)
5214 && vma + size <= seg->p_vaddr + seg->p_filesz)
5215 return vma - seg->p_vaddr + seg->p_offset;
5216 }
5217
5218 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5219 (unsigned long) vma);
d93f0186
NC
5220 return (long) vma;
5221}
5222
5223
dda8d76d
NC
5224/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5225 If PROBE is true, this is just a probe and we do not generate any error
5226 messages if the load fails. */
049b0c3a
NC
5227
5228static bfd_boolean
dda8d76d 5229get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5230{
2cf0635d
NC
5231 Elf32_External_Shdr * shdrs;
5232 Elf_Internal_Shdr * internal;
dda8d76d
NC
5233 unsigned int i;
5234 unsigned int size = filedata->file_header.e_shentsize;
5235 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5236
5237 /* PR binutils/17531: Cope with unexpected section header sizes. */
5238 if (size == 0 || num == 0)
5239 return FALSE;
5240 if (size < sizeof * shdrs)
5241 {
5242 if (! probe)
5243 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5244 return FALSE;
5245 }
5246 if (!probe && size > sizeof * shdrs)
5247 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5248
dda8d76d 5249 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5250 size, num,
5251 probe ? NULL : _("section headers"));
5252 if (shdrs == NULL)
5253 return FALSE;
252b5132 5254
dda8d76d
NC
5255 free (filedata->section_headers);
5256 filedata->section_headers = (Elf_Internal_Shdr *)
5257 cmalloc (num, sizeof (Elf_Internal_Shdr));
5258 if (filedata->section_headers == NULL)
252b5132 5259 {
049b0c3a 5260 if (!probe)
8b73c356 5261 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 5262 return FALSE;
252b5132
RH
5263 }
5264
dda8d76d 5265 for (i = 0, internal = filedata->section_headers;
560f3c1c 5266 i < num;
b34976b6 5267 i++, internal++)
252b5132
RH
5268 {
5269 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5270 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5271 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5272 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5273 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5274 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5275 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5276 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5277 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5278 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5279 if (!probe && internal->sh_link > num)
5280 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5281 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5282 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5283 }
5284
5285 free (shdrs);
049b0c3a 5286 return TRUE;
252b5132
RH
5287}
5288
dda8d76d
NC
5289/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5290
049b0c3a 5291static bfd_boolean
dda8d76d 5292get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5293{
dda8d76d
NC
5294 Elf64_External_Shdr * shdrs;
5295 Elf_Internal_Shdr * internal;
5296 unsigned int i;
5297 unsigned int size = filedata->file_header.e_shentsize;
5298 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5299
5300 /* PR binutils/17531: Cope with unexpected section header sizes. */
5301 if (size == 0 || num == 0)
5302 return FALSE;
dda8d76d 5303
049b0c3a
NC
5304 if (size < sizeof * shdrs)
5305 {
5306 if (! probe)
5307 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5308 return FALSE;
5309 }
dda8d76d 5310
049b0c3a
NC
5311 if (! probe && size > sizeof * shdrs)
5312 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5313
dda8d76d
NC
5314 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5315 filedata->file_header.e_shoff,
049b0c3a
NC
5316 size, num,
5317 probe ? NULL : _("section headers"));
5318 if (shdrs == NULL)
5319 return FALSE;
9ea033b2 5320
dda8d76d
NC
5321 free (filedata->section_headers);
5322 filedata->section_headers = (Elf_Internal_Shdr *)
5323 cmalloc (num, sizeof (Elf_Internal_Shdr));
5324 if (filedata->section_headers == NULL)
9ea033b2 5325 {
049b0c3a 5326 if (! probe)
8b73c356 5327 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 5328 return FALSE;
9ea033b2
NC
5329 }
5330
dda8d76d 5331 for (i = 0, internal = filedata->section_headers;
560f3c1c 5332 i < num;
b34976b6 5333 i++, internal++)
9ea033b2
NC
5334 {
5335 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5336 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5337 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5338 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5339 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5340 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5341 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5342 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5343 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5344 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5345 if (!probe && internal->sh_link > num)
5346 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5347 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5348 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5349 }
5350
5351 free (shdrs);
049b0c3a 5352 return TRUE;
9ea033b2
NC
5353}
5354
252b5132 5355static Elf_Internal_Sym *
dda8d76d
NC
5356get_32bit_elf_symbols (Filedata * filedata,
5357 Elf_Internal_Shdr * section,
5358 unsigned long * num_syms_return)
252b5132 5359{
ba5cdace 5360 unsigned long number = 0;
dd24e3da 5361 Elf32_External_Sym * esyms = NULL;
ba5cdace 5362 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5363 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5364 Elf_Internal_Sym * psym;
b34976b6 5365 unsigned int j;
252b5132 5366
c9c1d674
EG
5367 if (section->sh_size == 0)
5368 {
5369 if (num_syms_return != NULL)
5370 * num_syms_return = 0;
5371 return NULL;
5372 }
5373
dd24e3da 5374 /* Run some sanity checks first. */
c9c1d674 5375 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5376 {
c9c1d674 5377 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5378 printable_section_name (filedata, section),
5379 (unsigned long) section->sh_entsize);
ba5cdace 5380 goto exit_point;
dd24e3da
NC
5381 }
5382
dda8d76d 5383 if (section->sh_size > filedata->file_size)
f54498b4
NC
5384 {
5385 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5386 printable_section_name (filedata, section),
5387 (unsigned long) section->sh_size);
f54498b4
NC
5388 goto exit_point;
5389 }
5390
dd24e3da
NC
5391 number = section->sh_size / section->sh_entsize;
5392
5393 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5394 {
c9c1d674 5395 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5396 (unsigned long) section->sh_size,
dda8d76d 5397 printable_section_name (filedata, section),
8066deb1 5398 (unsigned long) section->sh_entsize);
ba5cdace 5399 goto exit_point;
dd24e3da
NC
5400 }
5401
dda8d76d 5402 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5403 section->sh_size, _("symbols"));
dd24e3da 5404 if (esyms == NULL)
ba5cdace 5405 goto exit_point;
252b5132 5406
6a40cf0c
NC
5407 {
5408 elf_section_list * entry;
5409
5410 shndx = NULL;
5411 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
dda8d76d 5412 if (entry->hdr->sh_link == (unsigned long) (section - filedata->section_headers))
c9c1d674 5413 {
dda8d76d 5414 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6a40cf0c
NC
5415 entry->hdr->sh_offset,
5416 1, entry->hdr->sh_size,
5417 _("symbol table section indicies"));
5418 if (shndx == NULL)
5419 goto exit_point;
5420 /* PR17531: file: heap-buffer-overflow */
5421 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5422 {
5423 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
dda8d76d 5424 printable_section_name (filedata, entry->hdr),
6a40cf0c
NC
5425 (unsigned long) entry->hdr->sh_size,
5426 (unsigned long) section->sh_size);
5427 goto exit_point;
5428 }
c9c1d674 5429 }
6a40cf0c 5430 }
9ad5cbcf 5431
3f5e193b 5432 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5433
5434 if (isyms == NULL)
5435 {
8b73c356
NC
5436 error (_("Out of memory reading %lu symbols\n"),
5437 (unsigned long) number);
dd24e3da 5438 goto exit_point;
252b5132
RH
5439 }
5440
dd24e3da 5441 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5442 {
5443 psym->st_name = BYTE_GET (esyms[j].st_name);
5444 psym->st_value = BYTE_GET (esyms[j].st_value);
5445 psym->st_size = BYTE_GET (esyms[j].st_size);
5446 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5447 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5448 psym->st_shndx
5449 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5450 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5451 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5452 psym->st_info = BYTE_GET (esyms[j].st_info);
5453 psym->st_other = BYTE_GET (esyms[j].st_other);
5454 }
5455
dd24e3da 5456 exit_point:
ba5cdace 5457 if (shndx != NULL)
9ad5cbcf 5458 free (shndx);
ba5cdace 5459 if (esyms != NULL)
dd24e3da 5460 free (esyms);
252b5132 5461
ba5cdace
NC
5462 if (num_syms_return != NULL)
5463 * num_syms_return = isyms == NULL ? 0 : number;
5464
252b5132
RH
5465 return isyms;
5466}
5467
9ea033b2 5468static Elf_Internal_Sym *
dda8d76d
NC
5469get_64bit_elf_symbols (Filedata * filedata,
5470 Elf_Internal_Shdr * section,
5471 unsigned long * num_syms_return)
9ea033b2 5472{
ba5cdace
NC
5473 unsigned long number = 0;
5474 Elf64_External_Sym * esyms = NULL;
5475 Elf_External_Sym_Shndx * shndx = NULL;
5476 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5477 Elf_Internal_Sym * psym;
b34976b6 5478 unsigned int j;
9ea033b2 5479
c9c1d674
EG
5480 if (section->sh_size == 0)
5481 {
5482 if (num_syms_return != NULL)
5483 * num_syms_return = 0;
5484 return NULL;
5485 }
5486
dd24e3da 5487 /* Run some sanity checks first. */
c9c1d674 5488 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5489 {
c9c1d674 5490 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5491 printable_section_name (filedata, section),
8066deb1 5492 (unsigned long) section->sh_entsize);
ba5cdace 5493 goto exit_point;
dd24e3da
NC
5494 }
5495
dda8d76d 5496 if (section->sh_size > filedata->file_size)
f54498b4
NC
5497 {
5498 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5499 printable_section_name (filedata, section),
8066deb1 5500 (unsigned long) section->sh_size);
f54498b4
NC
5501 goto exit_point;
5502 }
5503
dd24e3da
NC
5504 number = section->sh_size / section->sh_entsize;
5505
5506 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5507 {
c9c1d674 5508 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5509 (unsigned long) section->sh_size,
dda8d76d 5510 printable_section_name (filedata, section),
8066deb1 5511 (unsigned long) section->sh_entsize);
ba5cdace 5512 goto exit_point;
dd24e3da
NC
5513 }
5514
dda8d76d 5515 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5516 section->sh_size, _("symbols"));
a6e9f9df 5517 if (!esyms)
ba5cdace 5518 goto exit_point;
9ea033b2 5519
6a40cf0c
NC
5520 {
5521 elf_section_list * entry;
5522
5523 shndx = NULL;
5524 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
dda8d76d 5525 if (entry->hdr->sh_link == (unsigned long) (section - filedata->section_headers))
c9c1d674 5526 {
dda8d76d 5527 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6a40cf0c
NC
5528 entry->hdr->sh_offset,
5529 1, entry->hdr->sh_size,
5530 _("symbol table section indicies"));
5531 if (shndx == NULL)
5532 goto exit_point;
5533 /* PR17531: file: heap-buffer-overflow */
5534 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5535 {
5536 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
dda8d76d 5537 printable_section_name (filedata, entry->hdr),
6a40cf0c
NC
5538 (unsigned long) entry->hdr->sh_size,
5539 (unsigned long) section->sh_size);
5540 goto exit_point;
5541 }
c9c1d674 5542 }
6a40cf0c 5543 }
9ad5cbcf 5544
3f5e193b 5545 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5546
5547 if (isyms == NULL)
5548 {
8b73c356
NC
5549 error (_("Out of memory reading %lu symbols\n"),
5550 (unsigned long) number);
ba5cdace 5551 goto exit_point;
9ea033b2
NC
5552 }
5553
ba5cdace 5554 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5555 {
5556 psym->st_name = BYTE_GET (esyms[j].st_name);
5557 psym->st_info = BYTE_GET (esyms[j].st_info);
5558 psym->st_other = BYTE_GET (esyms[j].st_other);
5559 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5560
4fbb74a6 5561 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5562 psym->st_shndx
5563 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5564 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5565 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5566
66543521
AM
5567 psym->st_value = BYTE_GET (esyms[j].st_value);
5568 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5569 }
5570
ba5cdace
NC
5571 exit_point:
5572 if (shndx != NULL)
9ad5cbcf 5573 free (shndx);
ba5cdace
NC
5574 if (esyms != NULL)
5575 free (esyms);
5576
5577 if (num_syms_return != NULL)
5578 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5579
5580 return isyms;
5581}
5582
d1133906 5583static const char *
dda8d76d 5584get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5585{
5477e8a0 5586 static char buff[1024];
2cf0635d 5587 char * p = buff;
32ec8896
NC
5588 unsigned int field_size = is_32bit_elf ? 8 : 16;
5589 signed int sindex;
5590 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5591 bfd_vma os_flags = 0;
5592 bfd_vma proc_flags = 0;
5593 bfd_vma unknown_flags = 0;
148b93f2 5594 static const struct
5477e8a0 5595 {
2cf0635d 5596 const char * str;
32ec8896 5597 unsigned int len;
5477e8a0
L
5598 }
5599 flags [] =
5600 {
cfcac11d
NC
5601 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5602 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5603 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5604 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5605 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5606 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5607 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5608 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5609 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5610 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5611 /* IA-64 specific. */
5612 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5613 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5614 /* IA-64 OpenVMS specific. */
5615 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5616 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5617 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5618 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5619 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5620 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5621 /* Generic. */
cfcac11d 5622 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5623 /* SPARC specific. */
77115a4a 5624 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5625 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5626 /* ARM specific. */
5627 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5628 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5629 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5630 /* GNU specific. */
5631 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5632 /* VLE specific. */
5633 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5634 };
5635
5636 if (do_section_details)
5637 {
8d5ff12c
L
5638 sprintf (buff, "[%*.*lx]: ",
5639 field_size, field_size, (unsigned long) sh_flags);
5640 p += field_size + 4;
5477e8a0 5641 }
76da6bbe 5642
d1133906
NC
5643 while (sh_flags)
5644 {
5645 bfd_vma flag;
5646
5647 flag = sh_flags & - sh_flags;
5648 sh_flags &= ~ flag;
76da6bbe 5649
5477e8a0 5650 if (do_section_details)
d1133906 5651 {
5477e8a0
L
5652 switch (flag)
5653 {
91d6fa6a
NC
5654 case SHF_WRITE: sindex = 0; break;
5655 case SHF_ALLOC: sindex = 1; break;
5656 case SHF_EXECINSTR: sindex = 2; break;
5657 case SHF_MERGE: sindex = 3; break;
5658 case SHF_STRINGS: sindex = 4; break;
5659 case SHF_INFO_LINK: sindex = 5; break;
5660 case SHF_LINK_ORDER: sindex = 6; break;
5661 case SHF_OS_NONCONFORMING: sindex = 7; break;
5662 case SHF_GROUP: sindex = 8; break;
5663 case SHF_TLS: sindex = 9; break;
18ae9cc1 5664 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5665 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5666 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 5667
5477e8a0 5668 default:
91d6fa6a 5669 sindex = -1;
dda8d76d 5670 switch (filedata->file_header.e_machine)
148b93f2 5671 {
cfcac11d 5672 case EM_IA_64:
148b93f2 5673 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5674 sindex = 10;
148b93f2 5675 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5676 sindex = 11;
148b93f2 5677#ifdef BFD64
dda8d76d 5678 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
5679 switch (flag)
5680 {
91d6fa6a
NC
5681 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5682 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5683 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5684 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5685 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5686 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5687 default: break;
5688 }
5689#endif
cfcac11d
NC
5690 break;
5691
caa83f8b 5692 case EM_386:
22abe556 5693 case EM_IAMCU:
caa83f8b 5694 case EM_X86_64:
7f502d6c 5695 case EM_L1OM:
7a9068fe 5696 case EM_K1OM:
cfcac11d
NC
5697 case EM_OLD_SPARCV9:
5698 case EM_SPARC32PLUS:
5699 case EM_SPARCV9:
5700 case EM_SPARC:
18ae9cc1 5701 if (flag == SHF_ORDERED)
91d6fa6a 5702 sindex = 19;
cfcac11d 5703 break;
ac4c9b04
MG
5704
5705 case EM_ARM:
5706 switch (flag)
5707 {
5708 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5709 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5710 case SHF_COMDEF: sindex = 23; break;
5711 default: break;
5712 }
5713 break;
83eef883
AFB
5714 case EM_PPC:
5715 if (flag == SHF_PPC_VLE)
5716 sindex = 25;
5717 break;
ac4c9b04 5718
cfcac11d
NC
5719 default:
5720 break;
148b93f2 5721 }
5477e8a0
L
5722 }
5723
91d6fa6a 5724 if (sindex != -1)
5477e8a0 5725 {
8d5ff12c
L
5726 if (p != buff + field_size + 4)
5727 {
5728 if (size < (10 + 2))
bee0ee85
NC
5729 {
5730 warn (_("Internal error: not enough buffer room for section flag info"));
5731 return _("<unknown>");
5732 }
8d5ff12c
L
5733 size -= 2;
5734 *p++ = ',';
5735 *p++ = ' ';
5736 }
5737
91d6fa6a
NC
5738 size -= flags [sindex].len;
5739 p = stpcpy (p, flags [sindex].str);
5477e8a0 5740 }
3b22753a 5741 else if (flag & SHF_MASKOS)
8d5ff12c 5742 os_flags |= flag;
d1133906 5743 else if (flag & SHF_MASKPROC)
8d5ff12c 5744 proc_flags |= flag;
d1133906 5745 else
8d5ff12c 5746 unknown_flags |= flag;
5477e8a0
L
5747 }
5748 else
5749 {
5750 switch (flag)
5751 {
5752 case SHF_WRITE: *p = 'W'; break;
5753 case SHF_ALLOC: *p = 'A'; break;
5754 case SHF_EXECINSTR: *p = 'X'; break;
5755 case SHF_MERGE: *p = 'M'; break;
5756 case SHF_STRINGS: *p = 'S'; break;
5757 case SHF_INFO_LINK: *p = 'I'; break;
5758 case SHF_LINK_ORDER: *p = 'L'; break;
5759 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5760 case SHF_GROUP: *p = 'G'; break;
5761 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5762 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 5763 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 5764 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
5765
5766 default:
dda8d76d
NC
5767 if ((filedata->file_header.e_machine == EM_X86_64
5768 || filedata->file_header.e_machine == EM_L1OM
5769 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
5770 && flag == SHF_X86_64_LARGE)
5771 *p = 'l';
dda8d76d 5772 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 5773 && flag == SHF_ARM_PURECODE)
91f68a68 5774 *p = 'y';
dda8d76d 5775 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
5776 && flag == SHF_PPC_VLE)
5777 *p = 'v';
5477e8a0
L
5778 else if (flag & SHF_MASKOS)
5779 {
5780 *p = 'o';
5781 sh_flags &= ~ SHF_MASKOS;
5782 }
5783 else if (flag & SHF_MASKPROC)
5784 {
5785 *p = 'p';
5786 sh_flags &= ~ SHF_MASKPROC;
5787 }
5788 else
5789 *p = 'x';
5790 break;
5791 }
5792 p++;
d1133906
NC
5793 }
5794 }
76da6bbe 5795
8d5ff12c
L
5796 if (do_section_details)
5797 {
5798 if (os_flags)
5799 {
5800 size -= 5 + field_size;
5801 if (p != buff + field_size + 4)
5802 {
5803 if (size < (2 + 1))
bee0ee85
NC
5804 {
5805 warn (_("Internal error: not enough buffer room for section flag info"));
5806 return _("<unknown>");
5807 }
8d5ff12c
L
5808 size -= 2;
5809 *p++ = ',';
5810 *p++ = ' ';
5811 }
5812 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5813 (unsigned long) os_flags);
5814 p += 5 + field_size;
5815 }
5816 if (proc_flags)
5817 {
5818 size -= 7 + field_size;
5819 if (p != buff + field_size + 4)
5820 {
5821 if (size < (2 + 1))
bee0ee85
NC
5822 {
5823 warn (_("Internal error: not enough buffer room for section flag info"));
5824 return _("<unknown>");
5825 }
8d5ff12c
L
5826 size -= 2;
5827 *p++ = ',';
5828 *p++ = ' ';
5829 }
5830 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5831 (unsigned long) proc_flags);
5832 p += 7 + field_size;
5833 }
5834 if (unknown_flags)
5835 {
5836 size -= 10 + field_size;
5837 if (p != buff + field_size + 4)
5838 {
5839 if (size < (2 + 1))
bee0ee85
NC
5840 {
5841 warn (_("Internal error: not enough buffer room for section flag info"));
5842 return _("<unknown>");
5843 }
8d5ff12c
L
5844 size -= 2;
5845 *p++ = ',';
5846 *p++ = ' ';
5847 }
2b692964 5848 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5849 (unsigned long) unknown_flags);
5850 p += 10 + field_size;
5851 }
5852 }
5853
e9e44622 5854 *p = '\0';
d1133906
NC
5855 return buff;
5856}
5857
77115a4a 5858static unsigned int
ebdf1ebf 5859get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
5860{
5861 if (is_32bit_elf)
5862 {
5863 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 5864
ebdf1ebf
NC
5865 if (size < sizeof (* echdr))
5866 {
5867 error (_("Compressed section is too small even for a compression header\n"));
5868 return 0;
5869 }
5870
77115a4a
L
5871 chdr->ch_type = BYTE_GET (echdr->ch_type);
5872 chdr->ch_size = BYTE_GET (echdr->ch_size);
5873 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5874 return sizeof (*echdr);
5875 }
5876 else
5877 {
5878 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 5879
ebdf1ebf
NC
5880 if (size < sizeof (* echdr))
5881 {
5882 error (_("Compressed section is too small even for a compression header\n"));
5883 return 0;
5884 }
5885
77115a4a
L
5886 chdr->ch_type = BYTE_GET (echdr->ch_type);
5887 chdr->ch_size = BYTE_GET (echdr->ch_size);
5888 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5889 return sizeof (*echdr);
5890 }
5891}
5892
32ec8896 5893static bfd_boolean
dda8d76d 5894process_section_headers (Filedata * filedata)
252b5132 5895{
2cf0635d 5896 Elf_Internal_Shdr * section;
b34976b6 5897 unsigned int i;
252b5132 5898
dda8d76d 5899 filedata->section_headers = NULL;
252b5132 5900
dda8d76d 5901 if (filedata->file_header.e_shnum == 0)
252b5132 5902 {
82f2dbf7 5903 /* PR binutils/12467. */
dda8d76d 5904 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
5905 {
5906 warn (_("possibly corrupt ELF file header - it has a non-zero"
5907 " section header offset, but no section headers\n"));
5908 return FALSE;
5909 }
82f2dbf7 5910 else if (do_sections)
252b5132
RH
5911 printf (_("\nThere are no sections in this file.\n"));
5912
32ec8896 5913 return TRUE;
252b5132
RH
5914 }
5915
5916 if (do_sections && !do_header)
d3a49aa8
AM
5917 printf (ngettext ("There is %d section header, "
5918 "starting at offset 0x%lx:\n",
5919 "There are %d section headers, "
5920 "starting at offset 0x%lx:\n",
dda8d76d
NC
5921 filedata->file_header.e_shnum),
5922 filedata->file_header.e_shnum,
5923 (unsigned long) filedata->file_header.e_shoff);
252b5132 5924
9ea033b2
NC
5925 if (is_32bit_elf)
5926 {
dda8d76d 5927 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
5928 return FALSE;
5929 }
5930 else
5931 {
dda8d76d 5932 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 5933 return FALSE;
9ea033b2 5934 }
252b5132
RH
5935
5936 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
5937 if (filedata->file_header.e_shstrndx != SHN_UNDEF
5938 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 5939 {
dda8d76d 5940 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 5941
c256ffe7
JJ
5942 if (section->sh_size != 0)
5943 {
dda8d76d
NC
5944 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
5945 1, section->sh_size,
5946 _("string table"));
0de14b54 5947
dda8d76d 5948 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 5949 }
252b5132
RH
5950 }
5951
5952 /* Scan the sections for the dynamic symbol table
e3c8793a 5953 and dynamic string table and debug sections. */
252b5132
RH
5954 dynamic_symbols = NULL;
5955 dynamic_strings = NULL;
5956 dynamic_syminfo = NULL;
6a40cf0c 5957 symtab_shndx_list = NULL;
103f02d3 5958
89fac5e3 5959 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 5960 switch (filedata->file_header.e_machine)
89fac5e3
RS
5961 {
5962 case EM_MIPS:
5963 case EM_MIPS_RS3_LE:
5964 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5965 FDE addresses. However, the ABI also has a semi-official ILP32
5966 variant for which the normal FDE address size rules apply.
5967
5968 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5969 section, where XX is the size of longs in bits. Unfortunately,
5970 earlier compilers provided no way of distinguishing ILP32 objects
5971 from LP64 objects, so if there's any doubt, we should assume that
5972 the official LP64 form is being used. */
dda8d76d
NC
5973 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5974 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
5975 eh_addr_size = 8;
5976 break;
0f56a26a
DD
5977
5978 case EM_H8_300:
5979 case EM_H8_300H:
dda8d76d 5980 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
5981 {
5982 case E_H8_MACH_H8300:
5983 case E_H8_MACH_H8300HN:
5984 case E_H8_MACH_H8300SN:
5985 case E_H8_MACH_H8300SXN:
5986 eh_addr_size = 2;
5987 break;
5988 case E_H8_MACH_H8300H:
5989 case E_H8_MACH_H8300S:
5990 case E_H8_MACH_H8300SX:
5991 eh_addr_size = 4;
5992 break;
5993 }
f4236fe4
DD
5994 break;
5995
ff7eeb89 5996 case EM_M32C_OLD:
f4236fe4 5997 case EM_M32C:
dda8d76d 5998 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
5999 {
6000 case EF_M32C_CPU_M16C:
6001 eh_addr_size = 2;
6002 break;
6003 }
6004 break;
89fac5e3
RS
6005 }
6006
76ca31c0
NC
6007#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6008 do \
6009 { \
6010 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6011 if (section->sh_entsize != expected_entsize) \
9dd3a467 6012 { \
76ca31c0
NC
6013 char buf[40]; \
6014 sprintf_vma (buf, section->sh_entsize); \
6015 /* Note: coded this way so that there is a single string for \
6016 translation. */ \
6017 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6018 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6019 (unsigned) expected_entsize); \
9dd3a467 6020 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6021 } \
6022 } \
08d8fa11 6023 while (0)
9dd3a467
NC
6024
6025#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
6026 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
6027 sizeof (Elf64_External_##type))
6028
dda8d76d
NC
6029 for (i = 0, section = filedata->section_headers;
6030 i < filedata->file_header.e_shnum;
b34976b6 6031 i++, section++)
252b5132 6032 {
2cf0635d 6033 char * name = SECTION_NAME (section);
252b5132
RH
6034
6035 if (section->sh_type == SHT_DYNSYM)
6036 {
6037 if (dynamic_symbols != NULL)
6038 {
6039 error (_("File contains multiple dynamic symbol tables\n"));
6040 continue;
6041 }
6042
08d8fa11 6043 CHECK_ENTSIZE (section, i, Sym);
dda8d76d 6044 dynamic_symbols = GET_ELF_SYMBOLS (filedata, section, & num_dynamic_syms);
252b5132
RH
6045 }
6046 else if (section->sh_type == SHT_STRTAB
18bd398b 6047 && streq (name, ".dynstr"))
252b5132
RH
6048 {
6049 if (dynamic_strings != NULL)
6050 {
6051 error (_("File contains multiple dynamic string tables\n"));
6052 continue;
6053 }
6054
dda8d76d 6055 dynamic_strings = (char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6056 1, section->sh_size,
6057 _("dynamic strings"));
59245841 6058 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 6059 }
9ad5cbcf
AM
6060 else if (section->sh_type == SHT_SYMTAB_SHNDX)
6061 {
6a40cf0c 6062 elf_section_list * entry = xmalloc (sizeof * entry);
dda8d76d 6063
6a40cf0c
NC
6064 entry->hdr = section;
6065 entry->next = symtab_shndx_list;
6066 symtab_shndx_list = entry;
9ad5cbcf 6067 }
08d8fa11
JJ
6068 else if (section->sh_type == SHT_SYMTAB)
6069 CHECK_ENTSIZE (section, i, Sym);
6070 else if (section->sh_type == SHT_GROUP)
6071 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6072 else if (section->sh_type == SHT_REL)
6073 CHECK_ENTSIZE (section, i, Rel);
6074 else if (section->sh_type == SHT_RELA)
6075 CHECK_ENTSIZE (section, i, Rela);
252b5132 6076 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 6077 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 6078 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47 6079 || do_debug_str || do_debug_loc || do_debug_ranges
d85bf2ba 6080 || do_debug_addr || do_debug_cu_index || do_debug_links)
1b315056
CS
6081 && (const_strneq (name, ".debug_")
6082 || const_strneq (name, ".zdebug_")))
252b5132 6083 {
1b315056
CS
6084 if (name[1] == 'z')
6085 name += sizeof (".zdebug_") - 1;
6086 else
6087 name += sizeof (".debug_") - 1;
252b5132
RH
6088
6089 if (do_debugging
4723351a
CC
6090 || (do_debug_info && const_strneq (name, "info"))
6091 || (do_debug_info && const_strneq (name, "types"))
6092 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6093 || (do_debug_lines && strcmp (name, "line") == 0)
6094 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6095 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6096 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6097 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6098 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6099 || (do_debug_aranges && const_strneq (name, "aranges"))
6100 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6101 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6102 || (do_debug_frames && const_strneq (name, "frame"))
6103 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6104 || (do_debug_macinfo && const_strneq (name, "macro"))
6105 || (do_debug_str && const_strneq (name, "str"))
6106 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6107 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6108 || (do_debug_addr && const_strneq (name, "addr"))
6109 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6110 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6111 )
dda8d76d 6112 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132 6113 }
a262ae96 6114 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6115 else if ((do_debugging || do_debug_info)
0112cd26 6116 && const_strneq (name, ".gnu.linkonce.wi."))
dda8d76d 6117 request_dump_bynumber (filedata, i, DEBUG_DUMP);
18bd398b 6118 else if (do_debug_frames && streq (name, ".eh_frame"))
dda8d76d 6119 request_dump_bynumber (filedata, i, DEBUG_DUMP);
61364358
JK
6120 else if (do_gdb_index && (streq (name, ".gdb_index")
6121 || streq (name, ".debug_names")))
dda8d76d 6122 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884
TG
6123 /* Trace sections for Itanium VMS. */
6124 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6125 || do_trace_aranges)
6126 && const_strneq (name, ".trace_"))
6127 {
6128 name += sizeof (".trace_") - 1;
6129
6130 if (do_debugging
6131 || (do_trace_info && streq (name, "info"))
6132 || (do_trace_abbrevs && streq (name, "abbrev"))
6133 || (do_trace_aranges && streq (name, "aranges"))
6134 )
dda8d76d 6135 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884 6136 }
dda8d76d
NC
6137 else if ((do_debugging || do_debug_links)
6138 && (const_strneq (name, ".gnu_debuglink")
6139 || const_strneq (name, ".gnu_debugaltlink")))
6140 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132
RH
6141 }
6142
6143 if (! do_sections)
32ec8896 6144 return TRUE;
252b5132 6145
dda8d76d 6146 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6147 printf (_("\nSection Headers:\n"));
6148 else
6149 printf (_("\nSection Header:\n"));
76da6bbe 6150
f7a99963 6151 if (is_32bit_elf)
595cf52e 6152 {
5477e8a0 6153 if (do_section_details)
595cf52e
L
6154 {
6155 printf (_(" [Nr] Name\n"));
5477e8a0 6156 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6157 }
6158 else
6159 printf
6160 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6161 }
d974e256 6162 else if (do_wide)
595cf52e 6163 {
5477e8a0 6164 if (do_section_details)
595cf52e
L
6165 {
6166 printf (_(" [Nr] Name\n"));
5477e8a0 6167 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6168 }
6169 else
6170 printf
6171 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6172 }
f7a99963
NC
6173 else
6174 {
5477e8a0 6175 if (do_section_details)
595cf52e
L
6176 {
6177 printf (_(" [Nr] Name\n"));
5477e8a0
L
6178 printf (_(" Type Address Offset Link\n"));
6179 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6180 }
6181 else
6182 {
6183 printf (_(" [Nr] Name Type Address Offset\n"));
6184 printf (_(" Size EntSize Flags Link Info Align\n"));
6185 }
f7a99963 6186 }
252b5132 6187
5477e8a0
L
6188 if (do_section_details)
6189 printf (_(" Flags\n"));
6190
dda8d76d
NC
6191 for (i = 0, section = filedata->section_headers;
6192 i < filedata->file_header.e_shnum;
b34976b6 6193 i++, section++)
252b5132 6194 {
dd905818
NC
6195 /* Run some sanity checks on the section header. */
6196
6197 /* Check the sh_link field. */
6198 switch (section->sh_type)
6199 {
6200 case SHT_SYMTAB_SHNDX:
6201 case SHT_GROUP:
6202 case SHT_HASH:
6203 case SHT_GNU_HASH:
6204 case SHT_GNU_versym:
6205 case SHT_REL:
6206 case SHT_RELA:
6207 if (section->sh_link < 1
dda8d76d
NC
6208 || section->sh_link >= filedata->file_header.e_shnum
6209 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6210 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6211 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6212 i, section->sh_link);
6213 break;
6214
6215 case SHT_DYNAMIC:
6216 case SHT_SYMTAB:
6217 case SHT_DYNSYM:
6218 case SHT_GNU_verneed:
6219 case SHT_GNU_verdef:
6220 case SHT_GNU_LIBLIST:
6221 if (section->sh_link < 1
dda8d76d
NC
6222 || section->sh_link >= filedata->file_header.e_shnum
6223 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6224 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6225 i, section->sh_link);
6226 break;
6227
6228 case SHT_INIT_ARRAY:
6229 case SHT_FINI_ARRAY:
6230 case SHT_PREINIT_ARRAY:
6231 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6232 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6233 i, section->sh_link);
6234 break;
6235
6236 default:
6237 /* FIXME: Add support for target specific section types. */
6238#if 0 /* Currently we do not check other section types as there are too
6239 many special cases. Stab sections for example have a type
6240 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6241 section. */
6242 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6243 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6244 i, section->sh_link);
6245#endif
6246 break;
6247 }
6248
6249 /* Check the sh_info field. */
6250 switch (section->sh_type)
6251 {
6252 case SHT_REL:
6253 case SHT_RELA:
6254 if (section->sh_info < 1
dda8d76d
NC
6255 || section->sh_info >= filedata->file_header.e_shnum
6256 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6257 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6258 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6259 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
dd905818 6260 /* FIXME: Are other section types valid ? */
dda8d76d 6261 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
dd905818
NC
6262 {
6263 if (section->sh_info == 0
bef7475f
NC
6264 && (filedata->file_header.e_type == ET_EXEC
6265 || filedata->file_header.e_type == ET_DYN
6266 /* These next two tests may be redundant, but
6267 they have been left in for paranoia's sake. */
6268 || streq (SECTION_NAME (section), ".rel.dyn")
dd905818 6269 || streq (SECTION_NAME (section), ".rela.dyn")))
bef7475f
NC
6270 /* Dynamic relocations apply to segments, not sections, so
6271 they do not need an sh_info value. */
6272 ;
dd905818
NC
6273 else
6274 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6275 i, section->sh_info);
6276 }
6277 break;
6278
6279 case SHT_DYNAMIC:
6280 case SHT_HASH:
6281 case SHT_SYMTAB_SHNDX:
6282 case SHT_INIT_ARRAY:
6283 case SHT_FINI_ARRAY:
6284 case SHT_PREINIT_ARRAY:
6285 if (section->sh_info != 0)
6286 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6287 i, section->sh_info);
6288 break;
6289
6290 case SHT_GROUP:
6291 case SHT_SYMTAB:
6292 case SHT_DYNSYM:
6293 /* A symbol index - we assume that it is valid. */
6294 break;
6295
6296 default:
6297 /* FIXME: Add support for target specific section types. */
6298 if (section->sh_type == SHT_NOBITS)
6299 /* NOBITS section headers with non-zero sh_info fields can be
6300 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6301 information. The stripped sections have their headers
6302 preserved but their types set to SHT_NOBITS. So do not check
6303 this type of section. */
dd905818
NC
6304 ;
6305 else if (section->sh_flags & SHF_INFO_LINK)
6306 {
dda8d76d 6307 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6308 warn (_("[%2u]: Expected link to another section in info field"), i);
6309 }
a91e1603
L
6310 else if (section->sh_type < SHT_LOOS
6311 && (section->sh_flags & SHF_GNU_MBIND) == 0
6312 && section->sh_info != 0)
dd905818
NC
6313 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6314 i, section->sh_info);
6315 break;
6316 }
6317
3e6b6445 6318 /* Check the sh_size field. */
dda8d76d 6319 if (section->sh_size > filedata->file_size
3e6b6445
NC
6320 && section->sh_type != SHT_NOBITS
6321 && section->sh_type != SHT_NULL
6322 && section->sh_type < SHT_LOOS)
6323 warn (_("Size of section %u is larger than the entire file!\n"), i);
6324
7bfd842d 6325 printf (" [%2u] ", i);
5477e8a0 6326 if (do_section_details)
dda8d76d 6327 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6328 else
74e1a04b 6329 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6330
ea52a088 6331 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6332 get_section_type_name (filedata, section->sh_type));
0b4362b0 6333
f7a99963
NC
6334 if (is_32bit_elf)
6335 {
cfcac11d
NC
6336 const char * link_too_big = NULL;
6337
f7a99963 6338 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6339
f7a99963
NC
6340 printf ( " %6.6lx %6.6lx %2.2lx",
6341 (unsigned long) section->sh_offset,
6342 (unsigned long) section->sh_size,
6343 (unsigned long) section->sh_entsize);
d1133906 6344
5477e8a0
L
6345 if (do_section_details)
6346 fputs (" ", stdout);
6347 else
dda8d76d 6348 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6349
dda8d76d 6350 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6351 {
6352 link_too_big = "";
6353 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6354 an error but it can have special values in Solaris binaries. */
dda8d76d 6355 switch (filedata->file_header.e_machine)
cfcac11d 6356 {
caa83f8b 6357 case EM_386:
22abe556 6358 case EM_IAMCU:
caa83f8b 6359 case EM_X86_64:
7f502d6c 6360 case EM_L1OM:
7a9068fe 6361 case EM_K1OM:
cfcac11d
NC
6362 case EM_OLD_SPARCV9:
6363 case EM_SPARC32PLUS:
6364 case EM_SPARCV9:
6365 case EM_SPARC:
6366 if (section->sh_link == (SHN_BEFORE & 0xffff))
6367 link_too_big = "BEFORE";
6368 else if (section->sh_link == (SHN_AFTER & 0xffff))
6369 link_too_big = "AFTER";
6370 break;
6371 default:
6372 break;
6373 }
6374 }
6375
6376 if (do_section_details)
6377 {
6378 if (link_too_big != NULL && * link_too_big)
6379 printf ("<%s> ", link_too_big);
6380 else
6381 printf ("%2u ", section->sh_link);
6382 printf ("%3u %2lu\n", section->sh_info,
6383 (unsigned long) section->sh_addralign);
6384 }
6385 else
6386 printf ("%2u %3u %2lu\n",
6387 section->sh_link,
6388 section->sh_info,
6389 (unsigned long) section->sh_addralign);
6390
6391 if (link_too_big && ! * link_too_big)
6392 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6393 i, section->sh_link);
f7a99963 6394 }
d974e256
JJ
6395 else if (do_wide)
6396 {
6397 print_vma (section->sh_addr, LONG_HEX);
6398
6399 if ((long) section->sh_offset == section->sh_offset)
6400 printf (" %6.6lx", (unsigned long) section->sh_offset);
6401 else
6402 {
6403 putchar (' ');
6404 print_vma (section->sh_offset, LONG_HEX);
6405 }
6406
6407 if ((unsigned long) section->sh_size == section->sh_size)
6408 printf (" %6.6lx", (unsigned long) section->sh_size);
6409 else
6410 {
6411 putchar (' ');
6412 print_vma (section->sh_size, LONG_HEX);
6413 }
6414
6415 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6416 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6417 else
6418 {
6419 putchar (' ');
6420 print_vma (section->sh_entsize, LONG_HEX);
6421 }
6422
5477e8a0
L
6423 if (do_section_details)
6424 fputs (" ", stdout);
6425 else
dda8d76d 6426 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6427
72de5009 6428 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6429
6430 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6431 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6432 else
6433 {
6434 print_vma (section->sh_addralign, DEC);
6435 putchar ('\n');
6436 }
6437 }
5477e8a0 6438 else if (do_section_details)
595cf52e 6439 {
5477e8a0 6440 printf (" %-15.15s ",
dda8d76d 6441 get_section_type_name (filedata, section->sh_type));
595cf52e
L
6442 print_vma (section->sh_addr, LONG_HEX);
6443 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6444 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6445 else
6446 {
6447 printf (" ");
6448 print_vma (section->sh_offset, LONG_HEX);
6449 }
72de5009 6450 printf (" %u\n ", section->sh_link);
595cf52e 6451 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6452 putchar (' ');
595cf52e
L
6453 print_vma (section->sh_entsize, LONG_HEX);
6454
72de5009
AM
6455 printf (" %-16u %lu\n",
6456 section->sh_info,
595cf52e
L
6457 (unsigned long) section->sh_addralign);
6458 }
f7a99963
NC
6459 else
6460 {
6461 putchar (' ');
6462 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6463 if ((long) section->sh_offset == section->sh_offset)
6464 printf (" %8.8lx", (unsigned long) section->sh_offset);
6465 else
6466 {
6467 printf (" ");
6468 print_vma (section->sh_offset, LONG_HEX);
6469 }
f7a99963
NC
6470 printf ("\n ");
6471 print_vma (section->sh_size, LONG_HEX);
6472 printf (" ");
6473 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6474
dda8d76d 6475 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6476
72de5009
AM
6477 printf (" %2u %3u %lu\n",
6478 section->sh_link,
6479 section->sh_info,
f7a99963
NC
6480 (unsigned long) section->sh_addralign);
6481 }
5477e8a0
L
6482
6483 if (do_section_details)
77115a4a 6484 {
dda8d76d 6485 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6486 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6487 {
6488 /* Minimum section size is 12 bytes for 32-bit compression
6489 header + 12 bytes for compressed data header. */
6490 unsigned char buf[24];
d8024a91 6491
77115a4a 6492 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6493 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6494 sizeof (buf), _("compression header")))
6495 {
6496 Elf_Internal_Chdr chdr;
d8024a91 6497
ebdf1ebf 6498 (void) get_compression_header (&chdr, buf, sizeof (buf));
d8024a91 6499
77115a4a
L
6500 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6501 printf (" ZLIB, ");
6502 else
6503 printf (_(" [<unknown>: 0x%x], "),
6504 chdr.ch_type);
6505 print_vma (chdr.ch_size, LONG_HEX);
6506 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6507 }
6508 }
6509 }
252b5132
RH
6510 }
6511
5477e8a0 6512 if (!do_section_details)
3dbcc61d 6513 {
9fb71ee4
NC
6514 /* The ordering of the letters shown here matches the ordering of the
6515 corresponding SHF_xxx values, and hence the order in which these
6516 letters will be displayed to the user. */
6517 printf (_("Key to Flags:\n\
6518 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6519 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6520 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6521 if (filedata->file_header.e_machine == EM_X86_64
6522 || filedata->file_header.e_machine == EM_L1OM
6523 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6524 printf (_("l (large), "));
dda8d76d 6525 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6526 printf (_("y (purecode), "));
dda8d76d 6527 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6528 printf (_("v (VLE), "));
9fb71ee4 6529 printf ("p (processor specific)\n");
0b4362b0 6530 }
d1133906 6531
32ec8896 6532 return TRUE;
252b5132
RH
6533}
6534
f5842774
L
6535static const char *
6536get_group_flags (unsigned int flags)
6537{
1449284b 6538 static char buff[128];
220453ec 6539
6d913794
NC
6540 if (flags == 0)
6541 return "";
6542 else if (flags == GRP_COMDAT)
6543 return "COMDAT ";
f5842774 6544
6d913794
NC
6545 snprintf (buff, 14, _("[0x%x: "), flags);
6546
6547 flags &= ~ GRP_COMDAT;
6548 if (flags & GRP_MASKOS)
6549 {
6550 strcat (buff, "<OS specific>");
6551 flags &= ~ GRP_MASKOS;
f5842774 6552 }
6d913794
NC
6553
6554 if (flags & GRP_MASKPROC)
6555 {
6556 strcat (buff, "<PROC specific>");
6557 flags &= ~ GRP_MASKPROC;
6558 }
6559
6560 if (flags)
6561 strcat (buff, "<unknown>");
6562
6563 strcat (buff, "]");
f5842774
L
6564 return buff;
6565}
6566
32ec8896 6567static bfd_boolean
dda8d76d 6568process_section_groups (Filedata * filedata)
f5842774 6569{
2cf0635d 6570 Elf_Internal_Shdr * section;
f5842774 6571 unsigned int i;
2cf0635d
NC
6572 struct group * group;
6573 Elf_Internal_Shdr * symtab_sec;
6574 Elf_Internal_Shdr * strtab_sec;
6575 Elf_Internal_Sym * symtab;
ba5cdace 6576 unsigned long num_syms;
2cf0635d 6577 char * strtab;
c256ffe7 6578 size_t strtab_size;
d1f5c6e3
L
6579
6580 /* Don't process section groups unless needed. */
6581 if (!do_unwind && !do_section_groups)
32ec8896 6582 return TRUE;
f5842774 6583
dda8d76d 6584 if (filedata->file_header.e_shnum == 0)
f5842774
L
6585 {
6586 if (do_section_groups)
82f2dbf7 6587 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 6588
32ec8896 6589 return TRUE;
f5842774
L
6590 }
6591
dda8d76d 6592 if (filedata->section_headers == NULL)
f5842774
L
6593 {
6594 error (_("Section headers are not available!\n"));
fa1908fd 6595 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 6596 return FALSE;
f5842774
L
6597 }
6598
dda8d76d 6599 section_headers_groups = (struct group **) calloc (filedata->file_header.e_shnum,
3f5e193b 6600 sizeof (struct group *));
e4b17d5c
L
6601
6602 if (section_headers_groups == NULL)
6603 {
8b73c356 6604 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 6605 filedata->file_header.e_shnum);
32ec8896 6606 return FALSE;
e4b17d5c
L
6607 }
6608
f5842774 6609 /* Scan the sections for the group section. */
d1f5c6e3 6610 group_count = 0;
dda8d76d
NC
6611 for (i = 0, section = filedata->section_headers;
6612 i < filedata->file_header.e_shnum;
f5842774 6613 i++, section++)
e4b17d5c
L
6614 if (section->sh_type == SHT_GROUP)
6615 group_count++;
6616
d1f5c6e3
L
6617 if (group_count == 0)
6618 {
6619 if (do_section_groups)
6620 printf (_("\nThere are no section groups in this file.\n"));
6621
32ec8896 6622 return TRUE;
d1f5c6e3
L
6623 }
6624
3f5e193b 6625 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
6626
6627 if (section_groups == NULL)
6628 {
8b73c356
NC
6629 error (_("Out of memory reading %lu groups\n"),
6630 (unsigned long) group_count);
32ec8896 6631 return FALSE;
e4b17d5c
L
6632 }
6633
d1f5c6e3
L
6634 symtab_sec = NULL;
6635 strtab_sec = NULL;
6636 symtab = NULL;
ba5cdace 6637 num_syms = 0;
d1f5c6e3 6638 strtab = NULL;
c256ffe7 6639 strtab_size = 0;
dda8d76d
NC
6640 for (i = 0, section = filedata->section_headers, group = section_groups;
6641 i < filedata->file_header.e_shnum;
e4b17d5c 6642 i++, section++)
f5842774
L
6643 {
6644 if (section->sh_type == SHT_GROUP)
6645 {
dda8d76d 6646 const char * name = printable_section_name (filedata, section);
74e1a04b 6647 const char * group_name;
2cf0635d
NC
6648 unsigned char * start;
6649 unsigned char * indices;
f5842774 6650 unsigned int entry, j, size;
2cf0635d
NC
6651 Elf_Internal_Shdr * sec;
6652 Elf_Internal_Sym * sym;
f5842774
L
6653
6654 /* Get the symbol table. */
dda8d76d
NC
6655 if (section->sh_link >= filedata->file_header.e_shnum
6656 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 6657 != SHT_SYMTAB))
f5842774
L
6658 {
6659 error (_("Bad sh_link in group section `%s'\n"), name);
6660 continue;
6661 }
d1f5c6e3
L
6662
6663 if (symtab_sec != sec)
6664 {
6665 symtab_sec = sec;
6666 if (symtab)
6667 free (symtab);
dda8d76d 6668 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 6669 }
f5842774 6670
dd24e3da
NC
6671 if (symtab == NULL)
6672 {
6673 error (_("Corrupt header in group section `%s'\n"), name);
6674 continue;
6675 }
6676
ba5cdace
NC
6677 if (section->sh_info >= num_syms)
6678 {
6679 error (_("Bad sh_info in group section `%s'\n"), name);
6680 continue;
6681 }
6682
f5842774
L
6683 sym = symtab + section->sh_info;
6684
6685 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6686 {
4fbb74a6 6687 if (sym->st_shndx == 0
dda8d76d 6688 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
6689 {
6690 error (_("Bad sh_info in group section `%s'\n"), name);
6691 continue;
6692 }
ba2685cc 6693
dda8d76d 6694 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7
JJ
6695 strtab_sec = NULL;
6696 if (strtab)
6697 free (strtab);
f5842774 6698 strtab = NULL;
c256ffe7 6699 strtab_size = 0;
f5842774
L
6700 }
6701 else
6702 {
6703 /* Get the string table. */
dda8d76d 6704 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
6705 {
6706 strtab_sec = NULL;
6707 if (strtab)
6708 free (strtab);
6709 strtab = NULL;
6710 strtab_size = 0;
6711 }
6712 else if (strtab_sec
dda8d76d 6713 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
6714 {
6715 strtab_sec = sec;
6716 if (strtab)
6717 free (strtab);
071436c6 6718
dda8d76d 6719 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
6720 1, strtab_sec->sh_size,
6721 _("string table"));
c256ffe7 6722 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 6723 }
c256ffe7 6724 group_name = sym->st_name < strtab_size
2b692964 6725 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
6726 }
6727
c9c1d674
EG
6728 /* PR 17531: file: loop. */
6729 if (section->sh_entsize > section->sh_size)
6730 {
6731 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 6732 printable_section_name (filedata, section),
8066deb1
AM
6733 (unsigned long) section->sh_entsize,
6734 (unsigned long) section->sh_size);
c9c1d674
EG
6735 break;
6736 }
6737
dda8d76d 6738 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6739 1, section->sh_size,
6740 _("section data"));
59245841
NC
6741 if (start == NULL)
6742 continue;
f5842774
L
6743
6744 indices = start;
6745 size = (section->sh_size / section->sh_entsize) - 1;
6746 entry = byte_get (indices, 4);
6747 indices += 4;
e4b17d5c
L
6748
6749 if (do_section_groups)
6750 {
2b692964 6751 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6752 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6753
e4b17d5c
L
6754 printf (_(" [Index] Name\n"));
6755 }
6756
6757 group->group_index = i;
6758
f5842774
L
6759 for (j = 0; j < size; j++)
6760 {
2cf0635d 6761 struct group_list * g;
e4b17d5c 6762
f5842774
L
6763 entry = byte_get (indices, 4);
6764 indices += 4;
6765
dda8d76d 6766 if (entry >= filedata->file_header.e_shnum)
391cb864 6767 {
57028622
NC
6768 static unsigned num_group_errors = 0;
6769
6770 if (num_group_errors ++ < 10)
6771 {
6772 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 6773 entry, i, filedata->file_header.e_shnum - 1);
57028622 6774 if (num_group_errors == 10)
de194d85 6775 warn (_("Further error messages about overlarge group section indicies suppressed\n"));
57028622 6776 }
391cb864
L
6777 continue;
6778 }
391cb864 6779
4fbb74a6 6780 if (section_headers_groups [entry] != NULL)
e4b17d5c 6781 {
d1f5c6e3
L
6782 if (entry)
6783 {
57028622
NC
6784 static unsigned num_errs = 0;
6785
6786 if (num_errs ++ < 10)
6787 {
6788 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6789 entry, i,
6790 section_headers_groups [entry]->group_index);
6791 if (num_errs == 10)
6792 warn (_("Further error messages about already contained group sections suppressed\n"));
6793 }
d1f5c6e3
L
6794 continue;
6795 }
6796 else
6797 {
6798 /* Intel C/C++ compiler may put section 0 in a
32ec8896 6799 section group. We just warn it the first time
d1f5c6e3 6800 and ignore it afterwards. */
32ec8896 6801 static bfd_boolean warned = FALSE;
d1f5c6e3
L
6802 if (!warned)
6803 {
6804 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6805 section_headers_groups [entry]->group_index);
32ec8896 6806 warned = TRUE;
d1f5c6e3
L
6807 }
6808 }
e4b17d5c
L
6809 }
6810
4fbb74a6 6811 section_headers_groups [entry] = group;
e4b17d5c
L
6812
6813 if (do_section_groups)
6814 {
dda8d76d
NC
6815 sec = filedata->section_headers + entry;
6816 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
6817 }
6818
3f5e193b 6819 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6820 g->section_index = entry;
6821 g->next = group->root;
6822 group->root = g;
f5842774
L
6823 }
6824
f5842774
L
6825 if (start)
6826 free (start);
e4b17d5c
L
6827
6828 group++;
f5842774
L
6829 }
6830 }
6831
d1f5c6e3
L
6832 if (symtab)
6833 free (symtab);
6834 if (strtab)
6835 free (strtab);
32ec8896 6836 return TRUE;
f5842774
L
6837}
6838
28f997cf
TG
6839/* Data used to display dynamic fixups. */
6840
6841struct ia64_vms_dynfixup
6842{
6843 bfd_vma needed_ident; /* Library ident number. */
6844 bfd_vma needed; /* Index in the dstrtab of the library name. */
6845 bfd_vma fixup_needed; /* Index of the library. */
6846 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6847 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6848};
6849
6850/* Data used to display dynamic relocations. */
6851
6852struct ia64_vms_dynimgrela
6853{
6854 bfd_vma img_rela_cnt; /* Number of relocations. */
6855 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6856};
6857
6858/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6859 library). */
6860
32ec8896 6861static bfd_boolean
dda8d76d
NC
6862dump_ia64_vms_dynamic_fixups (Filedata * filedata,
6863 struct ia64_vms_dynfixup * fixup,
6864 const char * strtab,
6865 unsigned int strtab_sz)
28f997cf 6866{
32ec8896 6867 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 6868 long i;
32ec8896 6869 const char * lib_name;
28f997cf 6870
dda8d76d 6871 imfs = get_data (NULL, filedata, dynamic_addr + fixup->fixup_rela_off,
28f997cf
TG
6872 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6873 _("dynamic section image fixups"));
6874 if (!imfs)
32ec8896 6875 return FALSE;
28f997cf
TG
6876
6877 if (fixup->needed < strtab_sz)
6878 lib_name = strtab + fixup->needed;
6879 else
6880 {
32ec8896 6881 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 6882 (unsigned long) fixup->needed);
28f997cf
TG
6883 lib_name = "???";
6884 }
6885 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6886 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6887 printf
6888 (_("Seg Offset Type SymVec DataType\n"));
6889
6890 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6891 {
6892 unsigned int type;
6893 const char *rtype;
6894
6895 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6896 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6897 type = BYTE_GET (imfs [i].type);
6898 rtype = elf_ia64_reloc_type (type);
6899 if (rtype == NULL)
6900 printf (" 0x%08x ", type);
6901 else
6902 printf (" %-32s ", rtype);
6903 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6904 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6905 }
6906
6907 free (imfs);
32ec8896 6908 return TRUE;
28f997cf
TG
6909}
6910
6911/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6912
32ec8896 6913static bfd_boolean
dda8d76d 6914dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
6915{
6916 Elf64_External_VMS_IMAGE_RELA *imrs;
6917 long i;
6918
dda8d76d 6919 imrs = get_data (NULL, filedata, dynamic_addr + imgrela->img_rela_off,
28f997cf 6920 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6921 _("dynamic section image relocations"));
28f997cf 6922 if (!imrs)
32ec8896 6923 return FALSE;
28f997cf
TG
6924
6925 printf (_("\nImage relocs\n"));
6926 printf
6927 (_("Seg Offset Type Addend Seg Sym Off\n"));
6928
6929 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6930 {
6931 unsigned int type;
6932 const char *rtype;
6933
6934 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6935 printf ("%08" BFD_VMA_FMT "x ",
6936 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6937 type = BYTE_GET (imrs [i].type);
6938 rtype = elf_ia64_reloc_type (type);
6939 if (rtype == NULL)
6940 printf ("0x%08x ", type);
6941 else
6942 printf ("%-31s ", rtype);
6943 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6944 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6945 printf ("%08" BFD_VMA_FMT "x\n",
6946 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6947 }
6948
6949 free (imrs);
32ec8896 6950 return TRUE;
28f997cf
TG
6951}
6952
6953/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6954
32ec8896 6955static bfd_boolean
dda8d76d 6956process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
6957{
6958 struct ia64_vms_dynfixup fixup;
6959 struct ia64_vms_dynimgrela imgrela;
6960 Elf_Internal_Dyn *entry;
28f997cf
TG
6961 bfd_vma strtab_off = 0;
6962 bfd_vma strtab_sz = 0;
6963 char *strtab = NULL;
32ec8896 6964 bfd_boolean res = TRUE;
28f997cf
TG
6965
6966 memset (&fixup, 0, sizeof (fixup));
6967 memset (&imgrela, 0, sizeof (imgrela));
6968
6969 /* Note: the order of the entries is specified by the OpenVMS specs. */
6970 for (entry = dynamic_section;
6971 entry < dynamic_section + dynamic_nent;
6972 entry++)
6973 {
6974 switch (entry->d_tag)
6975 {
6976 case DT_IA_64_VMS_STRTAB_OFFSET:
6977 strtab_off = entry->d_un.d_val;
6978 break;
6979 case DT_STRSZ:
6980 strtab_sz = entry->d_un.d_val;
6981 if (strtab == NULL)
dda8d76d 6982 strtab = get_data (NULL, filedata, dynamic_addr + strtab_off,
28f997cf
TG
6983 1, strtab_sz, _("dynamic string section"));
6984 break;
6985
6986 case DT_IA_64_VMS_NEEDED_IDENT:
6987 fixup.needed_ident = entry->d_un.d_val;
6988 break;
6989 case DT_NEEDED:
6990 fixup.needed = entry->d_un.d_val;
6991 break;
6992 case DT_IA_64_VMS_FIXUP_NEEDED:
6993 fixup.fixup_needed = entry->d_un.d_val;
6994 break;
6995 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6996 fixup.fixup_rela_cnt = entry->d_un.d_val;
6997 break;
6998 case DT_IA_64_VMS_FIXUP_RELA_OFF:
6999 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7000 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7001 res = FALSE;
28f997cf 7002 break;
28f997cf
TG
7003 case DT_IA_64_VMS_IMG_RELA_CNT:
7004 imgrela.img_rela_cnt = entry->d_un.d_val;
7005 break;
7006 case DT_IA_64_VMS_IMG_RELA_OFF:
7007 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7008 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7009 res = FALSE;
28f997cf
TG
7010 break;
7011
7012 default:
7013 break;
7014 }
7015 }
7016
7017 if (strtab != NULL)
7018 free (strtab);
7019
7020 return res;
7021}
7022
85b1c36d 7023static struct
566b0d53 7024{
2cf0635d 7025 const char * name;
566b0d53
L
7026 int reloc;
7027 int size;
7028 int rela;
32ec8896
NC
7029}
7030 dynamic_relocations [] =
566b0d53 7031{
32ec8896
NC
7032 { "REL", DT_REL, DT_RELSZ, FALSE },
7033 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7034 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7035};
7036
252b5132 7037/* Process the reloc section. */
18bd398b 7038
32ec8896 7039static bfd_boolean
dda8d76d 7040process_relocs (Filedata * filedata)
252b5132 7041{
b34976b6
AM
7042 unsigned long rel_size;
7043 unsigned long rel_offset;
252b5132 7044
252b5132 7045 if (!do_reloc)
32ec8896 7046 return TRUE;
252b5132
RH
7047
7048 if (do_using_dynamic)
7049 {
32ec8896 7050 int is_rela;
2cf0635d 7051 const char * name;
32ec8896 7052 bfd_boolean has_dynamic_reloc;
566b0d53 7053 unsigned int i;
0de14b54 7054
32ec8896 7055 has_dynamic_reloc = FALSE;
252b5132 7056
566b0d53 7057 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7058 {
566b0d53
L
7059 is_rela = dynamic_relocations [i].rela;
7060 name = dynamic_relocations [i].name;
7061 rel_size = dynamic_info [dynamic_relocations [i].size];
7062 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 7063
32ec8896
NC
7064 if (rel_size)
7065 has_dynamic_reloc = TRUE;
566b0d53
L
7066
7067 if (is_rela == UNKNOWN)
aa903cfb 7068 {
566b0d53
L
7069 if (dynamic_relocations [i].reloc == DT_JMPREL)
7070 switch (dynamic_info[DT_PLTREL])
7071 {
7072 case DT_REL:
7073 is_rela = FALSE;
7074 break;
7075 case DT_RELA:
7076 is_rela = TRUE;
7077 break;
7078 }
aa903cfb 7079 }
252b5132 7080
566b0d53
L
7081 if (rel_size)
7082 {
7083 printf
7084 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7085 name, rel_offset, rel_size);
252b5132 7086
dda8d76d
NC
7087 dump_relocations (filedata,
7088 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7089 rel_size,
566b0d53 7090 dynamic_symbols, num_dynamic_syms,
bb4d2ac2 7091 dynamic_strings, dynamic_strings_length,
32ec8896 7092 is_rela, TRUE /* is_dynamic */);
566b0d53 7093 }
252b5132 7094 }
566b0d53 7095
dda8d76d
NC
7096 if (is_ia64_vms (filedata))
7097 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7098 has_dynamic_reloc = TRUE;
28f997cf 7099
566b0d53 7100 if (! has_dynamic_reloc)
252b5132
RH
7101 printf (_("\nThere are no dynamic relocations in this file.\n"));
7102 }
7103 else
7104 {
2cf0635d 7105 Elf_Internal_Shdr * section;
b34976b6 7106 unsigned long i;
32ec8896 7107 bfd_boolean found = FALSE;
252b5132 7108
dda8d76d
NC
7109 for (i = 0, section = filedata->section_headers;
7110 i < filedata->file_header.e_shnum;
b34976b6 7111 i++, section++)
252b5132
RH
7112 {
7113 if ( section->sh_type != SHT_RELA
7114 && section->sh_type != SHT_REL)
7115 continue;
7116
7117 rel_offset = section->sh_offset;
7118 rel_size = section->sh_size;
7119
7120 if (rel_size)
7121 {
2cf0635d 7122 Elf_Internal_Shdr * strsec;
b34976b6 7123 int is_rela;
d3a49aa8 7124 unsigned long num_rela;
103f02d3 7125
252b5132
RH
7126 printf (_("\nRelocation section "));
7127
dda8d76d 7128 if (filedata->string_table == NULL)
19936277 7129 printf ("%d", section->sh_name);
252b5132 7130 else
dda8d76d 7131 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7132
d3a49aa8
AM
7133 num_rela = rel_size / section->sh_entsize;
7134 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7135 " at offset 0x%lx contains %lu entries:\n",
7136 num_rela),
7137 rel_offset, num_rela);
252b5132 7138
d79b3d50
NC
7139 is_rela = section->sh_type == SHT_RELA;
7140
4fbb74a6 7141 if (section->sh_link != 0
dda8d76d 7142 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7143 {
2cf0635d
NC
7144 Elf_Internal_Shdr * symsec;
7145 Elf_Internal_Sym * symtab;
d79b3d50 7146 unsigned long nsyms;
c256ffe7 7147 unsigned long strtablen = 0;
2cf0635d 7148 char * strtab = NULL;
57346661 7149
dda8d76d 7150 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7151 if (symsec->sh_type != SHT_SYMTAB
7152 && symsec->sh_type != SHT_DYNSYM)
7153 continue;
7154
dda8d76d 7155 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
252b5132 7156
af3fc3bc
AM
7157 if (symtab == NULL)
7158 continue;
252b5132 7159
4fbb74a6 7160 if (symsec->sh_link != 0
dda8d76d 7161 && symsec->sh_link < filedata->file_header.e_shnum)
c256ffe7 7162 {
dda8d76d 7163 strsec = filedata->section_headers + symsec->sh_link;
103f02d3 7164
dda8d76d 7165 strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
071436c6
NC
7166 1, strsec->sh_size,
7167 _("string table"));
c256ffe7
JJ
7168 strtablen = strtab == NULL ? 0 : strsec->sh_size;
7169 }
252b5132 7170
dda8d76d 7171 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7172 symtab, nsyms, strtab, strtablen,
7173 is_rela,
7174 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
7175 if (strtab)
7176 free (strtab);
7177 free (symtab);
7178 }
7179 else
dda8d76d 7180 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7181 NULL, 0, NULL, 0, is_rela,
7182 FALSE /* is_dynamic */);
252b5132 7183
32ec8896 7184 found = TRUE;
252b5132
RH
7185 }
7186 }
7187
7188 if (! found)
45ac8f4f
NC
7189 {
7190 /* Users sometimes forget the -D option, so try to be helpful. */
7191 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7192 {
7193 if (dynamic_info [dynamic_relocations [i].size])
7194 {
7195 printf (_("\nThere are no static relocations in this file."));
7196 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7197
7198 break;
7199 }
7200 }
7201 if (i == ARRAY_SIZE (dynamic_relocations))
7202 printf (_("\nThere are no relocations in this file.\n"));
7203 }
252b5132
RH
7204 }
7205
32ec8896 7206 return TRUE;
252b5132
RH
7207}
7208
4d6ed7c8
NC
7209/* An absolute address consists of a section and an offset. If the
7210 section is NULL, the offset itself is the address, otherwise, the
7211 address equals to LOAD_ADDRESS(section) + offset. */
7212
7213struct absaddr
948f632f
DA
7214{
7215 unsigned short section;
7216 bfd_vma offset;
7217};
4d6ed7c8 7218
1949de15
L
7219#define ABSADDR(a) \
7220 ((a).section \
dda8d76d 7221 ? filedata->section_headers [(a).section].sh_addr + (a).offset \
1949de15
L
7222 : (a).offset)
7223
948f632f
DA
7224/* Find the nearest symbol at or below ADDR. Returns the symbol
7225 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7226
4d6ed7c8 7227static void
dda8d76d
NC
7228find_symbol_for_address (Filedata * filedata,
7229 Elf_Internal_Sym * symtab,
7230 unsigned long nsyms,
7231 const char * strtab,
7232 unsigned long strtab_size,
7233 struct absaddr addr,
7234 const char ** symname,
7235 bfd_vma * offset)
4d6ed7c8 7236{
d3ba0551 7237 bfd_vma dist = 0x100000;
2cf0635d 7238 Elf_Internal_Sym * sym;
948f632f
DA
7239 Elf_Internal_Sym * beg;
7240 Elf_Internal_Sym * end;
2cf0635d 7241 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7242
0b6ae522 7243 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7244 beg = symtab;
7245 end = symtab + nsyms;
0b6ae522 7246
948f632f 7247 while (beg < end)
4d6ed7c8 7248 {
948f632f
DA
7249 bfd_vma value;
7250
7251 sym = beg + (end - beg) / 2;
0b6ae522 7252
948f632f 7253 value = sym->st_value;
0b6ae522
DJ
7254 REMOVE_ARCH_BITS (value);
7255
948f632f 7256 if (sym->st_name != 0
4d6ed7c8 7257 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7258 && addr.offset >= value
7259 && addr.offset - value < dist)
4d6ed7c8
NC
7260 {
7261 best = sym;
0b6ae522 7262 dist = addr.offset - value;
4d6ed7c8
NC
7263 if (!dist)
7264 break;
7265 }
948f632f
DA
7266
7267 if (addr.offset < value)
7268 end = sym;
7269 else
7270 beg = sym + 1;
4d6ed7c8 7271 }
1b31d05e 7272
4d6ed7c8
NC
7273 if (best)
7274 {
57346661 7275 *symname = (best->st_name >= strtab_size
2b692964 7276 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7277 *offset = dist;
7278 return;
7279 }
1b31d05e 7280
4d6ed7c8
NC
7281 *symname = NULL;
7282 *offset = addr.offset;
7283}
7284
32ec8896 7285static /* signed */ int
948f632f
DA
7286symcmp (const void *p, const void *q)
7287{
7288 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7289 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7290
7291 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7292}
7293
7294/* Process the unwind section. */
7295
7296#include "unwind-ia64.h"
7297
7298struct ia64_unw_table_entry
7299{
7300 struct absaddr start;
7301 struct absaddr end;
7302 struct absaddr info;
7303};
7304
7305struct ia64_unw_aux_info
7306{
32ec8896
NC
7307 struct ia64_unw_table_entry * table; /* Unwind table. */
7308 unsigned long table_len; /* Length of unwind table. */
7309 unsigned char * info; /* Unwind info. */
7310 unsigned long info_size; /* Size of unwind info. */
7311 bfd_vma info_addr; /* Starting address of unwind info. */
7312 bfd_vma seg_base; /* Starting address of segment. */
7313 Elf_Internal_Sym * symtab; /* The symbol table. */
7314 unsigned long nsyms; /* Number of symbols. */
7315 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7316 unsigned long nfuns; /* Number of entries in funtab. */
7317 char * strtab; /* The string table. */
7318 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7319};
7320
32ec8896 7321static bfd_boolean
dda8d76d 7322dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7323{
2cf0635d 7324 struct ia64_unw_table_entry * tp;
948f632f 7325 unsigned long j, nfuns;
4d6ed7c8 7326 int in_body;
32ec8896 7327 bfd_boolean res = TRUE;
7036c0e1 7328
948f632f
DA
7329 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7330 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7331 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7332 aux->funtab[nfuns++] = aux->symtab[j];
7333 aux->nfuns = nfuns;
7334 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7335
4d6ed7c8
NC
7336 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7337 {
7338 bfd_vma stamp;
7339 bfd_vma offset;
2cf0635d
NC
7340 const unsigned char * dp;
7341 const unsigned char * head;
53774b7e 7342 const unsigned char * end;
2cf0635d 7343 const char * procname;
4d6ed7c8 7344
dda8d76d 7345 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7346 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7347
7348 fputs ("\n<", stdout);
7349
7350 if (procname)
7351 {
7352 fputs (procname, stdout);
7353
7354 if (offset)
7355 printf ("+%lx", (unsigned long) offset);
7356 }
7357
7358 fputs (">: [", stdout);
7359 print_vma (tp->start.offset, PREFIX_HEX);
7360 fputc ('-', stdout);
7361 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7362 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7363 (unsigned long) (tp->info.offset - aux->seg_base));
7364
53774b7e
NC
7365 /* PR 17531: file: 86232b32. */
7366 if (aux->info == NULL)
7367 continue;
7368
7369 /* PR 17531: file: 0997b4d1. */
7370 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
7371 {
7372 warn (_("Invalid offset %lx in table entry %ld\n"),
7373 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7374 res = FALSE;
53774b7e
NC
7375 continue;
7376 }
7377
1949de15 7378 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 7379 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7380
86f55779 7381 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7382 (unsigned) UNW_VER (stamp),
7383 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7384 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7385 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7386 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7387
7388 if (UNW_VER (stamp) != 1)
7389 {
2b692964 7390 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7391 continue;
7392 }
7393
7394 in_body = 0;
53774b7e
NC
7395 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7396 /* PR 17531: file: 16ceda89. */
7397 if (end > aux->info + aux->info_size)
7398 end = aux->info + aux->info_size;
7399 for (dp = head + 8; dp < end;)
b4477bc8 7400 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7401 }
948f632f
DA
7402
7403 free (aux->funtab);
32ec8896
NC
7404
7405 return res;
4d6ed7c8
NC
7406}
7407
53774b7e 7408static bfd_boolean
dda8d76d
NC
7409slurp_ia64_unwind_table (Filedata * filedata,
7410 struct ia64_unw_aux_info * aux,
7411 Elf_Internal_Shdr * sec)
4d6ed7c8 7412{
89fac5e3 7413 unsigned long size, nrelas, i;
2cf0635d
NC
7414 Elf_Internal_Phdr * seg;
7415 struct ia64_unw_table_entry * tep;
7416 Elf_Internal_Shdr * relsec;
7417 Elf_Internal_Rela * rela;
7418 Elf_Internal_Rela * rp;
7419 unsigned char * table;
7420 unsigned char * tp;
7421 Elf_Internal_Sym * sym;
7422 const char * relname;
4d6ed7c8 7423
53774b7e
NC
7424 aux->table_len = 0;
7425
4d6ed7c8
NC
7426 /* First, find the starting address of the segment that includes
7427 this section: */
7428
dda8d76d 7429 if (filedata->file_header.e_phnum)
4d6ed7c8 7430 {
dda8d76d 7431 if (! get_program_headers (filedata))
53774b7e 7432 return FALSE;
4d6ed7c8 7433
dda8d76d
NC
7434 for (seg = filedata->program_headers;
7435 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7436 ++seg)
4d6ed7c8
NC
7437 {
7438 if (seg->p_type != PT_LOAD)
7439 continue;
7440
7441 if (sec->sh_addr >= seg->p_vaddr
7442 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7443 {
7444 aux->seg_base = seg->p_vaddr;
7445 break;
7446 }
7447 }
4d6ed7c8
NC
7448 }
7449
7450 /* Second, build the unwind table from the contents of the unwind section: */
7451 size = sec->sh_size;
dda8d76d 7452 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7453 _("unwind table"));
a6e9f9df 7454 if (!table)
53774b7e 7455 return FALSE;
4d6ed7c8 7456
53774b7e 7457 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7458 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7459 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7460 tep = aux->table;
53774b7e
NC
7461
7462 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7463 {
7464 tep->start.section = SHN_UNDEF;
7465 tep->end.section = SHN_UNDEF;
7466 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7467 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7468 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7469 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7470 tep->start.offset += aux->seg_base;
7471 tep->end.offset += aux->seg_base;
7472 tep->info.offset += aux->seg_base;
7473 }
7474 free (table);
7475
41e92641 7476 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7477 for (relsec = filedata->section_headers;
7478 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7479 ++relsec)
7480 {
7481 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7482 || relsec->sh_info >= filedata->file_header.e_shnum
7483 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7484 continue;
7485
dda8d76d 7486 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7487 & rela, & nrelas))
53774b7e
NC
7488 {
7489 free (aux->table);
7490 aux->table = NULL;
7491 aux->table_len = 0;
7492 return FALSE;
7493 }
4d6ed7c8
NC
7494
7495 for (rp = rela; rp < rela + nrelas; ++rp)
7496 {
dda8d76d 7497 relname = elf_ia64_reloc_type (get_reloc_type (filedata, rp->r_info));
aca88567 7498 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 7499
82b1b41b
NC
7500 /* PR 17531: file: 9fa67536. */
7501 if (relname == NULL)
7502 {
dda8d76d
NC
7503 warn (_("Skipping unknown relocation type: %u\n"),
7504 get_reloc_type (filedata, rp->r_info));
82b1b41b
NC
7505 continue;
7506 }
948f632f 7507
0112cd26 7508 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7509 {
82b1b41b 7510 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7511 continue;
7512 }
7513
89fac5e3 7514 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7515
53774b7e
NC
7516 /* PR 17531: file: 5bc8d9bf. */
7517 if (i >= aux->table_len)
7518 {
7519 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7520 continue;
7521 }
7522
7523 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7524 {
7525 case 0:
7526 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7527 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7528 break;
7529 case 1:
7530 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7531 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7532 break;
7533 case 2:
7534 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7535 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7536 break;
7537 default:
7538 break;
7539 }
7540 }
7541
7542 free (rela);
7543 }
7544
53774b7e 7545 return TRUE;
4d6ed7c8
NC
7546}
7547
32ec8896 7548static bfd_boolean
dda8d76d 7549ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7550{
2cf0635d
NC
7551 Elf_Internal_Shdr * sec;
7552 Elf_Internal_Shdr * unwsec = NULL;
7553 Elf_Internal_Shdr * strsec;
89fac5e3 7554 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7555 struct ia64_unw_aux_info aux;
32ec8896 7556 bfd_boolean res = TRUE;
f1467e33 7557
4d6ed7c8
NC
7558 memset (& aux, 0, sizeof (aux));
7559
dda8d76d 7560 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7561 {
c256ffe7 7562 if (sec->sh_type == SHT_SYMTAB
dda8d76d 7563 && sec->sh_link < filedata->file_header.e_shnum)
4d6ed7c8 7564 {
dda8d76d 7565 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
4d6ed7c8 7566
dda8d76d 7567 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
7568 if (aux.strtab != NULL)
7569 {
7570 error (_("Multiple auxillary string tables encountered\n"));
7571 free (aux.strtab);
32ec8896 7572 res = FALSE;
4082ef84 7573 }
dda8d76d 7574 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
7575 1, strsec->sh_size,
7576 _("string table"));
c256ffe7 7577 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
7578 }
7579 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7580 unwcount++;
7581 }
7582
7583 if (!unwcount)
7584 printf (_("\nThere are no unwind sections in this file.\n"));
7585
7586 while (unwcount-- > 0)
7587 {
2cf0635d 7588 char * suffix;
579f31ac
JJ
7589 size_t len, len2;
7590
dda8d76d
NC
7591 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
7592 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
7593 if (sec->sh_type == SHT_IA_64_UNWIND)
7594 {
7595 unwsec = sec;
7596 break;
7597 }
4082ef84
NC
7598 /* We have already counted the number of SHT_IA64_UNWIND
7599 sections so the loop above should never fail. */
7600 assert (unwsec != NULL);
579f31ac
JJ
7601
7602 unwstart = i + 1;
7603 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7604
e4b17d5c
L
7605 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7606 {
7607 /* We need to find which section group it is in. */
4082ef84 7608 struct group_list * g;
e4b17d5c 7609
4082ef84
NC
7610 if (section_headers_groups == NULL
7611 || section_headers_groups [i] == NULL)
dda8d76d 7612 i = filedata->file_header.e_shnum;
4082ef84 7613 else
e4b17d5c 7614 {
4082ef84 7615 g = section_headers_groups [i]->root;
18bd398b 7616
4082ef84
NC
7617 for (; g != NULL; g = g->next)
7618 {
dda8d76d 7619 sec = filedata->section_headers + g->section_index;
e4b17d5c 7620
4082ef84
NC
7621 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7622 break;
7623 }
7624
7625 if (g == NULL)
dda8d76d 7626 i = filedata->file_header.e_shnum;
4082ef84 7627 }
e4b17d5c 7628 }
18bd398b 7629 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7630 {
18bd398b 7631 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7632 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7633 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7634 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7635 ++i, ++sec)
18bd398b
NC
7636 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7637 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7638 break;
7639 }
7640 else
7641 {
7642 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7643 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7644 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7645 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7646 suffix = "";
18bd398b 7647 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 7648 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7649 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7650 ++i, ++sec)
18bd398b
NC
7651 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
7652 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7653 break;
7654 }
7655
dda8d76d 7656 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
7657 {
7658 printf (_("\nCould not find unwind info section for "));
7659
dda8d76d 7660 if (filedata->string_table == NULL)
579f31ac
JJ
7661 printf ("%d", unwsec->sh_name);
7662 else
dda8d76d 7663 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
7664 }
7665 else
4d6ed7c8 7666 {
4d6ed7c8 7667 aux.info_addr = sec->sh_addr;
dda8d76d 7668 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
7669 sec->sh_size,
7670 _("unwind info"));
59245841 7671 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 7672
579f31ac 7673 printf (_("\nUnwind section "));
4d6ed7c8 7674
dda8d76d 7675 if (filedata->string_table == NULL)
579f31ac
JJ
7676 printf ("%d", unwsec->sh_name);
7677 else
dda8d76d 7678 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 7679
579f31ac 7680 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 7681 (unsigned long) unwsec->sh_offset,
89fac5e3 7682 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 7683
dda8d76d 7684 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 7685 && aux.table_len > 0)
dda8d76d 7686 dump_ia64_unwind (filedata, & aux);
579f31ac
JJ
7687
7688 if (aux.table)
7689 free ((char *) aux.table);
7690 if (aux.info)
7691 free ((char *) aux.info);
7692 aux.table = NULL;
7693 aux.info = NULL;
7694 }
4d6ed7c8 7695 }
4d6ed7c8 7696
4d6ed7c8
NC
7697 if (aux.symtab)
7698 free (aux.symtab);
7699 if (aux.strtab)
7700 free ((char *) aux.strtab);
32ec8896
NC
7701
7702 return res;
4d6ed7c8
NC
7703}
7704
3f5e193b 7705struct hppa_unw_table_entry
32ec8896
NC
7706{
7707 struct absaddr start;
7708 struct absaddr end;
7709 unsigned int Cannot_unwind:1; /* 0 */
7710 unsigned int Millicode:1; /* 1 */
7711 unsigned int Millicode_save_sr0:1; /* 2 */
7712 unsigned int Region_description:2; /* 3..4 */
7713 unsigned int reserved1:1; /* 5 */
7714 unsigned int Entry_SR:1; /* 6 */
7715 unsigned int Entry_FR:4; /* Number saved 7..10 */
7716 unsigned int Entry_GR:5; /* Number saved 11..15 */
7717 unsigned int Args_stored:1; /* 16 */
7718 unsigned int Variable_Frame:1; /* 17 */
7719 unsigned int Separate_Package_Body:1; /* 18 */
7720 unsigned int Frame_Extension_Millicode:1; /* 19 */
7721 unsigned int Stack_Overflow_Check:1; /* 20 */
7722 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
7723 unsigned int Ada_Region:1; /* 22 */
7724 unsigned int cxx_info:1; /* 23 */
7725 unsigned int cxx_try_catch:1; /* 24 */
7726 unsigned int sched_entry_seq:1; /* 25 */
7727 unsigned int reserved2:1; /* 26 */
7728 unsigned int Save_SP:1; /* 27 */
7729 unsigned int Save_RP:1; /* 28 */
7730 unsigned int Save_MRP_in_frame:1; /* 29 */
7731 unsigned int extn_ptr_defined:1; /* 30 */
7732 unsigned int Cleanup_defined:1; /* 31 */
7733
7734 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
7735 unsigned int HP_UX_interrupt_marker:1; /* 1 */
7736 unsigned int Large_frame:1; /* 2 */
7737 unsigned int Pseudo_SP_Set:1; /* 3 */
7738 unsigned int reserved4:1; /* 4 */
7739 unsigned int Total_frame_size:27; /* 5..31 */
7740};
3f5e193b 7741
57346661 7742struct hppa_unw_aux_info
948f632f 7743{
32ec8896
NC
7744 struct hppa_unw_table_entry * table; /* Unwind table. */
7745 unsigned long table_len; /* Length of unwind table. */
7746 bfd_vma seg_base; /* Starting address of segment. */
7747 Elf_Internal_Sym * symtab; /* The symbol table. */
7748 unsigned long nsyms; /* Number of symbols. */
7749 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7750 unsigned long nfuns; /* Number of entries in funtab. */
7751 char * strtab; /* The string table. */
7752 unsigned long strtab_size; /* Size of string table. */
948f632f 7753};
57346661 7754
32ec8896 7755static bfd_boolean
dda8d76d 7756dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 7757{
2cf0635d 7758 struct hppa_unw_table_entry * tp;
948f632f 7759 unsigned long j, nfuns;
32ec8896 7760 bfd_boolean res = TRUE;
948f632f
DA
7761
7762 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7763 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7764 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7765 aux->funtab[nfuns++] = aux->symtab[j];
7766 aux->nfuns = nfuns;
7767 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 7768
57346661
AM
7769 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7770 {
7771 bfd_vma offset;
2cf0635d 7772 const char * procname;
57346661 7773
dda8d76d 7774 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
7775 aux->strtab_size, tp->start, &procname,
7776 &offset);
7777
7778 fputs ("\n<", stdout);
7779
7780 if (procname)
7781 {
7782 fputs (procname, stdout);
7783
7784 if (offset)
7785 printf ("+%lx", (unsigned long) offset);
7786 }
7787
7788 fputs (">: [", stdout);
7789 print_vma (tp->start.offset, PREFIX_HEX);
7790 fputc ('-', stdout);
7791 print_vma (tp->end.offset, PREFIX_HEX);
7792 printf ("]\n\t");
7793
18bd398b
NC
7794#define PF(_m) if (tp->_m) printf (#_m " ");
7795#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
7796 PF(Cannot_unwind);
7797 PF(Millicode);
7798 PF(Millicode_save_sr0);
18bd398b 7799 /* PV(Region_description); */
57346661
AM
7800 PF(Entry_SR);
7801 PV(Entry_FR);
7802 PV(Entry_GR);
7803 PF(Args_stored);
7804 PF(Variable_Frame);
7805 PF(Separate_Package_Body);
7806 PF(Frame_Extension_Millicode);
7807 PF(Stack_Overflow_Check);
7808 PF(Two_Instruction_SP_Increment);
7809 PF(Ada_Region);
7810 PF(cxx_info);
7811 PF(cxx_try_catch);
7812 PF(sched_entry_seq);
7813 PF(Save_SP);
7814 PF(Save_RP);
7815 PF(Save_MRP_in_frame);
7816 PF(extn_ptr_defined);
7817 PF(Cleanup_defined);
7818 PF(MPE_XL_interrupt_marker);
7819 PF(HP_UX_interrupt_marker);
7820 PF(Large_frame);
7821 PF(Pseudo_SP_Set);
7822 PV(Total_frame_size);
7823#undef PF
7824#undef PV
7825 }
7826
18bd398b 7827 printf ("\n");
948f632f
DA
7828
7829 free (aux->funtab);
32ec8896
NC
7830
7831 return res;
57346661
AM
7832}
7833
32ec8896 7834static bfd_boolean
dda8d76d
NC
7835slurp_hppa_unwind_table (Filedata * filedata,
7836 struct hppa_unw_aux_info * aux,
7837 Elf_Internal_Shdr * sec)
57346661 7838{
1c0751b2 7839 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7840 Elf_Internal_Phdr * seg;
7841 struct hppa_unw_table_entry * tep;
7842 Elf_Internal_Shdr * relsec;
7843 Elf_Internal_Rela * rela;
7844 Elf_Internal_Rela * rp;
7845 unsigned char * table;
7846 unsigned char * tp;
7847 Elf_Internal_Sym * sym;
7848 const char * relname;
57346661 7849
57346661
AM
7850 /* First, find the starting address of the segment that includes
7851 this section. */
dda8d76d 7852 if (filedata->file_header.e_phnum)
57346661 7853 {
dda8d76d 7854 if (! get_program_headers (filedata))
32ec8896 7855 return FALSE;
57346661 7856
dda8d76d
NC
7857 for (seg = filedata->program_headers;
7858 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
7859 ++seg)
7860 {
7861 if (seg->p_type != PT_LOAD)
7862 continue;
7863
7864 if (sec->sh_addr >= seg->p_vaddr
7865 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7866 {
7867 aux->seg_base = seg->p_vaddr;
7868 break;
7869 }
7870 }
7871 }
7872
7873 /* Second, build the unwind table from the contents of the unwind
7874 section. */
7875 size = sec->sh_size;
dda8d76d 7876 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7877 _("unwind table"));
57346661 7878 if (!table)
32ec8896 7879 return FALSE;
57346661 7880
1c0751b2
DA
7881 unw_ent_size = 16;
7882 nentries = size / unw_ent_size;
7883 size = unw_ent_size * nentries;
57346661 7884
3f5e193b
NC
7885 tep = aux->table = (struct hppa_unw_table_entry *)
7886 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7887
1c0751b2 7888 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7889 {
7890 unsigned int tmp1, tmp2;
7891
7892 tep->start.section = SHN_UNDEF;
7893 tep->end.section = SHN_UNDEF;
7894
1c0751b2
DA
7895 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7896 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7897 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7898 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7899
7900 tep->start.offset += aux->seg_base;
7901 tep->end.offset += aux->seg_base;
57346661
AM
7902
7903 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
7904 tep->Millicode = (tmp1 >> 30) & 0x1;
7905 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
7906 tep->Region_description = (tmp1 >> 27) & 0x3;
7907 tep->reserved1 = (tmp1 >> 26) & 0x1;
7908 tep->Entry_SR = (tmp1 >> 25) & 0x1;
7909 tep->Entry_FR = (tmp1 >> 21) & 0xf;
7910 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7911 tep->Args_stored = (tmp1 >> 15) & 0x1;
7912 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7913 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7914 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7915 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7916 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7917 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7918 tep->cxx_info = (tmp1 >> 8) & 0x1;
7919 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7920 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7921 tep->reserved2 = (tmp1 >> 5) & 0x1;
7922 tep->Save_SP = (tmp1 >> 4) & 0x1;
7923 tep->Save_RP = (tmp1 >> 3) & 0x1;
7924 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7925 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7926 tep->Cleanup_defined = tmp1 & 0x1;
7927
7928 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7929 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7930 tep->Large_frame = (tmp2 >> 29) & 0x1;
7931 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7932 tep->reserved4 = (tmp2 >> 27) & 0x1;
7933 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7934 }
7935 free (table);
7936
7937 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
7938 for (relsec = filedata->section_headers;
7939 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
7940 ++relsec)
7941 {
7942 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7943 || relsec->sh_info >= filedata->file_header.e_shnum
7944 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
7945 continue;
7946
dda8d76d 7947 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 7948 & rela, & nrelas))
32ec8896 7949 return FALSE;
57346661
AM
7950
7951 for (rp = rela; rp < rela + nrelas; ++rp)
7952 {
dda8d76d 7953 relname = elf_hppa_reloc_type (get_reloc_type (filedata, rp->r_info));
aca88567 7954 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
7955
7956 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 7957 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
7958 {
7959 warn (_("Skipping unexpected relocation type %s\n"), relname);
7960 continue;
7961 }
7962
7963 i = rp->r_offset / unw_ent_size;
7964
89fac5e3 7965 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
7966 {
7967 case 0:
7968 aux->table[i].start.section = sym->st_shndx;
1e456d54 7969 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
7970 break;
7971 case 1:
7972 aux->table[i].end.section = sym->st_shndx;
1e456d54 7973 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
7974 break;
7975 default:
7976 break;
7977 }
7978 }
7979
7980 free (rela);
7981 }
7982
1c0751b2 7983 aux->table_len = nentries;
57346661 7984
32ec8896 7985 return TRUE;
57346661
AM
7986}
7987
32ec8896 7988static bfd_boolean
dda8d76d 7989hppa_process_unwind (Filedata * filedata)
57346661 7990{
57346661 7991 struct hppa_unw_aux_info aux;
2cf0635d
NC
7992 Elf_Internal_Shdr * unwsec = NULL;
7993 Elf_Internal_Shdr * strsec;
7994 Elf_Internal_Shdr * sec;
18bd398b 7995 unsigned long i;
32ec8896 7996 bfd_boolean res = TRUE;
57346661 7997
dda8d76d 7998 if (filedata->string_table == NULL)
32ec8896 7999 return FALSE;
1b31d05e
NC
8000
8001 memset (& aux, 0, sizeof (aux));
57346661 8002
dda8d76d 8003 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8004 {
c256ffe7 8005 if (sec->sh_type == SHT_SYMTAB
dda8d76d 8006 && sec->sh_link < filedata->file_header.e_shnum)
57346661 8007 {
dda8d76d 8008 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
57346661 8009
dda8d76d 8010 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
8011 if (aux.strtab != NULL)
8012 {
8013 error (_("Multiple auxillary string tables encountered\n"));
8014 free (aux.strtab);
32ec8896 8015 res = FALSE;
4082ef84 8016 }
dda8d76d 8017 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
8018 1, strsec->sh_size,
8019 _("string table"));
c256ffe7 8020 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 8021 }
18bd398b 8022 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8023 unwsec = sec;
8024 }
8025
8026 if (!unwsec)
8027 printf (_("\nThere are no unwind sections in this file.\n"));
8028
dda8d76d 8029 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8030 {
18bd398b 8031 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8032 {
d3a49aa8 8033 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size + 8);
dda8d76d 8034
d3a49aa8
AM
8035 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8036 "contains %lu entry:\n",
8037 "\nUnwind section '%s' at offset 0x%lx "
8038 "contains %lu entries:\n",
8039 num_unwind),
dda8d76d 8040 printable_section_name (filedata, sec),
57346661 8041 (unsigned long) sec->sh_offset,
d3a49aa8 8042 num_unwind);
57346661 8043
dda8d76d 8044 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896
NC
8045 res = FALSE;
8046
57346661 8047 if (aux.table_len > 0)
32ec8896 8048 {
dda8d76d 8049 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8050 res = FALSE;
8051 }
57346661
AM
8052
8053 if (aux.table)
8054 free ((char *) aux.table);
8055 aux.table = NULL;
8056 }
8057 }
8058
8059 if (aux.symtab)
8060 free (aux.symtab);
8061 if (aux.strtab)
8062 free ((char *) aux.strtab);
32ec8896
NC
8063
8064 return res;
57346661
AM
8065}
8066
0b6ae522
DJ
8067struct arm_section
8068{
a734115a
NC
8069 unsigned char * data; /* The unwind data. */
8070 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8071 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8072 unsigned long nrelas; /* The number of relocations. */
8073 unsigned int rel_type; /* REL or RELA ? */
8074 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8075};
8076
8077struct arm_unw_aux_info
8078{
dda8d76d 8079 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8080 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8081 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8082 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8083 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8084 char * strtab; /* The file's string table. */
8085 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8086};
8087
8088static const char *
dda8d76d
NC
8089arm_print_vma_and_name (Filedata * filedata,
8090 struct arm_unw_aux_info * aux,
8091 bfd_vma fn,
8092 struct absaddr addr)
0b6ae522
DJ
8093{
8094 const char *procname;
8095 bfd_vma sym_offset;
8096
8097 if (addr.section == SHN_UNDEF)
8098 addr.offset = fn;
8099
dda8d76d 8100 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8101 aux->strtab_size, addr, &procname,
8102 &sym_offset);
8103
8104 print_vma (fn, PREFIX_HEX);
8105
8106 if (procname)
8107 {
8108 fputs (" <", stdout);
8109 fputs (procname, stdout);
8110
8111 if (sym_offset)
8112 printf ("+0x%lx", (unsigned long) sym_offset);
8113 fputc ('>', stdout);
8114 }
8115
8116 return procname;
8117}
8118
8119static void
8120arm_free_section (struct arm_section *arm_sec)
8121{
8122 if (arm_sec->data != NULL)
8123 free (arm_sec->data);
8124
8125 if (arm_sec->rela != NULL)
8126 free (arm_sec->rela);
8127}
8128
a734115a
NC
8129/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8130 cached section and install SEC instead.
8131 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8132 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8133 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8134 relocation's offset in ADDR.
1b31d05e
NC
8135 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8136 into the string table of the symbol associated with the reloc. If no
8137 reloc was applied store -1 there.
8138 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8139
8140static bfd_boolean
dda8d76d
NC
8141get_unwind_section_word (Filedata * filedata,
8142 struct arm_unw_aux_info * aux,
1b31d05e
NC
8143 struct arm_section * arm_sec,
8144 Elf_Internal_Shdr * sec,
8145 bfd_vma word_offset,
8146 unsigned int * wordp,
8147 struct absaddr * addr,
8148 bfd_vma * sym_name)
0b6ae522
DJ
8149{
8150 Elf_Internal_Rela *rp;
8151 Elf_Internal_Sym *sym;
8152 const char * relname;
8153 unsigned int word;
8154 bfd_boolean wrapped;
8155
e0a31db1
NC
8156 if (sec == NULL || arm_sec == NULL)
8157 return FALSE;
8158
0b6ae522
DJ
8159 addr->section = SHN_UNDEF;
8160 addr->offset = 0;
8161
1b31d05e
NC
8162 if (sym_name != NULL)
8163 *sym_name = (bfd_vma) -1;
8164
a734115a 8165 /* If necessary, update the section cache. */
0b6ae522
DJ
8166 if (sec != arm_sec->sec)
8167 {
8168 Elf_Internal_Shdr *relsec;
8169
8170 arm_free_section (arm_sec);
8171
8172 arm_sec->sec = sec;
dda8d76d 8173 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8174 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8175 arm_sec->rela = NULL;
8176 arm_sec->nrelas = 0;
8177
dda8d76d
NC
8178 for (relsec = filedata->section_headers;
8179 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8180 ++relsec)
8181 {
dda8d76d
NC
8182 if (relsec->sh_info >= filedata->file_header.e_shnum
8183 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8184 /* PR 15745: Check the section type as well. */
8185 || (relsec->sh_type != SHT_REL
8186 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8187 continue;
8188
a734115a 8189 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8190 if (relsec->sh_type == SHT_REL)
8191 {
dda8d76d 8192 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8193 relsec->sh_size,
8194 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8195 return FALSE;
0b6ae522 8196 }
1ae40aa4 8197 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8198 {
dda8d76d 8199 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8200 relsec->sh_size,
8201 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8202 return FALSE;
0b6ae522 8203 }
1ae40aa4 8204 break;
0b6ae522
DJ
8205 }
8206
8207 arm_sec->next_rela = arm_sec->rela;
8208 }
8209
a734115a 8210 /* If there is no unwind data we can do nothing. */
0b6ae522 8211 if (arm_sec->data == NULL)
a734115a 8212 return FALSE;
0b6ae522 8213
e0a31db1 8214 /* If the offset is invalid then fail. */
f32ba729
NC
8215 if (/* PR 21343 *//* PR 18879 */
8216 sec->sh_size < 4
8217 || word_offset > (sec->sh_size - 4)
1a915552 8218 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8219 return FALSE;
8220
a734115a 8221 /* Get the word at the required offset. */
0b6ae522
DJ
8222 word = byte_get (arm_sec->data + word_offset, 4);
8223
0eff7165
NC
8224 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8225 if (arm_sec->rela == NULL)
8226 {
8227 * wordp = word;
8228 return TRUE;
8229 }
8230
a734115a 8231 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8232 wrapped = FALSE;
8233 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8234 {
8235 bfd_vma prelval, offset;
8236
8237 if (rp->r_offset > word_offset && !wrapped)
8238 {
8239 rp = arm_sec->rela;
8240 wrapped = TRUE;
8241 }
8242 if (rp->r_offset > word_offset)
8243 break;
8244
8245 if (rp->r_offset & 3)
8246 {
8247 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8248 (unsigned long) rp->r_offset);
8249 continue;
8250 }
8251
8252 if (rp->r_offset < word_offset)
8253 continue;
8254
74e1a04b
NC
8255 /* PR 17531: file: 027-161405-0.004 */
8256 if (aux->symtab == NULL)
8257 continue;
8258
0b6ae522
DJ
8259 if (arm_sec->rel_type == SHT_REL)
8260 {
8261 offset = word & 0x7fffffff;
8262 if (offset & 0x40000000)
8263 offset |= ~ (bfd_vma) 0x7fffffff;
8264 }
a734115a 8265 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8266 offset = rp->r_addend;
a734115a 8267 else
74e1a04b
NC
8268 {
8269 error (_("Unknown section relocation type %d encountered\n"),
8270 arm_sec->rel_type);
8271 break;
8272 }
0b6ae522 8273
071436c6
NC
8274 /* PR 17531 file: 027-1241568-0.004. */
8275 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8276 {
8277 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8278 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8279 break;
8280 }
8281
8282 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8283 offset += sym->st_value;
8284 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8285
a734115a 8286 /* Check that we are processing the expected reloc type. */
dda8d76d 8287 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8288 {
8289 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8290 if (relname == NULL)
8291 {
8292 warn (_("Skipping unknown ARM relocation type: %d\n"),
8293 (int) ELF32_R_TYPE (rp->r_info));
8294 continue;
8295 }
a734115a
NC
8296
8297 if (streq (relname, "R_ARM_NONE"))
8298 continue;
0b4362b0 8299
a734115a
NC
8300 if (! streq (relname, "R_ARM_PREL31"))
8301 {
071436c6 8302 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8303 continue;
8304 }
8305 }
dda8d76d 8306 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8307 {
8308 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8309 if (relname == NULL)
8310 {
8311 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8312 (int) ELF32_R_TYPE (rp->r_info));
8313 continue;
8314 }
0b4362b0 8315
a734115a
NC
8316 if (streq (relname, "R_C6000_NONE"))
8317 continue;
8318
8319 if (! streq (relname, "R_C6000_PREL31"))
8320 {
071436c6 8321 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8322 continue;
8323 }
8324
8325 prelval >>= 1;
8326 }
8327 else
74e1a04b
NC
8328 {
8329 /* This function currently only supports ARM and TI unwinders. */
8330 warn (_("Only TI and ARM unwinders are currently supported\n"));
8331 break;
8332 }
fa197c1c 8333
0b6ae522
DJ
8334 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8335 addr->section = sym->st_shndx;
8336 addr->offset = offset;
74e1a04b 8337
1b31d05e
NC
8338 if (sym_name)
8339 * sym_name = sym->st_name;
0b6ae522
DJ
8340 break;
8341 }
8342
8343 *wordp = word;
8344 arm_sec->next_rela = rp;
8345
a734115a 8346 return TRUE;
0b6ae522
DJ
8347}
8348
a734115a
NC
8349static const char *tic6x_unwind_regnames[16] =
8350{
0b4362b0
RM
8351 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8352 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8353 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8354};
fa197c1c 8355
0b6ae522 8356static void
fa197c1c 8357decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8358{
fa197c1c
PB
8359 int i;
8360
8361 for (i = 12; mask; mask >>= 1, i--)
8362 {
8363 if (mask & 1)
8364 {
8365 fputs (tic6x_unwind_regnames[i], stdout);
8366 if (mask > 1)
8367 fputs (", ", stdout);
8368 }
8369 }
8370}
0b6ae522
DJ
8371
8372#define ADVANCE \
8373 if (remaining == 0 && more_words) \
8374 { \
8375 data_offset += 4; \
dda8d76d 8376 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8377 data_offset, & word, & addr, NULL)) \
32ec8896 8378 return FALSE; \
0b6ae522
DJ
8379 remaining = 4; \
8380 more_words--; \
8381 } \
8382
8383#define GET_OP(OP) \
8384 ADVANCE; \
8385 if (remaining) \
8386 { \
8387 remaining--; \
8388 (OP) = word >> 24; \
8389 word <<= 8; \
8390 } \
8391 else \
8392 { \
2b692964 8393 printf (_("[Truncated opcode]\n")); \
32ec8896 8394 return FALSE; \
0b6ae522 8395 } \
cc5914eb 8396 printf ("0x%02x ", OP)
0b6ae522 8397
32ec8896 8398static bfd_boolean
dda8d76d
NC
8399decode_arm_unwind_bytecode (Filedata * filedata,
8400 struct arm_unw_aux_info * aux,
948f632f
DA
8401 unsigned int word,
8402 unsigned int remaining,
8403 unsigned int more_words,
8404 bfd_vma data_offset,
8405 Elf_Internal_Shdr * data_sec,
8406 struct arm_section * data_arm_sec)
fa197c1c
PB
8407{
8408 struct absaddr addr;
32ec8896 8409 bfd_boolean res = TRUE;
0b6ae522
DJ
8410
8411 /* Decode the unwinding instructions. */
8412 while (1)
8413 {
8414 unsigned int op, op2;
8415
8416 ADVANCE;
8417 if (remaining == 0)
8418 break;
8419 remaining--;
8420 op = word >> 24;
8421 word <<= 8;
8422
cc5914eb 8423 printf (" 0x%02x ", op);
0b6ae522
DJ
8424
8425 if ((op & 0xc0) == 0x00)
8426 {
8427 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8428
cc5914eb 8429 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8430 }
8431 else if ((op & 0xc0) == 0x40)
8432 {
8433 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8434
cc5914eb 8435 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8436 }
8437 else if ((op & 0xf0) == 0x80)
8438 {
8439 GET_OP (op2);
8440 if (op == 0x80 && op2 == 0)
8441 printf (_("Refuse to unwind"));
8442 else
8443 {
8444 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8445 bfd_boolean first = TRUE;
0b6ae522 8446 int i;
2b692964 8447
0b6ae522
DJ
8448 printf ("pop {");
8449 for (i = 0; i < 12; i++)
8450 if (mask & (1 << i))
8451 {
8452 if (first)
32ec8896 8453 first = FALSE;
0b6ae522
DJ
8454 else
8455 printf (", ");
8456 printf ("r%d", 4 + i);
8457 }
8458 printf ("}");
8459 }
8460 }
8461 else if ((op & 0xf0) == 0x90)
8462 {
8463 if (op == 0x9d || op == 0x9f)
8464 printf (_(" [Reserved]"));
8465 else
cc5914eb 8466 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8467 }
8468 else if ((op & 0xf0) == 0xa0)
8469 {
8470 int end = 4 + (op & 0x07);
32ec8896 8471 bfd_boolean first = TRUE;
0b6ae522 8472 int i;
61865e30 8473
0b6ae522
DJ
8474 printf (" pop {");
8475 for (i = 4; i <= end; i++)
8476 {
8477 if (first)
32ec8896 8478 first = FALSE;
0b6ae522
DJ
8479 else
8480 printf (", ");
8481 printf ("r%d", i);
8482 }
8483 if (op & 0x08)
8484 {
1b31d05e 8485 if (!first)
0b6ae522
DJ
8486 printf (", ");
8487 printf ("r14");
8488 }
8489 printf ("}");
8490 }
8491 else if (op == 0xb0)
8492 printf (_(" finish"));
8493 else if (op == 0xb1)
8494 {
8495 GET_OP (op2);
8496 if (op2 == 0 || (op2 & 0xf0) != 0)
8497 printf (_("[Spare]"));
8498 else
8499 {
8500 unsigned int mask = op2 & 0x0f;
32ec8896 8501 bfd_boolean first = TRUE;
0b6ae522 8502 int i;
61865e30 8503
0b6ae522
DJ
8504 printf ("pop {");
8505 for (i = 0; i < 12; i++)
8506 if (mask & (1 << i))
8507 {
8508 if (first)
32ec8896 8509 first = FALSE;
0b6ae522
DJ
8510 else
8511 printf (", ");
8512 printf ("r%d", i);
8513 }
8514 printf ("}");
8515 }
8516 }
8517 else if (op == 0xb2)
8518 {
b115cf96 8519 unsigned char buf[9];
0b6ae522
DJ
8520 unsigned int i, len;
8521 unsigned long offset;
61865e30 8522
b115cf96 8523 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8524 {
8525 GET_OP (buf[i]);
8526 if ((buf[i] & 0x80) == 0)
8527 break;
8528 }
4082ef84 8529 if (i == sizeof (buf))
32ec8896
NC
8530 {
8531 error (_("corrupt change to vsp"));
8532 res = FALSE;
8533 }
4082ef84
NC
8534 else
8535 {
8536 offset = read_uleb128 (buf, &len, buf + i + 1);
8537 assert (len == i + 1);
8538 offset = offset * 4 + 0x204;
8539 printf ("vsp = vsp + %ld", offset);
8540 }
0b6ae522 8541 }
61865e30 8542 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8543 {
61865e30
NC
8544 unsigned int first, last;
8545
8546 GET_OP (op2);
8547 first = op2 >> 4;
8548 last = op2 & 0x0f;
8549 if (op == 0xc8)
8550 first = first + 16;
8551 printf ("pop {D%d", first);
8552 if (last)
8553 printf ("-D%d", first + last);
8554 printf ("}");
8555 }
8556 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8557 {
8558 unsigned int count = op & 0x07;
8559
8560 printf ("pop {D8");
8561 if (count)
8562 printf ("-D%d", 8 + count);
8563 printf ("}");
8564 }
8565 else if (op >= 0xc0 && op <= 0xc5)
8566 {
8567 unsigned int count = op & 0x07;
8568
8569 printf (" pop {wR10");
8570 if (count)
8571 printf ("-wR%d", 10 + count);
8572 printf ("}");
8573 }
8574 else if (op == 0xc6)
8575 {
8576 unsigned int first, last;
8577
8578 GET_OP (op2);
8579 first = op2 >> 4;
8580 last = op2 & 0x0f;
8581 printf ("pop {wR%d", first);
8582 if (last)
8583 printf ("-wR%d", first + last);
8584 printf ("}");
8585 }
8586 else if (op == 0xc7)
8587 {
8588 GET_OP (op2);
8589 if (op2 == 0 || (op2 & 0xf0) != 0)
8590 printf (_("[Spare]"));
0b6ae522
DJ
8591 else
8592 {
61865e30 8593 unsigned int mask = op2 & 0x0f;
32ec8896 8594 bfd_boolean first = TRUE;
61865e30
NC
8595 int i;
8596
8597 printf ("pop {");
8598 for (i = 0; i < 4; i++)
8599 if (mask & (1 << i))
8600 {
8601 if (first)
32ec8896 8602 first = FALSE;
61865e30
NC
8603 else
8604 printf (", ");
8605 printf ("wCGR%d", i);
8606 }
8607 printf ("}");
0b6ae522
DJ
8608 }
8609 }
61865e30 8610 else
32ec8896
NC
8611 {
8612 printf (_(" [unsupported opcode]"));
8613 res = FALSE;
8614 }
8615
0b6ae522
DJ
8616 printf ("\n");
8617 }
32ec8896
NC
8618
8619 return res;
fa197c1c
PB
8620}
8621
32ec8896 8622static bfd_boolean
dda8d76d
NC
8623decode_tic6x_unwind_bytecode (Filedata * filedata,
8624 struct arm_unw_aux_info * aux,
948f632f
DA
8625 unsigned int word,
8626 unsigned int remaining,
8627 unsigned int more_words,
8628 bfd_vma data_offset,
8629 Elf_Internal_Shdr * data_sec,
8630 struct arm_section * data_arm_sec)
fa197c1c
PB
8631{
8632 struct absaddr addr;
8633
8634 /* Decode the unwinding instructions. */
8635 while (1)
8636 {
8637 unsigned int op, op2;
8638
8639 ADVANCE;
8640 if (remaining == 0)
8641 break;
8642 remaining--;
8643 op = word >> 24;
8644 word <<= 8;
8645
9cf03b7e 8646 printf (" 0x%02x ", op);
fa197c1c
PB
8647
8648 if ((op & 0xc0) == 0x00)
8649 {
8650 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 8651 printf (" sp = sp + %d", offset);
fa197c1c
PB
8652 }
8653 else if ((op & 0xc0) == 0x80)
8654 {
8655 GET_OP (op2);
8656 if (op == 0x80 && op2 == 0)
8657 printf (_("Refuse to unwind"));
8658 else
8659 {
8660 unsigned int mask = ((op & 0x1f) << 8) | op2;
8661 if (op & 0x20)
8662 printf ("pop compact {");
8663 else
8664 printf ("pop {");
8665
8666 decode_tic6x_unwind_regmask (mask);
8667 printf("}");
8668 }
8669 }
8670 else if ((op & 0xf0) == 0xc0)
8671 {
8672 unsigned int reg;
8673 unsigned int nregs;
8674 unsigned int i;
8675 const char *name;
a734115a
NC
8676 struct
8677 {
32ec8896
NC
8678 unsigned int offset;
8679 unsigned int reg;
fa197c1c
PB
8680 } regpos[16];
8681
8682 /* Scan entire instruction first so that GET_OP output is not
8683 interleaved with disassembly. */
8684 nregs = 0;
8685 for (i = 0; nregs < (op & 0xf); i++)
8686 {
8687 GET_OP (op2);
8688 reg = op2 >> 4;
8689 if (reg != 0xf)
8690 {
8691 regpos[nregs].offset = i * 2;
8692 regpos[nregs].reg = reg;
8693 nregs++;
8694 }
8695
8696 reg = op2 & 0xf;
8697 if (reg != 0xf)
8698 {
8699 regpos[nregs].offset = i * 2 + 1;
8700 regpos[nregs].reg = reg;
8701 nregs++;
8702 }
8703 }
8704
8705 printf (_("pop frame {"));
8706 reg = nregs - 1;
8707 for (i = i * 2; i > 0; i--)
8708 {
8709 if (regpos[reg].offset == i - 1)
8710 {
8711 name = tic6x_unwind_regnames[regpos[reg].reg];
8712 if (reg > 0)
8713 reg--;
8714 }
8715 else
8716 name = _("[pad]");
8717
8718 fputs (name, stdout);
8719 if (i > 1)
8720 printf (", ");
8721 }
8722
8723 printf ("}");
8724 }
8725 else if (op == 0xd0)
8726 printf (" MOV FP, SP");
8727 else if (op == 0xd1)
8728 printf (" __c6xabi_pop_rts");
8729 else if (op == 0xd2)
8730 {
8731 unsigned char buf[9];
8732 unsigned int i, len;
8733 unsigned long offset;
a734115a 8734
fa197c1c
PB
8735 for (i = 0; i < sizeof (buf); i++)
8736 {
8737 GET_OP (buf[i]);
8738 if ((buf[i] & 0x80) == 0)
8739 break;
8740 }
0eff7165
NC
8741 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
8742 if (i == sizeof (buf))
8743 {
0eff7165 8744 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 8745 return FALSE;
0eff7165 8746 }
948f632f 8747
f6f0e17b 8748 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
8749 assert (len == i + 1);
8750 offset = offset * 8 + 0x408;
8751 printf (_("sp = sp + %ld"), offset);
8752 }
8753 else if ((op & 0xf0) == 0xe0)
8754 {
8755 if ((op & 0x0f) == 7)
8756 printf (" RETURN");
8757 else
8758 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
8759 }
8760 else
8761 {
8762 printf (_(" [unsupported opcode]"));
8763 }
8764 putchar ('\n');
8765 }
32ec8896
NC
8766
8767 return TRUE;
fa197c1c
PB
8768}
8769
8770static bfd_vma
dda8d76d 8771arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
8772{
8773 bfd_vma offset;
8774
8775 offset = word & 0x7fffffff;
8776 if (offset & 0x40000000)
8777 offset |= ~ (bfd_vma) 0x7fffffff;
8778
dda8d76d 8779 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
8780 offset <<= 1;
8781
8782 return offset + where;
8783}
8784
32ec8896 8785static bfd_boolean
dda8d76d
NC
8786decode_arm_unwind (Filedata * filedata,
8787 struct arm_unw_aux_info * aux,
1b31d05e
NC
8788 unsigned int word,
8789 unsigned int remaining,
8790 bfd_vma data_offset,
8791 Elf_Internal_Shdr * data_sec,
8792 struct arm_section * data_arm_sec)
fa197c1c
PB
8793{
8794 int per_index;
8795 unsigned int more_words = 0;
37e14bc3 8796 struct absaddr addr;
1b31d05e 8797 bfd_vma sym_name = (bfd_vma) -1;
97953bab 8798 bfd_boolean res = TRUE;
fa197c1c
PB
8799
8800 if (remaining == 0)
8801 {
1b31d05e
NC
8802 /* Fetch the first word.
8803 Note - when decoding an object file the address extracted
8804 here will always be 0. So we also pass in the sym_name
8805 parameter so that we can find the symbol associated with
8806 the personality routine. */
dda8d76d 8807 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 8808 & word, & addr, & sym_name))
32ec8896 8809 return FALSE;
1b31d05e 8810
fa197c1c
PB
8811 remaining = 4;
8812 }
8813
8814 if ((word & 0x80000000) == 0)
8815 {
8816 /* Expand prel31 for personality routine. */
8817 bfd_vma fn;
8818 const char *procname;
8819
dda8d76d 8820 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 8821 printf (_(" Personality routine: "));
1b31d05e
NC
8822 if (fn == 0
8823 && addr.section == SHN_UNDEF && addr.offset == 0
8824 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
8825 {
8826 procname = aux->strtab + sym_name;
8827 print_vma (fn, PREFIX_HEX);
8828 if (procname)
8829 {
8830 fputs (" <", stdout);
8831 fputs (procname, stdout);
8832 fputc ('>', stdout);
8833 }
8834 }
8835 else
dda8d76d 8836 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
8837 fputc ('\n', stdout);
8838
8839 /* The GCC personality routines use the standard compact
8840 encoding, starting with one byte giving the number of
8841 words. */
8842 if (procname != NULL
8843 && (const_strneq (procname, "__gcc_personality_v0")
8844 || const_strneq (procname, "__gxx_personality_v0")
8845 || const_strneq (procname, "__gcj_personality_v0")
8846 || const_strneq (procname, "__gnu_objc_personality_v0")))
8847 {
8848 remaining = 0;
8849 more_words = 1;
8850 ADVANCE;
8851 if (!remaining)
8852 {
8853 printf (_(" [Truncated data]\n"));
32ec8896 8854 return FALSE;
fa197c1c
PB
8855 }
8856 more_words = word >> 24;
8857 word <<= 8;
8858 remaining--;
8859 per_index = -1;
8860 }
8861 else
32ec8896 8862 return TRUE;
fa197c1c
PB
8863 }
8864 else
8865 {
1b31d05e 8866 /* ARM EHABI Section 6.3:
0b4362b0 8867
1b31d05e 8868 An exception-handling table entry for the compact model looks like:
0b4362b0 8869
1b31d05e
NC
8870 31 30-28 27-24 23-0
8871 -- ----- ----- ----
8872 1 0 index Data for personalityRoutine[index] */
8873
dda8d76d 8874 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 8875 && (word & 0x70000000))
32ec8896
NC
8876 {
8877 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
8878 res = FALSE;
8879 }
1b31d05e 8880
fa197c1c 8881 per_index = (word >> 24) & 0x7f;
1b31d05e 8882 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
8883 if (per_index == 0)
8884 {
8885 more_words = 0;
8886 word <<= 8;
8887 remaining--;
8888 }
8889 else if (per_index < 3)
8890 {
8891 more_words = (word >> 16) & 0xff;
8892 word <<= 16;
8893 remaining -= 2;
8894 }
8895 }
8896
dda8d76d 8897 switch (filedata->file_header.e_machine)
fa197c1c
PB
8898 {
8899 case EM_ARM:
8900 if (per_index < 3)
8901 {
dda8d76d 8902 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
8903 data_offset, data_sec, data_arm_sec))
8904 res = FALSE;
fa197c1c
PB
8905 }
8906 else
1b31d05e
NC
8907 {
8908 warn (_("Unknown ARM compact model index encountered\n"));
8909 printf (_(" [reserved]\n"));
32ec8896 8910 res = FALSE;
1b31d05e 8911 }
fa197c1c
PB
8912 break;
8913
8914 case EM_TI_C6000:
8915 if (per_index < 3)
8916 {
dda8d76d 8917 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
8918 data_offset, data_sec, data_arm_sec))
8919 res = FALSE;
fa197c1c
PB
8920 }
8921 else if (per_index < 5)
8922 {
8923 if (((word >> 17) & 0x7f) == 0x7f)
8924 printf (_(" Restore stack from frame pointer\n"));
8925 else
8926 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
8927 printf (_(" Registers restored: "));
8928 if (per_index == 4)
8929 printf (" (compact) ");
8930 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
8931 putchar ('\n');
8932 printf (_(" Return register: %s\n"),
8933 tic6x_unwind_regnames[word & 0xf]);
8934 }
8935 else
1b31d05e 8936 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
8937 break;
8938
8939 default:
74e1a04b 8940 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 8941 filedata->file_header.e_machine);
32ec8896 8942 res = FALSE;
fa197c1c 8943 }
0b6ae522
DJ
8944
8945 /* Decode the descriptors. Not implemented. */
32ec8896
NC
8946
8947 return res;
0b6ae522
DJ
8948}
8949
32ec8896 8950static bfd_boolean
dda8d76d
NC
8951dump_arm_unwind (Filedata * filedata,
8952 struct arm_unw_aux_info * aux,
8953 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
8954{
8955 struct arm_section exidx_arm_sec, extab_arm_sec;
8956 unsigned int i, exidx_len;
948f632f 8957 unsigned long j, nfuns;
32ec8896 8958 bfd_boolean res = TRUE;
0b6ae522
DJ
8959
8960 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
8961 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
8962 exidx_len = exidx_sec->sh_size / 8;
8963
948f632f
DA
8964 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8965 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8966 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8967 aux->funtab[nfuns++] = aux->symtab[j];
8968 aux->nfuns = nfuns;
8969 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8970
0b6ae522
DJ
8971 for (i = 0; i < exidx_len; i++)
8972 {
8973 unsigned int exidx_fn, exidx_entry;
8974 struct absaddr fn_addr, entry_addr;
8975 bfd_vma fn;
8976
8977 fputc ('\n', stdout);
8978
dda8d76d 8979 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 8980 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 8981 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 8982 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 8983 {
948f632f 8984 free (aux->funtab);
1b31d05e
NC
8985 arm_free_section (& exidx_arm_sec);
8986 arm_free_section (& extab_arm_sec);
32ec8896 8987 return FALSE;
0b6ae522
DJ
8988 }
8989
83c257ca
NC
8990 /* ARM EHABI, Section 5:
8991 An index table entry consists of 2 words.
8992 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
8993 if (exidx_fn & 0x80000000)
32ec8896
NC
8994 {
8995 warn (_("corrupt index table entry: %x\n"), exidx_fn);
8996 res = FALSE;
8997 }
83c257ca 8998
dda8d76d 8999 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9000
dda8d76d 9001 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9002 fputs (": ", stdout);
9003
9004 if (exidx_entry == 1)
9005 {
9006 print_vma (exidx_entry, PREFIX_HEX);
9007 fputs (" [cantunwind]\n", stdout);
9008 }
9009 else if (exidx_entry & 0x80000000)
9010 {
9011 print_vma (exidx_entry, PREFIX_HEX);
9012 fputc ('\n', stdout);
dda8d76d 9013 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9014 }
9015 else
9016 {
8f73510c 9017 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9018 Elf_Internal_Shdr *table_sec;
9019
9020 fputs ("@", stdout);
dda8d76d 9021 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9022 print_vma (table, PREFIX_HEX);
9023 printf ("\n");
9024
9025 /* Locate the matching .ARM.extab. */
9026 if (entry_addr.section != SHN_UNDEF
dda8d76d 9027 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9028 {
dda8d76d 9029 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9030 table_offset = entry_addr.offset;
1a915552
NC
9031 /* PR 18879 */
9032 if (table_offset > table_sec->sh_size
9033 || ((bfd_signed_vma) table_offset) < 0)
9034 {
9035 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9036 (unsigned long) table_offset,
dda8d76d 9037 printable_section_name (filedata, table_sec));
32ec8896 9038 res = FALSE;
1a915552
NC
9039 continue;
9040 }
0b6ae522
DJ
9041 }
9042 else
9043 {
dda8d76d 9044 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9045 if (table_sec != NULL)
9046 table_offset = table - table_sec->sh_addr;
9047 }
32ec8896 9048
0b6ae522
DJ
9049 if (table_sec == NULL)
9050 {
9051 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9052 (unsigned long) table);
32ec8896 9053 res = FALSE;
0b6ae522
DJ
9054 continue;
9055 }
32ec8896 9056
dda8d76d 9057 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9058 &extab_arm_sec))
9059 res = FALSE;
0b6ae522
DJ
9060 }
9061 }
9062
9063 printf ("\n");
9064
948f632f 9065 free (aux->funtab);
0b6ae522
DJ
9066 arm_free_section (&exidx_arm_sec);
9067 arm_free_section (&extab_arm_sec);
32ec8896
NC
9068
9069 return res;
0b6ae522
DJ
9070}
9071
fa197c1c 9072/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9073
32ec8896 9074static bfd_boolean
dda8d76d 9075arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9076{
9077 struct arm_unw_aux_info aux;
9078 Elf_Internal_Shdr *unwsec = NULL;
9079 Elf_Internal_Shdr *strsec;
9080 Elf_Internal_Shdr *sec;
9081 unsigned long i;
fa197c1c 9082 unsigned int sec_type;
32ec8896 9083 bfd_boolean res = TRUE;
0b6ae522 9084
dda8d76d 9085 switch (filedata->file_header.e_machine)
fa197c1c
PB
9086 {
9087 case EM_ARM:
9088 sec_type = SHT_ARM_EXIDX;
9089 break;
9090
9091 case EM_TI_C6000:
9092 sec_type = SHT_C6000_UNWIND;
9093 break;
9094
0b4362b0 9095 default:
74e1a04b 9096 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9097 filedata->file_header.e_machine);
32ec8896 9098 return FALSE;
fa197c1c
PB
9099 }
9100
dda8d76d 9101 if (filedata->string_table == NULL)
32ec8896 9102 return FALSE;
1b31d05e
NC
9103
9104 memset (& aux, 0, sizeof (aux));
dda8d76d 9105 aux.filedata = filedata;
0b6ae522 9106
dda8d76d 9107 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9108 {
dda8d76d 9109 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < filedata->file_header.e_shnum)
0b6ae522 9110 {
dda8d76d 9111 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
0b6ae522 9112
dda8d76d 9113 strsec = filedata->section_headers + sec->sh_link;
74e1a04b
NC
9114
9115 /* PR binutils/17531 file: 011-12666-0.004. */
9116 if (aux.strtab != NULL)
9117 {
4082ef84 9118 error (_("Multiple string tables found in file.\n"));
74e1a04b 9119 free (aux.strtab);
32ec8896 9120 res = FALSE;
74e1a04b 9121 }
dda8d76d 9122 aux.strtab = get_data (NULL, filedata, strsec->sh_offset,
0b6ae522
DJ
9123 1, strsec->sh_size, _("string table"));
9124 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
9125 }
fa197c1c 9126 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9127 unwsec = sec;
9128 }
9129
1b31d05e 9130 if (unwsec == NULL)
0b6ae522 9131 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9132 else
dda8d76d 9133 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9134 {
9135 if (sec->sh_type == sec_type)
9136 {
d3a49aa8
AM
9137 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9138 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9139 "contains %lu entry:\n",
9140 "\nUnwind section '%s' at offset 0x%lx "
9141 "contains %lu entries:\n",
9142 num_unwind),
dda8d76d 9143 printable_section_name (filedata, sec),
1b31d05e 9144 (unsigned long) sec->sh_offset,
d3a49aa8 9145 num_unwind);
0b6ae522 9146
dda8d76d 9147 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9148 res = FALSE;
1b31d05e
NC
9149 }
9150 }
0b6ae522
DJ
9151
9152 if (aux.symtab)
9153 free (aux.symtab);
9154 if (aux.strtab)
9155 free ((char *) aux.strtab);
32ec8896
NC
9156
9157 return res;
0b6ae522
DJ
9158}
9159
32ec8896 9160static bfd_boolean
dda8d76d 9161process_unwind (Filedata * filedata)
57346661 9162{
2cf0635d
NC
9163 struct unwind_handler
9164 {
32ec8896 9165 unsigned int machtype;
dda8d76d 9166 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9167 } handlers[] =
9168 {
0b6ae522 9169 { EM_ARM, arm_process_unwind },
57346661
AM
9170 { EM_IA_64, ia64_process_unwind },
9171 { EM_PARISC, hppa_process_unwind },
fa197c1c 9172 { EM_TI_C6000, arm_process_unwind },
32ec8896 9173 { 0, NULL }
57346661
AM
9174 };
9175 int i;
9176
9177 if (!do_unwind)
32ec8896 9178 return TRUE;
57346661
AM
9179
9180 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9181 if (filedata->file_header.e_machine == handlers[i].machtype)
9182 return handlers[i].handler (filedata);
57346661 9183
1b31d05e 9184 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9185 get_machine_name (filedata->file_header.e_machine));
32ec8896 9186 return TRUE;
57346661
AM
9187}
9188
252b5132 9189static void
2cf0635d 9190dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
9191{
9192 switch (entry->d_tag)
9193 {
9194 case DT_MIPS_FLAGS:
9195 if (entry->d_un.d_val == 0)
4b68bca3 9196 printf (_("NONE"));
252b5132
RH
9197 else
9198 {
9199 static const char * opts[] =
9200 {
9201 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9202 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9203 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9204 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9205 "RLD_ORDER_SAFE"
9206 };
9207 unsigned int cnt;
32ec8896 9208 bfd_boolean first = TRUE;
2b692964 9209
60bca95a 9210 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9211 if (entry->d_un.d_val & (1 << cnt))
9212 {
9213 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9214 first = FALSE;
252b5132 9215 }
252b5132
RH
9216 }
9217 break;
103f02d3 9218
252b5132 9219 case DT_MIPS_IVERSION:
d79b3d50 9220 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 9221 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9222 else
76ca31c0
NC
9223 {
9224 char buf[40];
9225 sprintf_vma (buf, entry->d_un.d_ptr);
9226 /* Note: coded this way so that there is a single string for translation. */
9227 printf (_("<corrupt: %s>"), buf);
9228 }
252b5132 9229 break;
103f02d3 9230
252b5132
RH
9231 case DT_MIPS_TIME_STAMP:
9232 {
d5b07ef4 9233 char timebuf[128];
2cf0635d 9234 struct tm * tmp;
91d6fa6a 9235 time_t atime = entry->d_un.d_val;
82b1b41b 9236
91d6fa6a 9237 tmp = gmtime (&atime);
82b1b41b
NC
9238 /* PR 17531: file: 6accc532. */
9239 if (tmp == NULL)
9240 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9241 else
9242 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9243 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9244 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9245 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9246 }
9247 break;
103f02d3 9248
252b5132
RH
9249 case DT_MIPS_RLD_VERSION:
9250 case DT_MIPS_LOCAL_GOTNO:
9251 case DT_MIPS_CONFLICTNO:
9252 case DT_MIPS_LIBLISTNO:
9253 case DT_MIPS_SYMTABNO:
9254 case DT_MIPS_UNREFEXTNO:
9255 case DT_MIPS_HIPAGENO:
9256 case DT_MIPS_DELTA_CLASS_NO:
9257 case DT_MIPS_DELTA_INSTANCE_NO:
9258 case DT_MIPS_DELTA_RELOC_NO:
9259 case DT_MIPS_DELTA_SYM_NO:
9260 case DT_MIPS_DELTA_CLASSSYM_NO:
9261 case DT_MIPS_COMPACT_SIZE:
c69075ac 9262 print_vma (entry->d_un.d_val, DEC);
252b5132 9263 break;
103f02d3
UD
9264
9265 default:
4b68bca3 9266 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9267 }
4b68bca3 9268 putchar ('\n');
103f02d3
UD
9269}
9270
103f02d3 9271static void
2cf0635d 9272dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9273{
9274 switch (entry->d_tag)
9275 {
9276 case DT_HP_DLD_FLAGS:
9277 {
9278 static struct
9279 {
9280 long int bit;
2cf0635d 9281 const char * str;
5e220199
NC
9282 }
9283 flags[] =
9284 {
9285 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9286 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9287 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9288 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9289 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9290 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9291 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9292 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9293 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9294 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9295 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9296 { DT_HP_GST, "HP_GST" },
9297 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9298 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9299 { DT_HP_NODELETE, "HP_NODELETE" },
9300 { DT_HP_GROUP, "HP_GROUP" },
9301 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9302 };
32ec8896 9303 bfd_boolean first = TRUE;
5e220199 9304 size_t cnt;
f7a99963 9305 bfd_vma val = entry->d_un.d_val;
103f02d3 9306
60bca95a 9307 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9308 if (val & flags[cnt].bit)
30800947
NC
9309 {
9310 if (! first)
9311 putchar (' ');
9312 fputs (flags[cnt].str, stdout);
32ec8896 9313 first = FALSE;
30800947
NC
9314 val ^= flags[cnt].bit;
9315 }
76da6bbe 9316
103f02d3 9317 if (val != 0 || first)
f7a99963
NC
9318 {
9319 if (! first)
9320 putchar (' ');
9321 print_vma (val, HEX);
9322 }
103f02d3
UD
9323 }
9324 break;
76da6bbe 9325
252b5132 9326 default:
f7a99963
NC
9327 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9328 break;
252b5132 9329 }
35b1837e 9330 putchar ('\n');
252b5132
RH
9331}
9332
28f997cf
TG
9333#ifdef BFD64
9334
9335/* VMS vs Unix time offset and factor. */
9336
9337#define VMS_EPOCH_OFFSET 35067168000000000LL
9338#define VMS_GRANULARITY_FACTOR 10000000
9339
9340/* Display a VMS time in a human readable format. */
9341
9342static void
9343print_vms_time (bfd_int64_t vmstime)
9344{
9345 struct tm *tm;
9346 time_t unxtime;
9347
9348 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9349 tm = gmtime (&unxtime);
9350 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9351 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9352 tm->tm_hour, tm->tm_min, tm->tm_sec);
9353}
9354#endif /* BFD64 */
9355
ecc51f48 9356static void
2cf0635d 9357dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9358{
9359 switch (entry->d_tag)
9360 {
0de14b54 9361 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9362 /* First 3 slots reserved. */
ecc51f48
NC
9363 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9364 printf (" -- ");
9365 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9366 break;
9367
28f997cf
TG
9368 case DT_IA_64_VMS_LINKTIME:
9369#ifdef BFD64
9370 print_vms_time (entry->d_un.d_val);
9371#endif
9372 break;
9373
9374 case DT_IA_64_VMS_LNKFLAGS:
9375 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9376 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9377 printf (" CALL_DEBUG");
9378 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9379 printf (" NOP0BUFS");
9380 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9381 printf (" P0IMAGE");
9382 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9383 printf (" MKTHREADS");
9384 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9385 printf (" UPCALLS");
9386 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9387 printf (" IMGSTA");
9388 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9389 printf (" INITIALIZE");
9390 if (entry->d_un.d_val & VMS_LF_MAIN)
9391 printf (" MAIN");
9392 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9393 printf (" EXE_INIT");
9394 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9395 printf (" TBK_IN_IMG");
9396 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9397 printf (" DBG_IN_IMG");
9398 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9399 printf (" TBK_IN_DSF");
9400 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9401 printf (" DBG_IN_DSF");
9402 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9403 printf (" SIGNATURES");
9404 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9405 printf (" REL_SEG_OFF");
9406 break;
9407
bdf4d63a
JJ
9408 default:
9409 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9410 break;
ecc51f48 9411 }
bdf4d63a 9412 putchar ('\n');
ecc51f48
NC
9413}
9414
32ec8896 9415static bfd_boolean
dda8d76d 9416get_32bit_dynamic_section (Filedata * filedata)
252b5132 9417{
2cf0635d
NC
9418 Elf32_External_Dyn * edyn;
9419 Elf32_External_Dyn * ext;
9420 Elf_Internal_Dyn * entry;
103f02d3 9421
dda8d76d 9422 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9423 dynamic_size, _("dynamic section"));
a6e9f9df 9424 if (!edyn)
32ec8896 9425 return FALSE;
103f02d3 9426
071436c6
NC
9427 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9428 might not have the luxury of section headers. Look for the DT_NULL
9429 terminator to determine the number of entries. */
ba2685cc 9430 for (ext = edyn, dynamic_nent = 0;
53c3012c 9431 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9432 ext++)
9433 {
9434 dynamic_nent++;
9435 if (BYTE_GET (ext->d_tag) == DT_NULL)
9436 break;
9437 }
252b5132 9438
3f5e193b
NC
9439 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9440 sizeof (* entry));
b2d38a17 9441 if (dynamic_section == NULL)
252b5132 9442 {
8b73c356
NC
9443 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9444 (unsigned long) dynamic_nent);
9ea033b2 9445 free (edyn);
32ec8896 9446 return FALSE;
9ea033b2 9447 }
252b5132 9448
fb514b26 9449 for (ext = edyn, entry = dynamic_section;
ba2685cc 9450 entry < dynamic_section + dynamic_nent;
fb514b26 9451 ext++, entry++)
9ea033b2 9452 {
fb514b26
AM
9453 entry->d_tag = BYTE_GET (ext->d_tag);
9454 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9455 }
9456
9ea033b2
NC
9457 free (edyn);
9458
32ec8896 9459 return TRUE;
9ea033b2
NC
9460}
9461
32ec8896 9462static bfd_boolean
dda8d76d 9463get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9464{
2cf0635d
NC
9465 Elf64_External_Dyn * edyn;
9466 Elf64_External_Dyn * ext;
9467 Elf_Internal_Dyn * entry;
103f02d3 9468
071436c6 9469 /* Read in the data. */
dda8d76d 9470 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9471 dynamic_size, _("dynamic section"));
a6e9f9df 9472 if (!edyn)
32ec8896 9473 return FALSE;
103f02d3 9474
071436c6
NC
9475 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9476 might not have the luxury of section headers. Look for the DT_NULL
9477 terminator to determine the number of entries. */
ba2685cc 9478 for (ext = edyn, dynamic_nent = 0;
53c3012c
AM
9479 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
9480 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9481 ext++)
9482 {
9483 dynamic_nent++;
66543521 9484 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9485 break;
9486 }
252b5132 9487
3f5e193b
NC
9488 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9489 sizeof (* entry));
b2d38a17 9490 if (dynamic_section == NULL)
252b5132 9491 {
8b73c356
NC
9492 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9493 (unsigned long) dynamic_nent);
252b5132 9494 free (edyn);
32ec8896 9495 return FALSE;
252b5132
RH
9496 }
9497
071436c6 9498 /* Convert from external to internal formats. */
fb514b26 9499 for (ext = edyn, entry = dynamic_section;
ba2685cc 9500 entry < dynamic_section + dynamic_nent;
fb514b26 9501 ext++, entry++)
252b5132 9502 {
66543521
AM
9503 entry->d_tag = BYTE_GET (ext->d_tag);
9504 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9505 }
9506
9507 free (edyn);
9508
32ec8896 9509 return TRUE;
9ea033b2
NC
9510}
9511
e9e44622
JJ
9512static void
9513print_dynamic_flags (bfd_vma flags)
d1133906 9514{
32ec8896 9515 bfd_boolean first = TRUE;
13ae64f3 9516
d1133906
NC
9517 while (flags)
9518 {
9519 bfd_vma flag;
9520
9521 flag = flags & - flags;
9522 flags &= ~ flag;
9523
e9e44622 9524 if (first)
32ec8896 9525 first = FALSE;
e9e44622
JJ
9526 else
9527 putc (' ', stdout);
13ae64f3 9528
d1133906
NC
9529 switch (flag)
9530 {
e9e44622
JJ
9531 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9532 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9533 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9534 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9535 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9536 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9537 }
9538 }
e9e44622 9539 puts ("");
d1133906
NC
9540}
9541
b2d38a17
NC
9542/* Parse and display the contents of the dynamic section. */
9543
32ec8896 9544static bfd_boolean
dda8d76d 9545process_dynamic_section (Filedata * filedata)
9ea033b2 9546{
2cf0635d 9547 Elf_Internal_Dyn * entry;
9ea033b2
NC
9548
9549 if (dynamic_size == 0)
9550 {
9551 if (do_dynamic)
b2d38a17 9552 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 9553
32ec8896 9554 return TRUE;
9ea033b2
NC
9555 }
9556
9557 if (is_32bit_elf)
9558 {
dda8d76d 9559 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
9560 return FALSE;
9561 }
9562 else
9563 {
dda8d76d 9564 if (! get_64bit_dynamic_section (filedata))
32ec8896 9565 return FALSE;
9ea033b2 9566 }
9ea033b2 9567
252b5132
RH
9568 /* Find the appropriate symbol table. */
9569 if (dynamic_symbols == NULL)
9570 {
86dba8ee
AM
9571 for (entry = dynamic_section;
9572 entry < dynamic_section + dynamic_nent;
9573 ++entry)
252b5132 9574 {
c8286bd1 9575 Elf_Internal_Shdr section;
252b5132
RH
9576
9577 if (entry->d_tag != DT_SYMTAB)
9578 continue;
9579
9580 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
9581
9582 /* Since we do not know how big the symbol table is,
9583 we default to reading in the entire file (!) and
9584 processing that. This is overkill, I know, but it
e3c8793a 9585 should work. */
dda8d76d
NC
9586 section.sh_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
9587 if ((bfd_size_type) section.sh_offset > filedata->file_size)
7296a62a
NC
9588 {
9589 /* See PR 21379 for a reproducer. */
9590 error (_("Invalid DT_SYMTAB entry: %lx"), (long) section.sh_offset);
9591 return FALSE;
9592 }
252b5132 9593
fb52b2f4
NC
9594 if (archive_file_offset != 0)
9595 section.sh_size = archive_file_size - section.sh_offset;
9596 else
dda8d76d 9597 section.sh_size = filedata->file_size - section.sh_offset;
252b5132 9598
9ea033b2 9599 if (is_32bit_elf)
9ad5cbcf 9600 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 9601 else
9ad5cbcf 9602 section.sh_entsize = sizeof (Elf64_External_Sym);
dda8d76d 9603 section.sh_name = filedata->string_table_length;
252b5132 9604
dda8d76d 9605 dynamic_symbols = GET_ELF_SYMBOLS (filedata, &section, & num_dynamic_syms);
19936277 9606 if (num_dynamic_syms < 1)
252b5132
RH
9607 {
9608 error (_("Unable to determine the number of symbols to load\n"));
9609 continue;
9610 }
252b5132
RH
9611 }
9612 }
9613
9614 /* Similarly find a string table. */
9615 if (dynamic_strings == NULL)
9616 {
86dba8ee
AM
9617 for (entry = dynamic_section;
9618 entry < dynamic_section + dynamic_nent;
9619 ++entry)
252b5132
RH
9620 {
9621 unsigned long offset;
b34976b6 9622 long str_tab_len;
252b5132
RH
9623
9624 if (entry->d_tag != DT_STRTAB)
9625 continue;
9626
9627 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
9628
9629 /* Since we do not know how big the string table is,
9630 we default to reading in the entire file (!) and
9631 processing that. This is overkill, I know, but it
e3c8793a 9632 should work. */
252b5132 9633
dda8d76d 9634 offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
fb52b2f4
NC
9635
9636 if (archive_file_offset != 0)
9637 str_tab_len = archive_file_size - offset;
9638 else
86c6c6df 9639 str_tab_len = filedata->file_size - offset;
252b5132
RH
9640
9641 if (str_tab_len < 1)
9642 {
9643 error
9644 (_("Unable to determine the length of the dynamic string table\n"));
9645 continue;
9646 }
9647
dda8d76d 9648 dynamic_strings = (char *) get_data (NULL, filedata, offset, 1,
3f5e193b
NC
9649 str_tab_len,
9650 _("dynamic string table"));
59245841 9651 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
9652 break;
9653 }
9654 }
9655
9656 /* And find the syminfo section if available. */
9657 if (dynamic_syminfo == NULL)
9658 {
3e8bba36 9659 unsigned long syminsz = 0;
252b5132 9660
86dba8ee
AM
9661 for (entry = dynamic_section;
9662 entry < dynamic_section + dynamic_nent;
9663 ++entry)
252b5132
RH
9664 {
9665 if (entry->d_tag == DT_SYMINENT)
9666 {
9667 /* Note: these braces are necessary to avoid a syntax
9668 error from the SunOS4 C compiler. */
049b0c3a
NC
9669 /* PR binutils/17531: A corrupt file can trigger this test.
9670 So do not use an assert, instead generate an error message. */
9671 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 9672 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 9673 (int) entry->d_un.d_val);
252b5132
RH
9674 }
9675 else if (entry->d_tag == DT_SYMINSZ)
9676 syminsz = entry->d_un.d_val;
9677 else if (entry->d_tag == DT_SYMINFO)
dda8d76d 9678 dynamic_syminfo_offset = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 9679 syminsz);
252b5132
RH
9680 }
9681
9682 if (dynamic_syminfo_offset != 0 && syminsz != 0)
9683 {
2cf0635d
NC
9684 Elf_External_Syminfo * extsyminfo;
9685 Elf_External_Syminfo * extsym;
9686 Elf_Internal_Syminfo * syminfo;
252b5132
RH
9687
9688 /* There is a syminfo section. Read the data. */
3f5e193b 9689 extsyminfo = (Elf_External_Syminfo *)
dda8d76d 9690 get_data (NULL, filedata, dynamic_syminfo_offset, 1, syminsz,
3f5e193b 9691 _("symbol information"));
a6e9f9df 9692 if (!extsyminfo)
32ec8896 9693 return FALSE;
252b5132 9694
3f5e193b 9695 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
9696 if (dynamic_syminfo == NULL)
9697 {
8b73c356
NC
9698 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
9699 (unsigned long) syminsz);
32ec8896 9700 return FALSE;
252b5132
RH
9701 }
9702
9703 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
9704 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
9705 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
9706 ++syminfo, ++extsym)
252b5132 9707 {
86dba8ee
AM
9708 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
9709 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
9710 }
9711
9712 free (extsyminfo);
9713 }
9714 }
9715
9716 if (do_dynamic && dynamic_addr)
d3a49aa8
AM
9717 printf (ngettext ("\nDynamic section at offset 0x%lx "
9718 "contains %lu entry:\n",
9719 "\nDynamic section at offset 0x%lx "
9720 "contains %lu entries:\n",
9721 dynamic_nent),
8b73c356 9722 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
9723 if (do_dynamic)
9724 printf (_(" Tag Type Name/Value\n"));
9725
86dba8ee
AM
9726 for (entry = dynamic_section;
9727 entry < dynamic_section + dynamic_nent;
9728 entry++)
252b5132
RH
9729 {
9730 if (do_dynamic)
f7a99963 9731 {
2cf0635d 9732 const char * dtype;
e699b9ff 9733
f7a99963
NC
9734 putchar (' ');
9735 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 9736 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 9737 printf (" (%s)%*s", dtype,
32ec8896 9738 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 9739 }
252b5132
RH
9740
9741 switch (entry->d_tag)
9742 {
d1133906
NC
9743 case DT_FLAGS:
9744 if (do_dynamic)
e9e44622 9745 print_dynamic_flags (entry->d_un.d_val);
d1133906 9746 break;
76da6bbe 9747
252b5132
RH
9748 case DT_AUXILIARY:
9749 case DT_FILTER:
019148e4
L
9750 case DT_CONFIG:
9751 case DT_DEPAUDIT:
9752 case DT_AUDIT:
252b5132
RH
9753 if (do_dynamic)
9754 {
019148e4 9755 switch (entry->d_tag)
b34976b6 9756 {
019148e4
L
9757 case DT_AUXILIARY:
9758 printf (_("Auxiliary library"));
9759 break;
9760
9761 case DT_FILTER:
9762 printf (_("Filter library"));
9763 break;
9764
b34976b6 9765 case DT_CONFIG:
019148e4
L
9766 printf (_("Configuration file"));
9767 break;
9768
9769 case DT_DEPAUDIT:
9770 printf (_("Dependency audit library"));
9771 break;
9772
9773 case DT_AUDIT:
9774 printf (_("Audit library"));
9775 break;
9776 }
252b5132 9777
d79b3d50
NC
9778 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9779 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9780 else
f7a99963
NC
9781 {
9782 printf (": ");
9783 print_vma (entry->d_un.d_val, PREFIX_HEX);
9784 putchar ('\n');
9785 }
252b5132
RH
9786 }
9787 break;
9788
dcefbbbd 9789 case DT_FEATURE:
252b5132
RH
9790 if (do_dynamic)
9791 {
9792 printf (_("Flags:"));
86f55779 9793
252b5132
RH
9794 if (entry->d_un.d_val == 0)
9795 printf (_(" None\n"));
9796 else
9797 {
9798 unsigned long int val = entry->d_un.d_val;
86f55779 9799
252b5132
RH
9800 if (val & DTF_1_PARINIT)
9801 {
9802 printf (" PARINIT");
9803 val ^= DTF_1_PARINIT;
9804 }
dcefbbbd
L
9805 if (val & DTF_1_CONFEXP)
9806 {
9807 printf (" CONFEXP");
9808 val ^= DTF_1_CONFEXP;
9809 }
252b5132
RH
9810 if (val != 0)
9811 printf (" %lx", val);
9812 puts ("");
9813 }
9814 }
9815 break;
9816
9817 case DT_POSFLAG_1:
9818 if (do_dynamic)
9819 {
9820 printf (_("Flags:"));
86f55779 9821
252b5132
RH
9822 if (entry->d_un.d_val == 0)
9823 printf (_(" None\n"));
9824 else
9825 {
9826 unsigned long int val = entry->d_un.d_val;
86f55779 9827
252b5132
RH
9828 if (val & DF_P1_LAZYLOAD)
9829 {
9830 printf (" LAZYLOAD");
9831 val ^= DF_P1_LAZYLOAD;
9832 }
9833 if (val & DF_P1_GROUPPERM)
9834 {
9835 printf (" GROUPPERM");
9836 val ^= DF_P1_GROUPPERM;
9837 }
9838 if (val != 0)
9839 printf (" %lx", val);
9840 puts ("");
9841 }
9842 }
9843 break;
9844
9845 case DT_FLAGS_1:
9846 if (do_dynamic)
9847 {
9848 printf (_("Flags:"));
9849 if (entry->d_un.d_val == 0)
9850 printf (_(" None\n"));
9851 else
9852 {
9853 unsigned long int val = entry->d_un.d_val;
86f55779 9854
252b5132
RH
9855 if (val & DF_1_NOW)
9856 {
9857 printf (" NOW");
9858 val ^= DF_1_NOW;
9859 }
9860 if (val & DF_1_GLOBAL)
9861 {
9862 printf (" GLOBAL");
9863 val ^= DF_1_GLOBAL;
9864 }
9865 if (val & DF_1_GROUP)
9866 {
9867 printf (" GROUP");
9868 val ^= DF_1_GROUP;
9869 }
9870 if (val & DF_1_NODELETE)
9871 {
9872 printf (" NODELETE");
9873 val ^= DF_1_NODELETE;
9874 }
9875 if (val & DF_1_LOADFLTR)
9876 {
9877 printf (" LOADFLTR");
9878 val ^= DF_1_LOADFLTR;
9879 }
9880 if (val & DF_1_INITFIRST)
9881 {
9882 printf (" INITFIRST");
9883 val ^= DF_1_INITFIRST;
9884 }
9885 if (val & DF_1_NOOPEN)
9886 {
9887 printf (" NOOPEN");
9888 val ^= DF_1_NOOPEN;
9889 }
9890 if (val & DF_1_ORIGIN)
9891 {
9892 printf (" ORIGIN");
9893 val ^= DF_1_ORIGIN;
9894 }
9895 if (val & DF_1_DIRECT)
9896 {
9897 printf (" DIRECT");
9898 val ^= DF_1_DIRECT;
9899 }
9900 if (val & DF_1_TRANS)
9901 {
9902 printf (" TRANS");
9903 val ^= DF_1_TRANS;
9904 }
9905 if (val & DF_1_INTERPOSE)
9906 {
9907 printf (" INTERPOSE");
9908 val ^= DF_1_INTERPOSE;
9909 }
f7db6139 9910 if (val & DF_1_NODEFLIB)
dcefbbbd 9911 {
f7db6139
L
9912 printf (" NODEFLIB");
9913 val ^= DF_1_NODEFLIB;
dcefbbbd
L
9914 }
9915 if (val & DF_1_NODUMP)
9916 {
9917 printf (" NODUMP");
9918 val ^= DF_1_NODUMP;
9919 }
34b60028 9920 if (val & DF_1_CONFALT)
dcefbbbd 9921 {
34b60028
L
9922 printf (" CONFALT");
9923 val ^= DF_1_CONFALT;
9924 }
9925 if (val & DF_1_ENDFILTEE)
9926 {
9927 printf (" ENDFILTEE");
9928 val ^= DF_1_ENDFILTEE;
9929 }
9930 if (val & DF_1_DISPRELDNE)
9931 {
9932 printf (" DISPRELDNE");
9933 val ^= DF_1_DISPRELDNE;
9934 }
9935 if (val & DF_1_DISPRELPND)
9936 {
9937 printf (" DISPRELPND");
9938 val ^= DF_1_DISPRELPND;
9939 }
9940 if (val & DF_1_NODIRECT)
9941 {
9942 printf (" NODIRECT");
9943 val ^= DF_1_NODIRECT;
9944 }
9945 if (val & DF_1_IGNMULDEF)
9946 {
9947 printf (" IGNMULDEF");
9948 val ^= DF_1_IGNMULDEF;
9949 }
9950 if (val & DF_1_NOKSYMS)
9951 {
9952 printf (" NOKSYMS");
9953 val ^= DF_1_NOKSYMS;
9954 }
9955 if (val & DF_1_NOHDR)
9956 {
9957 printf (" NOHDR");
9958 val ^= DF_1_NOHDR;
9959 }
9960 if (val & DF_1_EDITED)
9961 {
9962 printf (" EDITED");
9963 val ^= DF_1_EDITED;
9964 }
9965 if (val & DF_1_NORELOC)
9966 {
9967 printf (" NORELOC");
9968 val ^= DF_1_NORELOC;
9969 }
9970 if (val & DF_1_SYMINTPOSE)
9971 {
9972 printf (" SYMINTPOSE");
9973 val ^= DF_1_SYMINTPOSE;
9974 }
9975 if (val & DF_1_GLOBAUDIT)
9976 {
9977 printf (" GLOBAUDIT");
9978 val ^= DF_1_GLOBAUDIT;
9979 }
9980 if (val & DF_1_SINGLETON)
9981 {
9982 printf (" SINGLETON");
9983 val ^= DF_1_SINGLETON;
dcefbbbd 9984 }
5c383f02
RO
9985 if (val & DF_1_STUB)
9986 {
9987 printf (" STUB");
9988 val ^= DF_1_STUB;
9989 }
9990 if (val & DF_1_PIE)
9991 {
9992 printf (" PIE");
9993 val ^= DF_1_PIE;
9994 }
b1202ffa
L
9995 if (val & DF_1_KMOD)
9996 {
9997 printf (" KMOD");
9998 val ^= DF_1_KMOD;
9999 }
10000 if (val & DF_1_WEAKFILTER)
10001 {
10002 printf (" WEAKFILTER");
10003 val ^= DF_1_WEAKFILTER;
10004 }
10005 if (val & DF_1_NOCOMMON)
10006 {
10007 printf (" NOCOMMON");
10008 val ^= DF_1_NOCOMMON;
10009 }
252b5132
RH
10010 if (val != 0)
10011 printf (" %lx", val);
10012 puts ("");
10013 }
10014 }
10015 break;
10016
10017 case DT_PLTREL:
566b0d53 10018 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10019 if (do_dynamic)
dda8d76d 10020 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10021 break;
10022
10023 case DT_NULL :
10024 case DT_NEEDED :
10025 case DT_PLTGOT :
10026 case DT_HASH :
10027 case DT_STRTAB :
10028 case DT_SYMTAB :
10029 case DT_RELA :
10030 case DT_INIT :
10031 case DT_FINI :
10032 case DT_SONAME :
10033 case DT_RPATH :
10034 case DT_SYMBOLIC:
10035 case DT_REL :
10036 case DT_DEBUG :
10037 case DT_TEXTREL :
10038 case DT_JMPREL :
019148e4 10039 case DT_RUNPATH :
252b5132
RH
10040 dynamic_info[entry->d_tag] = entry->d_un.d_val;
10041
10042 if (do_dynamic)
10043 {
2cf0635d 10044 char * name;
252b5132 10045
d79b3d50
NC
10046 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
10047 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10048 else
d79b3d50 10049 name = NULL;
252b5132
RH
10050
10051 if (name)
10052 {
10053 switch (entry->d_tag)
10054 {
10055 case DT_NEEDED:
10056 printf (_("Shared library: [%s]"), name);
10057
18bd398b 10058 if (streq (name, program_interpreter))
f7a99963 10059 printf (_(" program interpreter"));
252b5132
RH
10060 break;
10061
10062 case DT_SONAME:
f7a99963 10063 printf (_("Library soname: [%s]"), name);
252b5132
RH
10064 break;
10065
10066 case DT_RPATH:
f7a99963 10067 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10068 break;
10069
019148e4
L
10070 case DT_RUNPATH:
10071 printf (_("Library runpath: [%s]"), name);
10072 break;
10073
252b5132 10074 default:
f7a99963
NC
10075 print_vma (entry->d_un.d_val, PREFIX_HEX);
10076 break;
252b5132
RH
10077 }
10078 }
10079 else
f7a99963
NC
10080 print_vma (entry->d_un.d_val, PREFIX_HEX);
10081
10082 putchar ('\n');
252b5132
RH
10083 }
10084 break;
10085
10086 case DT_PLTRELSZ:
10087 case DT_RELASZ :
10088 case DT_STRSZ :
10089 case DT_RELSZ :
10090 case DT_RELAENT :
10091 case DT_SYMENT :
10092 case DT_RELENT :
566b0d53 10093 dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10094 /* Fall through. */
252b5132
RH
10095 case DT_PLTPADSZ:
10096 case DT_MOVEENT :
10097 case DT_MOVESZ :
10098 case DT_INIT_ARRAYSZ:
10099 case DT_FINI_ARRAYSZ:
047b2264
JJ
10100 case DT_GNU_CONFLICTSZ:
10101 case DT_GNU_LIBLISTSZ:
252b5132 10102 if (do_dynamic)
f7a99963
NC
10103 {
10104 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10105 printf (_(" (bytes)\n"));
f7a99963 10106 }
252b5132
RH
10107 break;
10108
10109 case DT_VERDEFNUM:
10110 case DT_VERNEEDNUM:
10111 case DT_RELACOUNT:
10112 case DT_RELCOUNT:
10113 if (do_dynamic)
f7a99963
NC
10114 {
10115 print_vma (entry->d_un.d_val, UNSIGNED);
10116 putchar ('\n');
10117 }
252b5132
RH
10118 break;
10119
10120 case DT_SYMINSZ:
10121 case DT_SYMINENT:
10122 case DT_SYMINFO:
10123 case DT_USED:
10124 case DT_INIT_ARRAY:
10125 case DT_FINI_ARRAY:
10126 if (do_dynamic)
10127 {
d79b3d50
NC
10128 if (entry->d_tag == DT_USED
10129 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 10130 {
2cf0635d 10131 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10132
b34976b6 10133 if (*name)
252b5132
RH
10134 {
10135 printf (_("Not needed object: [%s]\n"), name);
10136 break;
10137 }
10138 }
103f02d3 10139
f7a99963
NC
10140 print_vma (entry->d_un.d_val, PREFIX_HEX);
10141 putchar ('\n');
252b5132
RH
10142 }
10143 break;
10144
10145 case DT_BIND_NOW:
10146 /* The value of this entry is ignored. */
35b1837e
AM
10147 if (do_dynamic)
10148 putchar ('\n');
252b5132 10149 break;
103f02d3 10150
047b2264
JJ
10151 case DT_GNU_PRELINKED:
10152 if (do_dynamic)
10153 {
2cf0635d 10154 struct tm * tmp;
91d6fa6a 10155 time_t atime = entry->d_un.d_val;
047b2264 10156
91d6fa6a 10157 tmp = gmtime (&atime);
071436c6
NC
10158 /* PR 17533 file: 041-1244816-0.004. */
10159 if (tmp == NULL)
5a2cbcf4
L
10160 printf (_("<corrupt time val: %lx"),
10161 (unsigned long) atime);
071436c6
NC
10162 else
10163 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10164 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10165 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10166
10167 }
10168 break;
10169
fdc90cb4
JJ
10170 case DT_GNU_HASH:
10171 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10172 if (do_dynamic)
10173 {
10174 print_vma (entry->d_un.d_val, PREFIX_HEX);
10175 putchar ('\n');
10176 }
10177 break;
10178
252b5132
RH
10179 default:
10180 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 10181 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
10182 entry->d_un.d_val;
10183
10184 if (do_dynamic)
10185 {
dda8d76d 10186 switch (filedata->file_header.e_machine)
252b5132
RH
10187 {
10188 case EM_MIPS:
4fe85591 10189 case EM_MIPS_RS3_LE:
b2d38a17 10190 dynamic_section_mips_val (entry);
252b5132 10191 break;
103f02d3 10192 case EM_PARISC:
b2d38a17 10193 dynamic_section_parisc_val (entry);
103f02d3 10194 break;
ecc51f48 10195 case EM_IA_64:
b2d38a17 10196 dynamic_section_ia64_val (entry);
ecc51f48 10197 break;
252b5132 10198 default:
f7a99963
NC
10199 print_vma (entry->d_un.d_val, PREFIX_HEX);
10200 putchar ('\n');
252b5132
RH
10201 }
10202 }
10203 break;
10204 }
10205 }
10206
32ec8896 10207 return TRUE;
252b5132
RH
10208}
10209
10210static char *
d3ba0551 10211get_ver_flags (unsigned int flags)
252b5132 10212{
6d4f21f6 10213 static char buff[128];
252b5132
RH
10214
10215 buff[0] = 0;
10216
10217 if (flags == 0)
10218 return _("none");
10219
10220 if (flags & VER_FLG_BASE)
7bb1ad17 10221 strcat (buff, "BASE");
252b5132
RH
10222
10223 if (flags & VER_FLG_WEAK)
10224 {
10225 if (flags & VER_FLG_BASE)
7bb1ad17 10226 strcat (buff, " | ");
252b5132 10227
7bb1ad17 10228 strcat (buff, "WEAK");
252b5132
RH
10229 }
10230
44ec90b9
RO
10231 if (flags & VER_FLG_INFO)
10232 {
10233 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 10234 strcat (buff, " | ");
44ec90b9 10235
7bb1ad17 10236 strcat (buff, "INFO");
44ec90b9
RO
10237 }
10238
10239 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
10240 {
10241 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
10242 strcat (buff, " | ");
10243
10244 strcat (buff, _("<unknown>"));
10245 }
252b5132
RH
10246
10247 return buff;
10248}
10249
10250/* Display the contents of the version sections. */
98fb390a 10251
32ec8896 10252static bfd_boolean
dda8d76d 10253process_version_sections (Filedata * filedata)
252b5132 10254{
2cf0635d 10255 Elf_Internal_Shdr * section;
b34976b6 10256 unsigned i;
32ec8896 10257 bfd_boolean found = FALSE;
252b5132
RH
10258
10259 if (! do_version)
32ec8896 10260 return TRUE;
252b5132 10261
dda8d76d
NC
10262 for (i = 0, section = filedata->section_headers;
10263 i < filedata->file_header.e_shnum;
b34976b6 10264 i++, section++)
252b5132
RH
10265 {
10266 switch (section->sh_type)
10267 {
10268 case SHT_GNU_verdef:
10269 {
2cf0635d 10270 Elf_External_Verdef * edefs;
452bf675
AM
10271 unsigned long idx;
10272 unsigned long cnt;
2cf0635d 10273 char * endbuf;
252b5132 10274
32ec8896 10275 found = TRUE;
252b5132 10276
d3a49aa8
AM
10277 printf (ngettext ("\nVersion definition section '%s' "
10278 "contains %u entry:\n",
10279 "\nVersion definition section '%s' "
10280 "contains %u entries:\n",
10281 section->sh_info),
dda8d76d 10282 printable_section_name (filedata, section),
74e1a04b 10283 section->sh_info);
252b5132
RH
10284
10285 printf (_(" Addr: 0x"));
10286 printf_vma (section->sh_addr);
233f82cf 10287 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10288 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10289 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10290
3f5e193b 10291 edefs = (Elf_External_Verdef *)
dda8d76d 10292 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 10293 _("version definition section"));
a6e9f9df
AM
10294 if (!edefs)
10295 break;
59245841 10296 endbuf = (char *) edefs + section->sh_size;
252b5132 10297
1445030f 10298 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 10299 {
2cf0635d
NC
10300 char * vstart;
10301 Elf_External_Verdef * edef;
b34976b6 10302 Elf_Internal_Verdef ent;
2cf0635d 10303 Elf_External_Verdaux * eaux;
b34976b6 10304 Elf_Internal_Verdaux aux;
452bf675 10305 unsigned long isum;
b34976b6 10306 int j;
103f02d3 10307
252b5132 10308 vstart = ((char *) edefs) + idx;
54806181
AM
10309 if (vstart + sizeof (*edef) > endbuf)
10310 break;
252b5132
RH
10311
10312 edef = (Elf_External_Verdef *) vstart;
10313
10314 ent.vd_version = BYTE_GET (edef->vd_version);
10315 ent.vd_flags = BYTE_GET (edef->vd_flags);
10316 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
10317 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
10318 ent.vd_hash = BYTE_GET (edef->vd_hash);
10319 ent.vd_aux = BYTE_GET (edef->vd_aux);
10320 ent.vd_next = BYTE_GET (edef->vd_next);
10321
452bf675 10322 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
10323 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
10324
10325 printf (_(" Index: %d Cnt: %d "),
10326 ent.vd_ndx, ent.vd_cnt);
10327
452bf675 10328 /* Check for overflow. */
1445030f 10329 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
10330 break;
10331
252b5132
RH
10332 vstart += ent.vd_aux;
10333
1445030f
AM
10334 if (vstart + sizeof (*eaux) > endbuf)
10335 break;
252b5132
RH
10336 eaux = (Elf_External_Verdaux *) vstart;
10337
10338 aux.vda_name = BYTE_GET (eaux->vda_name);
10339 aux.vda_next = BYTE_GET (eaux->vda_next);
10340
d79b3d50
NC
10341 if (VALID_DYNAMIC_NAME (aux.vda_name))
10342 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
10343 else
10344 printf (_("Name index: %ld\n"), aux.vda_name);
10345
10346 isum = idx + ent.vd_aux;
10347
b34976b6 10348 for (j = 1; j < ent.vd_cnt; j++)
252b5132 10349 {
1445030f
AM
10350 if (aux.vda_next < sizeof (*eaux)
10351 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
10352 {
10353 warn (_("Invalid vda_next field of %lx\n"),
10354 aux.vda_next);
10355 j = ent.vd_cnt;
10356 break;
10357 }
dd24e3da 10358 /* Check for overflow. */
7e26601c 10359 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
10360 break;
10361
252b5132
RH
10362 isum += aux.vda_next;
10363 vstart += aux.vda_next;
10364
54806181
AM
10365 if (vstart + sizeof (*eaux) > endbuf)
10366 break;
1445030f 10367 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
10368
10369 aux.vda_name = BYTE_GET (eaux->vda_name);
10370 aux.vda_next = BYTE_GET (eaux->vda_next);
10371
d79b3d50 10372 if (VALID_DYNAMIC_NAME (aux.vda_name))
452bf675 10373 printf (_(" %#06lx: Parent %d: %s\n"),
d79b3d50 10374 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132 10375 else
452bf675 10376 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
10377 isum, j, aux.vda_name);
10378 }
dd24e3da 10379
54806181
AM
10380 if (j < ent.vd_cnt)
10381 printf (_(" Version def aux past end of section\n"));
252b5132 10382
c9f02c3e
MR
10383 /* PR 17531:
10384 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
10385 if (ent.vd_next < sizeof (*edef)
10386 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
10387 {
10388 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
10389 cnt = section->sh_info;
10390 break;
10391 }
452bf675 10392 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
10393 break;
10394
252b5132
RH
10395 idx += ent.vd_next;
10396 }
dd24e3da 10397
54806181
AM
10398 if (cnt < section->sh_info)
10399 printf (_(" Version definition past end of section\n"));
252b5132
RH
10400
10401 free (edefs);
10402 }
10403 break;
103f02d3 10404
252b5132
RH
10405 case SHT_GNU_verneed:
10406 {
2cf0635d 10407 Elf_External_Verneed * eneed;
452bf675
AM
10408 unsigned long idx;
10409 unsigned long cnt;
2cf0635d 10410 char * endbuf;
252b5132 10411
32ec8896 10412 found = TRUE;
252b5132 10413
d3a49aa8
AM
10414 printf (ngettext ("\nVersion needs section '%s' "
10415 "contains %u entry:\n",
10416 "\nVersion needs section '%s' "
10417 "contains %u entries:\n",
10418 section->sh_info),
dda8d76d 10419 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
10420
10421 printf (_(" Addr: 0x"));
10422 printf_vma (section->sh_addr);
72de5009 10423 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10424 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10425 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10426
dda8d76d 10427 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
10428 section->sh_offset, 1,
10429 section->sh_size,
9cf03b7e 10430 _("Version Needs section"));
a6e9f9df
AM
10431 if (!eneed)
10432 break;
59245841 10433 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
10434
10435 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
10436 {
2cf0635d 10437 Elf_External_Verneed * entry;
b34976b6 10438 Elf_Internal_Verneed ent;
452bf675 10439 unsigned long isum;
b34976b6 10440 int j;
2cf0635d 10441 char * vstart;
252b5132
RH
10442
10443 vstart = ((char *) eneed) + idx;
54806181
AM
10444 if (vstart + sizeof (*entry) > endbuf)
10445 break;
252b5132
RH
10446
10447 entry = (Elf_External_Verneed *) vstart;
10448
10449 ent.vn_version = BYTE_GET (entry->vn_version);
10450 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
10451 ent.vn_file = BYTE_GET (entry->vn_file);
10452 ent.vn_aux = BYTE_GET (entry->vn_aux);
10453 ent.vn_next = BYTE_GET (entry->vn_next);
10454
452bf675 10455 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 10456
d79b3d50
NC
10457 if (VALID_DYNAMIC_NAME (ent.vn_file))
10458 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
10459 else
10460 printf (_(" File: %lx"), ent.vn_file);
10461
10462 printf (_(" Cnt: %d\n"), ent.vn_cnt);
10463
dd24e3da 10464 /* Check for overflow. */
7e26601c 10465 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 10466 break;
252b5132
RH
10467 vstart += ent.vn_aux;
10468
10469 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
10470 {
2cf0635d 10471 Elf_External_Vernaux * eaux;
b34976b6 10472 Elf_Internal_Vernaux aux;
252b5132 10473
54806181
AM
10474 if (vstart + sizeof (*eaux) > endbuf)
10475 break;
252b5132
RH
10476 eaux = (Elf_External_Vernaux *) vstart;
10477
10478 aux.vna_hash = BYTE_GET (eaux->vna_hash);
10479 aux.vna_flags = BYTE_GET (eaux->vna_flags);
10480 aux.vna_other = BYTE_GET (eaux->vna_other);
10481 aux.vna_name = BYTE_GET (eaux->vna_name);
10482 aux.vna_next = BYTE_GET (eaux->vna_next);
10483
d79b3d50 10484 if (VALID_DYNAMIC_NAME (aux.vna_name))
452bf675 10485 printf (_(" %#06lx: Name: %s"),
d79b3d50 10486 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 10487 else
452bf675 10488 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
10489 isum, aux.vna_name);
10490
10491 printf (_(" Flags: %s Version: %d\n"),
10492 get_ver_flags (aux.vna_flags), aux.vna_other);
10493
1445030f
AM
10494 if (aux.vna_next < sizeof (*eaux)
10495 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
10496 {
10497 warn (_("Invalid vna_next field of %lx\n"),
10498 aux.vna_next);
10499 j = ent.vn_cnt;
10500 break;
10501 }
1445030f
AM
10502 /* Check for overflow. */
10503 if (aux.vna_next > (size_t) (endbuf - vstart))
10504 break;
252b5132
RH
10505 isum += aux.vna_next;
10506 vstart += aux.vna_next;
10507 }
9cf03b7e 10508
54806181 10509 if (j < ent.vn_cnt)
9cf03b7e 10510 warn (_("Missing Version Needs auxillary information\n"));
252b5132 10511
1445030f
AM
10512 if (ent.vn_next < sizeof (*entry)
10513 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 10514 {
452bf675 10515 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
10516 cnt = section->sh_info;
10517 break;
10518 }
1445030f
AM
10519 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
10520 break;
252b5132
RH
10521 idx += ent.vn_next;
10522 }
9cf03b7e 10523
54806181 10524 if (cnt < section->sh_info)
9cf03b7e 10525 warn (_("Missing Version Needs information\n"));
103f02d3 10526
252b5132
RH
10527 free (eneed);
10528 }
10529 break;
10530
10531 case SHT_GNU_versym:
10532 {
2cf0635d 10533 Elf_Internal_Shdr * link_section;
8b73c356
NC
10534 size_t total;
10535 unsigned int cnt;
2cf0635d
NC
10536 unsigned char * edata;
10537 unsigned short * data;
10538 char * strtab;
10539 Elf_Internal_Sym * symbols;
10540 Elf_Internal_Shdr * string_sec;
ba5cdace 10541 unsigned long num_syms;
d3ba0551 10542 long off;
252b5132 10543
dda8d76d 10544 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10545 break;
10546
dda8d76d 10547 link_section = filedata->section_headers + section->sh_link;
08d8fa11 10548 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 10549
dda8d76d 10550 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10551 break;
10552
32ec8896 10553 found = TRUE;
252b5132 10554
dda8d76d 10555 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
10556 if (symbols == NULL)
10557 break;
252b5132 10558
dda8d76d 10559 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 10560
dda8d76d 10561 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
10562 string_sec->sh_size,
10563 _("version string table"));
a6e9f9df 10564 if (!strtab)
0429c154
MS
10565 {
10566 free (symbols);
10567 break;
10568 }
252b5132 10569
d3a49aa8
AM
10570 printf (ngettext ("\nVersion symbols section '%s' "
10571 "contains %lu entry:\n",
10572 "\nVersion symbols section '%s' "
10573 "contains %lu entries:\n",
10574 total),
dda8d76d 10575 printable_section_name (filedata, section), (unsigned long) total);
252b5132
RH
10576
10577 printf (_(" Addr: "));
10578 printf_vma (section->sh_addr);
72de5009 10579 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10580 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10581 printable_section_name (filedata, link_section));
252b5132 10582
dda8d76d 10583 off = offset_from_vma (filedata,
d3ba0551
AM
10584 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10585 total * sizeof (short));
dda8d76d 10586 edata = (unsigned char *) get_data (NULL, filedata, off, total,
3f5e193b
NC
10587 sizeof (short),
10588 _("version symbol data"));
a6e9f9df
AM
10589 if (!edata)
10590 {
10591 free (strtab);
0429c154 10592 free (symbols);
a6e9f9df
AM
10593 break;
10594 }
252b5132 10595
3f5e193b 10596 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
10597
10598 for (cnt = total; cnt --;)
b34976b6
AM
10599 data[cnt] = byte_get (edata + cnt * sizeof (short),
10600 sizeof (short));
252b5132
RH
10601
10602 free (edata);
10603
10604 for (cnt = 0; cnt < total; cnt += 4)
10605 {
10606 int j, nn;
ab273396
AM
10607 char *name;
10608 char *invalid = _("*invalid*");
252b5132
RH
10609
10610 printf (" %03x:", cnt);
10611
10612 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 10613 switch (data[cnt + j])
252b5132
RH
10614 {
10615 case 0:
10616 fputs (_(" 0 (*local*) "), stdout);
10617 break;
10618
10619 case 1:
10620 fputs (_(" 1 (*global*) "), stdout);
10621 break;
10622
10623 default:
c244d050
NC
10624 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
10625 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 10626
dd24e3da 10627 /* If this index value is greater than the size of the symbols
ba5cdace
NC
10628 array, break to avoid an out-of-bounds read. */
10629 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
10630 {
10631 warn (_("invalid index into symbol array\n"));
10632 break;
10633 }
10634
ab273396
AM
10635 name = NULL;
10636 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 10637 {
b34976b6
AM
10638 Elf_Internal_Verneed ivn;
10639 unsigned long offset;
252b5132 10640
d93f0186 10641 offset = offset_from_vma
dda8d76d 10642 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 10643 sizeof (Elf_External_Verneed));
252b5132 10644
b34976b6 10645 do
252b5132 10646 {
b34976b6
AM
10647 Elf_Internal_Vernaux ivna;
10648 Elf_External_Verneed evn;
10649 Elf_External_Vernaux evna;
10650 unsigned long a_off;
252b5132 10651
dda8d76d 10652 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
10653 _("version need")) == NULL)
10654 break;
0b4362b0 10655
252b5132
RH
10656 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10657 ivn.vn_next = BYTE_GET (evn.vn_next);
10658
10659 a_off = offset + ivn.vn_aux;
10660
10661 do
10662 {
dda8d76d 10663 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
10664 1, _("version need aux (2)")) == NULL)
10665 {
10666 ivna.vna_next = 0;
10667 ivna.vna_other = 0;
10668 }
10669 else
10670 {
10671 ivna.vna_next = BYTE_GET (evna.vna_next);
10672 ivna.vna_other = BYTE_GET (evna.vna_other);
10673 }
252b5132
RH
10674
10675 a_off += ivna.vna_next;
10676 }
b34976b6 10677 while (ivna.vna_other != data[cnt + j]
252b5132
RH
10678 && ivna.vna_next != 0);
10679
b34976b6 10680 if (ivna.vna_other == data[cnt + j])
252b5132
RH
10681 {
10682 ivna.vna_name = BYTE_GET (evna.vna_name);
10683
54806181 10684 if (ivna.vna_name >= string_sec->sh_size)
ab273396 10685 name = invalid;
54806181
AM
10686 else
10687 name = strtab + ivna.vna_name;
252b5132
RH
10688 break;
10689 }
10690
10691 offset += ivn.vn_next;
10692 }
10693 while (ivn.vn_next);
10694 }
00d93f34 10695
ab273396 10696 if (data[cnt + j] != 0x8001
b34976b6 10697 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10698 {
b34976b6
AM
10699 Elf_Internal_Verdef ivd;
10700 Elf_External_Verdef evd;
10701 unsigned long offset;
252b5132 10702
d93f0186 10703 offset = offset_from_vma
dda8d76d 10704 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 10705 sizeof evd);
252b5132
RH
10706
10707 do
10708 {
dda8d76d 10709 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
10710 _("version def")) == NULL)
10711 {
10712 ivd.vd_next = 0;
948f632f 10713 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
10714 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
10715 break;
59245841
NC
10716 }
10717 else
10718 {
10719 ivd.vd_next = BYTE_GET (evd.vd_next);
10720 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10721 }
252b5132
RH
10722
10723 offset += ivd.vd_next;
10724 }
c244d050 10725 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
10726 && ivd.vd_next != 0);
10727
c244d050 10728 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 10729 {
b34976b6
AM
10730 Elf_External_Verdaux evda;
10731 Elf_Internal_Verdaux ivda;
252b5132
RH
10732
10733 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10734
dda8d76d 10735 if (get_data (&evda, filedata,
59245841
NC
10736 offset - ivd.vd_next + ivd.vd_aux,
10737 sizeof (evda), 1,
10738 _("version def aux")) == NULL)
10739 break;
252b5132
RH
10740
10741 ivda.vda_name = BYTE_GET (evda.vda_name);
10742
54806181 10743 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
10744 name = invalid;
10745 else if (name != NULL && name != invalid)
10746 name = _("*both*");
54806181
AM
10747 else
10748 name = strtab + ivda.vda_name;
252b5132
RH
10749 }
10750 }
ab273396
AM
10751 if (name != NULL)
10752 nn += printf ("(%s%-*s",
10753 name,
10754 12 - (int) strlen (name),
10755 ")");
252b5132
RH
10756
10757 if (nn < 18)
10758 printf ("%*c", 18 - nn, ' ');
10759 }
10760
10761 putchar ('\n');
10762 }
10763
10764 free (data);
10765 free (strtab);
10766 free (symbols);
10767 }
10768 break;
103f02d3 10769
252b5132
RH
10770 default:
10771 break;
10772 }
10773 }
10774
10775 if (! found)
10776 printf (_("\nNo version information found in this file.\n"));
10777
32ec8896 10778 return TRUE;
252b5132
RH
10779}
10780
d1133906 10781static const char *
dda8d76d 10782get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 10783{
b34976b6 10784 static char buff[32];
252b5132
RH
10785
10786 switch (binding)
10787 {
b34976b6
AM
10788 case STB_LOCAL: return "LOCAL";
10789 case STB_GLOBAL: return "GLOBAL";
10790 case STB_WEAK: return "WEAK";
252b5132
RH
10791 default:
10792 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
10793 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
10794 binding);
252b5132 10795 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
10796 {
10797 if (binding == STB_GNU_UNIQUE
dda8d76d 10798 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9c55345c 10799 /* GNU is still using the default value 0. */
dda8d76d 10800 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
3e7a7d11
NC
10801 return "UNIQUE";
10802 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
10803 }
252b5132 10804 else
e9e44622 10805 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
10806 return buff;
10807 }
10808}
10809
d1133906 10810static const char *
dda8d76d 10811get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 10812{
b34976b6 10813 static char buff[32];
252b5132
RH
10814
10815 switch (type)
10816 {
b34976b6
AM
10817 case STT_NOTYPE: return "NOTYPE";
10818 case STT_OBJECT: return "OBJECT";
10819 case STT_FUNC: return "FUNC";
10820 case STT_SECTION: return "SECTION";
10821 case STT_FILE: return "FILE";
10822 case STT_COMMON: return "COMMON";
10823 case STT_TLS: return "TLS";
15ab5209
DB
10824 case STT_RELC: return "RELC";
10825 case STT_SRELC: return "SRELC";
252b5132
RH
10826 default:
10827 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 10828 {
dda8d76d 10829 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 10830 return "THUMB_FUNC";
103f02d3 10831
dda8d76d 10832 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
10833 return "REGISTER";
10834
dda8d76d 10835 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
10836 return "PARISC_MILLI";
10837
e9e44622 10838 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 10839 }
252b5132 10840 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 10841 {
dda8d76d 10842 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
10843 {
10844 if (type == STT_HP_OPAQUE)
10845 return "HP_OPAQUE";
10846 if (type == STT_HP_STUB)
10847 return "HP_STUB";
10848 }
10849
d8045f23 10850 if (type == STT_GNU_IFUNC
dda8d76d
NC
10851 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
10852 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 10853 /* GNU is still using the default value 0. */
dda8d76d 10854 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
d8045f23
NC
10855 return "IFUNC";
10856
e9e44622 10857 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 10858 }
252b5132 10859 else
e9e44622 10860 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
10861 return buff;
10862 }
10863}
10864
d1133906 10865static const char *
d3ba0551 10866get_symbol_visibility (unsigned int visibility)
d1133906
NC
10867{
10868 switch (visibility)
10869 {
b34976b6
AM
10870 case STV_DEFAULT: return "DEFAULT";
10871 case STV_INTERNAL: return "INTERNAL";
10872 case STV_HIDDEN: return "HIDDEN";
d1133906 10873 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
10874 default:
10875 error (_("Unrecognized visibility value: %u"), visibility);
10876 return _("<unknown>");
d1133906
NC
10877 }
10878}
10879
fd85a6a1
NC
10880static const char *
10881get_solaris_symbol_visibility (unsigned int visibility)
10882{
10883 switch (visibility)
10884 {
10885 case 4: return "EXPORTED";
10886 case 5: return "SINGLETON";
10887 case 6: return "ELIMINATE";
10888 default: return get_symbol_visibility (visibility);
10889 }
10890}
10891
5e2b0d47
NC
10892static const char *
10893get_mips_symbol_other (unsigned int other)
10894{
10895 switch (other)
10896 {
32ec8896
NC
10897 case STO_OPTIONAL: return "OPTIONAL";
10898 case STO_MIPS_PLT: return "MIPS PLT";
10899 case STO_MIPS_PIC: return "MIPS PIC";
10900 case STO_MICROMIPS: return "MICROMIPS";
10901 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
10902 case STO_MIPS16: return "MIPS16";
10903 default: return NULL;
5e2b0d47
NC
10904 }
10905}
10906
28f997cf 10907static const char *
dda8d76d 10908get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 10909{
dda8d76d 10910 if (is_ia64_vms (filedata))
28f997cf
TG
10911 {
10912 static char res[32];
10913
10914 res[0] = 0;
10915
10916 /* Function types is for images and .STB files only. */
dda8d76d 10917 switch (filedata->file_header.e_type)
28f997cf
TG
10918 {
10919 case ET_DYN:
10920 case ET_EXEC:
10921 switch (VMS_ST_FUNC_TYPE (other))
10922 {
10923 case VMS_SFT_CODE_ADDR:
10924 strcat (res, " CA");
10925 break;
10926 case VMS_SFT_SYMV_IDX:
10927 strcat (res, " VEC");
10928 break;
10929 case VMS_SFT_FD:
10930 strcat (res, " FD");
10931 break;
10932 case VMS_SFT_RESERVE:
10933 strcat (res, " RSV");
10934 break;
10935 default:
bee0ee85
NC
10936 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
10937 VMS_ST_FUNC_TYPE (other));
10938 strcat (res, " <unknown>");
10939 break;
28f997cf
TG
10940 }
10941 break;
10942 default:
10943 break;
10944 }
10945 switch (VMS_ST_LINKAGE (other))
10946 {
10947 case VMS_STL_IGNORE:
10948 strcat (res, " IGN");
10949 break;
10950 case VMS_STL_RESERVE:
10951 strcat (res, " RSV");
10952 break;
10953 case VMS_STL_STD:
10954 strcat (res, " STD");
10955 break;
10956 case VMS_STL_LNK:
10957 strcat (res, " LNK");
10958 break;
10959 default:
bee0ee85
NC
10960 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
10961 VMS_ST_LINKAGE (other));
10962 strcat (res, " <unknown>");
10963 break;
28f997cf
TG
10964 }
10965
10966 if (res[0] != 0)
10967 return res + 1;
10968 else
10969 return res;
10970 }
10971 return NULL;
10972}
10973
6911b7dc
AM
10974static const char *
10975get_ppc64_symbol_other (unsigned int other)
10976{
10977 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
10978 {
10979 static char buf[32];
10980 snprintf (buf, sizeof buf, _("<localentry>: %d"),
10981 PPC64_LOCAL_ENTRY_OFFSET (other));
10982 return buf;
10983 }
10984 return NULL;
10985}
10986
5e2b0d47 10987static const char *
dda8d76d 10988get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
10989{
10990 const char * result = NULL;
10991 static char buff [32];
10992
10993 if (other == 0)
10994 return "";
10995
dda8d76d 10996 switch (filedata->file_header.e_machine)
5e2b0d47
NC
10997 {
10998 case EM_MIPS:
10999 result = get_mips_symbol_other (other);
28f997cf
TG
11000 break;
11001 case EM_IA_64:
dda8d76d 11002 result = get_ia64_symbol_other (filedata, other);
28f997cf 11003 break;
6911b7dc
AM
11004 case EM_PPC64:
11005 result = get_ppc64_symbol_other (other);
11006 break;
5e2b0d47 11007 default:
fd85a6a1 11008 result = NULL;
5e2b0d47
NC
11009 break;
11010 }
11011
11012 if (result)
11013 return result;
11014
11015 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11016 return buff;
11017}
11018
d1133906 11019static const char *
dda8d76d 11020get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11021{
b34976b6 11022 static char buff[32];
5cf1065c 11023
252b5132
RH
11024 switch (type)
11025 {
b34976b6
AM
11026 case SHN_UNDEF: return "UND";
11027 case SHN_ABS: return "ABS";
11028 case SHN_COMMON: return "COM";
252b5132 11029 default:
9ce701e2 11030 if (type == SHN_IA_64_ANSI_COMMON
dda8d76d
NC
11031 && filedata->file_header.e_machine == EM_IA_64
11032 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9ce701e2 11033 return "ANSI_COM";
dda8d76d
NC
11034 else if ((filedata->file_header.e_machine == EM_X86_64
11035 || filedata->file_header.e_machine == EM_L1OM
11036 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
11037 && type == SHN_X86_64_LCOMMON)
11038 return "LARGE_COM";
ac145307 11039 else if ((type == SHN_MIPS_SCOMMON
dda8d76d 11040 && filedata->file_header.e_machine == EM_MIPS)
ac145307 11041 || (type == SHN_TIC6X_SCOMMON
dda8d76d 11042 && filedata->file_header.e_machine == EM_TI_C6000))
172553c7
TS
11043 return "SCOM";
11044 else if (type == SHN_MIPS_SUNDEFINED
dda8d76d 11045 && filedata->file_header.e_machine == EM_MIPS)
172553c7 11046 return "SUND";
9ce701e2 11047 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 11048 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 11049 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
11050 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11051 else if (type >= SHN_LORESERVE)
11052 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
dda8d76d 11053 else if (type >= filedata->file_header.e_shnum)
e0a31db1 11054 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 11055 else
232e7cb8 11056 sprintf (buff, "%3d", type);
5cf1065c 11057 break;
252b5132 11058 }
5cf1065c
NC
11059
11060 return buff;
252b5132
RH
11061}
11062
66543521 11063static bfd_vma *
dda8d76d 11064get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
252b5132 11065{
2cf0635d
NC
11066 unsigned char * e_data;
11067 bfd_vma * i_data;
252b5132 11068
57028622
NC
11069 /* If the size_t type is smaller than the bfd_size_type, eg because
11070 you are building a 32-bit tool on a 64-bit host, then make sure
11071 that when (number) is cast to (size_t) no information is lost. */
11072 if (sizeof (size_t) < sizeof (bfd_size_type)
11073 && (bfd_size_type) ((size_t) number) != number)
11074 {
66cfc0fd
AM
11075 error (_("Size truncation prevents reading %s elements of size %u\n"),
11076 bfd_vmatoa ("u", number), ent_size);
57028622
NC
11077 return NULL;
11078 }
948f632f 11079
3102e897
NC
11080 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
11081 attempting to allocate memory when the read is bound to fail. */
dda8d76d 11082 if (ent_size * number > filedata->file_size)
3102e897 11083 {
66cfc0fd
AM
11084 error (_("Invalid number of dynamic entries: %s\n"),
11085 bfd_vmatoa ("u", number));
3102e897
NC
11086 return NULL;
11087 }
11088
57028622 11089 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
11090 if (e_data == NULL)
11091 {
66cfc0fd
AM
11092 error (_("Out of memory reading %s dynamic entries\n"),
11093 bfd_vmatoa ("u", number));
252b5132
RH
11094 return NULL;
11095 }
11096
dda8d76d 11097 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
252b5132 11098 {
66cfc0fd
AM
11099 error (_("Unable to read in %s bytes of dynamic data\n"),
11100 bfd_vmatoa ("u", number * ent_size));
3102e897 11101 free (e_data);
252b5132
RH
11102 return NULL;
11103 }
11104
57028622 11105 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
11106 if (i_data == NULL)
11107 {
66cfc0fd
AM
11108 error (_("Out of memory allocating space for %s dynamic entries\n"),
11109 bfd_vmatoa ("u", number));
252b5132
RH
11110 free (e_data);
11111 return NULL;
11112 }
11113
11114 while (number--)
66543521 11115 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
11116
11117 free (e_data);
11118
11119 return i_data;
11120}
11121
6bd1a22c 11122static void
dda8d76d 11123print_dynamic_symbol (Filedata * filedata, bfd_vma si, unsigned long hn)
6bd1a22c 11124{
2cf0635d 11125 Elf_Internal_Sym * psym;
6bd1a22c
L
11126 int n;
11127
6bd1a22c
L
11128 n = print_vma (si, DEC_5);
11129 if (n < 5)
0b4362b0 11130 fputs (&" "[n], stdout);
6bd1a22c 11131 printf (" %3lu: ", hn);
e0a31db1
NC
11132
11133 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
11134 {
3102e897
NC
11135 printf (_("<No info available for dynamic symbol number %lu>\n"),
11136 (unsigned long) si);
e0a31db1
NC
11137 return;
11138 }
11139
11140 psym = dynamic_symbols + si;
6bd1a22c
L
11141 print_vma (psym->st_value, LONG_HEX);
11142 putchar (' ');
11143 print_vma (psym->st_size, DEC_5);
11144
dda8d76d
NC
11145 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11146 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
fd85a6a1 11147
dda8d76d 11148 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11149 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11150 else
11151 {
11152 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11153
11154 printf (" %-7s", get_symbol_visibility (vis));
11155 /* Check to see if any other bits in the st_other field are set.
11156 Note - displaying this information disrupts the layout of the
11157 table being generated, but for the moment this case is very
11158 rare. */
11159 if (psym->st_other ^ vis)
dda8d76d 11160 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1
NC
11161 }
11162
dda8d76d 11163 printf (" %3.3s ", get_symbol_index_type (filedata, psym->st_shndx));
6bd1a22c
L
11164 if (VALID_DYNAMIC_NAME (psym->st_name))
11165 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11166 else
2b692964 11167 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
11168 putchar ('\n');
11169}
11170
bb4d2ac2 11171static const char *
dda8d76d 11172get_symbol_version_string (Filedata * filedata,
1449284b
NC
11173 bfd_boolean is_dynsym,
11174 const char * strtab,
11175 unsigned long int strtab_size,
11176 unsigned int si,
11177 Elf_Internal_Sym * psym,
11178 enum versioned_symbol_info * sym_info,
11179 unsigned short * vna_other)
bb4d2ac2 11180{
ab273396
AM
11181 unsigned char data[2];
11182 unsigned short vers_data;
11183 unsigned long offset;
bb4d2ac2 11184
ab273396
AM
11185 if (!is_dynsym
11186 || version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
11187 return NULL;
bb4d2ac2 11188
dda8d76d 11189 offset = offset_from_vma (filedata, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11190 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11191
dda8d76d 11192 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11193 sizeof (data), 1, _("version data")) == NULL)
11194 return NULL;
11195
11196 vers_data = byte_get (data, 2);
bb4d2ac2 11197
ab273396
AM
11198 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data <= 1)
11199 return NULL;
bb4d2ac2 11200
ab273396
AM
11201 /* Usually we'd only see verdef for defined symbols, and verneed for
11202 undefined symbols. However, symbols defined by the linker in
11203 .dynbss for variables copied from a shared library in order to
11204 avoid text relocations are defined yet have verneed. We could
11205 use a heuristic to detect the special case, for example, check
11206 for verneed first on symbols defined in SHT_NOBITS sections, but
11207 it is simpler and more reliable to just look for both verdef and
11208 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11209
ab273396
AM
11210 if (psym->st_shndx != SHN_UNDEF
11211 && vers_data != 0x8001
11212 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
11213 {
11214 Elf_Internal_Verdef ivd;
11215 Elf_Internal_Verdaux ivda;
11216 Elf_External_Verdaux evda;
11217 unsigned long off;
bb4d2ac2 11218
dda8d76d 11219 off = offset_from_vma (filedata,
ab273396
AM
11220 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
11221 sizeof (Elf_External_Verdef));
11222
11223 do
bb4d2ac2 11224 {
ab273396
AM
11225 Elf_External_Verdef evd;
11226
dda8d76d 11227 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11228 _("version def")) == NULL)
11229 {
11230 ivd.vd_ndx = 0;
11231 ivd.vd_aux = 0;
11232 ivd.vd_next = 0;
11233 }
11234 else
bb4d2ac2 11235 {
ab273396
AM
11236 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11237 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11238 ivd.vd_next = BYTE_GET (evd.vd_next);
11239 }
bb4d2ac2 11240
ab273396
AM
11241 off += ivd.vd_next;
11242 }
11243 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11244
ab273396
AM
11245 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11246 {
11247 off -= ivd.vd_next;
11248 off += ivd.vd_aux;
bb4d2ac2 11249
dda8d76d 11250 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
11251 _("version def aux")) != NULL)
11252 {
11253 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 11254
ab273396
AM
11255 if (psym->st_name != ivda.vda_name)
11256 {
11257 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
11258 ? symbol_hidden : symbol_public);
11259 return (ivda.vda_name < strtab_size
11260 ? strtab + ivda.vda_name : _("<corrupt>"));
11261 }
11262 }
11263 }
11264 }
bb4d2ac2 11265
ab273396
AM
11266 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
11267 {
11268 Elf_External_Verneed evn;
11269 Elf_Internal_Verneed ivn;
11270 Elf_Internal_Vernaux ivna;
bb4d2ac2 11271
dda8d76d 11272 offset = offset_from_vma (filedata,
ab273396
AM
11273 version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
11274 sizeof evn);
11275 do
11276 {
11277 unsigned long vna_off;
bb4d2ac2 11278
dda8d76d 11279 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
11280 _("version need")) == NULL)
11281 {
11282 ivna.vna_next = 0;
11283 ivna.vna_other = 0;
11284 ivna.vna_name = 0;
11285 break;
11286 }
bb4d2ac2 11287
ab273396
AM
11288 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11289 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 11290
ab273396 11291 vna_off = offset + ivn.vn_aux;
bb4d2ac2 11292
ab273396
AM
11293 do
11294 {
11295 Elf_External_Vernaux evna;
bb4d2ac2 11296
dda8d76d 11297 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 11298 _("version need aux (3)")) == NULL)
bb4d2ac2 11299 {
ab273396
AM
11300 ivna.vna_next = 0;
11301 ivna.vna_other = 0;
11302 ivna.vna_name = 0;
bb4d2ac2 11303 }
bb4d2ac2 11304 else
bb4d2ac2 11305 {
ab273396
AM
11306 ivna.vna_other = BYTE_GET (evna.vna_other);
11307 ivna.vna_next = BYTE_GET (evna.vna_next);
11308 ivna.vna_name = BYTE_GET (evna.vna_name);
11309 }
bb4d2ac2 11310
ab273396
AM
11311 vna_off += ivna.vna_next;
11312 }
11313 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 11314
ab273396
AM
11315 if (ivna.vna_other == vers_data)
11316 break;
bb4d2ac2 11317
ab273396
AM
11318 offset += ivn.vn_next;
11319 }
11320 while (ivn.vn_next != 0);
bb4d2ac2 11321
ab273396
AM
11322 if (ivna.vna_other == vers_data)
11323 {
11324 *sym_info = symbol_undefined;
11325 *vna_other = ivna.vna_other;
11326 return (ivna.vna_name < strtab_size
11327 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2
L
11328 }
11329 }
ab273396 11330 return NULL;
bb4d2ac2
L
11331}
11332
e3c8793a 11333/* Dump the symbol table. */
32ec8896 11334static bfd_boolean
dda8d76d 11335process_symbol_table (Filedata * filedata)
252b5132 11336{
2cf0635d 11337 Elf_Internal_Shdr * section;
8b73c356
NC
11338 bfd_size_type nbuckets = 0;
11339 bfd_size_type nchains = 0;
2cf0635d
NC
11340 bfd_vma * buckets = NULL;
11341 bfd_vma * chains = NULL;
fdc90cb4 11342 bfd_vma ngnubuckets = 0;
2cf0635d
NC
11343 bfd_vma * gnubuckets = NULL;
11344 bfd_vma * gnuchains = NULL;
6bd1a22c 11345 bfd_vma gnusymidx = 0;
071436c6 11346 bfd_size_type ngnuchains = 0;
252b5132 11347
2c610e4b 11348 if (!do_syms && !do_dyn_syms && !do_histogram)
32ec8896 11349 return TRUE;
252b5132 11350
6bd1a22c
L
11351 if (dynamic_info[DT_HASH]
11352 && (do_histogram
2c610e4b
L
11353 || (do_using_dynamic
11354 && !do_dyn_syms
11355 && dynamic_strings != NULL)))
252b5132 11356 {
66543521
AM
11357 unsigned char nb[8];
11358 unsigned char nc[8];
8b73c356 11359 unsigned int hash_ent_size = 4;
66543521 11360
dda8d76d
NC
11361 if ((filedata->file_header.e_machine == EM_ALPHA
11362 || filedata->file_header.e_machine == EM_S390
11363 || filedata->file_header.e_machine == EM_S390_OLD)
11364 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
66543521
AM
11365 hash_ent_size = 8;
11366
dda8d76d 11367 if (fseek (filedata->handle,
fb52b2f4 11368 (archive_file_offset
dda8d76d 11369 + offset_from_vma (filedata, dynamic_info[DT_HASH],
fb52b2f4 11370 sizeof nb + sizeof nc)),
d93f0186 11371 SEEK_SET))
252b5132 11372 {
591a748a 11373 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11374 goto no_hash;
252b5132
RH
11375 }
11376
dda8d76d 11377 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11378 {
11379 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11380 goto no_hash;
252b5132
RH
11381 }
11382
dda8d76d 11383 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11384 {
11385 error (_("Failed to read in number of chains\n"));
d3a44ec6 11386 goto no_hash;
252b5132
RH
11387 }
11388
66543521
AM
11389 nbuckets = byte_get (nb, hash_ent_size);
11390 nchains = byte_get (nc, hash_ent_size);
252b5132 11391
dda8d76d
NC
11392 buckets = get_dynamic_data (filedata, nbuckets, hash_ent_size);
11393 chains = get_dynamic_data (filedata, nchains, hash_ent_size);
252b5132 11394
d3a44ec6 11395 no_hash:
252b5132 11396 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
11397 {
11398 if (do_using_dynamic)
32ec8896 11399 return FALSE;
d3a44ec6
JJ
11400 free (buckets);
11401 free (chains);
11402 buckets = NULL;
11403 chains = NULL;
11404 nbuckets = 0;
11405 nchains = 0;
11406 }
252b5132
RH
11407 }
11408
6bd1a22c
L
11409 if (dynamic_info_DT_GNU_HASH
11410 && (do_histogram
2c610e4b
L
11411 || (do_using_dynamic
11412 && !do_dyn_syms
11413 && dynamic_strings != NULL)))
252b5132 11414 {
6bd1a22c
L
11415 unsigned char nb[16];
11416 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11417 bfd_vma buckets_vma;
11418
dda8d76d 11419 if (fseek (filedata->handle,
6bd1a22c 11420 (archive_file_offset
dda8d76d 11421 + offset_from_vma (filedata, dynamic_info_DT_GNU_HASH,
6bd1a22c
L
11422 sizeof nb)),
11423 SEEK_SET))
11424 {
11425 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11426 goto no_gnu_hash;
6bd1a22c 11427 }
252b5132 11428
dda8d76d 11429 if (fread (nb, 16, 1, filedata->handle) != 1)
6bd1a22c
L
11430 {
11431 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11432 goto no_gnu_hash;
6bd1a22c
L
11433 }
11434
11435 ngnubuckets = byte_get (nb, 4);
11436 gnusymidx = byte_get (nb + 4, 4);
11437 bitmaskwords = byte_get (nb + 8, 4);
11438 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 11439 if (is_32bit_elf)
6bd1a22c 11440 buckets_vma += bitmaskwords * 4;
f7a99963 11441 else
6bd1a22c 11442 buckets_vma += bitmaskwords * 8;
252b5132 11443
dda8d76d 11444 if (fseek (filedata->handle,
6bd1a22c 11445 (archive_file_offset
dda8d76d 11446 + offset_from_vma (filedata, buckets_vma, 4)),
6bd1a22c 11447 SEEK_SET))
252b5132 11448 {
6bd1a22c 11449 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11450 goto no_gnu_hash;
6bd1a22c
L
11451 }
11452
dda8d76d 11453 gnubuckets = get_dynamic_data (filedata, ngnubuckets, 4);
252b5132 11454
6bd1a22c 11455 if (gnubuckets == NULL)
d3a44ec6 11456 goto no_gnu_hash;
6bd1a22c
L
11457
11458 for (i = 0; i < ngnubuckets; i++)
11459 if (gnubuckets[i] != 0)
11460 {
11461 if (gnubuckets[i] < gnusymidx)
32ec8896 11462 return FALSE;
6bd1a22c
L
11463
11464 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
11465 maxchain = gnubuckets[i];
11466 }
11467
11468 if (maxchain == 0xffffffff)
d3a44ec6 11469 goto no_gnu_hash;
6bd1a22c
L
11470
11471 maxchain -= gnusymidx;
11472
dda8d76d 11473 if (fseek (filedata->handle,
6bd1a22c 11474 (archive_file_offset
dda8d76d 11475 + offset_from_vma (filedata, buckets_vma
6bd1a22c
L
11476 + 4 * (ngnubuckets + maxchain), 4)),
11477 SEEK_SET))
11478 {
11479 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11480 goto no_gnu_hash;
6bd1a22c
L
11481 }
11482
11483 do
11484 {
dda8d76d 11485 if (fread (nb, 4, 1, filedata->handle) != 1)
252b5132 11486 {
6bd1a22c 11487 error (_("Failed to determine last chain length\n"));
d3a44ec6 11488 goto no_gnu_hash;
6bd1a22c 11489 }
252b5132 11490
6bd1a22c 11491 if (maxchain + 1 == 0)
d3a44ec6 11492 goto no_gnu_hash;
252b5132 11493
6bd1a22c
L
11494 ++maxchain;
11495 }
11496 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 11497
dda8d76d 11498 if (fseek (filedata->handle,
6bd1a22c 11499 (archive_file_offset
dda8d76d 11500 + offset_from_vma (filedata, buckets_vma + 4 * ngnubuckets, 4)),
6bd1a22c
L
11501 SEEK_SET))
11502 {
11503 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11504 goto no_gnu_hash;
6bd1a22c
L
11505 }
11506
dda8d76d 11507 gnuchains = get_dynamic_data (filedata, maxchain, 4);
071436c6 11508 ngnuchains = maxchain;
6bd1a22c 11509
d3a44ec6 11510 no_gnu_hash:
6bd1a22c 11511 if (gnuchains == NULL)
d3a44ec6
JJ
11512 {
11513 free (gnubuckets);
d3a44ec6
JJ
11514 gnubuckets = NULL;
11515 ngnubuckets = 0;
f64fddf1 11516 if (do_using_dynamic)
32ec8896 11517 return FALSE;
d3a44ec6 11518 }
6bd1a22c
L
11519 }
11520
11521 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
11522 && do_syms
11523 && do_using_dynamic
3102e897
NC
11524 && dynamic_strings != NULL
11525 && dynamic_symbols != NULL)
6bd1a22c
L
11526 {
11527 unsigned long hn;
11528
11529 if (dynamic_info[DT_HASH])
11530 {
11531 bfd_vma si;
6bd6a03d 11532 char *visited;
6bd1a22c
L
11533
11534 printf (_("\nSymbol table for image:\n"));
11535 if (is_32bit_elf)
11536 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11537 else
11538 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11539
6bd6a03d
AM
11540 visited = xcmalloc (nchains, 1);
11541 memset (visited, 0, nchains);
6bd1a22c
L
11542 for (hn = 0; hn < nbuckets; hn++)
11543 {
6bd6a03d
AM
11544 for (si = buckets[hn]; si > 0; si = chains[si])
11545 {
dda8d76d 11546 print_dynamic_symbol (filedata, si, hn);
6bd6a03d
AM
11547 if (si >= nchains || visited[si])
11548 {
11549 error (_("histogram chain is corrupt\n"));
11550 break;
11551 }
11552 visited[si] = 1;
11553 }
252b5132 11554 }
6bd6a03d 11555 free (visited);
252b5132 11556 }
6bd1a22c
L
11557
11558 if (dynamic_info_DT_GNU_HASH)
11559 {
11560 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
11561 if (is_32bit_elf)
11562 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11563 else
11564 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11565
11566 for (hn = 0; hn < ngnubuckets; ++hn)
11567 if (gnubuckets[hn] != 0)
11568 {
11569 bfd_vma si = gnubuckets[hn];
11570 bfd_vma off = si - gnusymidx;
11571
11572 do
11573 {
dda8d76d 11574 print_dynamic_symbol (filedata, si, hn);
6bd1a22c
L
11575 si++;
11576 }
071436c6 11577 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
11578 }
11579 }
252b5132 11580 }
8b73c356 11581 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 11582 && filedata->section_headers != NULL)
252b5132 11583 {
b34976b6 11584 unsigned int i;
252b5132 11585
dda8d76d
NC
11586 for (i = 0, section = filedata->section_headers;
11587 i < filedata->file_header.e_shnum;
252b5132
RH
11588 i++, section++)
11589 {
b34976b6 11590 unsigned int si;
2cf0635d 11591 char * strtab = NULL;
c256ffe7 11592 unsigned long int strtab_size = 0;
2cf0635d
NC
11593 Elf_Internal_Sym * symtab;
11594 Elf_Internal_Sym * psym;
ba5cdace 11595 unsigned long num_syms;
252b5132 11596
2c610e4b
L
11597 if ((section->sh_type != SHT_SYMTAB
11598 && section->sh_type != SHT_DYNSYM)
11599 || (!do_syms
11600 && section->sh_type == SHT_SYMTAB))
252b5132
RH
11601 continue;
11602
dd24e3da
NC
11603 if (section->sh_entsize == 0)
11604 {
11605 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 11606 printable_section_name (filedata, section));
dd24e3da
NC
11607 continue;
11608 }
11609
d3a49aa8
AM
11610 num_syms = section->sh_size / section->sh_entsize;
11611 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
11612 "\nSymbol table '%s' contains %lu entries:\n",
11613 num_syms),
dda8d76d 11614 printable_section_name (filedata, section),
d3a49aa8 11615 num_syms);
dd24e3da 11616
f7a99963 11617 if (is_32bit_elf)
ca47b30c 11618 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 11619 else
ca47b30c 11620 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 11621
dda8d76d 11622 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
11623 if (symtab == NULL)
11624 continue;
11625
dda8d76d 11626 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 11627 {
dda8d76d
NC
11628 strtab = filedata->string_table;
11629 strtab_size = filedata->string_table_length;
c256ffe7 11630 }
dda8d76d 11631 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 11632 {
2cf0635d 11633 Elf_Internal_Shdr * string_sec;
252b5132 11634
dda8d76d 11635 string_sec = filedata->section_headers + section->sh_link;
252b5132 11636
dda8d76d 11637 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
11638 1, string_sec->sh_size,
11639 _("string table"));
c256ffe7 11640 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
11641 }
11642
ba5cdace 11643 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 11644 {
bb4d2ac2
L
11645 const char *version_string;
11646 enum versioned_symbol_info sym_info;
11647 unsigned short vna_other;
11648
5e220199 11649 printf ("%6d: ", si);
f7a99963
NC
11650 print_vma (psym->st_value, LONG_HEX);
11651 putchar (' ');
11652 print_vma (psym->st_size, DEC_5);
dda8d76d
NC
11653 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11654 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
11655 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11656 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11657 else
11658 {
11659 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11660
11661 printf (" %-7s", get_symbol_visibility (vis));
11662 /* Check to see if any other bits in the st_other field are set.
11663 Note - displaying this information disrupts the layout of the
11664 table being generated, but for the moment this case is very rare. */
11665 if (psym->st_other ^ vis)
dda8d76d 11666 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1 11667 }
dda8d76d 11668 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
c256ffe7 11669 print_symbol (25, psym->st_name < strtab_size
2b692964 11670 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 11671
bb4d2ac2 11672 version_string
dda8d76d 11673 = get_symbol_version_string (filedata,
bb4d2ac2
L
11674 section->sh_type == SHT_DYNSYM,
11675 strtab, strtab_size, si,
11676 psym, &sym_info, &vna_other);
11677 if (version_string)
252b5132 11678 {
bb4d2ac2
L
11679 if (sym_info == symbol_undefined)
11680 printf ("@%s (%d)", version_string, vna_other);
11681 else
11682 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
11683 version_string);
252b5132
RH
11684 }
11685
11686 putchar ('\n');
52c3c391
NC
11687
11688 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
dd905818
NC
11689 && si >= section->sh_info
11690 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
dda8d76d 11691 && filedata->file_header.e_machine != EM_MIPS
dd905818
NC
11692 /* Solaris binaries have been found to violate this requirement as
11693 well. Not sure if this is a bug or an ABI requirement. */
dda8d76d 11694 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
52c3c391 11695 warn (_("local symbol %u found at index >= %s's sh_info value of %u\n"),
dda8d76d 11696 si, printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11697 }
11698
11699 free (symtab);
dda8d76d 11700 if (strtab != filedata->string_table)
252b5132
RH
11701 free (strtab);
11702 }
11703 }
11704 else if (do_syms)
11705 printf
11706 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
11707
11708 if (do_histogram && buckets != NULL)
11709 {
2cf0635d
NC
11710 unsigned long * lengths;
11711 unsigned long * counts;
66543521
AM
11712 unsigned long hn;
11713 bfd_vma si;
11714 unsigned long maxlength = 0;
11715 unsigned long nzero_counts = 0;
11716 unsigned long nsyms = 0;
6bd6a03d 11717 char *visited;
252b5132 11718
d3a49aa8
AM
11719 printf (ngettext ("\nHistogram for bucket list length "
11720 "(total of %lu bucket):\n",
11721 "\nHistogram for bucket list length "
11722 "(total of %lu buckets):\n",
11723 (unsigned long) nbuckets),
66543521 11724 (unsigned long) nbuckets);
252b5132 11725
3f5e193b 11726 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
11727 if (lengths == NULL)
11728 {
8b73c356 11729 error (_("Out of memory allocating space for histogram buckets\n"));
32ec8896 11730 return FALSE;
252b5132 11731 }
6bd6a03d
AM
11732 visited = xcmalloc (nchains, 1);
11733 memset (visited, 0, nchains);
8b73c356
NC
11734
11735 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
11736 for (hn = 0; hn < nbuckets; ++hn)
11737 {
6bd6a03d 11738 for (si = buckets[hn]; si > 0; si = chains[si])
252b5132 11739 {
b34976b6 11740 ++nsyms;
252b5132 11741 if (maxlength < ++lengths[hn])
b34976b6 11742 ++maxlength;
6bd6a03d
AM
11743 if (si >= nchains || visited[si])
11744 {
11745 error (_("histogram chain is corrupt\n"));
11746 break;
11747 }
11748 visited[si] = 1;
252b5132
RH
11749 }
11750 }
6bd6a03d 11751 free (visited);
252b5132 11752
3f5e193b 11753 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
11754 if (counts == NULL)
11755 {
b2e951ec 11756 free (lengths);
8b73c356 11757 error (_("Out of memory allocating space for histogram counts\n"));
32ec8896 11758 return FALSE;
252b5132
RH
11759 }
11760
11761 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 11762 ++counts[lengths[hn]];
252b5132 11763
103f02d3 11764 if (nbuckets > 0)
252b5132 11765 {
66543521
AM
11766 unsigned long i;
11767 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 11768 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 11769 for (i = 1; i <= maxlength; ++i)
103f02d3 11770 {
66543521
AM
11771 nzero_counts += counts[i] * i;
11772 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11773 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
11774 (nzero_counts * 100.0) / nsyms);
11775 }
252b5132
RH
11776 }
11777
11778 free (counts);
11779 free (lengths);
11780 }
11781
11782 if (buckets != NULL)
11783 {
11784 free (buckets);
11785 free (chains);
11786 }
11787
d3a44ec6 11788 if (do_histogram && gnubuckets != NULL)
fdc90cb4 11789 {
2cf0635d
NC
11790 unsigned long * lengths;
11791 unsigned long * counts;
fdc90cb4
JJ
11792 unsigned long hn;
11793 unsigned long maxlength = 0;
11794 unsigned long nzero_counts = 0;
11795 unsigned long nsyms = 0;
fdc90cb4 11796
d3a49aa8
AM
11797 printf (ngettext ("\nHistogram for `.gnu.hash' bucket list length "
11798 "(total of %lu bucket):\n",
11799 "\nHistogram for `.gnu.hash' bucket list length "
11800 "(total of %lu buckets):\n",
11801 (unsigned long) ngnubuckets),
8b73c356
NC
11802 (unsigned long) ngnubuckets);
11803
3f5e193b 11804 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
11805 if (lengths == NULL)
11806 {
8b73c356 11807 error (_("Out of memory allocating space for gnu histogram buckets\n"));
32ec8896 11808 return FALSE;
fdc90cb4
JJ
11809 }
11810
fdc90cb4
JJ
11811 printf (_(" Length Number %% of total Coverage\n"));
11812
11813 for (hn = 0; hn < ngnubuckets; ++hn)
11814 if (gnubuckets[hn] != 0)
11815 {
11816 bfd_vma off, length = 1;
11817
6bd1a22c 11818 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
11819 /* PR 17531 file: 010-77222-0.004. */
11820 off < ngnuchains && (gnuchains[off] & 1) == 0;
11821 ++off)
fdc90cb4
JJ
11822 ++length;
11823 lengths[hn] = length;
11824 if (length > maxlength)
11825 maxlength = length;
11826 nsyms += length;
11827 }
11828
3f5e193b 11829 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
11830 if (counts == NULL)
11831 {
b2e951ec 11832 free (lengths);
8b73c356 11833 error (_("Out of memory allocating space for gnu histogram counts\n"));
32ec8896 11834 return FALSE;
fdc90cb4
JJ
11835 }
11836
11837 for (hn = 0; hn < ngnubuckets; ++hn)
11838 ++counts[lengths[hn]];
11839
11840 if (ngnubuckets > 0)
11841 {
11842 unsigned long j;
11843 printf (" 0 %-10lu (%5.1f%%)\n",
11844 counts[0], (counts[0] * 100.0) / ngnubuckets);
11845 for (j = 1; j <= maxlength; ++j)
11846 {
11847 nzero_counts += counts[j] * j;
11848 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11849 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
11850 (nzero_counts * 100.0) / nsyms);
11851 }
11852 }
11853
11854 free (counts);
11855 free (lengths);
11856 free (gnubuckets);
11857 free (gnuchains);
11858 }
11859
32ec8896 11860 return TRUE;
252b5132
RH
11861}
11862
32ec8896 11863static bfd_boolean
dda8d76d 11864process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 11865{
b4c96d0d 11866 unsigned int i;
252b5132
RH
11867
11868 if (dynamic_syminfo == NULL
11869 || !do_dynamic)
11870 /* No syminfo, this is ok. */
32ec8896 11871 return TRUE;
252b5132
RH
11872
11873 /* There better should be a dynamic symbol section. */
11874 if (dynamic_symbols == NULL || dynamic_strings == NULL)
32ec8896 11875 return FALSE;
252b5132
RH
11876
11877 if (dynamic_addr)
d3a49aa8
AM
11878 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
11879 "contains %d entry:\n",
11880 "\nDynamic info segment at offset 0x%lx "
11881 "contains %d entries:\n",
11882 dynamic_syminfo_nent),
252b5132
RH
11883 dynamic_syminfo_offset, dynamic_syminfo_nent);
11884
11885 printf (_(" Num: Name BoundTo Flags\n"));
11886 for (i = 0; i < dynamic_syminfo_nent; ++i)
11887 {
11888 unsigned short int flags = dynamic_syminfo[i].si_flags;
11889
31104126 11890 printf ("%4d: ", i);
4082ef84
NC
11891 if (i >= num_dynamic_syms)
11892 printf (_("<corrupt index>"));
11893 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
11894 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
11895 else
2b692964 11896 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 11897 putchar (' ');
252b5132
RH
11898
11899 switch (dynamic_syminfo[i].si_boundto)
11900 {
11901 case SYMINFO_BT_SELF:
11902 fputs ("SELF ", stdout);
11903 break;
11904 case SYMINFO_BT_PARENT:
11905 fputs ("PARENT ", stdout);
11906 break;
11907 default:
11908 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
11909 && dynamic_syminfo[i].si_boundto < dynamic_nent
11910 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 11911 {
d79b3d50 11912 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
11913 putchar (' ' );
11914 }
252b5132
RH
11915 else
11916 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
11917 break;
11918 }
11919
11920 if (flags & SYMINFO_FLG_DIRECT)
11921 printf (" DIRECT");
11922 if (flags & SYMINFO_FLG_PASSTHRU)
11923 printf (" PASSTHRU");
11924 if (flags & SYMINFO_FLG_COPY)
11925 printf (" COPY");
11926 if (flags & SYMINFO_FLG_LAZYLOAD)
11927 printf (" LAZYLOAD");
11928
11929 puts ("");
11930 }
11931
32ec8896 11932 return TRUE;
252b5132
RH
11933}
11934
b32e566b
NC
11935#define IN_RANGE(START,END,ADDR,OFF) \
11936 (((ADDR) >= (START)) && ((ADDR) + (OFF) < (END)))
11937
cf13d699
NC
11938/* Check to see if the given reloc needs to be handled in a target specific
11939 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
11940 FALSE.
11941
11942 If called with reloc == NULL, then this is a signal that reloc processing
11943 for the current section has finished, and any saved state should be
11944 discarded. */
09c11c86 11945
cf13d699 11946static bfd_boolean
dda8d76d
NC
11947target_specific_reloc_handling (Filedata * filedata,
11948 Elf_Internal_Rela * reloc,
11949 unsigned char * start,
11950 unsigned char * end,
11951 Elf_Internal_Sym * symtab,
11952 unsigned long num_syms)
252b5132 11953{
f84ce13b
NC
11954 unsigned int reloc_type = 0;
11955 unsigned long sym_index = 0;
11956
11957 if (reloc)
11958 {
dda8d76d 11959 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
11960 sym_index = get_reloc_symindex (reloc->r_info);
11961 }
252b5132 11962
dda8d76d 11963 switch (filedata->file_header.e_machine)
252b5132 11964 {
13761a11
NC
11965 case EM_MSP430:
11966 case EM_MSP430_OLD:
11967 {
11968 static Elf_Internal_Sym * saved_sym = NULL;
11969
f84ce13b
NC
11970 if (reloc == NULL)
11971 {
11972 saved_sym = NULL;
11973 return TRUE;
11974 }
11975
13761a11
NC
11976 switch (reloc_type)
11977 {
11978 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 11979 if (uses_msp430x_relocs (filedata))
13761a11 11980 break;
1a0670f3 11981 /* Fall through. */
13761a11 11982 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
11983 /* PR 21139. */
11984 if (sym_index >= num_syms)
11985 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
11986 sym_index);
11987 else
11988 saved_sym = symtab + sym_index;
13761a11
NC
11989 return TRUE;
11990
11991 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
11992 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
11993 goto handle_sym_diff;
0b4362b0 11994
13761a11
NC
11995 case 5: /* R_MSP430_16_BYTE */
11996 case 9: /* R_MSP430_8 */
dda8d76d 11997 if (uses_msp430x_relocs (filedata))
13761a11
NC
11998 break;
11999 goto handle_sym_diff;
12000
12001 case 2: /* R_MSP430_ABS16 */
12002 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12003 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12004 break;
12005 goto handle_sym_diff;
0b4362b0 12006
13761a11
NC
12007 handle_sym_diff:
12008 if (saved_sym != NULL)
12009 {
03f7786e 12010 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12011 bfd_vma value;
12012
f84ce13b
NC
12013 if (sym_index >= num_syms)
12014 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12015 sym_index);
03f7786e 12016 else
f84ce13b
NC
12017 {
12018 value = reloc->r_addend + (symtab[sym_index].st_value
12019 - saved_sym->st_value);
12020
b32e566b 12021 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12022 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12023 else
12024 /* PR 21137 */
12025 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12026 (long) reloc->r_offset);
f84ce13b 12027 }
13761a11
NC
12028
12029 saved_sym = NULL;
12030 return TRUE;
12031 }
12032 break;
12033
12034 default:
12035 if (saved_sym != NULL)
071436c6 12036 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12037 break;
12038 }
12039 break;
12040 }
12041
cf13d699
NC
12042 case EM_MN10300:
12043 case EM_CYGNUS_MN10300:
12044 {
12045 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12046
f84ce13b
NC
12047 if (reloc == NULL)
12048 {
12049 saved_sym = NULL;
12050 return TRUE;
12051 }
12052
cf13d699
NC
12053 switch (reloc_type)
12054 {
12055 case 34: /* R_MN10300_ALIGN */
12056 return TRUE;
12057 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12058 if (sym_index >= num_syms)
12059 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12060 sym_index);
12061 else
12062 saved_sym = symtab + sym_index;
cf13d699 12063 return TRUE;
f84ce13b 12064
cf13d699
NC
12065 case 1: /* R_MN10300_32 */
12066 case 2: /* R_MN10300_16 */
12067 if (saved_sym != NULL)
12068 {
03f7786e 12069 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12070 bfd_vma value;
252b5132 12071
f84ce13b
NC
12072 if (sym_index >= num_syms)
12073 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12074 sym_index);
03f7786e 12075 else
f84ce13b
NC
12076 {
12077 value = reloc->r_addend + (symtab[sym_index].st_value
12078 - saved_sym->st_value);
12079
b32e566b 12080 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12081 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12082 else
12083 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12084 (long) reloc->r_offset);
f84ce13b 12085 }
252b5132 12086
cf13d699
NC
12087 saved_sym = NULL;
12088 return TRUE;
12089 }
12090 break;
12091 default:
12092 if (saved_sym != NULL)
071436c6 12093 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12094 break;
12095 }
12096 break;
12097 }
6ff71e76
NC
12098
12099 case EM_RL78:
12100 {
12101 static bfd_vma saved_sym1 = 0;
12102 static bfd_vma saved_sym2 = 0;
12103 static bfd_vma value;
12104
f84ce13b
NC
12105 if (reloc == NULL)
12106 {
12107 saved_sym1 = saved_sym2 = 0;
12108 return TRUE;
12109 }
12110
6ff71e76
NC
12111 switch (reloc_type)
12112 {
12113 case 0x80: /* R_RL78_SYM. */
12114 saved_sym1 = saved_sym2;
f84ce13b
NC
12115 if (sym_index >= num_syms)
12116 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12117 sym_index);
12118 else
12119 {
12120 saved_sym2 = symtab[sym_index].st_value;
12121 saved_sym2 += reloc->r_addend;
12122 }
6ff71e76
NC
12123 return TRUE;
12124
12125 case 0x83: /* R_RL78_OPsub. */
12126 value = saved_sym1 - saved_sym2;
12127 saved_sym2 = saved_sym1 = 0;
12128 return TRUE;
12129 break;
12130
12131 case 0x41: /* R_RL78_ABS32. */
b32e566b 12132 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12133 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12134 else
12135 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12136 (long) reloc->r_offset);
6ff71e76
NC
12137 value = 0;
12138 return TRUE;
12139
12140 case 0x43: /* R_RL78_ABS16. */
b32e566b 12141 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12142 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12143 else
12144 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12145 (long) reloc->r_offset);
6ff71e76
NC
12146 value = 0;
12147 return TRUE;
12148
12149 default:
12150 break;
12151 }
12152 break;
12153 }
252b5132
RH
12154 }
12155
cf13d699 12156 return FALSE;
252b5132
RH
12157}
12158
aca88567
NC
12159/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12160 DWARF debug sections. This is a target specific test. Note - we do not
12161 go through the whole including-target-headers-multiple-times route, (as
12162 we have already done with <elf/h8.h>) because this would become very
12163 messy and even then this function would have to contain target specific
12164 information (the names of the relocs instead of their numeric values).
12165 FIXME: This is not the correct way to solve this problem. The proper way
12166 is to have target specific reloc sizing and typing functions created by
12167 the reloc-macros.h header, in the same way that it already creates the
12168 reloc naming functions. */
12169
12170static bfd_boolean
dda8d76d 12171is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12172{
d347c9df 12173 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12174 switch (filedata->file_header.e_machine)
aca88567 12175 {
41e92641 12176 case EM_386:
22abe556 12177 case EM_IAMCU:
41e92641 12178 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12179 case EM_68K:
12180 return reloc_type == 1; /* R_68K_32. */
a06ea964 12181 case EM_AARCH64:
9282b95a
JW
12182 return (reloc_type == 258
12183 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
d347c9df
PS
12184 case EM_ADAPTEVA_EPIPHANY:
12185 return reloc_type == 3;
aca88567 12186 case EM_ALPHA:
137b6b5f 12187 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12188 case EM_ARC:
12189 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12190 case EM_ARC_COMPACT:
12191 case EM_ARC_COMPACT2:
12192 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12193 case EM_ARM:
12194 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12195 case EM_AVR_OLD:
aca88567
NC
12196 case EM_AVR:
12197 return reloc_type == 1;
12198 case EM_BLACKFIN:
12199 return reloc_type == 0x12; /* R_byte4_data. */
12200 case EM_CRIS:
12201 return reloc_type == 3; /* R_CRIS_32. */
12202 case EM_CR16:
12203 return reloc_type == 3; /* R_CR16_NUM32. */
12204 case EM_CRX:
12205 return reloc_type == 15; /* R_CRX_NUM32. */
12206 case EM_CYGNUS_FRV:
12207 return reloc_type == 1;
41e92641
NC
12208 case EM_CYGNUS_D10V:
12209 case EM_D10V:
12210 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12211 case EM_CYGNUS_D30V:
12212 case EM_D30V:
12213 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12214 case EM_DLX:
12215 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12216 case EM_CYGNUS_FR30:
12217 case EM_FR30:
12218 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12219 case EM_FT32:
12220 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12221 case EM_H8S:
12222 case EM_H8_300:
12223 case EM_H8_300H:
12224 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12225 case EM_IA_64:
262cdac7
AM
12226 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12227 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12228 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12229 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12230 case EM_IP2K_OLD:
12231 case EM_IP2K:
12232 return reloc_type == 2; /* R_IP2K_32. */
12233 case EM_IQ2000:
12234 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12235 case EM_LATTICEMICO32:
12236 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12237 case EM_M32C_OLD:
aca88567
NC
12238 case EM_M32C:
12239 return reloc_type == 3; /* R_M32C_32. */
12240 case EM_M32R:
12241 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12242 case EM_68HC11:
12243 case EM_68HC12:
12244 return reloc_type == 6; /* R_M68HC11_32. */
aca88567
NC
12245 case EM_MCORE:
12246 return reloc_type == 1; /* R_MCORE_ADDR32. */
12247 case EM_CYGNUS_MEP:
12248 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12249 case EM_METAG:
12250 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12251 case EM_MICROBLAZE:
12252 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12253 case EM_MIPS:
12254 return reloc_type == 2; /* R_MIPS_32. */
12255 case EM_MMIX:
12256 return reloc_type == 4; /* R_MMIX_32. */
12257 case EM_CYGNUS_MN10200:
12258 case EM_MN10200:
12259 return reloc_type == 1; /* R_MN10200_32. */
12260 case EM_CYGNUS_MN10300:
12261 case EM_MN10300:
12262 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12263 case EM_MOXIE:
12264 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12265 case EM_MSP430_OLD:
12266 case EM_MSP430:
13761a11 12267 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12268 case EM_MT:
12269 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12270 case EM_NDS32:
12271 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12272 case EM_ALTERA_NIOS2:
36591ba1 12273 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12274 case EM_NIOS32:
12275 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12276 case EM_OR1K:
12277 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12278 case EM_PARISC:
5fda8eca
NC
12279 return (reloc_type == 1 /* R_PARISC_DIR32. */
12280 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12281 case EM_PJ:
12282 case EM_PJ_OLD:
12283 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12284 case EM_PPC64:
12285 return reloc_type == 1; /* R_PPC64_ADDR32. */
12286 case EM_PPC:
12287 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12288 case EM_TI_PRU:
12289 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12290 case EM_RISCV:
12291 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12292 case EM_RL78:
12293 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12294 case EM_RX:
12295 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
12296 case EM_S390_OLD:
12297 case EM_S390:
12298 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12299 case EM_SCORE:
12300 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12301 case EM_SH:
12302 return reloc_type == 1; /* R_SH_DIR32. */
12303 case EM_SPARC32PLUS:
12304 case EM_SPARCV9:
12305 case EM_SPARC:
12306 return reloc_type == 3 /* R_SPARC_32. */
12307 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12308 case EM_SPU:
12309 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12310 case EM_TI_C6000:
12311 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12312 case EM_TILEGX:
12313 return reloc_type == 2; /* R_TILEGX_32. */
12314 case EM_TILEPRO:
12315 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12316 case EM_CYGNUS_V850:
12317 case EM_V850:
12318 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12319 case EM_V800:
12320 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12321 case EM_VAX:
12322 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12323 case EM_VISIUM:
12324 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12325 case EM_WEBASSEMBLY:
12326 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12327 case EM_X86_64:
8a9036a4 12328 case EM_L1OM:
7a9068fe 12329 case EM_K1OM:
aca88567 12330 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12331 case EM_XC16X:
12332 case EM_C166:
12333 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12334 case EM_XGATE:
12335 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12336 case EM_XSTORMY16:
12337 return reloc_type == 1; /* R_XSTROMY16_32. */
12338 case EM_XTENSA_OLD:
12339 case EM_XTENSA:
12340 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 12341 default:
bee0ee85
NC
12342 {
12343 static unsigned int prev_warn = 0;
12344
12345 /* Avoid repeating the same warning multiple times. */
dda8d76d 12346 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12347 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12348 filedata->file_header.e_machine);
12349 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12350 return FALSE;
12351 }
aca88567
NC
12352 }
12353}
12354
12355/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12356 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12357
12358static bfd_boolean
dda8d76d 12359is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12360{
dda8d76d 12361 switch (filedata->file_header.e_machine)
d347c9df 12362 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12363 {
41e92641 12364 case EM_386:
22abe556 12365 case EM_IAMCU:
3e0873ac 12366 return reloc_type == 2; /* R_386_PC32. */
aca88567 12367 case EM_68K:
3e0873ac 12368 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12369 case EM_AARCH64:
12370 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12371 case EM_ADAPTEVA_EPIPHANY:
12372 return reloc_type == 6;
aca88567
NC
12373 case EM_ALPHA:
12374 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12375 case EM_ARC_COMPACT:
12376 case EM_ARC_COMPACT2:
12377 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12378 case EM_ARM:
3e0873ac 12379 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12380 case EM_AVR_OLD:
12381 case EM_AVR:
12382 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12383 case EM_MICROBLAZE:
12384 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12385 case EM_OR1K:
12386 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 12387 case EM_PARISC:
85acf597 12388 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
12389 case EM_PPC:
12390 return reloc_type == 26; /* R_PPC_REL32. */
12391 case EM_PPC64:
3e0873ac 12392 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
12393 case EM_S390_OLD:
12394 case EM_S390:
3e0873ac 12395 return reloc_type == 5; /* R_390_PC32. */
aca88567 12396 case EM_SH:
3e0873ac 12397 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
12398 case EM_SPARC32PLUS:
12399 case EM_SPARCV9:
12400 case EM_SPARC:
3e0873ac 12401 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
12402 case EM_SPU:
12403 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
12404 case EM_TILEGX:
12405 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
12406 case EM_TILEPRO:
12407 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
12408 case EM_VISIUM:
12409 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 12410 case EM_X86_64:
8a9036a4 12411 case EM_L1OM:
7a9068fe 12412 case EM_K1OM:
3e0873ac 12413 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
12414 case EM_XTENSA_OLD:
12415 case EM_XTENSA:
12416 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
12417 default:
12418 /* Do not abort or issue an error message here. Not all targets use
12419 pc-relative 32-bit relocs in their DWARF debug information and we
12420 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
12421 more helpful warning message will be generated by apply_relocations
12422 anyway, so just return. */
aca88567
NC
12423 return FALSE;
12424 }
12425}
12426
12427/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12428 a 64-bit absolute RELA relocation used in DWARF debug sections. */
12429
12430static bfd_boolean
dda8d76d 12431is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12432{
dda8d76d 12433 switch (filedata->file_header.e_machine)
aca88567 12434 {
a06ea964
NC
12435 case EM_AARCH64:
12436 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
12437 case EM_ALPHA:
12438 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 12439 case EM_IA_64:
262cdac7
AM
12440 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
12441 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
12442 case EM_PARISC:
12443 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
12444 case EM_PPC64:
12445 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
12446 case EM_RISCV:
12447 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
12448 case EM_SPARC32PLUS:
12449 case EM_SPARCV9:
12450 case EM_SPARC:
714da62f
NC
12451 return reloc_type == 32 /* R_SPARC_64. */
12452 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 12453 case EM_X86_64:
8a9036a4 12454 case EM_L1OM:
7a9068fe 12455 case EM_K1OM:
aca88567 12456 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
12457 case EM_S390_OLD:
12458 case EM_S390:
aa137e4d
NC
12459 return reloc_type == 22; /* R_S390_64. */
12460 case EM_TILEGX:
12461 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 12462 case EM_MIPS:
aa137e4d 12463 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
12464 default:
12465 return FALSE;
12466 }
12467}
12468
85acf597
RH
12469/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
12470 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
12471
12472static bfd_boolean
dda8d76d 12473is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 12474{
dda8d76d 12475 switch (filedata->file_header.e_machine)
85acf597 12476 {
a06ea964
NC
12477 case EM_AARCH64:
12478 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 12479 case EM_ALPHA:
aa137e4d 12480 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 12481 case EM_IA_64:
262cdac7
AM
12482 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
12483 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 12484 case EM_PARISC:
aa137e4d 12485 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 12486 case EM_PPC64:
aa137e4d 12487 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
12488 case EM_SPARC32PLUS:
12489 case EM_SPARCV9:
12490 case EM_SPARC:
aa137e4d 12491 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 12492 case EM_X86_64:
8a9036a4 12493 case EM_L1OM:
7a9068fe 12494 case EM_K1OM:
aa137e4d 12495 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
12496 case EM_S390_OLD:
12497 case EM_S390:
aa137e4d
NC
12498 return reloc_type == 23; /* R_S390_PC64. */
12499 case EM_TILEGX:
12500 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
12501 default:
12502 return FALSE;
12503 }
12504}
12505
4dc3c23d
AM
12506/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12507 a 24-bit absolute RELA relocation used in DWARF debug sections. */
12508
12509static bfd_boolean
dda8d76d 12510is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 12511{
dda8d76d 12512 switch (filedata->file_header.e_machine)
4dc3c23d
AM
12513 {
12514 case EM_CYGNUS_MN10200:
12515 case EM_MN10200:
12516 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
12517 case EM_FT32:
12518 return reloc_type == 5; /* R_FT32_20. */
4dc3c23d
AM
12519 default:
12520 return FALSE;
12521 }
12522}
12523
aca88567
NC
12524/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12525 a 16-bit absolute RELA relocation used in DWARF debug sections. */
12526
12527static bfd_boolean
dda8d76d 12528is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 12529{
d347c9df 12530 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12531 switch (filedata->file_header.e_machine)
4b78141a 12532 {
886a2506
NC
12533 case EM_ARC:
12534 case EM_ARC_COMPACT:
12535 case EM_ARC_COMPACT2:
12536 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
12537 case EM_ADAPTEVA_EPIPHANY:
12538 return reloc_type == 5;
aca88567
NC
12539 case EM_AVR_OLD:
12540 case EM_AVR:
12541 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
12542 case EM_CYGNUS_D10V:
12543 case EM_D10V:
12544 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
12545 case EM_FT32:
12546 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
12547 case EM_H8S:
12548 case EM_H8_300:
12549 case EM_H8_300H:
aca88567
NC
12550 return reloc_type == R_H8_DIR16;
12551 case EM_IP2K_OLD:
12552 case EM_IP2K:
12553 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 12554 case EM_M32C_OLD:
f4236fe4
DD
12555 case EM_M32C:
12556 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
12557 case EM_CYGNUS_MN10200:
12558 case EM_MN10200:
12559 return reloc_type == 2; /* R_MN10200_16. */
12560 case EM_CYGNUS_MN10300:
12561 case EM_MN10300:
12562 return reloc_type == 2; /* R_MN10300_16. */
aca88567 12563 case EM_MSP430:
dda8d76d 12564 if (uses_msp430x_relocs (filedata))
13761a11 12565 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 12566 /* Fall through. */
78c8d46c 12567 case EM_MSP430_OLD:
aca88567 12568 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
12569 case EM_NDS32:
12570 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 12571 case EM_ALTERA_NIOS2:
36591ba1 12572 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
12573 case EM_NIOS32:
12574 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
12575 case EM_OR1K:
12576 return reloc_type == 2; /* R_OR1K_16. */
2b100bb5
DD
12577 case EM_TI_PRU:
12578 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
12579 case EM_TI_C6000:
12580 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
12581 case EM_VISIUM:
12582 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
12583 case EM_XC16X:
12584 case EM_C166:
12585 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
12586 case EM_XGATE:
12587 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 12588 default:
aca88567 12589 return FALSE;
4b78141a
NC
12590 }
12591}
12592
03336641
JW
12593/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12594 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
12595
12596static bfd_boolean
12597is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12598{
12599 /* Please keep this table alpha-sorted for ease of visual lookup. */
12600 switch (filedata->file_header.e_machine)
12601 {
12602 case EM_RISCV:
12603 return reloc_type == 35; /* R_RISCV_ADD32. */
12604 default:
12605 return FALSE;
12606 }
12607}
12608
12609/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12610 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
12611
12612static bfd_boolean
12613is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12614{
12615 /* Please keep this table alpha-sorted for ease of visual lookup. */
12616 switch (filedata->file_header.e_machine)
12617 {
12618 case EM_RISCV:
12619 return reloc_type == 39; /* R_RISCV_SUB32. */
12620 default:
12621 return FALSE;
12622 }
12623}
12624
12625/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12626 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
12627
12628static bfd_boolean
12629is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12630{
12631 /* Please keep this table alpha-sorted for ease of visual lookup. */
12632 switch (filedata->file_header.e_machine)
12633 {
12634 case EM_RISCV:
12635 return reloc_type == 36; /* R_RISCV_ADD64. */
12636 default:
12637 return FALSE;
12638 }
12639}
12640
12641/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12642 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
12643
12644static bfd_boolean
12645is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12646{
12647 /* Please keep this table alpha-sorted for ease of visual lookup. */
12648 switch (filedata->file_header.e_machine)
12649 {
12650 case EM_RISCV:
12651 return reloc_type == 40; /* R_RISCV_SUB64. */
12652 default:
12653 return FALSE;
12654 }
12655}
12656
12657/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12658 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
12659
12660static bfd_boolean
12661is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12662{
12663 /* Please keep this table alpha-sorted for ease of visual lookup. */
12664 switch (filedata->file_header.e_machine)
12665 {
12666 case EM_RISCV:
12667 return reloc_type == 34; /* R_RISCV_ADD16. */
12668 default:
12669 return FALSE;
12670 }
12671}
12672
12673/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12674 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
12675
12676static bfd_boolean
12677is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12678{
12679 /* Please keep this table alpha-sorted for ease of visual lookup. */
12680 switch (filedata->file_header.e_machine)
12681 {
12682 case EM_RISCV:
12683 return reloc_type == 38; /* R_RISCV_SUB16. */
12684 default:
12685 return FALSE;
12686 }
12687}
12688
12689/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12690 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
12691
12692static bfd_boolean
12693is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12694{
12695 /* Please keep this table alpha-sorted for ease of visual lookup. */
12696 switch (filedata->file_header.e_machine)
12697 {
12698 case EM_RISCV:
12699 return reloc_type == 33; /* R_RISCV_ADD8. */
12700 default:
12701 return FALSE;
12702 }
12703}
12704
12705/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12706 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
12707
12708static bfd_boolean
12709is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12710{
12711 /* Please keep this table alpha-sorted for ease of visual lookup. */
12712 switch (filedata->file_header.e_machine)
12713 {
12714 case EM_RISCV:
12715 return reloc_type == 37; /* R_RISCV_SUB8. */
12716 default:
12717 return FALSE;
12718 }
12719}
12720
2a7b2e88
JK
12721/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
12722 relocation entries (possibly formerly used for SHT_GROUP sections). */
12723
12724static bfd_boolean
dda8d76d 12725is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 12726{
dda8d76d 12727 switch (filedata->file_header.e_machine)
2a7b2e88 12728 {
cb8f3167 12729 case EM_386: /* R_386_NONE. */
d347c9df 12730 case EM_68K: /* R_68K_NONE. */
cfb8c092 12731 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
12732 case EM_ALPHA: /* R_ALPHA_NONE. */
12733 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 12734 case EM_ARC: /* R_ARC_NONE. */
886a2506 12735 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 12736 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 12737 case EM_ARM: /* R_ARM_NONE. */
d347c9df 12738 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 12739 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
12740 case EM_FT32: /* R_FT32_NONE. */
12741 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 12742 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
12743 case EM_L1OM: /* R_X86_64_NONE. */
12744 case EM_M32R: /* R_M32R_NONE. */
12745 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 12746 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 12747 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
12748 case EM_NIOS32: /* R_NIOS_NONE. */
12749 case EM_OR1K: /* R_OR1K_NONE. */
12750 case EM_PARISC: /* R_PARISC_NONE. */
12751 case EM_PPC64: /* R_PPC64_NONE. */
12752 case EM_PPC: /* R_PPC_NONE. */
e23eba97 12753 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
12754 case EM_S390: /* R_390_NONE. */
12755 case EM_S390_OLD:
12756 case EM_SH: /* R_SH_NONE. */
12757 case EM_SPARC32PLUS:
12758 case EM_SPARC: /* R_SPARC_NONE. */
12759 case EM_SPARCV9:
aa137e4d
NC
12760 case EM_TILEGX: /* R_TILEGX_NONE. */
12761 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
12762 case EM_TI_C6000:/* R_C6000_NONE. */
12763 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 12764 case EM_XC16X:
f96bd6c2 12765 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 12766 return reloc_type == 0;
d347c9df 12767
a06ea964
NC
12768 case EM_AARCH64:
12769 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
12770 case EM_AVR_OLD:
12771 case EM_AVR:
12772 return (reloc_type == 0 /* R_AVR_NONE. */
12773 || reloc_type == 30 /* R_AVR_DIFF8. */
12774 || reloc_type == 31 /* R_AVR_DIFF16. */
12775 || reloc_type == 32 /* R_AVR_DIFF32. */);
12776 case EM_METAG:
12777 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
12778 case EM_NDS32:
12779 return (reloc_type == 0 /* R_XTENSA_NONE. */
12780 || reloc_type == 204 /* R_NDS32_DIFF8. */
12781 || reloc_type == 205 /* R_NDS32_DIFF16. */
12782 || reloc_type == 206 /* R_NDS32_DIFF32. */
12783 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
12784 case EM_TI_PRU:
12785 return (reloc_type == 0 /* R_PRU_NONE. */
12786 || reloc_type == 65 /* R_PRU_DIFF8. */
12787 || reloc_type == 66 /* R_PRU_DIFF16. */
12788 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
12789 case EM_XTENSA_OLD:
12790 case EM_XTENSA:
4dc3c23d
AM
12791 return (reloc_type == 0 /* R_XTENSA_NONE. */
12792 || reloc_type == 17 /* R_XTENSA_DIFF8. */
12793 || reloc_type == 18 /* R_XTENSA_DIFF16. */
12794 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
12795 }
12796 return FALSE;
12797}
12798
d1c4b12b
NC
12799/* Returns TRUE if there is a relocation against
12800 section NAME at OFFSET bytes. */
12801
12802bfd_boolean
12803reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
12804{
12805 Elf_Internal_Rela * relocs;
12806 Elf_Internal_Rela * rp;
12807
12808 if (dsec == NULL || dsec->reloc_info == NULL)
12809 return FALSE;
12810
12811 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
12812
12813 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
12814 if (rp->r_offset == offset)
12815 return TRUE;
12816
12817 return FALSE;
12818}
12819
cf13d699 12820/* Apply relocations to a section.
32ec8896
NC
12821 Returns TRUE upon success, FALSE otherwise.
12822 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
12823 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
12824 will be set to the number of relocs loaded.
12825
cf13d699 12826 Note: So far support has been added only for those relocations
32ec8896
NC
12827 which can be found in debug sections. FIXME: Add support for
12828 more relocations ? */
1b315056 12829
32ec8896 12830static bfd_boolean
dda8d76d 12831apply_relocations (Filedata * filedata,
d1c4b12b
NC
12832 const Elf_Internal_Shdr * section,
12833 unsigned char * start,
12834 bfd_size_type size,
1449284b 12835 void ** relocs_return,
d1c4b12b 12836 unsigned long * num_relocs_return)
1b315056 12837{
cf13d699 12838 Elf_Internal_Shdr * relsec;
0d2a7a93 12839 unsigned char * end = start + size;
32ec8896 12840 bfd_boolean res = TRUE;
cb8f3167 12841
d1c4b12b
NC
12842 if (relocs_return != NULL)
12843 {
12844 * (Elf_Internal_Rela **) relocs_return = NULL;
12845 * num_relocs_return = 0;
12846 }
12847
dda8d76d 12848 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
12849 /* No relocs to apply. */
12850 return TRUE;
1b315056 12851
cf13d699 12852 /* Find the reloc section associated with the section. */
dda8d76d
NC
12853 for (relsec = filedata->section_headers;
12854 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 12855 ++relsec)
252b5132 12856 {
41e92641
NC
12857 bfd_boolean is_rela;
12858 unsigned long num_relocs;
2cf0635d
NC
12859 Elf_Internal_Rela * relocs;
12860 Elf_Internal_Rela * rp;
12861 Elf_Internal_Shdr * symsec;
12862 Elf_Internal_Sym * symtab;
ba5cdace 12863 unsigned long num_syms;
2cf0635d 12864 Elf_Internal_Sym * sym;
252b5132 12865
41e92641 12866 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
12867 || relsec->sh_info >= filedata->file_header.e_shnum
12868 || filedata->section_headers + relsec->sh_info != section
c256ffe7 12869 || relsec->sh_size == 0
dda8d76d 12870 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 12871 continue;
428409d5 12872
41e92641
NC
12873 is_rela = relsec->sh_type == SHT_RELA;
12874
12875 if (is_rela)
12876 {
dda8d76d 12877 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 12878 relsec->sh_size, & relocs, & num_relocs))
32ec8896 12879 return FALSE;
41e92641
NC
12880 }
12881 else
12882 {
dda8d76d 12883 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 12884 relsec->sh_size, & relocs, & num_relocs))
32ec8896 12885 return FALSE;
41e92641
NC
12886 }
12887
12888 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 12889 if (filedata->file_header.e_machine == EM_SH)
41e92641 12890 is_rela = FALSE;
428409d5 12891
dda8d76d 12892 symsec = filedata->section_headers + relsec->sh_link;
1449284b
NC
12893 if (symsec->sh_type != SHT_SYMTAB
12894 && symsec->sh_type != SHT_DYNSYM)
32ec8896 12895 return FALSE;
dda8d76d 12896 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 12897
41e92641 12898 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 12899 {
41e92641
NC
12900 bfd_vma addend;
12901 unsigned int reloc_type;
12902 unsigned int reloc_size;
03336641
JW
12903 bfd_boolean reloc_inplace = FALSE;
12904 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 12905 unsigned char * rloc;
ba5cdace 12906 unsigned long sym_index;
4b78141a 12907
dda8d76d 12908 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 12909
dda8d76d 12910 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 12911 continue;
dda8d76d 12912 else if (is_none_reloc (filedata, reloc_type))
98fb390a 12913 continue;
dda8d76d
NC
12914 else if (is_32bit_abs_reloc (filedata, reloc_type)
12915 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 12916 reloc_size = 4;
dda8d76d
NC
12917 else if (is_64bit_abs_reloc (filedata, reloc_type)
12918 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 12919 reloc_size = 8;
dda8d76d 12920 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 12921 reloc_size = 3;
dda8d76d 12922 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 12923 reloc_size = 2;
03336641
JW
12924 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
12925 reloc_type))
12926 || is_32bit_inplace_add_reloc (filedata, reloc_type))
12927 {
12928 reloc_size = 4;
12929 reloc_inplace = TRUE;
12930 }
12931 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
12932 reloc_type))
12933 || is_64bit_inplace_add_reloc (filedata, reloc_type))
12934 {
12935 reloc_size = 8;
12936 reloc_inplace = TRUE;
12937 }
12938 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
12939 reloc_type))
12940 || is_16bit_inplace_add_reloc (filedata, reloc_type))
12941 {
12942 reloc_size = 2;
12943 reloc_inplace = TRUE;
12944 }
12945 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
12946 reloc_type))
12947 || is_8bit_inplace_add_reloc (filedata, reloc_type))
12948 {
12949 reloc_size = 1;
12950 reloc_inplace = TRUE;
12951 }
aca88567 12952 else
4b78141a 12953 {
bee0ee85 12954 static unsigned int prev_reloc = 0;
dda8d76d 12955
bee0ee85
NC
12956 if (reloc_type != prev_reloc)
12957 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 12958 reloc_type, printable_section_name (filedata, section));
bee0ee85 12959 prev_reloc = reloc_type;
32ec8896 12960 res = FALSE;
4b78141a
NC
12961 continue;
12962 }
103f02d3 12963
91d6fa6a 12964 rloc = start + rp->r_offset;
c8da6823 12965 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
12966 {
12967 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
12968 (unsigned long) rp->r_offset,
dda8d76d 12969 printable_section_name (filedata, section));
32ec8896 12970 res = FALSE;
700dd8b7
L
12971 continue;
12972 }
103f02d3 12973
ba5cdace
NC
12974 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
12975 if (sym_index >= num_syms)
12976 {
12977 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 12978 sym_index, printable_section_name (filedata, section));
32ec8896 12979 res = FALSE;
ba5cdace
NC
12980 continue;
12981 }
12982 sym = symtab + sym_index;
41e92641
NC
12983
12984 /* If the reloc has a symbol associated with it,
55f25fc3
L
12985 make sure that it is of an appropriate type.
12986
12987 Relocations against symbols without type can happen.
12988 Gcc -feliminate-dwarf2-dups may generate symbols
12989 without type for debug info.
12990
12991 Icc generates relocations against function symbols
12992 instead of local labels.
12993
12994 Relocations against object symbols can happen, eg when
12995 referencing a global array. For an example of this see
12996 the _clz.o binary in libgcc.a. */
aca88567 12997 if (sym != symtab
b8871f35 12998 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 12999 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13000 {
d3a49aa8 13001 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13002 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13003 printable_section_name (filedata, relsec),
d3a49aa8 13004 (long int)(rp - relocs));
32ec8896 13005 res = FALSE;
aca88567 13006 continue;
5b18a4bc 13007 }
252b5132 13008
4dc3c23d
AM
13009 addend = 0;
13010 if (is_rela)
13011 addend += rp->r_addend;
c47320c3
AM
13012 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13013 partial_inplace. */
4dc3c23d 13014 if (!is_rela
dda8d76d 13015 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13016 && reloc_type == 1)
dda8d76d
NC
13017 || ((filedata->file_header.e_machine == EM_PJ
13018 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13019 && reloc_type == 1)
dda8d76d
NC
13020 || ((filedata->file_header.e_machine == EM_D30V
13021 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13022 && reloc_type == 12)
13023 || reloc_inplace)
91d6fa6a 13024 addend += byte_get (rloc, reloc_size);
cb8f3167 13025
dda8d76d
NC
13026 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13027 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13028 {
13029 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13030 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13031 addend -= 8;
91d6fa6a 13032 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13033 reloc_size);
13034 }
03336641
JW
13035 else if (reloc_subtract)
13036 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13037 else
91d6fa6a 13038 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13039 }
252b5132 13040
5b18a4bc 13041 free (symtab);
f84ce13b
NC
13042 /* Let the target specific reloc processing code know that
13043 we have finished with these relocs. */
dda8d76d 13044 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13045
13046 if (relocs_return)
13047 {
13048 * (Elf_Internal_Rela **) relocs_return = relocs;
13049 * num_relocs_return = num_relocs;
13050 }
13051 else
13052 free (relocs);
13053
5b18a4bc
NC
13054 break;
13055 }
32ec8896
NC
13056
13057 return res;
5b18a4bc 13058}
103f02d3 13059
cf13d699 13060#ifdef SUPPORT_DISASSEMBLY
32ec8896 13061static bfd_boolean
dda8d76d 13062disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13063{
dda8d76d 13064 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13065
74e1a04b 13066 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13067
32ec8896 13068 return TRUE;
cf13d699
NC
13069}
13070#endif
13071
13072/* Reads in the contents of SECTION from FILE, returning a pointer
13073 to a malloc'ed buffer or NULL if something went wrong. */
13074
13075static char *
dda8d76d 13076get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13077{
dda8d76d 13078 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13079
13080 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13081 {
c6b78c96 13082 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13083 printable_section_name (filedata, section));
cf13d699
NC
13084 return NULL;
13085 }
13086
dda8d76d 13087 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13088 _("section contents"));
cf13d699
NC
13089}
13090
0e602686
NC
13091/* Uncompresses a section that was compressed using zlib, in place. */
13092
13093static bfd_boolean
dda8d76d
NC
13094uncompress_section_contents (unsigned char ** buffer,
13095 dwarf_size_type uncompressed_size,
13096 dwarf_size_type * size)
0e602686
NC
13097{
13098 dwarf_size_type compressed_size = *size;
13099 unsigned char * compressed_buffer = *buffer;
13100 unsigned char * uncompressed_buffer;
13101 z_stream strm;
13102 int rc;
13103
13104 /* It is possible the section consists of several compressed
13105 buffers concatenated together, so we uncompress in a loop. */
13106 /* PR 18313: The state field in the z_stream structure is supposed
13107 to be invisible to the user (ie us), but some compilers will
13108 still complain about it being used without initialisation. So
13109 we first zero the entire z_stream structure and then set the fields
13110 that we need. */
13111 memset (& strm, 0, sizeof strm);
13112 strm.avail_in = compressed_size;
13113 strm.next_in = (Bytef *) compressed_buffer;
13114 strm.avail_out = uncompressed_size;
13115 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13116
13117 rc = inflateInit (& strm);
13118 while (strm.avail_in > 0)
13119 {
13120 if (rc != Z_OK)
13121 goto fail;
13122 strm.next_out = ((Bytef *) uncompressed_buffer
13123 + (uncompressed_size - strm.avail_out));
13124 rc = inflate (&strm, Z_FINISH);
13125 if (rc != Z_STREAM_END)
13126 goto fail;
13127 rc = inflateReset (& strm);
13128 }
13129 rc = inflateEnd (& strm);
13130 if (rc != Z_OK
13131 || strm.avail_out != 0)
13132 goto fail;
13133
13134 *buffer = uncompressed_buffer;
13135 *size = uncompressed_size;
13136 return TRUE;
13137
13138 fail:
13139 free (uncompressed_buffer);
13140 /* Indicate decompression failure. */
13141 *buffer = NULL;
13142 return FALSE;
13143}
dd24e3da 13144
32ec8896 13145static bfd_boolean
dda8d76d 13146dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13147{
0e602686
NC
13148 Elf_Internal_Shdr * relsec;
13149 bfd_size_type num_bytes;
fd8008d8
L
13150 unsigned char * data;
13151 unsigned char * end;
13152 unsigned char * real_start;
13153 unsigned char * start;
0e602686 13154 bfd_boolean some_strings_shown;
cf13d699 13155
dda8d76d 13156 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13157 if (start == NULL)
c6b78c96
NC
13158 /* PR 21820: Do not fail if the section was empty. */
13159 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13160
0e602686 13161 num_bytes = section->sh_size;
cf13d699 13162
dda8d76d 13163 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13164
0e602686
NC
13165 if (decompress_dumps)
13166 {
13167 dwarf_size_type new_size = num_bytes;
13168 dwarf_size_type uncompressed_size = 0;
13169
13170 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13171 {
13172 Elf_Internal_Chdr chdr;
13173 unsigned int compression_header_size
ebdf1ebf
NC
13174 = get_compression_header (& chdr, (unsigned char *) start,
13175 num_bytes);
0e602686 13176
813dabb9 13177 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13178 {
813dabb9 13179 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13180 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13181 return FALSE;
813dabb9
L
13182 }
13183 else if (chdr.ch_addralign != section->sh_addralign)
13184 {
13185 warn (_("compressed section '%s' is corrupted\n"),
dda8d76d 13186 printable_section_name (filedata, section));
32ec8896 13187 return FALSE;
0e602686 13188 }
813dabb9
L
13189 uncompressed_size = chdr.ch_size;
13190 start += compression_header_size;
13191 new_size -= compression_header_size;
0e602686
NC
13192 }
13193 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13194 {
13195 /* Read the zlib header. In this case, it should be "ZLIB"
13196 followed by the uncompressed section size, 8 bytes in
13197 big-endian order. */
13198 uncompressed_size = start[4]; uncompressed_size <<= 8;
13199 uncompressed_size += start[5]; uncompressed_size <<= 8;
13200 uncompressed_size += start[6]; uncompressed_size <<= 8;
13201 uncompressed_size += start[7]; uncompressed_size <<= 8;
13202 uncompressed_size += start[8]; uncompressed_size <<= 8;
13203 uncompressed_size += start[9]; uncompressed_size <<= 8;
13204 uncompressed_size += start[10]; uncompressed_size <<= 8;
13205 uncompressed_size += start[11];
13206 start += 12;
13207 new_size -= 12;
13208 }
13209
1835f746
NC
13210 if (uncompressed_size)
13211 {
13212 if (uncompress_section_contents (& start,
13213 uncompressed_size, & new_size))
13214 num_bytes = new_size;
13215 else
13216 {
13217 error (_("Unable to decompress section %s\n"),
dda8d76d 13218 printable_section_name (filedata, section));
32ec8896 13219 return FALSE;
1835f746
NC
13220 }
13221 }
bc303e5d
NC
13222 else
13223 start = real_start;
0e602686 13224 }
fd8008d8 13225
cf13d699
NC
13226 /* If the section being dumped has relocations against it the user might
13227 be expecting these relocations to have been applied. Check for this
13228 case and issue a warning message in order to avoid confusion.
13229 FIXME: Maybe we ought to have an option that dumps a section with
13230 relocs applied ? */
dda8d76d
NC
13231 for (relsec = filedata->section_headers;
13232 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13233 ++relsec)
13234 {
13235 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13236 || relsec->sh_info >= filedata->file_header.e_shnum
13237 || filedata->section_headers + relsec->sh_info != section
cf13d699 13238 || relsec->sh_size == 0
dda8d76d 13239 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13240 continue;
13241
13242 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13243 break;
13244 }
13245
cf13d699
NC
13246 data = start;
13247 end = start + num_bytes;
13248 some_strings_shown = FALSE;
13249
13250 while (data < end)
13251 {
13252 while (!ISPRINT (* data))
13253 if (++ data >= end)
13254 break;
13255
13256 if (data < end)
13257 {
071436c6
NC
13258 size_t maxlen = end - data;
13259
cf13d699 13260#ifndef __MSVCRT__
c975cc98
NC
13261 /* PR 11128: Use two separate invocations in order to work
13262 around bugs in the Solaris 8 implementation of printf. */
13263 printf (" [%6tx] ", data - start);
cf13d699 13264#else
071436c6 13265 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 13266#endif
4082ef84
NC
13267 if (maxlen > 0)
13268 {
fd8008d8 13269 print_symbol ((int) maxlen, (const char *) data);
4082ef84 13270 putchar ('\n');
fd8008d8 13271 data += strnlen ((const char *) data, maxlen);
4082ef84
NC
13272 }
13273 else
13274 {
13275 printf (_("<corrupt>\n"));
13276 data = end;
13277 }
cf13d699
NC
13278 some_strings_shown = TRUE;
13279 }
13280 }
13281
13282 if (! some_strings_shown)
13283 printf (_(" No strings found in this section."));
13284
0e602686 13285 free (real_start);
cf13d699
NC
13286
13287 putchar ('\n');
32ec8896 13288 return TRUE;
cf13d699
NC
13289}
13290
32ec8896 13291static bfd_boolean
dda8d76d
NC
13292dump_section_as_bytes (Elf_Internal_Shdr * section,
13293 Filedata * filedata,
13294 bfd_boolean relocate)
cf13d699
NC
13295{
13296 Elf_Internal_Shdr * relsec;
0e602686
NC
13297 bfd_size_type bytes;
13298 bfd_size_type section_size;
13299 bfd_vma addr;
13300 unsigned char * data;
13301 unsigned char * real_start;
13302 unsigned char * start;
13303
dda8d76d 13304 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13305 if (start == NULL)
c6b78c96
NC
13306 /* PR 21820: Do not fail if the section was empty. */
13307 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 13308
0e602686 13309 section_size = section->sh_size;
cf13d699 13310
dda8d76d 13311 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13312
0e602686
NC
13313 if (decompress_dumps)
13314 {
13315 dwarf_size_type new_size = section_size;
13316 dwarf_size_type uncompressed_size = 0;
13317
13318 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13319 {
13320 Elf_Internal_Chdr chdr;
13321 unsigned int compression_header_size
ebdf1ebf 13322 = get_compression_header (& chdr, start, section_size);
0e602686 13323
813dabb9 13324 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13325 {
813dabb9 13326 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13327 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13328 return FALSE;
0e602686 13329 }
813dabb9
L
13330 else if (chdr.ch_addralign != section->sh_addralign)
13331 {
13332 warn (_("compressed section '%s' is corrupted\n"),
dda8d76d 13333 printable_section_name (filedata, section));
32ec8896 13334 return FALSE;
813dabb9
L
13335 }
13336 uncompressed_size = chdr.ch_size;
13337 start += compression_header_size;
13338 new_size -= compression_header_size;
0e602686
NC
13339 }
13340 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13341 {
13342 /* Read the zlib header. In this case, it should be "ZLIB"
13343 followed by the uncompressed section size, 8 bytes in
13344 big-endian order. */
13345 uncompressed_size = start[4]; uncompressed_size <<= 8;
13346 uncompressed_size += start[5]; uncompressed_size <<= 8;
13347 uncompressed_size += start[6]; uncompressed_size <<= 8;
13348 uncompressed_size += start[7]; uncompressed_size <<= 8;
13349 uncompressed_size += start[8]; uncompressed_size <<= 8;
13350 uncompressed_size += start[9]; uncompressed_size <<= 8;
13351 uncompressed_size += start[10]; uncompressed_size <<= 8;
13352 uncompressed_size += start[11];
13353 start += 12;
13354 new_size -= 12;
13355 }
13356
f055032e
NC
13357 if (uncompressed_size)
13358 {
13359 if (uncompress_section_contents (& start, uncompressed_size,
13360 & new_size))
bc303e5d
NC
13361 {
13362 section_size = new_size;
13363 }
f055032e
NC
13364 else
13365 {
13366 error (_("Unable to decompress section %s\n"),
dda8d76d 13367 printable_section_name (filedata, section));
bc303e5d 13368 /* FIXME: Print the section anyway ? */
32ec8896 13369 return FALSE;
f055032e
NC
13370 }
13371 }
bc303e5d
NC
13372 else
13373 start = real_start;
0e602686 13374 }
14ae95f2 13375
cf13d699
NC
13376 if (relocate)
13377 {
dda8d76d 13378 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
32ec8896 13379 return FALSE;
cf13d699
NC
13380 }
13381 else
13382 {
13383 /* If the section being dumped has relocations against it the user might
13384 be expecting these relocations to have been applied. Check for this
13385 case and issue a warning message in order to avoid confusion.
13386 FIXME: Maybe we ought to have an option that dumps a section with
13387 relocs applied ? */
dda8d76d
NC
13388 for (relsec = filedata->section_headers;
13389 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13390 ++relsec)
13391 {
13392 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13393 || relsec->sh_info >= filedata->file_header.e_shnum
13394 || filedata->section_headers + relsec->sh_info != section
cf13d699 13395 || relsec->sh_size == 0
dda8d76d 13396 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13397 continue;
13398
13399 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13400 break;
13401 }
13402 }
13403
13404 addr = section->sh_addr;
0e602686 13405 bytes = section_size;
cf13d699
NC
13406 data = start;
13407
13408 while (bytes)
13409 {
13410 int j;
13411 int k;
13412 int lbytes;
13413
13414 lbytes = (bytes > 16 ? 16 : bytes);
13415
13416 printf (" 0x%8.8lx ", (unsigned long) addr);
13417
13418 for (j = 0; j < 16; j++)
13419 {
13420 if (j < lbytes)
13421 printf ("%2.2x", data[j]);
13422 else
13423 printf (" ");
13424
13425 if ((j & 3) == 3)
13426 printf (" ");
13427 }
13428
13429 for (j = 0; j < lbytes; j++)
13430 {
13431 k = data[j];
13432 if (k >= ' ' && k < 0x7f)
13433 printf ("%c", k);
13434 else
13435 printf (".");
13436 }
13437
13438 putchar ('\n');
13439
13440 data += lbytes;
13441 addr += lbytes;
13442 bytes -= lbytes;
13443 }
13444
0e602686 13445 free (real_start);
cf13d699
NC
13446
13447 putchar ('\n');
32ec8896 13448 return TRUE;
cf13d699
NC
13449}
13450
32ec8896 13451static bfd_boolean
dda8d76d
NC
13452load_specific_debug_section (enum dwarf_section_display_enum debug,
13453 const Elf_Internal_Shdr * sec,
13454 void * data)
1007acb3 13455{
2cf0635d 13456 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 13457 char buf [64];
dda8d76d
NC
13458 Filedata * filedata = (Filedata *) data;
13459
19e6b90e 13460 if (section->start != NULL)
dda8d76d
NC
13461 {
13462 /* If it is already loaded, do nothing. */
13463 if (streq (section->filename, filedata->file_name))
13464 return TRUE;
13465 free (section->start);
13466 }
1007acb3 13467
19e6b90e
L
13468 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
13469 section->address = sec->sh_addr;
06614111 13470 section->user_data = NULL;
dda8d76d
NC
13471 section->filename = filedata->file_name;
13472 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
13473 sec->sh_offset, 1,
13474 sec->sh_size, buf);
59245841
NC
13475 if (section->start == NULL)
13476 section->size = 0;
13477 else
13478 {
77115a4a
L
13479 unsigned char *start = section->start;
13480 dwarf_size_type size = sec->sh_size;
dab394de 13481 dwarf_size_type uncompressed_size = 0;
77115a4a
L
13482
13483 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
13484 {
13485 Elf_Internal_Chdr chdr;
d8024a91
NC
13486 unsigned int compression_header_size;
13487
f53be977
L
13488 if (size < (is_32bit_elf
13489 ? sizeof (Elf32_External_Chdr)
13490 : sizeof (Elf64_External_Chdr)))
d8024a91
NC
13491 {
13492 warn (_("compressed section %s is too small to contain a compression header"),
13493 section->name);
32ec8896 13494 return FALSE;
d8024a91
NC
13495 }
13496
ebdf1ebf 13497 compression_header_size = get_compression_header (&chdr, start, size);
d8024a91 13498
813dabb9
L
13499 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
13500 {
13501 warn (_("section '%s' has unsupported compress type: %d\n"),
13502 section->name, chdr.ch_type);
32ec8896 13503 return FALSE;
813dabb9
L
13504 }
13505 else if (chdr.ch_addralign != sec->sh_addralign)
13506 {
13507 warn (_("compressed section '%s' is corrupted\n"),
13508 section->name);
32ec8896 13509 return FALSE;
813dabb9 13510 }
dab394de 13511 uncompressed_size = chdr.ch_size;
77115a4a
L
13512 start += compression_header_size;
13513 size -= compression_header_size;
13514 }
dab394de
L
13515 else if (size > 12 && streq ((char *) start, "ZLIB"))
13516 {
13517 /* Read the zlib header. In this case, it should be "ZLIB"
13518 followed by the uncompressed section size, 8 bytes in
13519 big-endian order. */
13520 uncompressed_size = start[4]; uncompressed_size <<= 8;
13521 uncompressed_size += start[5]; uncompressed_size <<= 8;
13522 uncompressed_size += start[6]; uncompressed_size <<= 8;
13523 uncompressed_size += start[7]; uncompressed_size <<= 8;
13524 uncompressed_size += start[8]; uncompressed_size <<= 8;
13525 uncompressed_size += start[9]; uncompressed_size <<= 8;
13526 uncompressed_size += start[10]; uncompressed_size <<= 8;
13527 uncompressed_size += start[11];
13528 start += 12;
13529 size -= 12;
13530 }
13531
1835f746 13532 if (uncompressed_size)
77115a4a 13533 {
1835f746
NC
13534 if (uncompress_section_contents (&start, uncompressed_size,
13535 &size))
13536 {
13537 /* Free the compressed buffer, update the section buffer
13538 and the section size if uncompress is successful. */
13539 free (section->start);
13540 section->start = start;
13541 }
13542 else
13543 {
13544 error (_("Unable to decompress section %s\n"),
dda8d76d 13545 printable_section_name (filedata, sec));
32ec8896 13546 return FALSE;
1835f746 13547 }
77115a4a 13548 }
bc303e5d 13549
77115a4a 13550 section->size = size;
59245841 13551 }
4a114e3e 13552
1b315056 13553 if (section->start == NULL)
32ec8896 13554 return FALSE;
1b315056 13555
19e6b90e 13556 if (debug_displays [debug].relocate)
32ec8896 13557 {
dda8d76d 13558 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
13559 & section->reloc_info, & section->num_relocs))
13560 return FALSE;
13561 }
d1c4b12b
NC
13562 else
13563 {
13564 section->reloc_info = NULL;
13565 section->num_relocs = 0;
13566 }
1007acb3 13567
32ec8896 13568 return TRUE;
1007acb3
L
13569}
13570
657d0d47
CC
13571/* If this is not NULL, load_debug_section will only look for sections
13572 within the list of sections given here. */
32ec8896 13573static unsigned int * section_subset = NULL;
657d0d47 13574
32ec8896 13575bfd_boolean
dda8d76d 13576load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 13577{
2cf0635d
NC
13578 struct dwarf_section * section = &debug_displays [debug].section;
13579 Elf_Internal_Shdr * sec;
dda8d76d
NC
13580 Filedata * filedata = (Filedata *) data;
13581
f425ec66
NC
13582 /* Without section headers we cannot find any sections. */
13583 if (filedata->section_headers == NULL)
13584 return FALSE;
13585
9c1ce108
AM
13586 if (filedata->string_table == NULL
13587 && filedata->file_header.e_shstrndx != SHN_UNDEF
13588 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
13589 {
13590 Elf_Internal_Shdr * strs;
13591
13592 /* Read in the string table, so that we have section names to scan. */
13593 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
13594
4dff97b2 13595 if (strs != NULL && strs->sh_size != 0)
dda8d76d 13596 {
9c1ce108
AM
13597 filedata->string_table
13598 = (char *) get_data (NULL, filedata, strs->sh_offset,
13599 1, strs->sh_size, _("string table"));
dda8d76d 13600
9c1ce108
AM
13601 filedata->string_table_length
13602 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
13603 }
13604 }
d966045b
DJ
13605
13606 /* Locate the debug section. */
dda8d76d 13607 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
13608 if (sec != NULL)
13609 section->name = section->uncompressed_name;
13610 else
13611 {
dda8d76d 13612 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
13613 if (sec != NULL)
13614 section->name = section->compressed_name;
13615 }
13616 if (sec == NULL)
32ec8896 13617 return FALSE;
d966045b 13618
657d0d47
CC
13619 /* If we're loading from a subset of sections, and we've loaded
13620 a section matching this name before, it's likely that it's a
13621 different one. */
13622 if (section_subset != NULL)
13623 free_debug_section (debug);
13624
dda8d76d 13625 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
13626}
13627
19e6b90e
L
13628void
13629free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 13630{
2cf0635d 13631 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 13632
19e6b90e
L
13633 if (section->start == NULL)
13634 return;
1007acb3 13635
19e6b90e
L
13636 free ((char *) section->start);
13637 section->start = NULL;
13638 section->address = 0;
13639 section->size = 0;
1007acb3
L
13640}
13641
32ec8896 13642static bfd_boolean
dda8d76d 13643display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 13644{
2cf0635d 13645 char * name = SECTION_NAME (section);
dda8d76d 13646 const char * print_name = printable_section_name (filedata, section);
19e6b90e 13647 bfd_size_type length;
32ec8896 13648 bfd_boolean result = TRUE;
3f5e193b 13649 int i;
1007acb3 13650
19e6b90e
L
13651 length = section->sh_size;
13652 if (length == 0)
1007acb3 13653 {
74e1a04b 13654 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 13655 return TRUE;
1007acb3 13656 }
5dff79d8
NC
13657 if (section->sh_type == SHT_NOBITS)
13658 {
13659 /* There is no point in dumping the contents of a debugging section
13660 which has the NOBITS type - the bits in the file will be random.
13661 This can happen when a file containing a .eh_frame section is
13662 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
13663 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
13664 print_name);
32ec8896 13665 return FALSE;
5dff79d8 13666 }
1007acb3 13667
0112cd26 13668 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 13669 name = ".debug_info";
1007acb3 13670
19e6b90e
L
13671 /* See if we know how to display the contents of this section. */
13672 for (i = 0; i < max; i++)
d85bf2ba
NC
13673 {
13674 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
13675 struct dwarf_section_display * display = debug_displays + i;
13676 struct dwarf_section * sec = & display->section;
d966045b 13677
d85bf2ba
NC
13678 if (streq (sec->uncompressed_name, name)
13679 || (id == line && const_strneq (name, ".debug_line."))
13680 || streq (sec->compressed_name, name))
13681 {
13682 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 13683
d85bf2ba
NC
13684 if (secondary)
13685 free_debug_section (id);
dda8d76d 13686
d85bf2ba
NC
13687 if (i == line && const_strneq (name, ".debug_line."))
13688 sec->name = name;
13689 else if (streq (sec->uncompressed_name, name))
13690 sec->name = sec->uncompressed_name;
13691 else
13692 sec->name = sec->compressed_name;
657d0d47 13693
d85bf2ba
NC
13694 if (load_specific_debug_section (id, section, filedata))
13695 {
13696 /* If this debug section is part of a CU/TU set in a .dwp file,
13697 restrict load_debug_section to the sections in that set. */
13698 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 13699
d85bf2ba 13700 result &= display->display (sec, filedata);
657d0d47 13701
d85bf2ba 13702 section_subset = NULL;
1007acb3 13703
d85bf2ba
NC
13704 if (secondary || (id != info && id != abbrev))
13705 free_debug_section (id);
13706 }
13707 break;
13708 }
13709 }
1007acb3 13710
19e6b90e 13711 if (i == max)
1007acb3 13712 {
74e1a04b 13713 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 13714 result = FALSE;
1007acb3
L
13715 }
13716
19e6b90e 13717 return result;
5b18a4bc 13718}
103f02d3 13719
aef1f6d0
DJ
13720/* Set DUMP_SECTS for all sections where dumps were requested
13721 based on section name. */
13722
13723static void
dda8d76d 13724initialise_dumps_byname (Filedata * filedata)
aef1f6d0 13725{
2cf0635d 13726 struct dump_list_entry * cur;
aef1f6d0
DJ
13727
13728 for (cur = dump_sects_byname; cur; cur = cur->next)
13729 {
13730 unsigned int i;
32ec8896 13731 bfd_boolean any = FALSE;
aef1f6d0 13732
dda8d76d
NC
13733 for (i = 0; i < filedata->file_header.e_shnum; i++)
13734 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 13735 {
dda8d76d 13736 request_dump_bynumber (filedata, i, cur->type);
32ec8896 13737 any = TRUE;
aef1f6d0
DJ
13738 }
13739
13740 if (!any)
13741 warn (_("Section '%s' was not dumped because it does not exist!\n"),
13742 cur->name);
13743 }
13744}
13745
32ec8896 13746static bfd_boolean
dda8d76d 13747process_section_contents (Filedata * filedata)
5b18a4bc 13748{
2cf0635d 13749 Elf_Internal_Shdr * section;
19e6b90e 13750 unsigned int i;
32ec8896 13751 bfd_boolean res = TRUE;
103f02d3 13752
19e6b90e 13753 if (! do_dump)
32ec8896 13754 return TRUE;
103f02d3 13755
dda8d76d 13756 initialise_dumps_byname (filedata);
aef1f6d0 13757
dda8d76d
NC
13758 for (i = 0, section = filedata->section_headers;
13759 i < filedata->file_header.e_shnum && i < filedata->num_dump_sects;
19e6b90e
L
13760 i++, section++)
13761 {
dda8d76d
NC
13762 dump_type dump = filedata->dump_sects[i];
13763
19e6b90e 13764#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
13765 if (dump & DISASS_DUMP)
13766 {
13767 if (! disassemble_section (section, filedata))
13768 res = FALSE;
13769 }
19e6b90e 13770#endif
dda8d76d 13771 if (dump & HEX_DUMP)
32ec8896 13772 {
dda8d76d 13773 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
13774 res = FALSE;
13775 }
103f02d3 13776
dda8d76d 13777 if (dump & RELOC_DUMP)
32ec8896 13778 {
dda8d76d 13779 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
13780 res = FALSE;
13781 }
09c11c86 13782
dda8d76d 13783 if (dump & STRING_DUMP)
32ec8896 13784 {
dda8d76d 13785 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
13786 res = FALSE;
13787 }
cf13d699 13788
dda8d76d 13789 if (dump & DEBUG_DUMP)
32ec8896 13790 {
dda8d76d 13791 if (! display_debug_section (i, section, filedata))
32ec8896
NC
13792 res = FALSE;
13793 }
5b18a4bc 13794 }
103f02d3 13795
19e6b90e
L
13796 /* Check to see if the user requested a
13797 dump of a section that does not exist. */
dda8d76d 13798 while (i < filedata->num_dump_sects)
0ee3043f 13799 {
dda8d76d 13800 if (filedata->dump_sects[i])
32ec8896
NC
13801 {
13802 warn (_("Section %d was not dumped because it does not exist!\n"), i);
13803 res = FALSE;
13804 }
0ee3043f
NC
13805 i++;
13806 }
32ec8896
NC
13807
13808 return res;
5b18a4bc 13809}
103f02d3 13810
5b18a4bc 13811static void
19e6b90e 13812process_mips_fpe_exception (int mask)
5b18a4bc 13813{
19e6b90e
L
13814 if (mask)
13815 {
32ec8896
NC
13816 bfd_boolean first = TRUE;
13817
19e6b90e 13818 if (mask & OEX_FPU_INEX)
32ec8896 13819 fputs ("INEX", stdout), first = FALSE;
19e6b90e 13820 if (mask & OEX_FPU_UFLO)
32ec8896 13821 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 13822 if (mask & OEX_FPU_OFLO)
32ec8896 13823 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 13824 if (mask & OEX_FPU_DIV0)
32ec8896 13825 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
13826 if (mask & OEX_FPU_INVAL)
13827 printf ("%sINVAL", first ? "" : "|");
13828 }
5b18a4bc 13829 else
19e6b90e 13830 fputs ("0", stdout);
5b18a4bc 13831}
103f02d3 13832
f6f0e17b
NC
13833/* Display's the value of TAG at location P. If TAG is
13834 greater than 0 it is assumed to be an unknown tag, and
13835 a message is printed to this effect. Otherwise it is
13836 assumed that a message has already been printed.
13837
13838 If the bottom bit of TAG is set it assumed to have a
13839 string value, otherwise it is assumed to have an integer
13840 value.
13841
13842 Returns an updated P pointing to the first unread byte
13843 beyond the end of TAG's value.
13844
13845 Reads at or beyond END will not be made. */
13846
13847static unsigned char *
60abdbed 13848display_tag_value (signed int tag,
f6f0e17b
NC
13849 unsigned char * p,
13850 const unsigned char * const end)
13851{
13852 unsigned long val;
13853
13854 if (tag > 0)
13855 printf (" Tag_unknown_%d: ", tag);
13856
13857 if (p >= end)
13858 {
4082ef84 13859 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
13860 }
13861 else if (tag & 1)
13862 {
071436c6
NC
13863 /* PR 17531 file: 027-19978-0.004. */
13864 size_t maxlen = (end - p) - 1;
13865
13866 putchar ('"');
4082ef84
NC
13867 if (maxlen > 0)
13868 {
13869 print_symbol ((int) maxlen, (const char *) p);
13870 p += strnlen ((char *) p, maxlen) + 1;
13871 }
13872 else
13873 {
13874 printf (_("<corrupt string tag>"));
13875 p = (unsigned char *) end;
13876 }
071436c6 13877 printf ("\"\n");
f6f0e17b
NC
13878 }
13879 else
13880 {
13881 unsigned int len;
13882
13883 val = read_uleb128 (p, &len, end);
13884 p += len;
13885 printf ("%ld (0x%lx)\n", val, val);
13886 }
13887
4082ef84 13888 assert (p <= end);
f6f0e17b
NC
13889 return p;
13890}
13891
53a346d8
CZ
13892/* ARC ABI attributes section. */
13893
13894static unsigned char *
13895display_arc_attribute (unsigned char * p,
13896 const unsigned char * const end)
13897{
13898 unsigned int tag;
13899 unsigned int len;
13900 unsigned int val;
13901
13902 tag = read_uleb128 (p, &len, end);
13903 p += len;
13904
13905 switch (tag)
13906 {
13907 case Tag_ARC_PCS_config:
13908 val = read_uleb128 (p, &len, end);
13909 p += len;
13910 printf (" Tag_ARC_PCS_config: ");
13911 switch (val)
13912 {
13913 case 0:
13914 printf (_("Absent/Non standard\n"));
13915 break;
13916 case 1:
13917 printf (_("Bare metal/mwdt\n"));
13918 break;
13919 case 2:
13920 printf (_("Bare metal/newlib\n"));
13921 break;
13922 case 3:
13923 printf (_("Linux/uclibc\n"));
13924 break;
13925 case 4:
13926 printf (_("Linux/glibc\n"));
13927 break;
13928 default:
13929 printf (_("Unknown\n"));
13930 break;
13931 }
13932 break;
13933
13934 case Tag_ARC_CPU_base:
13935 val = read_uleb128 (p, &len, end);
13936 p += len;
13937 printf (" Tag_ARC_CPU_base: ");
13938 switch (val)
13939 {
13940 default:
13941 case TAG_CPU_NONE:
13942 printf (_("Absent\n"));
13943 break;
13944 case TAG_CPU_ARC6xx:
13945 printf ("ARC6xx\n");
13946 break;
13947 case TAG_CPU_ARC7xx:
13948 printf ("ARC7xx\n");
13949 break;
13950 case TAG_CPU_ARCEM:
13951 printf ("ARCEM\n");
13952 break;
13953 case TAG_CPU_ARCHS:
13954 printf ("ARCHS\n");
13955 break;
13956 }
13957 break;
13958
13959 case Tag_ARC_CPU_variation:
13960 val = read_uleb128 (p, &len, end);
13961 p += len;
13962 printf (" Tag_ARC_CPU_variation: ");
13963 switch (val)
13964 {
13965 default:
13966 if (val > 0 && val < 16)
53a346d8 13967 printf ("Core%d\n", val);
d8cbc93b
JL
13968 else
13969 printf ("Unknown\n");
13970 break;
13971
53a346d8
CZ
13972 case 0:
13973 printf (_("Absent\n"));
13974 break;
13975 }
13976 break;
13977
13978 case Tag_ARC_CPU_name:
13979 printf (" Tag_ARC_CPU_name: ");
13980 p = display_tag_value (-1, p, end);
13981 break;
13982
13983 case Tag_ARC_ABI_rf16:
13984 val = read_uleb128 (p, &len, end);
13985 p += len;
13986 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
13987 break;
13988
13989 case Tag_ARC_ABI_osver:
13990 val = read_uleb128 (p, &len, end);
13991 p += len;
13992 printf (" Tag_ARC_ABI_osver: v%d\n", val);
13993 break;
13994
13995 case Tag_ARC_ABI_pic:
13996 case Tag_ARC_ABI_sda:
13997 val = read_uleb128 (p, &len, end);
13998 p += len;
13999 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
14000 : " Tag_ARC_ABI_pic: ");
14001 switch (val)
14002 {
14003 case 0:
14004 printf (_("Absent\n"));
14005 break;
14006 case 1:
14007 printf ("MWDT\n");
14008 break;
14009 case 2:
14010 printf ("GNU\n");
14011 break;
14012 default:
14013 printf (_("Unknown\n"));
14014 break;
14015 }
14016 break;
14017
14018 case Tag_ARC_ABI_tls:
14019 val = read_uleb128 (p, &len, end);
14020 p += len;
14021 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
14022 break;
14023
14024 case Tag_ARC_ABI_enumsize:
14025 val = read_uleb128 (p, &len, end);
14026 p += len;
14027 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
14028 _("smallest"));
14029 break;
14030
14031 case Tag_ARC_ABI_exceptions:
14032 val = read_uleb128 (p, &len, end);
14033 p += len;
14034 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
14035 : _("default"));
14036 break;
14037
14038 case Tag_ARC_ABI_double_size:
14039 val = read_uleb128 (p, &len, end);
14040 p += len;
14041 printf (" Tag_ARC_ABI_double_size: %d\n", val);
14042 break;
14043
14044 case Tag_ARC_ISA_config:
14045 printf (" Tag_ARC_ISA_config: ");
14046 p = display_tag_value (-1, p, end);
14047 break;
14048
14049 case Tag_ARC_ISA_apex:
14050 printf (" Tag_ARC_ISA_apex: ");
14051 p = display_tag_value (-1, p, end);
14052 break;
14053
14054 case Tag_ARC_ISA_mpy_option:
14055 val = read_uleb128 (p, &len, end);
14056 p += len;
14057 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
14058 break;
14059
14060 default:
14061 return display_tag_value (tag & 1, p, end);
14062 }
14063
14064 return p;
14065}
14066
11c1ff18
PB
14067/* ARM EABI attributes section. */
14068typedef struct
14069{
70e99720 14070 unsigned int tag;
2cf0635d 14071 const char * name;
11c1ff18 14072 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 14073 unsigned int type;
2cf0635d 14074 const char ** table;
11c1ff18
PB
14075} arm_attr_public_tag;
14076
2cf0635d 14077static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 14078 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 14079 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
ff8646ee 14080 "v8-M.mainline"};
2cf0635d
NC
14081static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
14082static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 14083 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 14084static const char * arm_attr_tag_FP_arch[] =
bca38921 14085 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 14086 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 14087static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 14088static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
14089 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
14090 "NEON for ARMv8.1"};
2cf0635d 14091static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
14092 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
14093 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 14094static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 14095 {"V6", "SB", "TLS", "Unused"};
2cf0635d 14096static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 14097 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 14098static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 14099 {"Absolute", "PC-relative", "None"};
2cf0635d 14100static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 14101 {"None", "direct", "GOT-indirect"};
2cf0635d 14102static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 14103 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
14104static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
14105static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 14106 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
14107static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
14108static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
14109static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 14110 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 14111static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 14112 {"Unused", "small", "int", "forced to int"};
2cf0635d 14113static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 14114 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 14115static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 14116 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 14117static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 14118 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 14119static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
14120 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14121 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 14122static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
14123 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14124 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 14125static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 14126static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 14127 {"Not Allowed", "Allowed"};
2cf0635d 14128static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 14129 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
14130static const char * arm_attr_tag_DSP_extension[] =
14131 {"Follow architecture", "Allowed"};
dd24e3da 14132static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
14133 {"Not Allowed", "Allowed"};
14134static const char * arm_attr_tag_DIV_use[] =
dd24e3da 14135 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 14136 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
14137static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
14138static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 14139 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 14140 "TrustZone and Virtualization Extensions"};
dd24e3da 14141static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 14142 {"Not Allowed", "Allowed"};
11c1ff18
PB
14143
14144#define LOOKUP(id, name) \
14145 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 14146static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
14147{
14148 {4, "CPU_raw_name", 1, NULL},
14149 {5, "CPU_name", 1, NULL},
14150 LOOKUP(6, CPU_arch),
14151 {7, "CPU_arch_profile", 0, NULL},
14152 LOOKUP(8, ARM_ISA_use),
14153 LOOKUP(9, THUMB_ISA_use),
75375b3e 14154 LOOKUP(10, FP_arch),
11c1ff18 14155 LOOKUP(11, WMMX_arch),
f5f53991
AS
14156 LOOKUP(12, Advanced_SIMD_arch),
14157 LOOKUP(13, PCS_config),
11c1ff18
PB
14158 LOOKUP(14, ABI_PCS_R9_use),
14159 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 14160 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
14161 LOOKUP(17, ABI_PCS_GOT_use),
14162 LOOKUP(18, ABI_PCS_wchar_t),
14163 LOOKUP(19, ABI_FP_rounding),
14164 LOOKUP(20, ABI_FP_denormal),
14165 LOOKUP(21, ABI_FP_exceptions),
14166 LOOKUP(22, ABI_FP_user_exceptions),
14167 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
14168 {24, "ABI_align_needed", 0, NULL},
14169 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
14170 LOOKUP(26, ABI_enum_size),
14171 LOOKUP(27, ABI_HardFP_use),
14172 LOOKUP(28, ABI_VFP_args),
14173 LOOKUP(29, ABI_WMMX_args),
14174 LOOKUP(30, ABI_optimization_goals),
14175 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 14176 {32, "compatibility", 0, NULL},
f5f53991 14177 LOOKUP(34, CPU_unaligned_access),
75375b3e 14178 LOOKUP(36, FP_HP_extension),
8e79c3df 14179 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
14180 LOOKUP(42, MPextension_use),
14181 LOOKUP(44, DIV_use),
15afaa63 14182 LOOKUP(46, DSP_extension),
f5f53991
AS
14183 {64, "nodefaults", 0, NULL},
14184 {65, "also_compatible_with", 0, NULL},
14185 LOOKUP(66, T2EE_use),
14186 {67, "conformance", 1, NULL},
14187 LOOKUP(68, Virtualization_use),
cd21e546 14188 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
14189};
14190#undef LOOKUP
14191
11c1ff18 14192static unsigned char *
f6f0e17b
NC
14193display_arm_attribute (unsigned char * p,
14194 const unsigned char * const end)
11c1ff18 14195{
70e99720 14196 unsigned int tag;
11c1ff18 14197 unsigned int len;
70e99720 14198 unsigned int val;
2cf0635d 14199 arm_attr_public_tag * attr;
11c1ff18 14200 unsigned i;
70e99720 14201 unsigned int type;
11c1ff18 14202
f6f0e17b 14203 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
14204 p += len;
14205 attr = NULL;
2cf0635d 14206 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
14207 {
14208 if (arm_attr_public_tags[i].tag == tag)
14209 {
14210 attr = &arm_attr_public_tags[i];
14211 break;
14212 }
14213 }
14214
14215 if (attr)
14216 {
14217 printf (" Tag_%s: ", attr->name);
14218 switch (attr->type)
14219 {
14220 case 0:
14221 switch (tag)
14222 {
14223 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 14224 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14225 p += len;
14226 switch (val)
14227 {
2b692964
NC
14228 case 0: printf (_("None\n")); break;
14229 case 'A': printf (_("Application\n")); break;
14230 case 'R': printf (_("Realtime\n")); break;
14231 case 'M': printf (_("Microcontroller\n")); break;
14232 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
14233 default: printf ("??? (%d)\n", val); break;
14234 }
14235 break;
14236
75375b3e 14237 case 24: /* Tag_align_needed. */
f6f0e17b 14238 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14239 p += len;
14240 switch (val)
14241 {
2b692964
NC
14242 case 0: printf (_("None\n")); break;
14243 case 1: printf (_("8-byte\n")); break;
14244 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
14245 case 3: printf ("??? 3\n"); break;
14246 default:
14247 if (val <= 12)
dd24e3da 14248 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14249 1 << val);
14250 else
14251 printf ("??? (%d)\n", val);
14252 break;
14253 }
14254 break;
14255
14256 case 25: /* Tag_align_preserved. */
f6f0e17b 14257 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14258 p += len;
14259 switch (val)
14260 {
2b692964
NC
14261 case 0: printf (_("None\n")); break;
14262 case 1: printf (_("8-byte, except leaf SP\n")); break;
14263 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
14264 case 3: printf ("??? 3\n"); break;
14265 default:
14266 if (val <= 12)
dd24e3da 14267 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14268 1 << val);
14269 else
14270 printf ("??? (%d)\n", val);
14271 break;
14272 }
14273 break;
14274
11c1ff18 14275 case 32: /* Tag_compatibility. */
071436c6 14276 {
071436c6
NC
14277 val = read_uleb128 (p, &len, end);
14278 p += len;
071436c6 14279 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
14280 if (p < end - 1)
14281 {
14282 size_t maxlen = (end - p) - 1;
14283
14284 print_symbol ((int) maxlen, (const char *) p);
14285 p += strnlen ((char *) p, maxlen) + 1;
14286 }
14287 else
14288 {
14289 printf (_("<corrupt>"));
14290 p = (unsigned char *) end;
14291 }
071436c6 14292 putchar ('\n');
071436c6 14293 }
11c1ff18
PB
14294 break;
14295
f5f53991 14296 case 64: /* Tag_nodefaults. */
541a3cbd
NC
14297 /* PR 17531: file: 001-505008-0.01. */
14298 if (p < end)
14299 p++;
2b692964 14300 printf (_("True\n"));
f5f53991
AS
14301 break;
14302
14303 case 65: /* Tag_also_compatible_with. */
f6f0e17b 14304 val = read_uleb128 (p, &len, end);
f5f53991
AS
14305 p += len;
14306 if (val == 6 /* Tag_CPU_arch. */)
14307 {
f6f0e17b 14308 val = read_uleb128 (p, &len, end);
f5f53991 14309 p += len;
071436c6 14310 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
14311 printf ("??? (%d)\n", val);
14312 else
14313 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
14314 }
14315 else
14316 printf ("???\n");
071436c6
NC
14317 while (p < end && *(p++) != '\0' /* NUL terminator. */)
14318 ;
f5f53991
AS
14319 break;
14320
11c1ff18 14321 default:
bee0ee85
NC
14322 printf (_("<unknown: %d>\n"), tag);
14323 break;
11c1ff18
PB
14324 }
14325 return p;
14326
14327 case 1:
f6f0e17b 14328 return display_tag_value (-1, p, end);
11c1ff18 14329 case 2:
f6f0e17b 14330 return display_tag_value (0, p, end);
11c1ff18
PB
14331
14332 default:
14333 assert (attr->type & 0x80);
f6f0e17b 14334 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14335 p += len;
14336 type = attr->type & 0x7f;
14337 if (val >= type)
14338 printf ("??? (%d)\n", val);
14339 else
14340 printf ("%s\n", attr->table[val]);
14341 return p;
14342 }
14343 }
11c1ff18 14344
f6f0e17b 14345 return display_tag_value (tag, p, end);
11c1ff18
PB
14346}
14347
104d59d1 14348static unsigned char *
60bca95a 14349display_gnu_attribute (unsigned char * p,
60abdbed 14350 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 14351 const unsigned char * const end)
104d59d1
JM
14352{
14353 int tag;
14354 unsigned int len;
60abdbed 14355 unsigned int val;
104d59d1 14356
f6f0e17b 14357 tag = read_uleb128 (p, &len, end);
104d59d1
JM
14358 p += len;
14359
14360 /* Tag_compatibility is the only generic GNU attribute defined at
14361 present. */
14362 if (tag == 32)
14363 {
f6f0e17b 14364 val = read_uleb128 (p, &len, end);
104d59d1 14365 p += len;
071436c6
NC
14366
14367 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
14368 if (p == end)
14369 {
071436c6 14370 printf (_("<corrupt>\n"));
f6f0e17b
NC
14371 warn (_("corrupt vendor attribute\n"));
14372 }
14373 else
14374 {
4082ef84
NC
14375 if (p < end - 1)
14376 {
14377 size_t maxlen = (end - p) - 1;
071436c6 14378
4082ef84
NC
14379 print_symbol ((int) maxlen, (const char *) p);
14380 p += strnlen ((char *) p, maxlen) + 1;
14381 }
14382 else
14383 {
14384 printf (_("<corrupt>"));
14385 p = (unsigned char *) end;
14386 }
071436c6 14387 putchar ('\n');
f6f0e17b 14388 }
104d59d1
JM
14389 return p;
14390 }
14391
14392 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 14393 return display_proc_gnu_attribute (p, tag, end);
104d59d1 14394
f6f0e17b 14395 return display_tag_value (tag, p, end);
104d59d1
JM
14396}
14397
34c8bcba 14398static unsigned char *
f6f0e17b 14399display_power_gnu_attribute (unsigned char * p,
60abdbed 14400 unsigned int tag,
f6f0e17b 14401 const unsigned char * const end)
34c8bcba 14402{
34c8bcba 14403 unsigned int len;
005d79fd 14404 unsigned int val;
34c8bcba
JM
14405
14406 if (tag == Tag_GNU_Power_ABI_FP)
14407 {
f6f0e17b 14408 val = read_uleb128 (p, &len, end);
34c8bcba
JM
14409 p += len;
14410 printf (" Tag_GNU_Power_ABI_FP: ");
005d79fd
AM
14411 if (len == 0)
14412 {
14413 printf (_("<corrupt>\n"));
14414 return p;
14415 }
60bca95a 14416
005d79fd
AM
14417 if (val > 15)
14418 printf ("(%#x), ", val);
14419
14420 switch (val & 3)
34c8bcba
JM
14421 {
14422 case 0:
005d79fd 14423 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
14424 break;
14425 case 1:
005d79fd 14426 printf (_("hard float, "));
34c8bcba
JM
14427 break;
14428 case 2:
005d79fd 14429 printf (_("soft float, "));
34c8bcba 14430 break;
3c7b9897 14431 case 3:
005d79fd 14432 printf (_("single-precision hard float, "));
3c7b9897 14433 break;
005d79fd
AM
14434 }
14435
14436 switch (val & 0xC)
14437 {
14438 case 0:
14439 printf (_("unspecified long double\n"));
14440 break;
14441 case 4:
14442 printf (_("128-bit IBM long double\n"));
14443 break;
14444 case 8:
14445 printf (_("64-bit long double\n"));
14446 break;
14447 case 12:
14448 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
14449 break;
14450 }
14451 return p;
005d79fd 14452 }
34c8bcba 14453
c6e65352
DJ
14454 if (tag == Tag_GNU_Power_ABI_Vector)
14455 {
f6f0e17b 14456 val = read_uleb128 (p, &len, end);
c6e65352
DJ
14457 p += len;
14458 printf (" Tag_GNU_Power_ABI_Vector: ");
005d79fd
AM
14459 if (len == 0)
14460 {
14461 printf (_("<corrupt>\n"));
14462 return p;
14463 }
14464
14465 if (val > 3)
14466 printf ("(%#x), ", val);
14467
14468 switch (val & 3)
c6e65352
DJ
14469 {
14470 case 0:
005d79fd 14471 printf (_("unspecified\n"));
c6e65352
DJ
14472 break;
14473 case 1:
005d79fd 14474 printf (_("generic\n"));
c6e65352
DJ
14475 break;
14476 case 2:
14477 printf ("AltiVec\n");
14478 break;
14479 case 3:
14480 printf ("SPE\n");
14481 break;
c6e65352
DJ
14482 }
14483 return p;
005d79fd 14484 }
c6e65352 14485
f82e0623
NF
14486 if (tag == Tag_GNU_Power_ABI_Struct_Return)
14487 {
005d79fd
AM
14488 val = read_uleb128 (p, &len, end);
14489 p += len;
14490 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
14491 if (len == 0)
f6f0e17b 14492 {
005d79fd 14493 printf (_("<corrupt>\n"));
f6f0e17b
NC
14494 return p;
14495 }
0b4362b0 14496
005d79fd
AM
14497 if (val > 2)
14498 printf ("(%#x), ", val);
14499
14500 switch (val & 3)
14501 {
14502 case 0:
14503 printf (_("unspecified\n"));
14504 break;
14505 case 1:
14506 printf ("r3/r4\n");
14507 break;
14508 case 2:
14509 printf (_("memory\n"));
14510 break;
14511 case 3:
14512 printf ("???\n");
14513 break;
14514 }
f82e0623
NF
14515 return p;
14516 }
14517
f6f0e17b 14518 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
14519}
14520
643f7afb
AK
14521static unsigned char *
14522display_s390_gnu_attribute (unsigned char * p,
60abdbed 14523 unsigned int tag,
643f7afb
AK
14524 const unsigned char * const end)
14525{
14526 unsigned int len;
14527 int val;
14528
14529 if (tag == Tag_GNU_S390_ABI_Vector)
14530 {
14531 val = read_uleb128 (p, &len, end);
14532 p += len;
14533 printf (" Tag_GNU_S390_ABI_Vector: ");
14534
14535 switch (val)
14536 {
14537 case 0:
14538 printf (_("any\n"));
14539 break;
14540 case 1:
14541 printf (_("software\n"));
14542 break;
14543 case 2:
14544 printf (_("hardware\n"));
14545 break;
14546 default:
14547 printf ("??? (%d)\n", val);
14548 break;
14549 }
14550 return p;
14551 }
14552
14553 return display_tag_value (tag & 1, p, end);
14554}
14555
9e8c70f9 14556static void
60abdbed 14557display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
14558{
14559 if (mask)
14560 {
32ec8896 14561 bfd_boolean first = TRUE;
071436c6 14562
9e8c70f9 14563 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 14564 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 14565 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 14566 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 14567 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 14568 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 14569 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 14570 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 14571 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 14572 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 14573 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 14574 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 14575 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 14576 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 14577 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 14578 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 14579 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 14580 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 14581 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 14582 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 14583 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 14584 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 14585 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 14586 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 14587 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 14588 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 14589 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 14590 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 14591 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 14592 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 14593 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 14594 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
14595 }
14596 else
071436c6
NC
14597 fputc ('0', stdout);
14598 fputc ('\n', stdout);
9e8c70f9
DM
14599}
14600
3d68f91c 14601static void
60abdbed 14602display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
14603{
14604 if (mask)
14605 {
32ec8896 14606 bfd_boolean first = TRUE;
071436c6 14607
3d68f91c 14608 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 14609 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 14610 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 14611 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 14612 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 14613 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 14614 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 14615 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 14616 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 14617 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 14618 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 14619 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 14620 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 14621 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 14622 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 14623 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 14624 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 14625 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 14626 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 14627 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 14628 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 14629 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
14630 }
14631 else
071436c6
NC
14632 fputc ('0', stdout);
14633 fputc ('\n', stdout);
3d68f91c
JM
14634}
14635
9e8c70f9 14636static unsigned char *
f6f0e17b 14637display_sparc_gnu_attribute (unsigned char * p,
60abdbed 14638 unsigned int tag,
f6f0e17b 14639 const unsigned char * const end)
9e8c70f9 14640{
3d68f91c
JM
14641 unsigned int len;
14642 int val;
14643
9e8c70f9
DM
14644 if (tag == Tag_GNU_Sparc_HWCAPS)
14645 {
f6f0e17b 14646 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
14647 p += len;
14648 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
14649 display_sparc_hwcaps (val);
14650 return p;
3d68f91c
JM
14651 }
14652 if (tag == Tag_GNU_Sparc_HWCAPS2)
14653 {
14654 val = read_uleb128 (p, &len, end);
14655 p += len;
14656 printf (" Tag_GNU_Sparc_HWCAPS2: ");
14657 display_sparc_hwcaps2 (val);
14658 return p;
14659 }
9e8c70f9 14660
f6f0e17b 14661 return display_tag_value (tag, p, end);
9e8c70f9
DM
14662}
14663
351cdf24 14664static void
32ec8896 14665print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
14666{
14667 switch (val)
14668 {
14669 case Val_GNU_MIPS_ABI_FP_ANY:
14670 printf (_("Hard or soft float\n"));
14671 break;
14672 case Val_GNU_MIPS_ABI_FP_DOUBLE:
14673 printf (_("Hard float (double precision)\n"));
14674 break;
14675 case Val_GNU_MIPS_ABI_FP_SINGLE:
14676 printf (_("Hard float (single precision)\n"));
14677 break;
14678 case Val_GNU_MIPS_ABI_FP_SOFT:
14679 printf (_("Soft float\n"));
14680 break;
14681 case Val_GNU_MIPS_ABI_FP_OLD_64:
14682 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
14683 break;
14684 case Val_GNU_MIPS_ABI_FP_XX:
14685 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
14686 break;
14687 case Val_GNU_MIPS_ABI_FP_64:
14688 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
14689 break;
14690 case Val_GNU_MIPS_ABI_FP_64A:
14691 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
14692 break;
3350cc01
CM
14693 case Val_GNU_MIPS_ABI_FP_NAN2008:
14694 printf (_("NaN 2008 compatibility\n"));
14695 break;
351cdf24
MF
14696 default:
14697 printf ("??? (%d)\n", val);
14698 break;
14699 }
14700}
14701
2cf19d5c 14702static unsigned char *
f6f0e17b 14703display_mips_gnu_attribute (unsigned char * p,
60abdbed 14704 unsigned int tag,
f6f0e17b 14705 const unsigned char * const end)
2cf19d5c 14706{
2cf19d5c
JM
14707 if (tag == Tag_GNU_MIPS_ABI_FP)
14708 {
f6f0e17b 14709 unsigned int len;
32ec8896 14710 unsigned int val;
f6f0e17b
NC
14711
14712 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
14713 p += len;
14714 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 14715
351cdf24
MF
14716 print_mips_fp_abi_value (val);
14717
2cf19d5c
JM
14718 return p;
14719 }
14720
a9f58168
CF
14721 if (tag == Tag_GNU_MIPS_ABI_MSA)
14722 {
14723 unsigned int len;
32ec8896 14724 unsigned int val;
a9f58168
CF
14725
14726 val = read_uleb128 (p, &len, end);
14727 p += len;
14728 printf (" Tag_GNU_MIPS_ABI_MSA: ");
14729
14730 switch (val)
14731 {
14732 case Val_GNU_MIPS_ABI_MSA_ANY:
14733 printf (_("Any MSA or not\n"));
14734 break;
14735 case Val_GNU_MIPS_ABI_MSA_128:
14736 printf (_("128-bit MSA\n"));
14737 break;
14738 default:
14739 printf ("??? (%d)\n", val);
14740 break;
14741 }
14742 return p;
14743 }
14744
f6f0e17b 14745 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
14746}
14747
59e6276b 14748static unsigned char *
f6f0e17b
NC
14749display_tic6x_attribute (unsigned char * p,
14750 const unsigned char * const end)
59e6276b 14751{
60abdbed 14752 unsigned int tag;
59e6276b
JM
14753 unsigned int len;
14754 int val;
14755
f6f0e17b 14756 tag = read_uleb128 (p, &len, end);
59e6276b
JM
14757 p += len;
14758
14759 switch (tag)
14760 {
75fa6dc1 14761 case Tag_ISA:
f6f0e17b 14762 val = read_uleb128 (p, &len, end);
59e6276b 14763 p += len;
75fa6dc1 14764 printf (" Tag_ISA: ");
59e6276b
JM
14765
14766 switch (val)
14767 {
75fa6dc1 14768 case C6XABI_Tag_ISA_none:
59e6276b
JM
14769 printf (_("None\n"));
14770 break;
75fa6dc1 14771 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
14772 printf ("C62x\n");
14773 break;
75fa6dc1 14774 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
14775 printf ("C67x\n");
14776 break;
75fa6dc1 14777 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
14778 printf ("C67x+\n");
14779 break;
75fa6dc1 14780 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
14781 printf ("C64x\n");
14782 break;
75fa6dc1 14783 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
14784 printf ("C64x+\n");
14785 break;
75fa6dc1 14786 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
14787 printf ("C674x\n");
14788 break;
14789 default:
14790 printf ("??? (%d)\n", val);
14791 break;
14792 }
14793 return p;
14794
87779176 14795 case Tag_ABI_wchar_t:
f6f0e17b 14796 val = read_uleb128 (p, &len, end);
87779176
JM
14797 p += len;
14798 printf (" Tag_ABI_wchar_t: ");
14799 switch (val)
14800 {
14801 case 0:
14802 printf (_("Not used\n"));
14803 break;
14804 case 1:
14805 printf (_("2 bytes\n"));
14806 break;
14807 case 2:
14808 printf (_("4 bytes\n"));
14809 break;
14810 default:
14811 printf ("??? (%d)\n", val);
14812 break;
14813 }
14814 return p;
14815
14816 case Tag_ABI_stack_align_needed:
f6f0e17b 14817 val = read_uleb128 (p, &len, end);
87779176
JM
14818 p += len;
14819 printf (" Tag_ABI_stack_align_needed: ");
14820 switch (val)
14821 {
14822 case 0:
14823 printf (_("8-byte\n"));
14824 break;
14825 case 1:
14826 printf (_("16-byte\n"));
14827 break;
14828 default:
14829 printf ("??? (%d)\n", val);
14830 break;
14831 }
14832 return p;
14833
14834 case Tag_ABI_stack_align_preserved:
f6f0e17b 14835 val = read_uleb128 (p, &len, end);
87779176
JM
14836 p += len;
14837 printf (" Tag_ABI_stack_align_preserved: ");
14838 switch (val)
14839 {
14840 case 0:
14841 printf (_("8-byte\n"));
14842 break;
14843 case 1:
14844 printf (_("16-byte\n"));
14845 break;
14846 default:
14847 printf ("??? (%d)\n", val);
14848 break;
14849 }
14850 return p;
14851
b5593623 14852 case Tag_ABI_DSBT:
f6f0e17b 14853 val = read_uleb128 (p, &len, end);
b5593623
JM
14854 p += len;
14855 printf (" Tag_ABI_DSBT: ");
14856 switch (val)
14857 {
14858 case 0:
14859 printf (_("DSBT addressing not used\n"));
14860 break;
14861 case 1:
14862 printf (_("DSBT addressing used\n"));
14863 break;
14864 default:
14865 printf ("??? (%d)\n", val);
14866 break;
14867 }
14868 return p;
14869
87779176 14870 case Tag_ABI_PID:
f6f0e17b 14871 val = read_uleb128 (p, &len, end);
87779176
JM
14872 p += len;
14873 printf (" Tag_ABI_PID: ");
14874 switch (val)
14875 {
14876 case 0:
14877 printf (_("Data addressing position-dependent\n"));
14878 break;
14879 case 1:
14880 printf (_("Data addressing position-independent, GOT near DP\n"));
14881 break;
14882 case 2:
14883 printf (_("Data addressing position-independent, GOT far from DP\n"));
14884 break;
14885 default:
14886 printf ("??? (%d)\n", val);
14887 break;
14888 }
14889 return p;
14890
14891 case Tag_ABI_PIC:
f6f0e17b 14892 val = read_uleb128 (p, &len, end);
87779176
JM
14893 p += len;
14894 printf (" Tag_ABI_PIC: ");
14895 switch (val)
14896 {
14897 case 0:
14898 printf (_("Code addressing position-dependent\n"));
14899 break;
14900 case 1:
14901 printf (_("Code addressing position-independent\n"));
14902 break;
14903 default:
14904 printf ("??? (%d)\n", val);
14905 break;
14906 }
14907 return p;
14908
14909 case Tag_ABI_array_object_alignment:
f6f0e17b 14910 val = read_uleb128 (p, &len, end);
87779176
JM
14911 p += len;
14912 printf (" Tag_ABI_array_object_alignment: ");
14913 switch (val)
14914 {
14915 case 0:
14916 printf (_("8-byte\n"));
14917 break;
14918 case 1:
14919 printf (_("4-byte\n"));
14920 break;
14921 case 2:
14922 printf (_("16-byte\n"));
14923 break;
14924 default:
14925 printf ("??? (%d)\n", val);
14926 break;
14927 }
14928 return p;
14929
14930 case Tag_ABI_array_object_align_expected:
f6f0e17b 14931 val = read_uleb128 (p, &len, end);
87779176
JM
14932 p += len;
14933 printf (" Tag_ABI_array_object_align_expected: ");
14934 switch (val)
14935 {
14936 case 0:
14937 printf (_("8-byte\n"));
14938 break;
14939 case 1:
14940 printf (_("4-byte\n"));
14941 break;
14942 case 2:
14943 printf (_("16-byte\n"));
14944 break;
14945 default:
14946 printf ("??? (%d)\n", val);
14947 break;
14948 }
14949 return p;
14950
3cbd1c06 14951 case Tag_ABI_compatibility:
071436c6 14952 {
071436c6
NC
14953 val = read_uleb128 (p, &len, end);
14954 p += len;
14955 printf (" Tag_ABI_compatibility: ");
071436c6 14956 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
14957 if (p < end - 1)
14958 {
14959 size_t maxlen = (end - p) - 1;
14960
14961 print_symbol ((int) maxlen, (const char *) p);
14962 p += strnlen ((char *) p, maxlen) + 1;
14963 }
14964 else
14965 {
14966 printf (_("<corrupt>"));
14967 p = (unsigned char *) end;
14968 }
071436c6 14969 putchar ('\n');
071436c6
NC
14970 return p;
14971 }
87779176
JM
14972
14973 case Tag_ABI_conformance:
071436c6 14974 {
4082ef84
NC
14975 printf (" Tag_ABI_conformance: \"");
14976 if (p < end - 1)
14977 {
14978 size_t maxlen = (end - p) - 1;
071436c6 14979
4082ef84
NC
14980 print_symbol ((int) maxlen, (const char *) p);
14981 p += strnlen ((char *) p, maxlen) + 1;
14982 }
14983 else
14984 {
14985 printf (_("<corrupt>"));
14986 p = (unsigned char *) end;
14987 }
071436c6 14988 printf ("\"\n");
071436c6
NC
14989 return p;
14990 }
59e6276b
JM
14991 }
14992
f6f0e17b
NC
14993 return display_tag_value (tag, p, end);
14994}
59e6276b 14995
f6f0e17b 14996static void
60abdbed 14997display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
14998{
14999 unsigned long addr = 0;
15000 size_t bytes = end - p;
15001
e0a31db1 15002 assert (end > p);
f6f0e17b 15003 while (bytes)
87779176 15004 {
f6f0e17b
NC
15005 int j;
15006 int k;
15007 int lbytes = (bytes > 16 ? 16 : bytes);
15008
15009 printf (" 0x%8.8lx ", addr);
15010
15011 for (j = 0; j < 16; j++)
15012 {
15013 if (j < lbytes)
15014 printf ("%2.2x", p[j]);
15015 else
15016 printf (" ");
15017
15018 if ((j & 3) == 3)
15019 printf (" ");
15020 }
15021
15022 for (j = 0; j < lbytes; j++)
15023 {
15024 k = p[j];
15025 if (k >= ' ' && k < 0x7f)
15026 printf ("%c", k);
15027 else
15028 printf (".");
15029 }
15030
15031 putchar ('\n');
15032
15033 p += lbytes;
15034 bytes -= lbytes;
15035 addr += lbytes;
87779176 15036 }
59e6276b 15037
f6f0e17b 15038 putchar ('\n');
59e6276b
JM
15039}
15040
13761a11
NC
15041static unsigned char *
15042display_msp430x_attribute (unsigned char * p,
15043 const unsigned char * const end)
15044{
15045 unsigned int len;
60abdbed
NC
15046 unsigned int val;
15047 unsigned int tag;
13761a11
NC
15048
15049 tag = read_uleb128 (p, & len, end);
15050 p += len;
0b4362b0 15051
13761a11
NC
15052 switch (tag)
15053 {
15054 case OFBA_MSPABI_Tag_ISA:
15055 val = read_uleb128 (p, &len, end);
15056 p += len;
15057 printf (" Tag_ISA: ");
15058 switch (val)
15059 {
15060 case 0: printf (_("None\n")); break;
15061 case 1: printf (_("MSP430\n")); break;
15062 case 2: printf (_("MSP430X\n")); break;
15063 default: printf ("??? (%d)\n", val); break;
15064 }
15065 break;
15066
15067 case OFBA_MSPABI_Tag_Code_Model:
15068 val = read_uleb128 (p, &len, end);
15069 p += len;
15070 printf (" Tag_Code_Model: ");
15071 switch (val)
15072 {
15073 case 0: printf (_("None\n")); break;
15074 case 1: printf (_("Small\n")); break;
15075 case 2: printf (_("Large\n")); break;
15076 default: printf ("??? (%d)\n", val); break;
15077 }
15078 break;
15079
15080 case OFBA_MSPABI_Tag_Data_Model:
15081 val = read_uleb128 (p, &len, end);
15082 p += len;
15083 printf (" Tag_Data_Model: ");
15084 switch (val)
15085 {
15086 case 0: printf (_("None\n")); break;
15087 case 1: printf (_("Small\n")); break;
15088 case 2: printf (_("Large\n")); break;
15089 case 3: printf (_("Restricted Large\n")); break;
15090 default: printf ("??? (%d)\n", val); break;
15091 }
15092 break;
15093
15094 default:
15095 printf (_(" <unknown tag %d>: "), tag);
15096
15097 if (tag & 1)
15098 {
071436c6 15099 putchar ('"');
4082ef84
NC
15100 if (p < end - 1)
15101 {
15102 size_t maxlen = (end - p) - 1;
15103
15104 print_symbol ((int) maxlen, (const char *) p);
15105 p += strnlen ((char *) p, maxlen) + 1;
15106 }
15107 else
15108 {
15109 printf (_("<corrupt>"));
15110 p = (unsigned char *) end;
15111 }
071436c6 15112 printf ("\"\n");
13761a11
NC
15113 }
15114 else
15115 {
15116 val = read_uleb128 (p, &len, end);
15117 p += len;
15118 printf ("%d (0x%x)\n", val, val);
15119 }
15120 break;
15121 }
15122
4082ef84 15123 assert (p <= end);
13761a11
NC
15124 return p;
15125}
15126
32ec8896 15127static bfd_boolean
dda8d76d 15128process_attributes (Filedata * filedata,
60bca95a 15129 const char * public_name,
104d59d1 15130 unsigned int proc_type,
f6f0e17b 15131 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 15132 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 15133{
2cf0635d 15134 Elf_Internal_Shdr * sect;
11c1ff18 15135 unsigned i;
32ec8896 15136 bfd_boolean res = TRUE;
11c1ff18
PB
15137
15138 /* Find the section header so that we get the size. */
dda8d76d
NC
15139 for (i = 0, sect = filedata->section_headers;
15140 i < filedata->file_header.e_shnum;
11c1ff18
PB
15141 i++, sect++)
15142 {
071436c6
NC
15143 unsigned char * contents;
15144 unsigned char * p;
15145
104d59d1 15146 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
15147 continue;
15148
dda8d76d 15149 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 15150 sect->sh_size, _("attributes"));
60bca95a 15151 if (contents == NULL)
32ec8896
NC
15152 {
15153 res = FALSE;
15154 continue;
15155 }
60bca95a 15156
11c1ff18 15157 p = contents;
60abdbed
NC
15158 /* The first character is the version of the attributes.
15159 Currently only version 1, (aka 'A') is recognised here. */
15160 if (*p != 'A')
32ec8896
NC
15161 {
15162 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
15163 res = FALSE;
15164 }
60abdbed 15165 else
11c1ff18 15166 {
071436c6
NC
15167 bfd_vma section_len;
15168
15169 section_len = sect->sh_size - 1;
11c1ff18 15170 p++;
60bca95a 15171
071436c6 15172 while (section_len > 0)
11c1ff18 15173 {
071436c6 15174 bfd_vma attr_len;
e9847026 15175 unsigned int namelen;
11c1ff18 15176 bfd_boolean public_section;
104d59d1 15177 bfd_boolean gnu_section;
11c1ff18 15178
071436c6 15179 if (section_len <= 4)
e0a31db1
NC
15180 {
15181 error (_("Tag section ends prematurely\n"));
32ec8896 15182 res = FALSE;
e0a31db1
NC
15183 break;
15184 }
071436c6 15185 attr_len = byte_get (p, 4);
11c1ff18 15186 p += 4;
60bca95a 15187
071436c6 15188 if (attr_len > section_len)
11c1ff18 15189 {
071436c6
NC
15190 error (_("Bad attribute length (%u > %u)\n"),
15191 (unsigned) attr_len, (unsigned) section_len);
15192 attr_len = section_len;
32ec8896 15193 res = FALSE;
11c1ff18 15194 }
74e1a04b 15195 /* PR 17531: file: 001-101425-0.004 */
071436c6 15196 else if (attr_len < 5)
74e1a04b 15197 {
071436c6 15198 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 15199 res = FALSE;
74e1a04b
NC
15200 break;
15201 }
e9847026 15202
071436c6
NC
15203 section_len -= attr_len;
15204 attr_len -= 4;
15205
15206 namelen = strnlen ((char *) p, attr_len) + 1;
15207 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
15208 {
15209 error (_("Corrupt attribute section name\n"));
32ec8896 15210 res = FALSE;
e9847026
NC
15211 break;
15212 }
15213
071436c6
NC
15214 printf (_("Attribute Section: "));
15215 print_symbol (INT_MAX, (const char *) p);
15216 putchar ('\n');
60bca95a
NC
15217
15218 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
15219 public_section = TRUE;
15220 else
15221 public_section = FALSE;
60bca95a
NC
15222
15223 if (streq ((char *) p, "gnu"))
104d59d1
JM
15224 gnu_section = TRUE;
15225 else
15226 gnu_section = FALSE;
60bca95a 15227
11c1ff18 15228 p += namelen;
071436c6 15229 attr_len -= namelen;
e0a31db1 15230
071436c6 15231 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 15232 {
e0a31db1 15233 int tag;
11c1ff18
PB
15234 int val;
15235 bfd_vma size;
071436c6 15236 unsigned char * end;
60bca95a 15237
e0a31db1 15238 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 15239 if (attr_len < 6)
e0a31db1
NC
15240 {
15241 error (_("Unused bytes at end of section\n"));
32ec8896 15242 res = FALSE;
e0a31db1
NC
15243 section_len = 0;
15244 break;
15245 }
15246
15247 tag = *(p++);
11c1ff18 15248 size = byte_get (p, 4);
071436c6 15249 if (size > attr_len)
11c1ff18 15250 {
e9847026 15251 error (_("Bad subsection length (%u > %u)\n"),
071436c6 15252 (unsigned) size, (unsigned) attr_len);
32ec8896 15253 res = FALSE;
071436c6 15254 size = attr_len;
11c1ff18 15255 }
e0a31db1
NC
15256 /* PR binutils/17531: Safe handling of corrupt files. */
15257 if (size < 6)
15258 {
15259 error (_("Bad subsection length (%u < 6)\n"),
15260 (unsigned) size);
32ec8896 15261 res = FALSE;
e0a31db1
NC
15262 section_len = 0;
15263 break;
15264 }
60bca95a 15265
071436c6 15266 attr_len -= size;
11c1ff18 15267 end = p + size - 1;
071436c6 15268 assert (end <= contents + sect->sh_size);
11c1ff18 15269 p += 4;
60bca95a 15270
11c1ff18
PB
15271 switch (tag)
15272 {
15273 case 1:
2b692964 15274 printf (_("File Attributes\n"));
11c1ff18
PB
15275 break;
15276 case 2:
2b692964 15277 printf (_("Section Attributes:"));
11c1ff18
PB
15278 goto do_numlist;
15279 case 3:
2b692964 15280 printf (_("Symbol Attributes:"));
1a0670f3 15281 /* Fall through. */
11c1ff18
PB
15282 do_numlist:
15283 for (;;)
15284 {
91d6fa6a 15285 unsigned int j;
60bca95a 15286
f6f0e17b 15287 val = read_uleb128 (p, &j, end);
91d6fa6a 15288 p += j;
11c1ff18
PB
15289 if (val == 0)
15290 break;
15291 printf (" %d", val);
15292 }
15293 printf ("\n");
15294 break;
15295 default:
2b692964 15296 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
15297 public_section = FALSE;
15298 break;
15299 }
60bca95a 15300
071436c6 15301 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
15302 {
15303 while (p < end)
f6f0e17b 15304 p = display_pub_attribute (p, end);
60abdbed 15305 assert (p == end);
104d59d1 15306 }
071436c6 15307 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
15308 {
15309 while (p < end)
15310 p = display_gnu_attribute (p,
f6f0e17b
NC
15311 display_proc_gnu_attribute,
15312 end);
60abdbed 15313 assert (p == end);
11c1ff18 15314 }
071436c6 15315 else if (p < end)
11c1ff18 15316 {
071436c6 15317 printf (_(" Unknown attribute:\n"));
f6f0e17b 15318 display_raw_attribute (p, end);
11c1ff18
PB
15319 p = end;
15320 }
071436c6
NC
15321 else
15322 attr_len = 0;
11c1ff18
PB
15323 }
15324 }
15325 }
d70c5fc7 15326
60bca95a 15327 free (contents);
11c1ff18 15328 }
32ec8896
NC
15329
15330 return res;
11c1ff18
PB
15331}
15332
ccb4c951
RS
15333/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
15334 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
15335 and return the VMA of the next entry, or -1 if there was a problem.
15336 Does not read from DATA_END or beyond. */
ccb4c951
RS
15337
15338static bfd_vma
82b1b41b
NC
15339print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
15340 unsigned char * data_end)
ccb4c951
RS
15341{
15342 printf (" ");
15343 print_vma (addr, LONG_HEX);
15344 printf (" ");
15345 if (addr < pltgot + 0xfff0)
15346 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
15347 else
15348 printf ("%10s", "");
15349 printf (" ");
15350 if (data == NULL)
2b692964 15351 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
15352 else
15353 {
15354 bfd_vma entry;
82b1b41b 15355 unsigned char * from = data + addr - pltgot;
ccb4c951 15356
82b1b41b
NC
15357 if (from + (is_32bit_elf ? 4 : 8) > data_end)
15358 {
15359 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
15360 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
15361 return (bfd_vma) -1;
15362 }
15363 else
15364 {
15365 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15366 print_vma (entry, LONG_HEX);
15367 }
ccb4c951
RS
15368 }
15369 return addr + (is_32bit_elf ? 4 : 8);
15370}
15371
861fb55a
DJ
15372/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
15373 PLTGOT. Print the Address and Initial fields of an entry at VMA
15374 ADDR and return the VMA of the next entry. */
15375
15376static bfd_vma
2cf0635d 15377print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
15378{
15379 printf (" ");
15380 print_vma (addr, LONG_HEX);
15381 printf (" ");
15382 if (data == NULL)
2b692964 15383 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
15384 else
15385 {
15386 bfd_vma entry;
15387
15388 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15389 print_vma (entry, LONG_HEX);
15390 }
15391 return addr + (is_32bit_elf ? 4 : 8);
15392}
15393
351cdf24
MF
15394static void
15395print_mips_ases (unsigned int mask)
15396{
15397 if (mask & AFL_ASE_DSP)
15398 fputs ("\n\tDSP ASE", stdout);
15399 if (mask & AFL_ASE_DSPR2)
15400 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
15401 if (mask & AFL_ASE_DSPR3)
15402 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
15403 if (mask & AFL_ASE_EVA)
15404 fputs ("\n\tEnhanced VA Scheme", stdout);
15405 if (mask & AFL_ASE_MCU)
15406 fputs ("\n\tMCU (MicroController) ASE", stdout);
15407 if (mask & AFL_ASE_MDMX)
15408 fputs ("\n\tMDMX ASE", stdout);
15409 if (mask & AFL_ASE_MIPS3D)
15410 fputs ("\n\tMIPS-3D ASE", stdout);
15411 if (mask & AFL_ASE_MT)
15412 fputs ("\n\tMT ASE", stdout);
15413 if (mask & AFL_ASE_SMARTMIPS)
15414 fputs ("\n\tSmartMIPS ASE", stdout);
15415 if (mask & AFL_ASE_VIRT)
15416 fputs ("\n\tVZ ASE", stdout);
15417 if (mask & AFL_ASE_MSA)
15418 fputs ("\n\tMSA ASE", stdout);
15419 if (mask & AFL_ASE_MIPS16)
15420 fputs ("\n\tMIPS16 ASE", stdout);
15421 if (mask & AFL_ASE_MICROMIPS)
15422 fputs ("\n\tMICROMIPS ASE", stdout);
15423 if (mask & AFL_ASE_XPA)
15424 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
15425 if (mask & AFL_ASE_MIPS16E2)
15426 fputs ("\n\tMIPS16e2 ASE", stdout);
351cdf24
MF
15427 if (mask == 0)
15428 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
15429 else if ((mask & ~AFL_ASE_MASK) != 0)
15430 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
15431}
15432
15433static void
15434print_mips_isa_ext (unsigned int isa_ext)
15435{
15436 switch (isa_ext)
15437 {
15438 case 0:
15439 fputs (_("None"), stdout);
15440 break;
15441 case AFL_EXT_XLR:
15442 fputs ("RMI XLR", stdout);
15443 break;
2c629856
N
15444 case AFL_EXT_OCTEON3:
15445 fputs ("Cavium Networks Octeon3", stdout);
15446 break;
351cdf24
MF
15447 case AFL_EXT_OCTEON2:
15448 fputs ("Cavium Networks Octeon2", stdout);
15449 break;
15450 case AFL_EXT_OCTEONP:
15451 fputs ("Cavium Networks OcteonP", stdout);
15452 break;
15453 case AFL_EXT_LOONGSON_3A:
15454 fputs ("Loongson 3A", stdout);
15455 break;
15456 case AFL_EXT_OCTEON:
15457 fputs ("Cavium Networks Octeon", stdout);
15458 break;
15459 case AFL_EXT_5900:
15460 fputs ("Toshiba R5900", stdout);
15461 break;
15462 case AFL_EXT_4650:
15463 fputs ("MIPS R4650", stdout);
15464 break;
15465 case AFL_EXT_4010:
15466 fputs ("LSI R4010", stdout);
15467 break;
15468 case AFL_EXT_4100:
15469 fputs ("NEC VR4100", stdout);
15470 break;
15471 case AFL_EXT_3900:
15472 fputs ("Toshiba R3900", stdout);
15473 break;
15474 case AFL_EXT_10000:
15475 fputs ("MIPS R10000", stdout);
15476 break;
15477 case AFL_EXT_SB1:
15478 fputs ("Broadcom SB-1", stdout);
15479 break;
15480 case AFL_EXT_4111:
15481 fputs ("NEC VR4111/VR4181", stdout);
15482 break;
15483 case AFL_EXT_4120:
15484 fputs ("NEC VR4120", stdout);
15485 break;
15486 case AFL_EXT_5400:
15487 fputs ("NEC VR5400", stdout);
15488 break;
15489 case AFL_EXT_5500:
15490 fputs ("NEC VR5500", stdout);
15491 break;
15492 case AFL_EXT_LOONGSON_2E:
15493 fputs ("ST Microelectronics Loongson 2E", stdout);
15494 break;
15495 case AFL_EXT_LOONGSON_2F:
15496 fputs ("ST Microelectronics Loongson 2F", stdout);
15497 break;
38bf472a
MR
15498 case AFL_EXT_INTERAPTIV_MR2:
15499 fputs ("Imagination interAptiv MR2", stdout);
15500 break;
351cdf24 15501 default:
00ac7aa0 15502 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
15503 }
15504}
15505
32ec8896 15506static signed int
351cdf24
MF
15507get_mips_reg_size (int reg_size)
15508{
15509 return (reg_size == AFL_REG_NONE) ? 0
15510 : (reg_size == AFL_REG_32) ? 32
15511 : (reg_size == AFL_REG_64) ? 64
15512 : (reg_size == AFL_REG_128) ? 128
15513 : -1;
15514}
15515
32ec8896 15516static bfd_boolean
dda8d76d 15517process_mips_specific (Filedata * filedata)
5b18a4bc 15518{
2cf0635d 15519 Elf_Internal_Dyn * entry;
351cdf24 15520 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
15521 size_t liblist_offset = 0;
15522 size_t liblistno = 0;
15523 size_t conflictsno = 0;
15524 size_t options_offset = 0;
15525 size_t conflicts_offset = 0;
861fb55a
DJ
15526 size_t pltrelsz = 0;
15527 size_t pltrel = 0;
ccb4c951 15528 bfd_vma pltgot = 0;
861fb55a
DJ
15529 bfd_vma mips_pltgot = 0;
15530 bfd_vma jmprel = 0;
ccb4c951
RS
15531 bfd_vma local_gotno = 0;
15532 bfd_vma gotsym = 0;
15533 bfd_vma symtabno = 0;
32ec8896 15534 bfd_boolean res = TRUE;
103f02d3 15535
dda8d76d 15536 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
15537 display_mips_gnu_attribute))
15538 res = FALSE;
2cf19d5c 15539
dda8d76d 15540 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
15541
15542 if (sect != NULL)
15543 {
15544 Elf_External_ABIFlags_v0 *abiflags_ext;
15545 Elf_Internal_ABIFlags_v0 abiflags_in;
15546
15547 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
15548 {
15549 error (_("Corrupt MIPS ABI Flags section.\n"));
15550 res = FALSE;
15551 }
351cdf24
MF
15552 else
15553 {
dda8d76d 15554 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
15555 sect->sh_size, _("MIPS ABI Flags section"));
15556 if (abiflags_ext)
15557 {
15558 abiflags_in.version = BYTE_GET (abiflags_ext->version);
15559 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
15560 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
15561 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
15562 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
15563 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
15564 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
15565 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
15566 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
15567 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
15568 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
15569
15570 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
15571 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
15572 if (abiflags_in.isa_rev > 1)
15573 printf ("r%d", abiflags_in.isa_rev);
15574 printf ("\nGPR size: %d",
15575 get_mips_reg_size (abiflags_in.gpr_size));
15576 printf ("\nCPR1 size: %d",
15577 get_mips_reg_size (abiflags_in.cpr1_size));
15578 printf ("\nCPR2 size: %d",
15579 get_mips_reg_size (abiflags_in.cpr2_size));
15580 fputs ("\nFP ABI: ", stdout);
15581 print_mips_fp_abi_value (abiflags_in.fp_abi);
15582 fputs ("ISA Extension: ", stdout);
15583 print_mips_isa_ext (abiflags_in.isa_ext);
15584 fputs ("\nASEs:", stdout);
15585 print_mips_ases (abiflags_in.ases);
15586 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
15587 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
15588 fputc ('\n', stdout);
15589 free (abiflags_ext);
15590 }
15591 }
15592 }
15593
19e6b90e
L
15594 /* We have a lot of special sections. Thanks SGI! */
15595 if (dynamic_section == NULL)
bbdd9a68
MR
15596 {
15597 /* No dynamic information available. See if there is static GOT. */
dda8d76d 15598 sect = find_section (filedata, ".got");
bbdd9a68
MR
15599 if (sect != NULL)
15600 {
15601 unsigned char *data_end;
15602 unsigned char *data;
15603 bfd_vma ent, end;
15604 int addr_size;
15605
15606 pltgot = sect->sh_addr;
15607
15608 ent = pltgot;
15609 addr_size = (is_32bit_elf ? 4 : 8);
15610 end = pltgot + sect->sh_size;
15611
dda8d76d 15612 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
15613 end - pltgot, 1,
15614 _("Global Offset Table data"));
15615 /* PR 12855: Null data is handled gracefully throughout. */
15616 data_end = data + (end - pltgot);
15617
15618 printf (_("\nStatic GOT:\n"));
15619 printf (_(" Canonical gp value: "));
15620 print_vma (ent + 0x7ff0, LONG_HEX);
15621 printf ("\n\n");
15622
15623 /* In a dynamic binary GOT[0] is reserved for the dynamic
15624 loader to store the lazy resolver pointer, however in
15625 a static binary it may well have been omitted and GOT
15626 reduced to a table of addresses.
15627 PR 21344: Check for the entry being fully available
15628 before fetching it. */
15629 if (data
15630 && data + ent - pltgot + addr_size <= data_end
15631 && byte_get (data + ent - pltgot, addr_size) == 0)
15632 {
15633 printf (_(" Reserved entries:\n"));
15634 printf (_(" %*s %10s %*s\n"),
15635 addr_size * 2, _("Address"), _("Access"),
15636 addr_size * 2, _("Value"));
15637 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15638 printf ("\n");
15639 if (ent == (bfd_vma) -1)
15640 goto sgot_print_fail;
15641
15642 /* Check for the MSB of GOT[1] being set, identifying a
15643 GNU object. This entry will be used by some runtime
15644 loaders, to store the module pointer. Otherwise this
15645 is an ordinary local entry.
15646 PR 21344: Check for the entry being fully available
15647 before fetching it. */
15648 if (data
15649 && data + ent - pltgot + addr_size <= data_end
15650 && (byte_get (data + ent - pltgot, addr_size)
15651 >> (addr_size * 8 - 1)) != 0)
15652 {
15653 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15654 printf ("\n");
15655 if (ent == (bfd_vma) -1)
15656 goto sgot_print_fail;
15657 }
15658 printf ("\n");
15659 }
15660
f17e9d8a 15661 if (data != NULL && ent < end)
bbdd9a68
MR
15662 {
15663 printf (_(" Local entries:\n"));
15664 printf (" %*s %10s %*s\n",
15665 addr_size * 2, _("Address"), _("Access"),
15666 addr_size * 2, _("Value"));
15667 while (ent < end)
15668 {
15669 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15670 printf ("\n");
15671 if (ent == (bfd_vma) -1)
15672 goto sgot_print_fail;
15673 }
15674 printf ("\n");
15675 }
15676
15677 sgot_print_fail:
15678 if (data)
15679 free (data);
15680 }
15681 return res;
15682 }
252b5132 15683
071436c6
NC
15684 for (entry = dynamic_section;
15685 /* PR 17531 file: 012-50589-0.004. */
15686 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
15687 ++entry)
252b5132
RH
15688 switch (entry->d_tag)
15689 {
15690 case DT_MIPS_LIBLIST:
d93f0186 15691 liblist_offset
dda8d76d 15692 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 15693 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
15694 break;
15695 case DT_MIPS_LIBLISTNO:
15696 liblistno = entry->d_un.d_val;
15697 break;
15698 case DT_MIPS_OPTIONS:
dda8d76d 15699 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
15700 break;
15701 case DT_MIPS_CONFLICT:
d93f0186 15702 conflicts_offset
dda8d76d 15703 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 15704 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
15705 break;
15706 case DT_MIPS_CONFLICTNO:
15707 conflictsno = entry->d_un.d_val;
15708 break;
ccb4c951 15709 case DT_PLTGOT:
861fb55a
DJ
15710 pltgot = entry->d_un.d_ptr;
15711 break;
ccb4c951
RS
15712 case DT_MIPS_LOCAL_GOTNO:
15713 local_gotno = entry->d_un.d_val;
15714 break;
15715 case DT_MIPS_GOTSYM:
15716 gotsym = entry->d_un.d_val;
15717 break;
15718 case DT_MIPS_SYMTABNO:
15719 symtabno = entry->d_un.d_val;
15720 break;
861fb55a
DJ
15721 case DT_MIPS_PLTGOT:
15722 mips_pltgot = entry->d_un.d_ptr;
15723 break;
15724 case DT_PLTREL:
15725 pltrel = entry->d_un.d_val;
15726 break;
15727 case DT_PLTRELSZ:
15728 pltrelsz = entry->d_un.d_val;
15729 break;
15730 case DT_JMPREL:
15731 jmprel = entry->d_un.d_ptr;
15732 break;
252b5132
RH
15733 default:
15734 break;
15735 }
15736
15737 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
15738 {
2cf0635d 15739 Elf32_External_Lib * elib;
252b5132
RH
15740 size_t cnt;
15741
dda8d76d 15742 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
3f5e193b
NC
15743 liblistno,
15744 sizeof (Elf32_External_Lib),
9cf03b7e 15745 _("liblist section data"));
a6e9f9df 15746 if (elib)
252b5132 15747 {
d3a49aa8
AM
15748 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
15749 "\nSection '.liblist' contains %lu entries:\n",
15750 (unsigned long) liblistno),
a6e9f9df 15751 (unsigned long) liblistno);
2b692964 15752 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
15753 stdout);
15754
15755 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 15756 {
a6e9f9df 15757 Elf32_Lib liblist;
91d6fa6a 15758 time_t atime;
d5b07ef4 15759 char timebuf[128];
2cf0635d 15760 struct tm * tmp;
a6e9f9df
AM
15761
15762 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 15763 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
15764 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
15765 liblist.l_version = BYTE_GET (elib[cnt].l_version);
15766 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
15767
91d6fa6a 15768 tmp = gmtime (&atime);
e9e44622
JJ
15769 snprintf (timebuf, sizeof (timebuf),
15770 "%04u-%02u-%02uT%02u:%02u:%02u",
15771 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
15772 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 15773
31104126 15774 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
15775 if (VALID_DYNAMIC_NAME (liblist.l_name))
15776 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
15777 else
2b692964 15778 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
15779 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
15780 liblist.l_version);
a6e9f9df
AM
15781
15782 if (liblist.l_flags == 0)
2b692964 15783 puts (_(" NONE"));
a6e9f9df
AM
15784 else
15785 {
15786 static const struct
252b5132 15787 {
2cf0635d 15788 const char * name;
a6e9f9df 15789 int bit;
252b5132 15790 }
a6e9f9df
AM
15791 l_flags_vals[] =
15792 {
15793 { " EXACT_MATCH", LL_EXACT_MATCH },
15794 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
15795 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
15796 { " EXPORTS", LL_EXPORTS },
15797 { " DELAY_LOAD", LL_DELAY_LOAD },
15798 { " DELTA", LL_DELTA }
15799 };
15800 int flags = liblist.l_flags;
15801 size_t fcnt;
15802
60bca95a 15803 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
15804 if ((flags & l_flags_vals[fcnt].bit) != 0)
15805 {
15806 fputs (l_flags_vals[fcnt].name, stdout);
15807 flags ^= l_flags_vals[fcnt].bit;
15808 }
15809 if (flags != 0)
15810 printf (" %#x", (unsigned int) flags);
252b5132 15811
a6e9f9df
AM
15812 puts ("");
15813 }
252b5132 15814 }
252b5132 15815
a6e9f9df
AM
15816 free (elib);
15817 }
32ec8896
NC
15818 else
15819 res = FALSE;
252b5132
RH
15820 }
15821
15822 if (options_offset != 0)
15823 {
2cf0635d 15824 Elf_External_Options * eopt;
2cf0635d
NC
15825 Elf_Internal_Options * iopt;
15826 Elf_Internal_Options * option;
252b5132
RH
15827 size_t offset;
15828 int cnt;
dda8d76d 15829 sect = filedata->section_headers;
252b5132
RH
15830
15831 /* Find the section header so that we get the size. */
dda8d76d 15832 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 15833 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
15834 if (sect == NULL)
15835 {
15836 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 15837 return FALSE;
071436c6 15838 }
252b5132 15839
dda8d76d 15840 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 15841 sect->sh_size, _("options"));
a6e9f9df 15842 if (eopt)
252b5132 15843 {
3f5e193b
NC
15844 iopt = (Elf_Internal_Options *)
15845 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
15846 if (iopt == NULL)
15847 {
fb324ee9 15848 error (_("Out of memory allocating space for MIPS options\n"));
32ec8896 15849 return FALSE;
a6e9f9df 15850 }
76da6bbe 15851
a6e9f9df
AM
15852 offset = cnt = 0;
15853 option = iopt;
252b5132 15854
82b1b41b 15855 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 15856 {
2cf0635d 15857 Elf_External_Options * eoption;
252b5132 15858
a6e9f9df 15859 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 15860
a6e9f9df
AM
15861 option->kind = BYTE_GET (eoption->kind);
15862 option->size = BYTE_GET (eoption->size);
15863 option->section = BYTE_GET (eoption->section);
15864 option->info = BYTE_GET (eoption->info);
76da6bbe 15865
82b1b41b
NC
15866 /* PR 17531: file: ffa0fa3b. */
15867 if (option->size < sizeof (* eopt)
15868 || offset + option->size > sect->sh_size)
15869 {
55325047 15870 error (_("Invalid size (%u) for MIPS option\n"), option->size);
32ec8896 15871 return FALSE;
82b1b41b 15872 }
a6e9f9df 15873 offset += option->size;
14ae95f2 15874
a6e9f9df
AM
15875 ++option;
15876 ++cnt;
15877 }
252b5132 15878
d3a49aa8
AM
15879 printf (ngettext ("\nSection '%s' contains %d entry:\n",
15880 "\nSection '%s' contains %d entries:\n",
15881 cnt),
dda8d76d 15882 printable_section_name (filedata, sect), cnt);
76da6bbe 15883
a6e9f9df 15884 option = iopt;
82b1b41b 15885 offset = 0;
252b5132 15886
a6e9f9df 15887 while (cnt-- > 0)
252b5132 15888 {
a6e9f9df
AM
15889 size_t len;
15890
15891 switch (option->kind)
252b5132 15892 {
a6e9f9df
AM
15893 case ODK_NULL:
15894 /* This shouldn't happen. */
15895 printf (" NULL %d %lx", option->section, option->info);
15896 break;
15897 case ODK_REGINFO:
15898 printf (" REGINFO ");
dda8d76d 15899 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df
AM
15900 {
15901 /* 32bit form. */
2cf0635d 15902 Elf32_External_RegInfo * ereg;
b34976b6 15903 Elf32_RegInfo reginfo;
a6e9f9df
AM
15904
15905 ereg = (Elf32_External_RegInfo *) (option + 1);
15906 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
15907 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
15908 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
15909 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
15910 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
15911 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
15912
15913 printf ("GPR %08lx GP 0x%lx\n",
15914 reginfo.ri_gprmask,
15915 (unsigned long) reginfo.ri_gp_value);
15916 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
15917 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
15918 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
15919 }
15920 else
15921 {
15922 /* 64 bit form. */
2cf0635d 15923 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
15924 Elf64_Internal_RegInfo reginfo;
15925
15926 ereg = (Elf64_External_RegInfo *) (option + 1);
15927 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
15928 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
15929 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
15930 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
15931 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 15932 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
15933
15934 printf ("GPR %08lx GP 0x",
15935 reginfo.ri_gprmask);
15936 printf_vma (reginfo.ri_gp_value);
15937 printf ("\n");
15938
15939 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
15940 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
15941 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
15942 }
15943 ++option;
15944 continue;
15945 case ODK_EXCEPTIONS:
15946 fputs (" EXCEPTIONS fpe_min(", stdout);
15947 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
15948 fputs (") fpe_max(", stdout);
15949 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
15950 fputs (")", stdout);
15951
15952 if (option->info & OEX_PAGE0)
15953 fputs (" PAGE0", stdout);
15954 if (option->info & OEX_SMM)
15955 fputs (" SMM", stdout);
15956 if (option->info & OEX_FPDBUG)
15957 fputs (" FPDBUG", stdout);
15958 if (option->info & OEX_DISMISS)
15959 fputs (" DISMISS", stdout);
15960 break;
15961 case ODK_PAD:
15962 fputs (" PAD ", stdout);
15963 if (option->info & OPAD_PREFIX)
15964 fputs (" PREFIX", stdout);
15965 if (option->info & OPAD_POSTFIX)
15966 fputs (" POSTFIX", stdout);
15967 if (option->info & OPAD_SYMBOL)
15968 fputs (" SYMBOL", stdout);
15969 break;
15970 case ODK_HWPATCH:
15971 fputs (" HWPATCH ", stdout);
15972 if (option->info & OHW_R4KEOP)
15973 fputs (" R4KEOP", stdout);
15974 if (option->info & OHW_R8KPFETCH)
15975 fputs (" R8KPFETCH", stdout);
15976 if (option->info & OHW_R5KEOP)
15977 fputs (" R5KEOP", stdout);
15978 if (option->info & OHW_R5KCVTL)
15979 fputs (" R5KCVTL", stdout);
15980 break;
15981 case ODK_FILL:
15982 fputs (" FILL ", stdout);
15983 /* XXX Print content of info word? */
15984 break;
15985 case ODK_TAGS:
15986 fputs (" TAGS ", stdout);
15987 /* XXX Print content of info word? */
15988 break;
15989 case ODK_HWAND:
15990 fputs (" HWAND ", stdout);
15991 if (option->info & OHWA0_R4KEOP_CHECKED)
15992 fputs (" R4KEOP_CHECKED", stdout);
15993 if (option->info & OHWA0_R4KEOP_CLEAN)
15994 fputs (" R4KEOP_CLEAN", stdout);
15995 break;
15996 case ODK_HWOR:
15997 fputs (" HWOR ", stdout);
15998 if (option->info & OHWA0_R4KEOP_CHECKED)
15999 fputs (" R4KEOP_CHECKED", stdout);
16000 if (option->info & OHWA0_R4KEOP_CLEAN)
16001 fputs (" R4KEOP_CLEAN", stdout);
16002 break;
16003 case ODK_GP_GROUP:
16004 printf (" GP_GROUP %#06lx self-contained %#06lx",
16005 option->info & OGP_GROUP,
16006 (option->info & OGP_SELF) >> 16);
16007 break;
16008 case ODK_IDENT:
16009 printf (" IDENT %#06lx self-contained %#06lx",
16010 option->info & OGP_GROUP,
16011 (option->info & OGP_SELF) >> 16);
16012 break;
16013 default:
16014 /* This shouldn't happen. */
16015 printf (" %3d ??? %d %lx",
16016 option->kind, option->section, option->info);
16017 break;
252b5132 16018 }
a6e9f9df 16019
2cf0635d 16020 len = sizeof (* eopt);
a6e9f9df 16021 while (len < option->size)
82b1b41b 16022 {
7e27a9d5 16023 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 16024
82b1b41b
NC
16025 if (ISPRINT (datum))
16026 printf ("%c", datum);
16027 else
16028 printf ("\\%03o", datum);
16029 len ++;
16030 }
a6e9f9df 16031 fputs ("\n", stdout);
82b1b41b
NC
16032
16033 offset += option->size;
252b5132 16034 ++option;
252b5132
RH
16035 }
16036
a6e9f9df 16037 free (eopt);
252b5132 16038 }
32ec8896
NC
16039 else
16040 res = FALSE;
252b5132
RH
16041 }
16042
16043 if (conflicts_offset != 0 && conflictsno != 0)
16044 {
2cf0635d 16045 Elf32_Conflict * iconf;
252b5132
RH
16046 size_t cnt;
16047
16048 if (dynamic_symbols == NULL)
16049 {
591a748a 16050 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 16051 return FALSE;
252b5132
RH
16052 }
16053
7296a62a
NC
16054 /* PR 21345 - print a slightly more helpful error message
16055 if we are sure that the cmalloc will fail. */
dda8d76d 16056 if (conflictsno * sizeof (* iconf) > filedata->file_size)
7296a62a
NC
16057 {
16058 error (_("Overlarge number of conflicts detected: %lx\n"),
16059 (long) conflictsno);
16060 return FALSE;
16061 }
16062
3f5e193b 16063 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
16064 if (iconf == NULL)
16065 {
8b73c356 16066 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 16067 return FALSE;
252b5132
RH
16068 }
16069
9ea033b2 16070 if (is_32bit_elf)
252b5132 16071 {
2cf0635d 16072 Elf32_External_Conflict * econf32;
a6e9f9df 16073
3f5e193b 16074 econf32 = (Elf32_External_Conflict *)
dda8d76d 16075 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16076 sizeof (* econf32), _("conflict"));
a6e9f9df 16077 if (!econf32)
32ec8896 16078 return FALSE;
252b5132
RH
16079
16080 for (cnt = 0; cnt < conflictsno; ++cnt)
16081 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
16082
16083 free (econf32);
252b5132
RH
16084 }
16085 else
16086 {
2cf0635d 16087 Elf64_External_Conflict * econf64;
a6e9f9df 16088
3f5e193b 16089 econf64 = (Elf64_External_Conflict *)
dda8d76d 16090 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16091 sizeof (* econf64), _("conflict"));
a6e9f9df 16092 if (!econf64)
32ec8896 16093 return FALSE;
252b5132
RH
16094
16095 for (cnt = 0; cnt < conflictsno; ++cnt)
16096 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
16097
16098 free (econf64);
252b5132
RH
16099 }
16100
d3a49aa8
AM
16101 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
16102 "\nSection '.conflict' contains %lu entries:\n",
16103 (unsigned long) conflictsno),
c7e7ca54 16104 (unsigned long) conflictsno);
252b5132
RH
16105 puts (_(" Num: Index Value Name"));
16106
16107 for (cnt = 0; cnt < conflictsno; ++cnt)
16108 {
b34976b6 16109 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
16110
16111 if (iconf[cnt] >= num_dynamic_syms)
16112 printf (_("<corrupt symbol index>"));
d79b3d50 16113 else
e0a31db1
NC
16114 {
16115 Elf_Internal_Sym * psym;
16116
16117 psym = & dynamic_symbols[iconf[cnt]];
16118 print_vma (psym->st_value, FULL_HEX);
16119 putchar (' ');
16120 if (VALID_DYNAMIC_NAME (psym->st_name))
16121 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
16122 else
16123 printf (_("<corrupt: %14ld>"), psym->st_name);
16124 }
31104126 16125 putchar ('\n');
252b5132
RH
16126 }
16127
252b5132
RH
16128 free (iconf);
16129 }
16130
ccb4c951
RS
16131 if (pltgot != 0 && local_gotno != 0)
16132 {
91d6fa6a 16133 bfd_vma ent, local_end, global_end;
bbeee7ea 16134 size_t i, offset;
2cf0635d 16135 unsigned char * data;
82b1b41b 16136 unsigned char * data_end;
bbeee7ea 16137 int addr_size;
ccb4c951 16138
91d6fa6a 16139 ent = pltgot;
ccb4c951
RS
16140 addr_size = (is_32bit_elf ? 4 : 8);
16141 local_end = pltgot + local_gotno * addr_size;
ccb4c951 16142
74e1a04b
NC
16143 /* PR binutils/17533 file: 012-111227-0.004 */
16144 if (symtabno < gotsym)
16145 {
16146 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 16147 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 16148 return FALSE;
74e1a04b 16149 }
82b1b41b 16150
74e1a04b 16151 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
16152 /* PR 17531: file: 54c91a34. */
16153 if (global_end < local_end)
16154 {
16155 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 16156 return FALSE;
82b1b41b 16157 }
948f632f 16158
dda8d76d
NC
16159 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
16160 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
16161 global_end - pltgot, 1,
16162 _("Global Offset Table data"));
919383ac 16163 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 16164 data_end = data + (global_end - pltgot);
59245841 16165
ccb4c951
RS
16166 printf (_("\nPrimary GOT:\n"));
16167 printf (_(" Canonical gp value: "));
16168 print_vma (pltgot + 0x7ff0, LONG_HEX);
16169 printf ("\n\n");
16170
16171 printf (_(" Reserved entries:\n"));
16172 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
16173 addr_size * 2, _("Address"), _("Access"),
16174 addr_size * 2, _("Initial"));
82b1b41b 16175 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 16176 printf (_(" Lazy resolver\n"));
82b1b41b
NC
16177 if (ent == (bfd_vma) -1)
16178 goto got_print_fail;
75ec1fdb 16179
c4ab9505
MR
16180 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
16181 This entry will be used by some runtime loaders, to store the
16182 module pointer. Otherwise this is an ordinary local entry.
16183 PR 21344: Check for the entry being fully available before
16184 fetching it. */
16185 if (data
16186 && data + ent - pltgot + addr_size <= data_end
16187 && (byte_get (data + ent - pltgot, addr_size)
16188 >> (addr_size * 8 - 1)) != 0)
16189 {
16190 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16191 printf (_(" Module pointer (GNU extension)\n"));
16192 if (ent == (bfd_vma) -1)
16193 goto got_print_fail;
ccb4c951
RS
16194 }
16195 printf ("\n");
16196
f17e9d8a 16197 if (data != NULL && ent < local_end)
ccb4c951
RS
16198 {
16199 printf (_(" Local entries:\n"));
cc5914eb 16200 printf (" %*s %10s %*s\n",
2b692964
NC
16201 addr_size * 2, _("Address"), _("Access"),
16202 addr_size * 2, _("Initial"));
91d6fa6a 16203 while (ent < local_end)
ccb4c951 16204 {
82b1b41b 16205 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16206 printf ("\n");
82b1b41b
NC
16207 if (ent == (bfd_vma) -1)
16208 goto got_print_fail;
ccb4c951
RS
16209 }
16210 printf ("\n");
16211 }
16212
f17e9d8a 16213 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
16214 {
16215 int sym_width;
16216
16217 printf (_(" Global entries:\n"));
cc5914eb 16218 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
16219 addr_size * 2, _("Address"),
16220 _("Access"),
2b692964 16221 addr_size * 2, _("Initial"),
9cf03b7e
NC
16222 addr_size * 2, _("Sym.Val."),
16223 _("Type"),
16224 /* Note for translators: "Ndx" = abbreviated form of "Index". */
16225 _("Ndx"), _("Name"));
0b4362b0 16226
ccb4c951 16227 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 16228
ccb4c951
RS
16229 for (i = gotsym; i < symtabno; i++)
16230 {
82b1b41b 16231 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16232 printf (" ");
e0a31db1
NC
16233
16234 if (dynamic_symbols == NULL)
16235 printf (_("<no dynamic symbols>"));
16236 else if (i < num_dynamic_syms)
16237 {
16238 Elf_Internal_Sym * psym = dynamic_symbols + i;
16239
16240 print_vma (psym->st_value, LONG_HEX);
16241 printf (" %-7s %3s ",
dda8d76d
NC
16242 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16243 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16244
16245 if (VALID_DYNAMIC_NAME (psym->st_name))
16246 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16247 else
16248 printf (_("<corrupt: %14ld>"), psym->st_name);
16249 }
ccb4c951 16250 else
7fc5ac57
JBG
16251 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
16252 (unsigned long) i);
e0a31db1 16253
ccb4c951 16254 printf ("\n");
82b1b41b
NC
16255 if (ent == (bfd_vma) -1)
16256 break;
ccb4c951
RS
16257 }
16258 printf ("\n");
16259 }
16260
82b1b41b 16261 got_print_fail:
ccb4c951
RS
16262 if (data)
16263 free (data);
16264 }
16265
861fb55a
DJ
16266 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
16267 {
91d6fa6a 16268 bfd_vma ent, end;
861fb55a
DJ
16269 size_t offset, rel_offset;
16270 unsigned long count, i;
2cf0635d 16271 unsigned char * data;
861fb55a 16272 int addr_size, sym_width;
2cf0635d 16273 Elf_Internal_Rela * rels;
861fb55a 16274
dda8d76d 16275 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
16276 if (pltrel == DT_RELA)
16277 {
dda8d76d 16278 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16279 return FALSE;
861fb55a
DJ
16280 }
16281 else
16282 {
dda8d76d 16283 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16284 return FALSE;
861fb55a
DJ
16285 }
16286
91d6fa6a 16287 ent = mips_pltgot;
861fb55a
DJ
16288 addr_size = (is_32bit_elf ? 4 : 8);
16289 end = mips_pltgot + (2 + count) * addr_size;
16290
dda8d76d
NC
16291 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
16292 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 16293 1, _("Procedure Linkage Table data"));
59245841 16294 if (data == NULL)
32ec8896 16295 return FALSE;
59245841 16296
9cf03b7e 16297 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
16298 printf (_(" Reserved entries:\n"));
16299 printf (_(" %*s %*s Purpose\n"),
2b692964 16300 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 16301 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16302 printf (_(" PLT lazy resolver\n"));
91d6fa6a 16303 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16304 printf (_(" Module pointer\n"));
861fb55a
DJ
16305 printf ("\n");
16306
16307 printf (_(" Entries:\n"));
cc5914eb 16308 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
16309 addr_size * 2, _("Address"),
16310 addr_size * 2, _("Initial"),
16311 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
16312 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
16313 for (i = 0; i < count; i++)
16314 {
df97ab2a 16315 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 16316
91d6fa6a 16317 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 16318 printf (" ");
e0a31db1 16319
df97ab2a
MF
16320 if (idx >= num_dynamic_syms)
16321 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 16322 else
e0a31db1 16323 {
df97ab2a 16324 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
16325
16326 print_vma (psym->st_value, LONG_HEX);
16327 printf (" %-7s %3s ",
dda8d76d
NC
16328 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16329 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16330 if (VALID_DYNAMIC_NAME (psym->st_name))
16331 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16332 else
16333 printf (_("<corrupt: %14ld>"), psym->st_name);
16334 }
861fb55a
DJ
16335 printf ("\n");
16336 }
16337 printf ("\n");
16338
16339 if (data)
16340 free (data);
16341 free (rels);
16342 }
16343
32ec8896 16344 return res;
252b5132
RH
16345}
16346
32ec8896 16347static bfd_boolean
dda8d76d 16348process_nds32_specific (Filedata * filedata)
35c08157
KLC
16349{
16350 Elf_Internal_Shdr *sect = NULL;
16351
dda8d76d 16352 sect = find_section (filedata, ".nds32_e_flags");
35c08157
KLC
16353 if (sect != NULL)
16354 {
16355 unsigned int *flag;
16356
16357 printf ("\nNDS32 elf flags section:\n");
dda8d76d 16358 flag = get_data (NULL, filedata, sect->sh_offset, 1,
35c08157
KLC
16359 sect->sh_size, _("NDS32 elf flags section"));
16360
32ec8896
NC
16361 if (! flag)
16362 return FALSE;
16363
35c08157
KLC
16364 switch ((*flag) & 0x3)
16365 {
16366 case 0:
16367 printf ("(VEC_SIZE):\tNo entry.\n");
16368 break;
16369 case 1:
16370 printf ("(VEC_SIZE):\t4 bytes\n");
16371 break;
16372 case 2:
16373 printf ("(VEC_SIZE):\t16 bytes\n");
16374 break;
16375 case 3:
16376 printf ("(VEC_SIZE):\treserved\n");
16377 break;
16378 }
16379 }
16380
16381 return TRUE;
16382}
16383
32ec8896 16384static bfd_boolean
dda8d76d 16385process_gnu_liblist (Filedata * filedata)
047b2264 16386{
2cf0635d
NC
16387 Elf_Internal_Shdr * section;
16388 Elf_Internal_Shdr * string_sec;
16389 Elf32_External_Lib * elib;
16390 char * strtab;
c256ffe7 16391 size_t strtab_size;
047b2264 16392 size_t cnt;
d3a49aa8 16393 unsigned long num_liblist;
047b2264 16394 unsigned i;
32ec8896 16395 bfd_boolean res = TRUE;
047b2264
JJ
16396
16397 if (! do_arch)
32ec8896 16398 return TRUE;
047b2264 16399
dda8d76d
NC
16400 for (i = 0, section = filedata->section_headers;
16401 i < filedata->file_header.e_shnum;
b34976b6 16402 i++, section++)
047b2264
JJ
16403 {
16404 switch (section->sh_type)
16405 {
16406 case SHT_GNU_LIBLIST:
dda8d76d 16407 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
16408 break;
16409
3f5e193b 16410 elib = (Elf32_External_Lib *)
dda8d76d 16411 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 16412 _("liblist section data"));
047b2264
JJ
16413
16414 if (elib == NULL)
32ec8896
NC
16415 {
16416 res = FALSE;
16417 break;
16418 }
047b2264 16419
dda8d76d
NC
16420 string_sec = filedata->section_headers + section->sh_link;
16421 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
16422 string_sec->sh_size,
16423 _("liblist string table"));
047b2264
JJ
16424 if (strtab == NULL
16425 || section->sh_entsize != sizeof (Elf32_External_Lib))
16426 {
16427 free (elib);
2842702f 16428 free (strtab);
32ec8896 16429 res = FALSE;
047b2264
JJ
16430 break;
16431 }
59245841 16432 strtab_size = string_sec->sh_size;
047b2264 16433
d3a49aa8
AM
16434 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
16435 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
16436 "\nLibrary list section '%s' contains %lu entries:\n",
16437 num_liblist),
dda8d76d 16438 printable_section_name (filedata, section),
d3a49aa8 16439 num_liblist);
047b2264 16440
2b692964 16441 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
16442
16443 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
16444 ++cnt)
16445 {
16446 Elf32_Lib liblist;
91d6fa6a 16447 time_t atime;
d5b07ef4 16448 char timebuf[128];
2cf0635d 16449 struct tm * tmp;
047b2264
JJ
16450
16451 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16452 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
16453 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16454 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16455 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16456
91d6fa6a 16457 tmp = gmtime (&atime);
e9e44622
JJ
16458 snprintf (timebuf, sizeof (timebuf),
16459 "%04u-%02u-%02uT%02u:%02u:%02u",
16460 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16461 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
16462
16463 printf ("%3lu: ", (unsigned long) cnt);
16464 if (do_wide)
c256ffe7 16465 printf ("%-20s", liblist.l_name < strtab_size
2b692964 16466 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 16467 else
c256ffe7 16468 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 16469 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
16470 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
16471 liblist.l_version, liblist.l_flags);
16472 }
16473
16474 free (elib);
2842702f 16475 free (strtab);
047b2264
JJ
16476 }
16477 }
16478
32ec8896 16479 return res;
047b2264
JJ
16480}
16481
9437c45b 16482static const char *
dda8d76d 16483get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
16484{
16485 static char buff[64];
103f02d3 16486
dda8d76d 16487 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
16488 switch (e_type)
16489 {
57346661 16490 case NT_AUXV:
1ec5cd37 16491 return _("NT_AUXV (auxiliary vector)");
57346661 16492 case NT_PRSTATUS:
1ec5cd37 16493 return _("NT_PRSTATUS (prstatus structure)");
57346661 16494 case NT_FPREGSET:
1ec5cd37 16495 return _("NT_FPREGSET (floating point registers)");
57346661 16496 case NT_PRPSINFO:
1ec5cd37 16497 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 16498 case NT_TASKSTRUCT:
1ec5cd37 16499 return _("NT_TASKSTRUCT (task structure)");
57346661 16500 case NT_PRXFPREG:
1ec5cd37 16501 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
16502 case NT_PPC_VMX:
16503 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
16504 case NT_PPC_VSX:
16505 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
16506 case NT_PPC_TAR:
16507 return _("NT_PPC_TAR (ppc TAR register)");
16508 case NT_PPC_PPR:
16509 return _("NT_PPC_PPR (ppc PPR register)");
16510 case NT_PPC_DSCR:
16511 return _("NT_PPC_DSCR (ppc DSCR register)");
16512 case NT_PPC_EBB:
16513 return _("NT_PPC_EBB (ppc EBB registers)");
16514 case NT_PPC_PMU:
16515 return _("NT_PPC_PMU (ppc PMU registers)");
16516 case NT_PPC_TM_CGPR:
16517 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
16518 case NT_PPC_TM_CFPR:
16519 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
16520 case NT_PPC_TM_CVMX:
16521 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
16522 case NT_PPC_TM_CVSX:
16523 return _("NT_PPC_TM_VSX (ppc checkpointed VSX registers)");
16524 case NT_PPC_TM_SPR:
16525 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
16526 case NT_PPC_TM_CTAR:
16527 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
16528 case NT_PPC_TM_CPPR:
16529 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
16530 case NT_PPC_TM_CDSCR:
16531 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
16532 case NT_386_TLS:
16533 return _("NT_386_TLS (x86 TLS information)");
16534 case NT_386_IOPERM:
16535 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
16536 case NT_X86_XSTATE:
16537 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
16538 case NT_S390_HIGH_GPRS:
16539 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
16540 case NT_S390_TIMER:
16541 return _("NT_S390_TIMER (s390 timer register)");
16542 case NT_S390_TODCMP:
16543 return _("NT_S390_TODCMP (s390 TOD comparator register)");
16544 case NT_S390_TODPREG:
16545 return _("NT_S390_TODPREG (s390 TOD programmable register)");
16546 case NT_S390_CTRS:
16547 return _("NT_S390_CTRS (s390 control registers)");
16548 case NT_S390_PREFIX:
16549 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
16550 case NT_S390_LAST_BREAK:
16551 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
16552 case NT_S390_SYSTEM_CALL:
16553 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
16554 case NT_S390_TDB:
16555 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
16556 case NT_S390_VXRS_LOW:
16557 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
16558 case NT_S390_VXRS_HIGH:
16559 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
16560 case NT_S390_GS_CB:
16561 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
16562 case NT_S390_GS_BC:
16563 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
16564 case NT_ARM_VFP:
16565 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
16566 case NT_ARM_TLS:
16567 return _("NT_ARM_TLS (AArch TLS registers)");
16568 case NT_ARM_HW_BREAK:
16569 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
16570 case NT_ARM_HW_WATCH:
16571 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 16572 case NT_PSTATUS:
1ec5cd37 16573 return _("NT_PSTATUS (pstatus structure)");
57346661 16574 case NT_FPREGS:
1ec5cd37 16575 return _("NT_FPREGS (floating point registers)");
57346661 16576 case NT_PSINFO:
1ec5cd37 16577 return _("NT_PSINFO (psinfo structure)");
57346661 16578 case NT_LWPSTATUS:
1ec5cd37 16579 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 16580 case NT_LWPSINFO:
1ec5cd37 16581 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 16582 case NT_WIN32PSTATUS:
1ec5cd37 16583 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
16584 case NT_SIGINFO:
16585 return _("NT_SIGINFO (siginfo_t data)");
16586 case NT_FILE:
16587 return _("NT_FILE (mapped files)");
1ec5cd37
NC
16588 default:
16589 break;
16590 }
16591 else
16592 switch (e_type)
16593 {
16594 case NT_VERSION:
16595 return _("NT_VERSION (version)");
16596 case NT_ARCH:
16597 return _("NT_ARCH (architecture)");
9ef920e9 16598 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 16599 return _("OPEN");
9ef920e9 16600 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 16601 return _("func");
1ec5cd37
NC
16602 default:
16603 break;
16604 }
16605
e9e44622 16606 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 16607 return buff;
779fe533
NC
16608}
16609
32ec8896 16610static bfd_boolean
9ece1fa9
TT
16611print_core_note (Elf_Internal_Note *pnote)
16612{
16613 unsigned int addr_size = is_32bit_elf ? 4 : 8;
16614 bfd_vma count, page_size;
16615 unsigned char *descdata, *filenames, *descend;
16616
16617 if (pnote->type != NT_FILE)
04ac15ab
AS
16618 {
16619 if (do_wide)
16620 printf ("\n");
16621 return TRUE;
16622 }
9ece1fa9
TT
16623
16624#ifndef BFD64
16625 if (!is_32bit_elf)
16626 {
16627 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
16628 /* Still "successful". */
32ec8896 16629 return TRUE;
9ece1fa9
TT
16630 }
16631#endif
16632
16633 if (pnote->descsz < 2 * addr_size)
16634 {
32ec8896
NC
16635 error (_(" Malformed note - too short for header\n"));
16636 return FALSE;
9ece1fa9
TT
16637 }
16638
16639 descdata = (unsigned char *) pnote->descdata;
16640 descend = descdata + pnote->descsz;
16641
16642 if (descdata[pnote->descsz - 1] != '\0')
16643 {
32ec8896
NC
16644 error (_(" Malformed note - does not end with \\0\n"));
16645 return FALSE;
9ece1fa9
TT
16646 }
16647
16648 count = byte_get (descdata, addr_size);
16649 descdata += addr_size;
16650
16651 page_size = byte_get (descdata, addr_size);
16652 descdata += addr_size;
16653
5396a86e
AM
16654 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
16655 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 16656 {
32ec8896
NC
16657 error (_(" Malformed note - too short for supplied file count\n"));
16658 return FALSE;
9ece1fa9
TT
16659 }
16660
16661 printf (_(" Page size: "));
16662 print_vma (page_size, DEC);
16663 printf ("\n");
16664
16665 printf (_(" %*s%*s%*s\n"),
16666 (int) (2 + 2 * addr_size), _("Start"),
16667 (int) (4 + 2 * addr_size), _("End"),
16668 (int) (4 + 2 * addr_size), _("Page Offset"));
16669 filenames = descdata + count * 3 * addr_size;
595712bb 16670 while (count-- > 0)
9ece1fa9
TT
16671 {
16672 bfd_vma start, end, file_ofs;
16673
16674 if (filenames == descend)
16675 {
32ec8896
NC
16676 error (_(" Malformed note - filenames end too early\n"));
16677 return FALSE;
9ece1fa9
TT
16678 }
16679
16680 start = byte_get (descdata, addr_size);
16681 descdata += addr_size;
16682 end = byte_get (descdata, addr_size);
16683 descdata += addr_size;
16684 file_ofs = byte_get (descdata, addr_size);
16685 descdata += addr_size;
16686
16687 printf (" ");
16688 print_vma (start, FULL_HEX);
16689 printf (" ");
16690 print_vma (end, FULL_HEX);
16691 printf (" ");
16692 print_vma (file_ofs, FULL_HEX);
16693 printf ("\n %s\n", filenames);
16694
16695 filenames += 1 + strlen ((char *) filenames);
16696 }
16697
32ec8896 16698 return TRUE;
9ece1fa9
TT
16699}
16700
1118d252
RM
16701static const char *
16702get_gnu_elf_note_type (unsigned e_type)
16703{
1449284b 16704 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
16705 switch (e_type)
16706 {
16707 case NT_GNU_ABI_TAG:
16708 return _("NT_GNU_ABI_TAG (ABI version tag)");
16709 case NT_GNU_HWCAP:
16710 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
16711 case NT_GNU_BUILD_ID:
16712 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
16713 case NT_GNU_GOLD_VERSION:
16714 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
16715 case NT_GNU_PROPERTY_TYPE_0:
16716 return _("NT_GNU_PROPERTY_TYPE_0");
16717 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
16718 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
16719 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
16720 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 16721 default:
1449284b
NC
16722 {
16723 static char buff[64];
1118d252 16724
1449284b
NC
16725 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
16726 return buff;
16727 }
16728 }
1118d252
RM
16729}
16730
9ef920e9 16731static void
1fc87489 16732decode_x86_isa (unsigned int bitmask)
9ef920e9
NC
16733{
16734 while (bitmask)
16735 {
1fc87489 16736 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
16737
16738 bitmask &= ~ bit;
16739 switch (bit)
16740 {
16741 case GNU_PROPERTY_X86_ISA_1_486: printf ("i486"); break;
16742 case GNU_PROPERTY_X86_ISA_1_586: printf ("586"); break;
16743 case GNU_PROPERTY_X86_ISA_1_686: printf ("686"); break;
16744 case GNU_PROPERTY_X86_ISA_1_SSE: printf ("SSE"); break;
16745 case GNU_PROPERTY_X86_ISA_1_SSE2: printf ("SSE2"); break;
16746 case GNU_PROPERTY_X86_ISA_1_SSE3: printf ("SSE3"); break;
16747 case GNU_PROPERTY_X86_ISA_1_SSSE3: printf ("SSSE3"); break;
16748 case GNU_PROPERTY_X86_ISA_1_SSE4_1: printf ("SSE4_1"); break;
16749 case GNU_PROPERTY_X86_ISA_1_SSE4_2: printf ("SSE4_2"); break;
16750 case GNU_PROPERTY_X86_ISA_1_AVX: printf ("AVX"); break;
16751 case GNU_PROPERTY_X86_ISA_1_AVX2: printf ("AVX2"); break;
16752 case GNU_PROPERTY_X86_ISA_1_AVX512F: printf ("AVX512F"); break;
16753 case GNU_PROPERTY_X86_ISA_1_AVX512CD: printf ("AVX512CD"); break;
16754 case GNU_PROPERTY_X86_ISA_1_AVX512ER: printf ("AVX512ER"); break;
16755 case GNU_PROPERTY_X86_ISA_1_AVX512PF: printf ("AVX512PF"); break;
16756 case GNU_PROPERTY_X86_ISA_1_AVX512VL: printf ("AVX512VL"); break;
16757 case GNU_PROPERTY_X86_ISA_1_AVX512DQ: printf ("AVX512DQ"); break;
16758 case GNU_PROPERTY_X86_ISA_1_AVX512BW: printf ("AVX512BW"); break;
1fc87489 16759 default: printf (_("<unknown: %x>"), bit); break;
9ef920e9
NC
16760 }
16761 if (bitmask)
16762 printf (", ");
16763 }
16764}
16765
ee2fdd6f
L
16766static void
16767decode_x86_feature (unsigned int type, unsigned int bitmask)
16768{
16769 while (bitmask)
16770 {
16771 unsigned int bit = bitmask & (- bitmask);
16772
16773 bitmask &= ~ bit;
16774 switch (bit)
16775 {
16776 case GNU_PROPERTY_X86_FEATURE_1_IBT:
16777 switch (type)
16778 {
16779 case GNU_PROPERTY_X86_FEATURE_1_AND:
16780 printf ("IBT");
16781 break;
16782 default:
16783 /* This should never happen. */
16784 abort ();
16785 }
16786 break;
48580982
L
16787 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
16788 switch (type)
16789 {
16790 case GNU_PROPERTY_X86_FEATURE_1_AND:
16791 printf ("SHSTK");
16792 break;
16793 default:
16794 /* This should never happen. */
16795 abort ();
16796 }
16797 break;
ee2fdd6f
L
16798 default:
16799 printf (_("<unknown: %x>"), bit);
16800 break;
16801 }
16802 if (bitmask)
16803 printf (", ");
16804 }
16805}
16806
9ef920e9 16807static void
dda8d76d 16808print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
16809{
16810 unsigned char * ptr = (unsigned char *) pnote->descdata;
16811 unsigned char * ptr_end = ptr + pnote->descsz;
16812 unsigned int size = is_32bit_elf ? 4 : 8;
16813
16814 printf (_(" Properties: "));
16815
1fc87489 16816 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
16817 {
16818 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
16819 return;
16820 }
16821
6ab2c4ed 16822 while (ptr < ptr_end)
9ef920e9 16823 {
1fc87489 16824 unsigned int j;
6ab2c4ed
MC
16825 unsigned int type;
16826 unsigned int datasz;
16827
16828 if ((size_t) (ptr_end - ptr) < 8)
16829 {
16830 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
16831 break;
16832 }
16833
16834 type = byte_get (ptr, 4);
16835 datasz = byte_get (ptr + 4, 4);
9ef920e9 16836
1fc87489 16837 ptr += 8;
9ef920e9 16838
6ab2c4ed 16839 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 16840 {
1fc87489
L
16841 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
16842 type, datasz);
9ef920e9 16843 break;
1fc87489 16844 }
9ef920e9 16845
1fc87489
L
16846 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
16847 {
dda8d76d
NC
16848 if (filedata->file_header.e_machine == EM_X86_64
16849 || filedata->file_header.e_machine == EM_IAMCU
16850 || filedata->file_header.e_machine == EM_386)
1fc87489
L
16851 {
16852 switch (type)
16853 {
16854 case GNU_PROPERTY_X86_ISA_1_USED:
16855 printf ("x86 ISA used: ");
16856 if (datasz != 4)
16857 printf (_("<corrupt length: %#x> "), datasz);
16858 else
16859 decode_x86_isa (byte_get (ptr, 4));
16860 goto next;
9ef920e9 16861
1fc87489
L
16862 case GNU_PROPERTY_X86_ISA_1_NEEDED:
16863 printf ("x86 ISA needed: ");
16864 if (datasz != 4)
16865 printf (_("<corrupt length: %#x> "), datasz);
16866 else
16867 decode_x86_isa (byte_get (ptr, 4));
16868 goto next;
9ef920e9 16869
ee2fdd6f
L
16870 case GNU_PROPERTY_X86_FEATURE_1_AND:
16871 printf ("x86 feature: ");
16872 if (datasz != 4)
16873 printf (_("<corrupt length: %#x> "), datasz);
16874 else
16875 decode_x86_feature (type, byte_get (ptr, 4));
16876 goto next;
16877
1fc87489
L
16878 default:
16879 break;
16880 }
16881 }
16882 }
16883 else
16884 {
16885 switch (type)
9ef920e9 16886 {
1fc87489
L
16887 case GNU_PROPERTY_STACK_SIZE:
16888 printf (_("stack size: "));
16889 if (datasz != size)
16890 printf (_("<corrupt length: %#x> "), datasz);
16891 else
16892 printf ("%#lx", (unsigned long) byte_get (ptr, size));
16893 goto next;
16894
16895 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
16896 printf ("no copy on protected ");
16897 if (datasz)
16898 printf (_("<corrupt length: %#x> "), datasz);
16899 goto next;
16900
16901 default:
9ef920e9
NC
16902 break;
16903 }
9ef920e9
NC
16904 }
16905
1fc87489
L
16906 if (type < GNU_PROPERTY_LOPROC)
16907 printf (_("<unknown type %#x data: "), type);
16908 else if (type < GNU_PROPERTY_LOUSER)
16909 printf (_("<procesor-specific type %#x data: "), type);
16910 else
16911 printf (_("<application-specific type %#x data: "), type);
16912 for (j = 0; j < datasz; ++j)
16913 printf ("%02x ", ptr[j] & 0xff);
16914 printf (">");
16915
16916next:
9ef920e9 16917 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
16918 if (ptr == ptr_end)
16919 break;
1fc87489 16920
6ab2c4ed
MC
16921 if (do_wide)
16922 printf (", ");
16923 else
16924 printf ("\n\t");
9ef920e9
NC
16925 }
16926
16927 printf ("\n");
16928}
16929
32ec8896 16930static bfd_boolean
dda8d76d 16931print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 16932{
1449284b 16933 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
16934 switch (pnote->type)
16935 {
16936 case NT_GNU_BUILD_ID:
16937 {
16938 unsigned long i;
16939
16940 printf (_(" Build ID: "));
16941 for (i = 0; i < pnote->descsz; ++i)
16942 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 16943 printf ("\n");
664f90a3
TT
16944 }
16945 break;
16946
16947 case NT_GNU_ABI_TAG:
16948 {
16949 unsigned long os, major, minor, subminor;
16950 const char *osname;
16951
3102e897
NC
16952 /* PR 17531: file: 030-599401-0.004. */
16953 if (pnote->descsz < 16)
16954 {
16955 printf (_(" <corrupt GNU_ABI_TAG>\n"));
16956 break;
16957 }
16958
664f90a3
TT
16959 os = byte_get ((unsigned char *) pnote->descdata, 4);
16960 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
16961 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
16962 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
16963
16964 switch (os)
16965 {
16966 case GNU_ABI_TAG_LINUX:
16967 osname = "Linux";
16968 break;
16969 case GNU_ABI_TAG_HURD:
16970 osname = "Hurd";
16971 break;
16972 case GNU_ABI_TAG_SOLARIS:
16973 osname = "Solaris";
16974 break;
16975 case GNU_ABI_TAG_FREEBSD:
16976 osname = "FreeBSD";
16977 break;
16978 case GNU_ABI_TAG_NETBSD:
16979 osname = "NetBSD";
16980 break;
14ae95f2
RM
16981 case GNU_ABI_TAG_SYLLABLE:
16982 osname = "Syllable";
16983 break;
16984 case GNU_ABI_TAG_NACL:
16985 osname = "NaCl";
16986 break;
664f90a3
TT
16987 default:
16988 osname = "Unknown";
16989 break;
16990 }
16991
16992 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
16993 major, minor, subminor);
16994 }
16995 break;
926c5385
CC
16996
16997 case NT_GNU_GOLD_VERSION:
16998 {
16999 unsigned long i;
17000
17001 printf (_(" Version: "));
17002 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
17003 printf ("%c", pnote->descdata[i]);
17004 printf ("\n");
17005 }
17006 break;
1449284b
NC
17007
17008 case NT_GNU_HWCAP:
17009 {
17010 unsigned long num_entries, mask;
17011
17012 /* Hardware capabilities information. Word 0 is the number of entries.
17013 Word 1 is a bitmask of enabled entries. The rest of the descriptor
17014 is a series of entries, where each entry is a single byte followed
17015 by a nul terminated string. The byte gives the bit number to test
17016 if enabled in the bitmask. */
17017 printf (_(" Hardware Capabilities: "));
17018 if (pnote->descsz < 8)
17019 {
32ec8896
NC
17020 error (_("<corrupt GNU_HWCAP>\n"));
17021 return FALSE;
1449284b
NC
17022 }
17023 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
17024 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17025 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
17026 /* FIXME: Add code to display the entries... */
17027 }
17028 break;
17029
9ef920e9 17030 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 17031 print_gnu_property_note (filedata, pnote);
9ef920e9
NC
17032 break;
17033
1449284b
NC
17034 default:
17035 /* Handle unrecognised types. An error message should have already been
17036 created by get_gnu_elf_note_type(), so all that we need to do is to
17037 display the data. */
17038 {
17039 unsigned long i;
17040
17041 printf (_(" Description data: "));
17042 for (i = 0; i < pnote->descsz; ++i)
17043 printf ("%02x ", pnote->descdata[i] & 0xff);
17044 printf ("\n");
17045 }
17046 break;
664f90a3
TT
17047 }
17048
32ec8896 17049 return TRUE;
664f90a3
TT
17050}
17051
685080f2
NC
17052static const char *
17053get_v850_elf_note_type (enum v850_notes n_type)
17054{
17055 static char buff[64];
17056
17057 switch (n_type)
17058 {
17059 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
17060 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
17061 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
17062 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
17063 case V850_NOTE_CACHE_INFO: return _("Use of cache");
17064 case V850_NOTE_MMU_INFO: return _("Use of MMU");
17065 default:
17066 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
17067 return buff;
17068 }
17069}
17070
32ec8896 17071static bfd_boolean
685080f2
NC
17072print_v850_note (Elf_Internal_Note * pnote)
17073{
17074 unsigned int val;
17075
17076 if (pnote->descsz != 4)
32ec8896
NC
17077 return FALSE;
17078
685080f2
NC
17079 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
17080
17081 if (val == 0)
17082 {
17083 printf (_("not set\n"));
32ec8896 17084 return TRUE;
685080f2
NC
17085 }
17086
17087 switch (pnote->type)
17088 {
17089 case V850_NOTE_ALIGNMENT:
17090 switch (val)
17091 {
32ec8896
NC
17092 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
17093 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
17094 }
17095 break;
14ae95f2 17096
685080f2
NC
17097 case V850_NOTE_DATA_SIZE:
17098 switch (val)
17099 {
32ec8896
NC
17100 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
17101 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
17102 }
17103 break;
14ae95f2 17104
685080f2
NC
17105 case V850_NOTE_FPU_INFO:
17106 switch (val)
17107 {
32ec8896
NC
17108 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
17109 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
17110 }
17111 break;
14ae95f2 17112
685080f2
NC
17113 case V850_NOTE_MMU_INFO:
17114 case V850_NOTE_CACHE_INFO:
17115 case V850_NOTE_SIMD_INFO:
17116 if (val == EF_RH850_SIMD)
17117 {
17118 printf (_("yes\n"));
32ec8896 17119 return TRUE;
685080f2
NC
17120 }
17121 break;
17122
17123 default:
17124 /* An 'unknown note type' message will already have been displayed. */
17125 break;
17126 }
17127
17128 printf (_("unknown value: %x\n"), val);
32ec8896 17129 return FALSE;
685080f2
NC
17130}
17131
32ec8896 17132static bfd_boolean
c6056a74
SF
17133process_netbsd_elf_note (Elf_Internal_Note * pnote)
17134{
17135 unsigned int version;
17136
17137 switch (pnote->type)
17138 {
17139 case NT_NETBSD_IDENT:
17140 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
17141 if ((version / 10000) % 100)
17142 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
17143 version, version / 100000000, (version / 1000000) % 100,
17144 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 17145 'A' + (version / 10000) % 26);
c6056a74
SF
17146 else
17147 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
17148 version, version / 100000000, (version / 1000000) % 100,
15f205b1 17149 (version / 100) % 100);
32ec8896 17150 return TRUE;
c6056a74
SF
17151
17152 case NT_NETBSD_MARCH:
17153 printf (" NetBSD\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
17154 pnote->descdata);
32ec8896 17155 return TRUE;
c6056a74
SF
17156
17157 default:
32ec8896
NC
17158 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n", pnote->descsz,
17159 pnote->type);
17160 return FALSE;
c6056a74 17161 }
c6056a74
SF
17162}
17163
f4ddf30f 17164static const char *
dda8d76d 17165get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 17166{
f4ddf30f
JB
17167 switch (e_type)
17168 {
17169 case NT_FREEBSD_THRMISC:
17170 return _("NT_THRMISC (thrmisc structure)");
17171 case NT_FREEBSD_PROCSTAT_PROC:
17172 return _("NT_PROCSTAT_PROC (proc data)");
17173 case NT_FREEBSD_PROCSTAT_FILES:
17174 return _("NT_PROCSTAT_FILES (files data)");
17175 case NT_FREEBSD_PROCSTAT_VMMAP:
17176 return _("NT_PROCSTAT_VMMAP (vmmap data)");
17177 case NT_FREEBSD_PROCSTAT_GROUPS:
17178 return _("NT_PROCSTAT_GROUPS (groups data)");
17179 case NT_FREEBSD_PROCSTAT_UMASK:
17180 return _("NT_PROCSTAT_UMASK (umask data)");
17181 case NT_FREEBSD_PROCSTAT_RLIMIT:
17182 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
17183 case NT_FREEBSD_PROCSTAT_OSREL:
17184 return _("NT_PROCSTAT_OSREL (osreldate data)");
17185 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
17186 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
17187 case NT_FREEBSD_PROCSTAT_AUXV:
17188 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
17189 case NT_FREEBSD_PTLWPINFO:
17190 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 17191 }
dda8d76d 17192 return get_note_type (filedata, e_type);
f4ddf30f
JB
17193}
17194
9437c45b 17195static const char *
dda8d76d 17196get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
17197{
17198 static char buff[64];
17199
b4db1224 17200 if (e_type == NT_NETBSDCORE_PROCINFO)
dda8d76d 17201 return _("NetBSD procinfo structure");
9437c45b
JT
17202
17203 /* As of Jan 2002 there are no other machine-independent notes
17204 defined for NetBSD core files. If the note type is less
17205 than the start of the machine-dependent note types, we don't
17206 understand it. */
17207
b4db1224 17208 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 17209 {
e9e44622 17210 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
17211 return buff;
17212 }
17213
dda8d76d 17214 switch (filedata->file_header.e_machine)
9437c45b
JT
17215 {
17216 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
17217 and PT_GETFPREGS == mach+2. */
17218
17219 case EM_OLD_ALPHA:
17220 case EM_ALPHA:
17221 case EM_SPARC:
17222 case EM_SPARC32PLUS:
17223 case EM_SPARCV9:
17224 switch (e_type)
17225 {
2b692964 17226 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 17227 return _("PT_GETREGS (reg structure)");
2b692964 17228 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 17229 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17230 default:
17231 break;
17232 }
17233 break;
17234
17235 /* On all other arch's, PT_GETREGS == mach+1 and
17236 PT_GETFPREGS == mach+3. */
17237 default:
17238 switch (e_type)
17239 {
2b692964 17240 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 17241 return _("PT_GETREGS (reg structure)");
2b692964 17242 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 17243 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17244 default:
17245 break;
17246 }
17247 }
17248
9cf03b7e 17249 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 17250 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
17251 return buff;
17252}
17253
70616151
TT
17254static const char *
17255get_stapsdt_note_type (unsigned e_type)
17256{
17257 static char buff[64];
17258
17259 switch (e_type)
17260 {
17261 case NT_STAPSDT:
17262 return _("NT_STAPSDT (SystemTap probe descriptors)");
17263
17264 default:
17265 break;
17266 }
17267
17268 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17269 return buff;
17270}
17271
32ec8896 17272static bfd_boolean
c6a9fc58
TT
17273print_stapsdt_note (Elf_Internal_Note *pnote)
17274{
17275 int addr_size = is_32bit_elf ? 4 : 8;
17276 char *data = pnote->descdata;
17277 char *data_end = pnote->descdata + pnote->descsz;
17278 bfd_vma pc, base_addr, semaphore;
17279 char *provider, *probe, *arg_fmt;
17280
17281 pc = byte_get ((unsigned char *) data, addr_size);
17282 data += addr_size;
17283 base_addr = byte_get ((unsigned char *) data, addr_size);
17284 data += addr_size;
17285 semaphore = byte_get ((unsigned char *) data, addr_size);
17286 data += addr_size;
17287
17288 provider = data;
17289 data += strlen (data) + 1;
17290 probe = data;
17291 data += strlen (data) + 1;
17292 arg_fmt = data;
17293 data += strlen (data) + 1;
17294
17295 printf (_(" Provider: %s\n"), provider);
17296 printf (_(" Name: %s\n"), probe);
17297 printf (_(" Location: "));
17298 print_vma (pc, FULL_HEX);
17299 printf (_(", Base: "));
17300 print_vma (base_addr, FULL_HEX);
17301 printf (_(", Semaphore: "));
17302 print_vma (semaphore, FULL_HEX);
9cf03b7e 17303 printf ("\n");
c6a9fc58
TT
17304 printf (_(" Arguments: %s\n"), arg_fmt);
17305
17306 return data == data_end;
17307}
17308
00e98fc7
TG
17309static const char *
17310get_ia64_vms_note_type (unsigned e_type)
17311{
17312 static char buff[64];
17313
17314 switch (e_type)
17315 {
17316 case NT_VMS_MHD:
17317 return _("NT_VMS_MHD (module header)");
17318 case NT_VMS_LNM:
17319 return _("NT_VMS_LNM (language name)");
17320 case NT_VMS_SRC:
17321 return _("NT_VMS_SRC (source files)");
17322 case NT_VMS_TITLE:
9cf03b7e 17323 return "NT_VMS_TITLE";
00e98fc7
TG
17324 case NT_VMS_EIDC:
17325 return _("NT_VMS_EIDC (consistency check)");
17326 case NT_VMS_FPMODE:
17327 return _("NT_VMS_FPMODE (FP mode)");
17328 case NT_VMS_LINKTIME:
9cf03b7e 17329 return "NT_VMS_LINKTIME";
00e98fc7
TG
17330 case NT_VMS_IMGNAM:
17331 return _("NT_VMS_IMGNAM (image name)");
17332 case NT_VMS_IMGID:
17333 return _("NT_VMS_IMGID (image id)");
17334 case NT_VMS_LINKID:
17335 return _("NT_VMS_LINKID (link id)");
17336 case NT_VMS_IMGBID:
17337 return _("NT_VMS_IMGBID (build id)");
17338 case NT_VMS_GSTNAM:
17339 return _("NT_VMS_GSTNAM (sym table name)");
17340 case NT_VMS_ORIG_DYN:
9cf03b7e 17341 return "NT_VMS_ORIG_DYN";
00e98fc7 17342 case NT_VMS_PATCHTIME:
9cf03b7e 17343 return "NT_VMS_PATCHTIME";
00e98fc7
TG
17344 default:
17345 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17346 return buff;
17347 }
17348}
17349
32ec8896 17350static bfd_boolean
00e98fc7
TG
17351print_ia64_vms_note (Elf_Internal_Note * pnote)
17352{
17353 switch (pnote->type)
17354 {
17355 case NT_VMS_MHD:
17356 if (pnote->descsz > 36)
17357 {
17358 size_t l = strlen (pnote->descdata + 34);
17359 printf (_(" Creation date : %.17s\n"), pnote->descdata);
17360 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
17361 printf (_(" Module name : %s\n"), pnote->descdata + 34);
17362 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
17363 }
17364 else
17365 printf (_(" Invalid size\n"));
17366 break;
17367 case NT_VMS_LNM:
17368 printf (_(" Language: %s\n"), pnote->descdata);
17369 break;
17370#ifdef BFD64
17371 case NT_VMS_FPMODE:
9cf03b7e 17372 printf (_(" Floating Point mode: "));
4a5cb34f 17373 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 17374 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
17375 break;
17376 case NT_VMS_LINKTIME:
17377 printf (_(" Link time: "));
17378 print_vms_time
17379 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
17380 printf ("\n");
17381 break;
17382 case NT_VMS_PATCHTIME:
17383 printf (_(" Patch time: "));
17384 print_vms_time
17385 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
17386 printf ("\n");
17387 break;
17388 case NT_VMS_ORIG_DYN:
17389 printf (_(" Major id: %u, minor id: %u\n"),
17390 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
17391 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 17392 printf (_(" Last modified : "));
00e98fc7
TG
17393 print_vms_time
17394 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 17395 printf (_("\n Link flags : "));
4a5cb34f 17396 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 17397 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 17398 printf (_(" Header flags: 0x%08x\n"),
948f632f 17399 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
00e98fc7
TG
17400 printf (_(" Image id : %s\n"), pnote->descdata + 32);
17401 break;
17402#endif
17403 case NT_VMS_IMGNAM:
17404 printf (_(" Image name: %s\n"), pnote->descdata);
17405 break;
17406 case NT_VMS_GSTNAM:
17407 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
17408 break;
17409 case NT_VMS_IMGID:
17410 printf (_(" Image id: %s\n"), pnote->descdata);
17411 break;
17412 case NT_VMS_LINKID:
17413 printf (_(" Linker id: %s\n"), pnote->descdata);
17414 break;
17415 default:
32ec8896 17416 return FALSE;
00e98fc7 17417 }
32ec8896 17418 return TRUE;
00e98fc7
TG
17419}
17420
6f156d7a
NC
17421/* Find the symbol associated with a build attribute that is attached
17422 to address OFFSET. If PNAME is non-NULL then store the name of
17423 the symbol (if found) in the provided pointer, Returns NULL if a
17424 symbol could not be found. */
c799a79d 17425
6f156d7a
NC
17426static Elf_Internal_Sym *
17427get_symbol_for_build_attribute (Filedata * filedata,
17428 unsigned long offset,
17429 bfd_boolean is_open_attr,
17430 const char ** pname)
9ef920e9 17431{
dda8d76d 17432 static Filedata * saved_filedata = NULL;
c799a79d
NC
17433 static char * strtab;
17434 static unsigned long strtablen;
17435 static Elf_Internal_Sym * symtab;
17436 static unsigned long nsyms;
7296a62a
NC
17437 Elf_Internal_Sym * saved_sym = NULL;
17438 Elf_Internal_Sym * sym;
9ef920e9 17439
dda8d76d
NC
17440 if (filedata->section_headers != NULL
17441 && (saved_filedata == NULL || filedata != saved_filedata))
9ef920e9 17442 {
c799a79d 17443 Elf_Internal_Shdr * symsec;
9ef920e9 17444
c799a79d 17445 /* Load the symbol and string sections. */
dda8d76d
NC
17446 for (symsec = filedata->section_headers;
17447 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 17448 symsec ++)
9ef920e9 17449 {
c799a79d 17450 if (symsec->sh_type == SHT_SYMTAB)
9ef920e9 17451 {
dda8d76d 17452 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
9ef920e9 17453
dda8d76d 17454 if (symsec->sh_link < filedata->file_header.e_shnum)
c799a79d 17455 {
dda8d76d 17456 Elf_Internal_Shdr * strtab_sec = filedata->section_headers + symsec->sh_link;
c799a79d 17457
dda8d76d 17458 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
c799a79d
NC
17459 1, strtab_sec->sh_size,
17460 _("string table"));
17461 strtablen = strtab != NULL ? strtab_sec->sh_size : 0;
17462 }
9ef920e9
NC
17463 }
17464 }
dda8d76d 17465 saved_filedata = filedata;
9ef920e9
NC
17466 }
17467
c799a79d 17468 if (symtab == NULL || strtab == NULL)
6f156d7a 17469 return NULL;
9ef920e9 17470
c799a79d
NC
17471 /* Find a symbol whose value matches offset. */
17472 for (sym = symtab; sym < symtab + nsyms; sym ++)
17473 if (sym->st_value == offset)
17474 {
17475 if (sym->st_name >= strtablen)
17476 /* Huh ? This should not happen. */
17477 continue;
9ef920e9 17478
c799a79d
NC
17479 if (strtab[sym->st_name] == 0)
17480 continue;
9ef920e9 17481
8fd75781
NC
17482 /* The AArch64 and ARM architectures define mapping symbols
17483 (eg $d, $x, $t) which we want to ignore. */
17484 if (strtab[sym->st_name] == '$'
17485 && strtab[sym->st_name + 1] != 0
17486 && strtab[sym->st_name + 2] == 0)
17487 continue;
17488
c799a79d
NC
17489 if (is_open_attr)
17490 {
17491 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
17492 and FILE or OBJECT symbols over NOTYPE symbols. We skip
17493 FUNC symbols entirely. */
17494 switch (ELF_ST_TYPE (sym->st_info))
17495 {
c799a79d 17496 case STT_OBJECT:
6f156d7a 17497 case STT_FILE:
c799a79d 17498 saved_sym = sym;
6f156d7a
NC
17499 if (sym->st_size)
17500 {
17501 /* If the symbol has a size associated
17502 with it then we can stop searching. */
17503 sym = symtab + nsyms;
17504 }
c799a79d 17505 continue;
9ef920e9 17506
c799a79d
NC
17507 case STT_FUNC:
17508 /* Ignore function symbols. */
17509 continue;
17510
17511 default:
17512 break;
17513 }
17514
17515 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 17516 {
c799a79d
NC
17517 case STB_GLOBAL:
17518 if (saved_sym == NULL
17519 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
17520 saved_sym = sym;
17521 break;
c871dade 17522
c799a79d
NC
17523 case STB_LOCAL:
17524 if (saved_sym == NULL)
17525 saved_sym = sym;
17526 break;
17527
17528 default:
9ef920e9
NC
17529 break;
17530 }
17531 }
c799a79d
NC
17532 else
17533 {
17534 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
17535 continue;
17536
17537 saved_sym = sym;
17538 break;
17539 }
17540 }
17541
6f156d7a
NC
17542 if (saved_sym && pname)
17543 * pname = strtab + saved_sym->st_name;
17544
17545 return saved_sym;
c799a79d
NC
17546}
17547
17548static bfd_boolean
dda8d76d
NC
17549print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
17550 Filedata * filedata)
c799a79d 17551{
6f156d7a
NC
17552 static unsigned long global_offset = 0;
17553 static unsigned long global_end = 0;
17554 static unsigned long func_offset = 0;
17555 static unsigned long func_end = 0;
c871dade 17556
6f156d7a
NC
17557 Elf_Internal_Sym * sym;
17558 const char * name;
17559 unsigned long start;
17560 unsigned long end;
17561 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
17562
17563 switch (pnote->descsz)
c799a79d 17564 {
6f156d7a
NC
17565 case 0:
17566 /* A zero-length description means that the range of
17567 the previous note of the same type should be used. */
c799a79d 17568 if (is_open_attr)
c871dade 17569 {
6f156d7a
NC
17570 if (global_end > global_offset)
17571 printf (_(" Applies to region from %#lx to %#lx\n"),
17572 global_offset, global_end);
17573 else
17574 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
17575 }
17576 else
17577 {
6f156d7a
NC
17578 if (func_end > func_offset)
17579 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
17580 else
17581 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 17582 }
6f156d7a 17583 return TRUE;
9ef920e9 17584
6f156d7a
NC
17585 case 4:
17586 start = byte_get ((unsigned char *) pnote->descdata, 4);
17587 end = 0;
17588 break;
17589
17590 case 8:
17591 if (is_32bit_elf)
17592 {
17593 /* FIXME: We should check that version 3+ notes are being used here... */
17594 start = byte_get ((unsigned char *) pnote->descdata, 4);
17595 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17596 }
17597 else
17598 {
17599 start = byte_get ((unsigned char *) pnote->descdata, 8);
17600 end = 0;
17601 }
17602 break;
17603
17604 case 16:
17605 start = byte_get ((unsigned char *) pnote->descdata, 8);
17606 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
17607 break;
17608
17609 default:
c799a79d
NC
17610 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
17611 printf (_(" <invalid descsz>"));
17612 return FALSE;
17613 }
17614
6f156d7a
NC
17615 name = NULL;
17616 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
17617 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
17618 in order to avoid them being confused with the start address of the
17619 first function in the file... */
17620 if (sym == NULL && is_open_attr)
17621 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
17622 & name);
6f156d7a
NC
17623
17624 if (end == 0 && sym != NULL && sym->st_size > 0)
17625 end = start + sym->st_size;
c799a79d
NC
17626
17627 if (is_open_attr)
17628 {
6f156d7a
NC
17629 /* FIXME: Need to properly allow for section alignment. 16 is just the alignment used on x86_64. */
17630 if (global_end > 0 && start > BFD_ALIGN (global_end, 16))
17631 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
17632 global_end + 1, start - 1);
17633
17634 printf (_(" Applies to region from %#lx"), start);
17635 global_offset = start;
17636
17637 if (end)
17638 {
17639 printf (_(" to %#lx"), end);
17640 global_end = end;
17641 }
c799a79d
NC
17642 }
17643 else
17644 {
6f156d7a
NC
17645 printf (_(" Applies to region from %#lx"), start);
17646 func_offset = start;
17647
17648 if (end)
17649 {
17650 printf (_(" to %#lx"), end);
17651 func_end = end;
17652 }
c799a79d
NC
17653 }
17654
6f156d7a
NC
17655 if (sym && name)
17656 printf (_(" (%s)"), name);
17657
17658 printf ("\n");
17659 return TRUE;
9ef920e9
NC
17660}
17661
17662static bfd_boolean
17663print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
17664{
1d15e434
NC
17665 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
17666 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
17667 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
17668 char name_type;
17669 char name_attribute;
1d15e434 17670 const char * expected_types;
9ef920e9
NC
17671 const char * name = pnote->namedata;
17672 const char * text;
88305e1b 17673 signed int left;
9ef920e9
NC
17674
17675 if (name == NULL || pnote->namesz < 2)
17676 {
17677 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 17678 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
17679 return FALSE;
17680 }
17681
6f156d7a
NC
17682 if (do_wide)
17683 left = 28;
17684 else
17685 left = 20;
88305e1b
NC
17686
17687 /* Version 2 of the spec adds a "GA" prefix to the name field. */
17688 if (name[0] == 'G' && name[1] == 'A')
17689 {
6f156d7a
NC
17690 if (pnote->namesz < 4)
17691 {
17692 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
17693 print_symbol (-20, _(" <corrupt name>"));
17694 return FALSE;
17695 }
17696
88305e1b
NC
17697 printf ("GA");
17698 name += 2;
17699 left -= 2;
17700 }
17701
9ef920e9
NC
17702 switch ((name_type = * name))
17703 {
17704 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
17705 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
17706 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
17707 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
17708 printf ("%c", * name);
88305e1b 17709 left --;
9ef920e9
NC
17710 break;
17711 default:
17712 error (_("unrecognised attribute type in name field: %d\n"), name_type);
17713 print_symbol (-20, _("<unknown name type>"));
17714 return FALSE;
17715 }
17716
9ef920e9
NC
17717 ++ name;
17718 text = NULL;
17719
17720 switch ((name_attribute = * name))
17721 {
17722 case GNU_BUILD_ATTRIBUTE_VERSION:
17723 text = _("<version>");
1d15e434 17724 expected_types = string_expected;
9ef920e9
NC
17725 ++ name;
17726 break;
17727 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
17728 text = _("<stack prot>");
75d7d298 17729 expected_types = "!+*";
9ef920e9
NC
17730 ++ name;
17731 break;
17732 case GNU_BUILD_ATTRIBUTE_RELRO:
17733 text = _("<relro>");
1d15e434 17734 expected_types = bool_expected;
9ef920e9
NC
17735 ++ name;
17736 break;
17737 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
17738 text = _("<stack size>");
1d15e434 17739 expected_types = number_expected;
9ef920e9
NC
17740 ++ name;
17741 break;
17742 case GNU_BUILD_ATTRIBUTE_TOOL:
17743 text = _("<tool>");
1d15e434 17744 expected_types = string_expected;
9ef920e9
NC
17745 ++ name;
17746 break;
17747 case GNU_BUILD_ATTRIBUTE_ABI:
17748 text = _("<ABI>");
17749 expected_types = "$*";
17750 ++ name;
17751 break;
17752 case GNU_BUILD_ATTRIBUTE_PIC:
17753 text = _("<PIC>");
1d15e434 17754 expected_types = number_expected;
9ef920e9
NC
17755 ++ name;
17756 break;
a8be5506
NC
17757 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
17758 text = _("<short enum>");
1d15e434 17759 expected_types = bool_expected;
a8be5506
NC
17760 ++ name;
17761 break;
9ef920e9
NC
17762 default:
17763 if (ISPRINT (* name))
17764 {
17765 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
17766
17767 if (len > left && ! do_wide)
17768 len = left;
75d7d298 17769 printf ("%.*s:", len, name);
9ef920e9 17770 left -= len;
0dd6ae21 17771 name += len;
9ef920e9
NC
17772 }
17773 else
17774 {
3e6b6445 17775 static char tmpbuf [128];
88305e1b 17776
3e6b6445
NC
17777 error (_("unrecognised byte in name field: %d\n"), * name);
17778 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
17779 text = tmpbuf;
17780 name ++;
9ef920e9
NC
17781 }
17782 expected_types = "*$!+";
17783 break;
17784 }
17785
17786 if (text)
88305e1b 17787 left -= printf ("%s", text);
9ef920e9
NC
17788
17789 if (strchr (expected_types, name_type) == NULL)
75d7d298 17790 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
17791
17792 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
17793 {
17794 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
17795 (unsigned long) pnote->namesz,
17796 (long) (name - pnote->namedata));
17797 return FALSE;
17798 }
17799
17800 if (left < 1 && ! do_wide)
17801 return TRUE;
17802
17803 switch (name_type)
17804 {
17805 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
17806 {
b06b2c92 17807 unsigned int bytes;
ddef72cd
NC
17808 unsigned long long val = 0;
17809 unsigned int shift = 0;
17810 char * decoded = NULL;
17811
b06b2c92
NC
17812 bytes = pnote->namesz - (name - pnote->namedata);
17813 if (bytes > 0)
17814 /* The -1 is because the name field is always 0 terminated, and we
17815 want to be able to ensure that the shift in the while loop below
17816 will not overflow. */
17817 -- bytes;
17818
ddef72cd
NC
17819 if (bytes > sizeof (val))
17820 {
3e6b6445
NC
17821 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
17822 bytes);
17823 bytes = sizeof (val);
ddef72cd 17824 }
3e6b6445
NC
17825 /* We do not bother to warn if bytes == 0 as this can
17826 happen with some early versions of the gcc plugin. */
9ef920e9
NC
17827
17828 while (bytes --)
17829 {
79a964dc
NC
17830 unsigned long byte = (* name ++) & 0xff;
17831
17832 val |= byte << shift;
9ef920e9
NC
17833 shift += 8;
17834 }
17835
75d7d298 17836 switch (name_attribute)
9ef920e9 17837 {
75d7d298 17838 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
17839 switch (val)
17840 {
75d7d298
NC
17841 case 0: decoded = "static"; break;
17842 case 1: decoded = "pic"; break;
17843 case 2: decoded = "PIC"; break;
17844 case 3: decoded = "pie"; break;
17845 case 4: decoded = "PIE"; break;
17846 default: break;
9ef920e9 17847 }
75d7d298
NC
17848 break;
17849 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
17850 switch (val)
9ef920e9 17851 {
75d7d298
NC
17852 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
17853 case 0: decoded = "off"; break;
17854 case 1: decoded = "on"; break;
17855 case 2: decoded = "all"; break;
17856 case 3: decoded = "strong"; break;
17857 case 4: decoded = "explicit"; break;
17858 default: break;
9ef920e9 17859 }
75d7d298
NC
17860 break;
17861 default:
17862 break;
9ef920e9
NC
17863 }
17864
75d7d298 17865 if (decoded != NULL)
3e6b6445
NC
17866 {
17867 print_symbol (-left, decoded);
17868 left = 0;
17869 }
17870 else if (val == 0)
17871 {
17872 printf ("0x0");
17873 left -= 3;
17874 }
9ef920e9 17875 else
75d7d298
NC
17876 {
17877 if (do_wide)
ddef72cd 17878 left -= printf ("0x%llx", val);
75d7d298 17879 else
ddef72cd 17880 left -= printf ("0x%-.*llx", left, val);
75d7d298 17881 }
9ef920e9
NC
17882 }
17883 break;
17884 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
17885 left -= print_symbol (- left, name);
17886 break;
17887 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
17888 left -= print_symbol (- left, "true");
17889 break;
17890 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
17891 left -= print_symbol (- left, "false");
17892 break;
17893 }
17894
17895 if (do_wide && left > 0)
17896 printf ("%-*s", left, " ");
17897
17898 return TRUE;
17899}
17900
6d118b09
NC
17901/* Note that by the ELF standard, the name field is already null byte
17902 terminated, and namesz includes the terminating null byte.
17903 I.E. the value of namesz for the name "FSF" is 4.
17904
e3c8793a 17905 If the value of namesz is zero, there is no name present. */
9ef920e9 17906
32ec8896 17907static bfd_boolean
9ef920e9 17908process_note (Elf_Internal_Note * pnote,
dda8d76d 17909 Filedata * filedata)
779fe533 17910{
2cf0635d
NC
17911 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
17912 const char * nt;
9437c45b
JT
17913
17914 if (pnote->namesz == 0)
1ec5cd37
NC
17915 /* If there is no note name, then use the default set of
17916 note type strings. */
dda8d76d 17917 nt = get_note_type (filedata, pnote->type);
1ec5cd37 17918
1118d252
RM
17919 else if (const_strneq (pnote->namedata, "GNU"))
17920 /* GNU-specific object file notes. */
17921 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
17922
17923 else if (const_strneq (pnote->namedata, "FreeBSD"))
17924 /* FreeBSD-specific core file notes. */
dda8d76d 17925 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 17926
0112cd26 17927 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 17928 /* NetBSD-specific core file notes. */
dda8d76d 17929 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 17930
c6056a74
SF
17931 else if (const_strneq (pnote->namedata, "NetBSD"))
17932 /* NetBSD-specific core file notes. */
17933 return process_netbsd_elf_note (pnote);
17934
b15fa79e
AM
17935 else if (strneq (pnote->namedata, "SPU/", 4))
17936 {
17937 /* SPU-specific core file notes. */
17938 nt = pnote->namedata + 4;
17939 name = "SPU";
17940 }
17941
00e98fc7
TG
17942 else if (const_strneq (pnote->namedata, "IPF/VMS"))
17943 /* VMS/ia64-specific file notes. */
17944 nt = get_ia64_vms_note_type (pnote->type);
17945
70616151
TT
17946 else if (const_strneq (pnote->namedata, "stapsdt"))
17947 nt = get_stapsdt_note_type (pnote->type);
17948
9437c45b 17949 else
1ec5cd37
NC
17950 /* Don't recognize this note name; just use the default set of
17951 note type strings. */
dda8d76d 17952 nt = get_note_type (filedata, pnote->type);
9437c45b 17953
1449284b 17954 printf (" ");
9ef920e9 17955
483767a3
AM
17956 if (((const_strneq (pnote->namedata, "GA")
17957 && strchr ("*$!+", pnote->namedata[2]) != NULL)
17958 || strchr ("*$!+", pnote->namedata[0]) != NULL)
17959 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
17960 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
17961 print_gnu_build_attribute_name (pnote);
17962 else
17963 print_symbol (-20, name);
17964
17965 if (do_wide)
17966 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
17967 else
17968 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
17969
17970 if (const_strneq (pnote->namedata, "IPF/VMS"))
17971 return print_ia64_vms_note (pnote);
664f90a3 17972 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 17973 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
17974 else if (const_strneq (pnote->namedata, "stapsdt"))
17975 return print_stapsdt_note (pnote);
9ece1fa9
TT
17976 else if (const_strneq (pnote->namedata, "CORE"))
17977 return print_core_note (pnote);
483767a3
AM
17978 else if (((const_strneq (pnote->namedata, "GA")
17979 && strchr ("*$!+", pnote->namedata[2]) != NULL)
17980 || strchr ("*$!+", pnote->namedata[0]) != NULL)
17981 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
17982 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 17983 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 17984
9ef920e9 17985 if (pnote->descsz)
1449284b
NC
17986 {
17987 unsigned long i;
17988
17989 printf (_(" description data: "));
17990 for (i = 0; i < pnote->descsz; i++)
17991 printf ("%02x ", pnote->descdata[i]);
04ac15ab
AS
17992 if (!do_wide)
17993 printf ("\n");
1449284b
NC
17994 }
17995
9ef920e9
NC
17996 if (do_wide)
17997 printf ("\n");
17998
32ec8896 17999 return TRUE;
1449284b 18000}
6d118b09 18001
32ec8896 18002static bfd_boolean
dda8d76d
NC
18003process_notes_at (Filedata * filedata,
18004 Elf_Internal_Shdr * section,
18005 bfd_vma offset,
82ed9683
L
18006 bfd_vma length,
18007 bfd_vma align)
779fe533 18008{
2cf0635d
NC
18009 Elf_External_Note * pnotes;
18010 Elf_External_Note * external;
4dff97b2
NC
18011 char * end;
18012 bfd_boolean res = TRUE;
103f02d3 18013
779fe533 18014 if (length <= 0)
32ec8896 18015 return FALSE;
103f02d3 18016
1449284b
NC
18017 if (section)
18018 {
dda8d76d 18019 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 18020 if (pnotes)
32ec8896 18021 {
dda8d76d 18022 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
32ec8896
NC
18023 return FALSE;
18024 }
1449284b
NC
18025 }
18026 else
82ed9683 18027 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 18028 _("notes"));
4dff97b2 18029
dd24e3da 18030 if (pnotes == NULL)
32ec8896 18031 return FALSE;
779fe533 18032
103f02d3 18033 external = pnotes;
103f02d3 18034
1449284b 18035 if (section)
dda8d76d 18036 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
18037 else
18038 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
18039 (unsigned long) offset, (unsigned long) length);
18040
82ed9683
L
18041 /* NB: Some note sections may have alignment value of 0 or 1. gABI
18042 specifies that notes should be aligned to 4 bytes in 32-bit
18043 objects and to 8 bytes in 64-bit objects. As a Linux extension,
18044 we also support 4 byte alignment in 64-bit objects. If section
18045 alignment is less than 4, we treate alignment as 4 bytes. */
18046 if (align < 4)
18047 align = 4;
18048 else if (align != 4 && align != 8)
18049 {
18050 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
18051 (long) align);
18052 return FALSE;
18053 }
18054
2aee03ae 18055 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 18056
c8071705
NC
18057 end = (char *) pnotes + length;
18058 while ((char *) external < end)
779fe533 18059 {
b34976b6 18060 Elf_Internal_Note inote;
15b42fb0 18061 size_t min_notesz;
4dff97b2 18062 char * next;
2cf0635d 18063 char * temp = NULL;
c8071705 18064 size_t data_remaining = end - (char *) external;
6d118b09 18065
dda8d76d 18066 if (!is_ia64_vms (filedata))
15b42fb0 18067 {
9dd3a467
NC
18068 /* PR binutils/15191
18069 Make sure that there is enough data to read. */
15b42fb0
AM
18070 min_notesz = offsetof (Elf_External_Note, name);
18071 if (data_remaining < min_notesz)
9dd3a467 18072 {
d3a49aa8
AM
18073 warn (ngettext ("Corrupt note: only %ld byte remains, "
18074 "not enough for a full note\n",
18075 "Corrupt note: only %ld bytes remain, "
18076 "not enough for a full note\n",
18077 data_remaining),
18078 (long) data_remaining);
9dd3a467
NC
18079 break;
18080 }
5396a86e
AM
18081 data_remaining -= min_notesz;
18082
15b42fb0
AM
18083 inote.type = BYTE_GET (external->type);
18084 inote.namesz = BYTE_GET (external->namesz);
18085 inote.namedata = external->name;
18086 inote.descsz = BYTE_GET (external->descsz);
276da9b3 18087 inote.descdata = ((char *) external
4dff97b2 18088 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 18089 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 18090 next = ((char *) external
4dff97b2 18091 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 18092 }
00e98fc7 18093 else
15b42fb0
AM
18094 {
18095 Elf64_External_VMS_Note *vms_external;
00e98fc7 18096
9dd3a467
NC
18097 /* PR binutils/15191
18098 Make sure that there is enough data to read. */
15b42fb0
AM
18099 min_notesz = offsetof (Elf64_External_VMS_Note, name);
18100 if (data_remaining < min_notesz)
9dd3a467 18101 {
d3a49aa8
AM
18102 warn (ngettext ("Corrupt note: only %ld byte remains, "
18103 "not enough for a full note\n",
18104 "Corrupt note: only %ld bytes remain, "
18105 "not enough for a full note\n",
18106 data_remaining),
18107 (long) data_remaining);
9dd3a467
NC
18108 break;
18109 }
5396a86e 18110 data_remaining -= min_notesz;
3e55a963 18111
15b42fb0
AM
18112 vms_external = (Elf64_External_VMS_Note *) external;
18113 inote.type = BYTE_GET (vms_external->type);
18114 inote.namesz = BYTE_GET (vms_external->namesz);
18115 inote.namedata = vms_external->name;
18116 inote.descsz = BYTE_GET (vms_external->descsz);
18117 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
18118 inote.descpos = offset + (inote.descdata - (char *) pnotes);
18119 next = inote.descdata + align_power (inote.descsz, 3);
18120 }
18121
5396a86e
AM
18122 /* PR 17531: file: 3443835e. */
18123 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
18124 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
18125 || (size_t) (inote.descdata - inote.namedata) > data_remaining
18126 || (size_t) (next - inote.descdata) < inote.descsz
18127 || ((size_t) (next - inote.descdata)
18128 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 18129 {
15b42fb0 18130 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 18131 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
18132 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
18133 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
18134 break;
18135 }
18136
15b42fb0 18137 external = (Elf_External_Note *) next;
dd24e3da 18138
6d118b09
NC
18139 /* Verify that name is null terminated. It appears that at least
18140 one version of Linux (RedHat 6.0) generates corefiles that don't
18141 comply with the ELF spec by failing to include the null byte in
18142 namesz. */
8b971f9f 18143 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 18144 {
5396a86e 18145 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 18146 {
5396a86e
AM
18147 temp = (char *) malloc (inote.namesz + 1);
18148 if (temp == NULL)
18149 {
18150 error (_("Out of memory allocating space for inote name\n"));
18151 res = FALSE;
18152 break;
18153 }
76da6bbe 18154
5396a86e
AM
18155 memcpy (temp, inote.namedata, inote.namesz);
18156 inote.namedata = temp;
18157 }
18158 inote.namedata[inote.namesz] = 0;
6d118b09
NC
18159 }
18160
dda8d76d 18161 if (! process_note (& inote, filedata))
6b4bf3bc 18162 res = FALSE;
103f02d3 18163
6d118b09
NC
18164 if (temp != NULL)
18165 {
18166 free (temp);
18167 temp = NULL;
18168 }
779fe533
NC
18169 }
18170
18171 free (pnotes);
103f02d3 18172
779fe533
NC
18173 return res;
18174}
18175
32ec8896 18176static bfd_boolean
dda8d76d 18177process_corefile_note_segments (Filedata * filedata)
779fe533 18178{
2cf0635d 18179 Elf_Internal_Phdr * segment;
b34976b6 18180 unsigned int i;
32ec8896 18181 bfd_boolean res = TRUE;
103f02d3 18182
dda8d76d 18183 if (! get_program_headers (filedata))
6b4bf3bc 18184 return TRUE;
103f02d3 18185
dda8d76d
NC
18186 for (i = 0, segment = filedata->program_headers;
18187 i < filedata->file_header.e_phnum;
b34976b6 18188 i++, segment++)
779fe533
NC
18189 {
18190 if (segment->p_type == PT_NOTE)
dda8d76d 18191 if (! process_notes_at (filedata, NULL,
32ec8896 18192 (bfd_vma) segment->p_offset,
82ed9683
L
18193 (bfd_vma) segment->p_filesz,
18194 (bfd_vma) segment->p_align))
32ec8896 18195 res = FALSE;
779fe533 18196 }
103f02d3 18197
779fe533
NC
18198 return res;
18199}
18200
32ec8896 18201static bfd_boolean
dda8d76d 18202process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
18203{
18204 Elf_External_Note * pnotes;
18205 Elf_External_Note * external;
c8071705 18206 char * end;
32ec8896 18207 bfd_boolean res = TRUE;
685080f2
NC
18208
18209 if (length <= 0)
32ec8896 18210 return FALSE;
685080f2 18211
dda8d76d 18212 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
18213 _("v850 notes"));
18214 if (pnotes == NULL)
32ec8896 18215 return FALSE;
685080f2
NC
18216
18217 external = pnotes;
c8071705 18218 end = (char*) pnotes + length;
685080f2
NC
18219
18220 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
18221 (unsigned long) offset, (unsigned long) length);
18222
c8071705 18223 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
18224 {
18225 Elf_External_Note * next;
18226 Elf_Internal_Note inote;
18227
18228 inote.type = BYTE_GET (external->type);
18229 inote.namesz = BYTE_GET (external->namesz);
18230 inote.namedata = external->name;
18231 inote.descsz = BYTE_GET (external->descsz);
18232 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
18233 inote.descpos = offset + (inote.descdata - (char *) pnotes);
18234
c8071705
NC
18235 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
18236 {
18237 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
18238 inote.descdata = inote.namedata;
18239 inote.namesz = 0;
18240 }
18241
685080f2
NC
18242 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
18243
c8071705 18244 if ( ((char *) next > end)
685080f2
NC
18245 || ((char *) next < (char *) pnotes))
18246 {
18247 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
18248 (unsigned long) ((char *) external - (char *) pnotes));
18249 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
18250 inote.type, inote.namesz, inote.descsz);
18251 break;
18252 }
18253
18254 external = next;
18255
18256 /* Prevent out-of-bounds indexing. */
c8071705 18257 if ( inote.namedata + inote.namesz > end
685080f2
NC
18258 || inote.namedata + inote.namesz < inote.namedata)
18259 {
18260 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
18261 (unsigned long) ((char *) external - (char *) pnotes));
18262 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
18263 inote.type, inote.namesz, inote.descsz);
18264 break;
18265 }
18266
18267 printf (" %s: ", get_v850_elf_note_type (inote.type));
18268
18269 if (! print_v850_note (& inote))
18270 {
32ec8896 18271 res = FALSE;
685080f2
NC
18272 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
18273 inote.namesz, inote.descsz);
18274 }
18275 }
18276
18277 free (pnotes);
18278
18279 return res;
18280}
18281
32ec8896 18282static bfd_boolean
dda8d76d 18283process_note_sections (Filedata * filedata)
1ec5cd37 18284{
2cf0635d 18285 Elf_Internal_Shdr * section;
1ec5cd37 18286 unsigned long i;
32ec8896
NC
18287 unsigned int n = 0;
18288 bfd_boolean res = TRUE;
1ec5cd37 18289
dda8d76d
NC
18290 for (i = 0, section = filedata->section_headers;
18291 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 18292 i++, section++)
685080f2
NC
18293 {
18294 if (section->sh_type == SHT_NOTE)
18295 {
dda8d76d 18296 if (! process_notes_at (filedata, section,
32ec8896 18297 (bfd_vma) section->sh_offset,
82ed9683
L
18298 (bfd_vma) section->sh_size,
18299 (bfd_vma) section->sh_addralign))
32ec8896 18300 res = FALSE;
685080f2
NC
18301 n++;
18302 }
18303
dda8d76d
NC
18304 if (( filedata->file_header.e_machine == EM_V800
18305 || filedata->file_header.e_machine == EM_V850
18306 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
18307 && section->sh_type == SHT_RENESAS_INFO)
18308 {
dda8d76d 18309 if (! process_v850_notes (filedata,
32ec8896
NC
18310 (bfd_vma) section->sh_offset,
18311 (bfd_vma) section->sh_size))
18312 res = FALSE;
685080f2
NC
18313 n++;
18314 }
18315 }
df565f32
NC
18316
18317 if (n == 0)
18318 /* Try processing NOTE segments instead. */
dda8d76d 18319 return process_corefile_note_segments (filedata);
1ec5cd37
NC
18320
18321 return res;
18322}
18323
32ec8896 18324static bfd_boolean
dda8d76d 18325process_notes (Filedata * filedata)
779fe533
NC
18326{
18327 /* If we have not been asked to display the notes then do nothing. */
18328 if (! do_notes)
32ec8896 18329 return TRUE;
103f02d3 18330
dda8d76d
NC
18331 if (filedata->file_header.e_type != ET_CORE)
18332 return process_note_sections (filedata);
103f02d3 18333
779fe533 18334 /* No program headers means no NOTE segment. */
dda8d76d
NC
18335 if (filedata->file_header.e_phnum > 0)
18336 return process_corefile_note_segments (filedata);
779fe533 18337
1ec5cd37 18338 printf (_("No note segments present in the core file.\n"));
32ec8896 18339 return TRUE;
779fe533
NC
18340}
18341
60abdbed
NC
18342static unsigned char *
18343display_public_gnu_attributes (unsigned char * start,
18344 const unsigned char * const end)
18345{
18346 printf (_(" Unknown GNU attribute: %s\n"), start);
18347
18348 start += strnlen ((char *) start, end - start);
18349 display_raw_attribute (start, end);
18350
18351 return (unsigned char *) end;
18352}
18353
18354static unsigned char *
18355display_generic_attribute (unsigned char * start,
18356 unsigned int tag,
18357 const unsigned char * const end)
18358{
18359 if (tag == 0)
18360 return (unsigned char *) end;
18361
18362 return display_tag_value (tag, start, end);
18363}
18364
32ec8896 18365static bfd_boolean
dda8d76d 18366process_arch_specific (Filedata * filedata)
252b5132 18367{
a952a375 18368 if (! do_arch)
32ec8896 18369 return TRUE;
a952a375 18370
dda8d76d 18371 switch (filedata->file_header.e_machine)
252b5132 18372 {
53a346d8
CZ
18373 case EM_ARC:
18374 case EM_ARC_COMPACT:
18375 case EM_ARC_COMPACT2:
dda8d76d 18376 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
18377 display_arc_attribute,
18378 display_generic_attribute);
11c1ff18 18379 case EM_ARM:
dda8d76d 18380 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
18381 display_arm_attribute,
18382 display_generic_attribute);
18383
252b5132 18384 case EM_MIPS:
4fe85591 18385 case EM_MIPS_RS3_LE:
dda8d76d 18386 return process_mips_specific (filedata);
60abdbed
NC
18387
18388 case EM_MSP430:
dda8d76d
NC
18389 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
18390 display_msp430x_attribute,
18391 display_generic_attribute);
60abdbed 18392
35c08157 18393 case EM_NDS32:
dda8d76d 18394 return process_nds32_specific (filedata);
60abdbed 18395
34c8bcba 18396 case EM_PPC:
b82317dd 18397 case EM_PPC64:
dda8d76d 18398 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18399 display_power_gnu_attribute);
18400
643f7afb
AK
18401 case EM_S390:
18402 case EM_S390_OLD:
dda8d76d 18403 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18404 display_s390_gnu_attribute);
18405
9e8c70f9
DM
18406 case EM_SPARC:
18407 case EM_SPARC32PLUS:
18408 case EM_SPARCV9:
dda8d76d 18409 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18410 display_sparc_gnu_attribute);
18411
59e6276b 18412 case EM_TI_C6000:
dda8d76d 18413 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
18414 display_tic6x_attribute,
18415 display_generic_attribute);
18416
252b5132 18417 default:
dda8d76d 18418 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
18419 display_public_gnu_attributes,
18420 display_generic_attribute);
252b5132 18421 }
252b5132
RH
18422}
18423
32ec8896 18424static bfd_boolean
dda8d76d 18425get_file_header (Filedata * filedata)
252b5132 18426{
9ea033b2 18427 /* Read in the identity array. */
dda8d76d 18428 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18429 return FALSE;
252b5132 18430
9ea033b2 18431 /* Determine how to read the rest of the header. */
dda8d76d 18432 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 18433 {
1a0670f3
AM
18434 default:
18435 case ELFDATANONE:
adab8cdc
AO
18436 case ELFDATA2LSB:
18437 byte_get = byte_get_little_endian;
18438 byte_put = byte_put_little_endian;
18439 break;
18440 case ELFDATA2MSB:
18441 byte_get = byte_get_big_endian;
18442 byte_put = byte_put_big_endian;
18443 break;
9ea033b2
NC
18444 }
18445
18446 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 18447 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
18448
18449 /* Read in the rest of the header. */
18450 if (is_32bit_elf)
18451 {
18452 Elf32_External_Ehdr ehdr32;
252b5132 18453
dda8d76d 18454 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18455 return FALSE;
103f02d3 18456
dda8d76d
NC
18457 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
18458 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
18459 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
18460 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
18461 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
18462 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
18463 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
18464 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
18465 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
18466 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
18467 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
18468 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
18469 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 18470 }
252b5132 18471 else
9ea033b2
NC
18472 {
18473 Elf64_External_Ehdr ehdr64;
a952a375
NC
18474
18475 /* If we have been compiled with sizeof (bfd_vma) == 4, then
18476 we will not be able to cope with the 64bit data found in
18477 64 ELF files. Detect this now and abort before we start
50c2245b 18478 overwriting things. */
a952a375
NC
18479 if (sizeof (bfd_vma) < 8)
18480 {
e3c8793a
NC
18481 error (_("This instance of readelf has been built without support for a\n\
1848264 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 18483 return FALSE;
a952a375 18484 }
103f02d3 18485
dda8d76d 18486 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18487 return FALSE;
103f02d3 18488
dda8d76d
NC
18489 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
18490 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
18491 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
18492 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
18493 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
18494 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
18495 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
18496 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
18497 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
18498 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
18499 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
18500 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
18501 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 18502 }
252b5132 18503
dda8d76d 18504 if (filedata->file_header.e_shoff)
7ece0d85
JJ
18505 {
18506 /* There may be some extensions in the first section header. Don't
18507 bomb if we can't read it. */
18508 if (is_32bit_elf)
dda8d76d 18509 get_32bit_section_headers (filedata, TRUE);
7ece0d85 18510 else
dda8d76d 18511 get_64bit_section_headers (filedata, TRUE);
7ece0d85 18512 }
560f3c1c 18513
32ec8896 18514 return TRUE;
252b5132
RH
18515}
18516
dda8d76d
NC
18517static void
18518close_file (Filedata * filedata)
18519{
18520 if (filedata)
18521 {
18522 if (filedata->handle)
18523 fclose (filedata->handle);
18524 free (filedata);
18525 }
18526}
18527
18528void
18529close_debug_file (void * data)
18530{
18531 close_file ((Filedata *) data);
18532}
18533
18534static Filedata *
18535open_file (const char * pathname)
18536{
18537 struct stat statbuf;
18538 Filedata * filedata = NULL;
18539
18540 if (stat (pathname, & statbuf) < 0
18541 || ! S_ISREG (statbuf.st_mode))
18542 goto fail;
18543
18544 filedata = calloc (1, sizeof * filedata);
18545 if (filedata == NULL)
18546 goto fail;
18547
18548 filedata->handle = fopen (pathname, "rb");
18549 if (filedata->handle == NULL)
18550 goto fail;
18551
18552 filedata->file_size = (bfd_size_type) statbuf.st_size;
18553 filedata->file_name = pathname;
18554
18555 if (! get_file_header (filedata))
18556 goto fail;
18557
18558 if (filedata->file_header.e_shoff)
18559 {
18560 bfd_boolean res;
18561
18562 /* Read the section headers again, this time for real. */
18563 if (is_32bit_elf)
18564 res = get_32bit_section_headers (filedata, FALSE);
18565 else
18566 res = get_64bit_section_headers (filedata, FALSE);
18567
18568 if (!res)
18569 goto fail;
18570 }
18571
18572 return filedata;
18573
18574 fail:
18575 if (filedata)
18576 {
18577 if (filedata->handle)
18578 fclose (filedata->handle);
18579 free (filedata);
18580 }
18581 return NULL;
18582}
18583
18584void *
18585open_debug_file (const char * pathname)
18586{
18587 return open_file (pathname);
18588}
18589
fb52b2f4
NC
18590/* Process one ELF object file according to the command line options.
18591 This file may actually be stored in an archive. The file is
32ec8896
NC
18592 positioned at the start of the ELF object. Returns TRUE if no
18593 problems were encountered, FALSE otherwise. */
fb52b2f4 18594
32ec8896 18595static bfd_boolean
dda8d76d 18596process_object (Filedata * filedata)
252b5132 18597{
dda8d76d 18598 Filedata * separates;
252b5132 18599 unsigned int i;
32ec8896 18600 bfd_boolean res = TRUE;
252b5132 18601
dda8d76d 18602 if (! get_file_header (filedata))
252b5132 18603 {
dda8d76d 18604 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 18605 return FALSE;
252b5132
RH
18606 }
18607
18608 /* Initialise per file variables. */
60bca95a 18609 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
18610 version_info[i] = 0;
18611
60bca95a 18612 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 18613 dynamic_info[i] = 0;
5115b233 18614 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
18615
18616 /* Process the file. */
18617 if (show_name)
dda8d76d 18618 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 18619
18bd398b
NC
18620 /* Initialise the dump_sects array from the cmdline_dump_sects array.
18621 Note we do this even if cmdline_dump_sects is empty because we
18622 must make sure that the dump_sets array is zeroed out before each
18623 object file is processed. */
dda8d76d
NC
18624 if (filedata->num_dump_sects > cmdline.num_dump_sects)
18625 memset (filedata->dump_sects, 0, filedata->num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 18626
dda8d76d 18627 if (cmdline.num_dump_sects > 0)
18bd398b 18628 {
dda8d76d 18629 if (filedata->num_dump_sects == 0)
18bd398b 18630 /* A sneaky way of allocating the dump_sects array. */
dda8d76d 18631 request_dump_bynumber (filedata, cmdline.num_dump_sects, 0);
18bd398b 18632
dda8d76d
NC
18633 assert (filedata->num_dump_sects >= cmdline.num_dump_sects);
18634 memcpy (filedata->dump_sects, cmdline.dump_sects,
18635 cmdline.num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 18636 }
d70c5fc7 18637
dda8d76d 18638 if (! process_file_header (filedata))
32ec8896 18639 return FALSE;
252b5132 18640
dda8d76d 18641 if (! process_section_headers (filedata))
2f62977e 18642 {
32ec8896
NC
18643 /* Without loaded section headers we cannot process lots of things. */
18644 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 18645
2f62977e 18646 if (! do_using_dynamic)
32ec8896 18647 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 18648 }
252b5132 18649
dda8d76d 18650 if (! process_section_groups (filedata))
32ec8896
NC
18651 /* Without loaded section groups we cannot process unwind. */
18652 do_unwind = FALSE;
d1f5c6e3 18653
dda8d76d
NC
18654 if (process_program_headers (filedata))
18655 process_dynamic_section (filedata);
32ec8896
NC
18656 else
18657 res = FALSE;
252b5132 18658
dda8d76d 18659 if (! process_relocs (filedata))
32ec8896 18660 res = FALSE;
252b5132 18661
dda8d76d 18662 if (! process_unwind (filedata))
32ec8896 18663 res = FALSE;
4d6ed7c8 18664
dda8d76d 18665 if (! process_symbol_table (filedata))
32ec8896 18666 res = FALSE;
252b5132 18667
dda8d76d 18668 if (! process_syminfo (filedata))
32ec8896 18669 res = FALSE;
252b5132 18670
dda8d76d 18671 if (! process_version_sections (filedata))
32ec8896 18672 res = FALSE;
252b5132 18673
82ed9683
L
18674 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
18675 separates = load_separate_debug_file (filedata, filedata->file_name);
18676 else
18677 separates = NULL;
dda8d76d
NC
18678
18679 if (! process_section_contents (filedata))
32ec8896 18680 res = FALSE;
f5842774 18681
dda8d76d
NC
18682 if (separates)
18683 {
18684 if (! process_section_headers (separates))
18685 res = FALSE;
18686 else if (! process_section_contents (separates))
18687 res = FALSE;
18688 }
18689
18690 if (! process_notes (filedata))
32ec8896 18691 res = FALSE;
103f02d3 18692
dda8d76d 18693 if (! process_gnu_liblist (filedata))
32ec8896 18694 res = FALSE;
047b2264 18695
dda8d76d 18696 if (! process_arch_specific (filedata))
32ec8896 18697 res = FALSE;
252b5132 18698
dda8d76d
NC
18699 free (filedata->program_headers);
18700 filedata->program_headers = NULL;
d93f0186 18701
dda8d76d
NC
18702 free (filedata->section_headers);
18703 filedata->section_headers = NULL;
252b5132 18704
dda8d76d
NC
18705 free (filedata->string_table);
18706 filedata->string_table = NULL;
18707 filedata->string_table_length = 0;
252b5132
RH
18708
18709 if (dynamic_strings)
18710 {
18711 free (dynamic_strings);
18712 dynamic_strings = NULL;
d79b3d50 18713 dynamic_strings_length = 0;
252b5132
RH
18714 }
18715
18716 if (dynamic_symbols)
18717 {
18718 free (dynamic_symbols);
18719 dynamic_symbols = NULL;
19936277 18720 num_dynamic_syms = 0;
252b5132
RH
18721 }
18722
18723 if (dynamic_syminfo)
18724 {
18725 free (dynamic_syminfo);
18726 dynamic_syminfo = NULL;
18727 }
ff78d6d6 18728
293c573e
MR
18729 if (dynamic_section)
18730 {
18731 free (dynamic_section);
18732 dynamic_section = NULL;
18733 }
18734
e4b17d5c
L
18735 if (section_headers_groups)
18736 {
18737 free (section_headers_groups);
18738 section_headers_groups = NULL;
18739 }
18740
18741 if (section_groups)
18742 {
2cf0635d
NC
18743 struct group_list * g;
18744 struct group_list * next;
e4b17d5c
L
18745
18746 for (i = 0; i < group_count; i++)
18747 {
18748 for (g = section_groups [i].root; g != NULL; g = next)
18749 {
18750 next = g->next;
18751 free (g);
18752 }
18753 }
18754
18755 free (section_groups);
18756 section_groups = NULL;
18757 }
18758
19e6b90e 18759 free_debug_memory ();
18bd398b 18760
32ec8896 18761 return res;
252b5132
RH
18762}
18763
2cf0635d 18764/* Process an ELF archive.
32ec8896
NC
18765 On entry the file is positioned just after the ARMAG string.
18766 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 18767
32ec8896 18768static bfd_boolean
dda8d76d 18769process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
18770{
18771 struct archive_info arch;
18772 struct archive_info nested_arch;
18773 size_t got;
32ec8896 18774 bfd_boolean ret = TRUE;
2cf0635d 18775
32ec8896 18776 show_name = TRUE;
2cf0635d
NC
18777
18778 /* The ARCH structure is used to hold information about this archive. */
18779 arch.file_name = NULL;
18780 arch.file = NULL;
18781 arch.index_array = NULL;
18782 arch.sym_table = NULL;
18783 arch.longnames = NULL;
18784
18785 /* The NESTED_ARCH structure is used as a single-item cache of information
18786 about a nested archive (when members of a thin archive reside within
18787 another regular archive file). */
18788 nested_arch.file_name = NULL;
18789 nested_arch.file = NULL;
18790 nested_arch.index_array = NULL;
18791 nested_arch.sym_table = NULL;
18792 nested_arch.longnames = NULL;
18793
dda8d76d
NC
18794 if (setup_archive (&arch, filedata->file_name, filedata->handle,
18795 is_thin_archive, do_archive_index) != 0)
2cf0635d 18796 {
32ec8896 18797 ret = FALSE;
2cf0635d 18798 goto out;
4145f1d5 18799 }
fb52b2f4 18800
4145f1d5
NC
18801 if (do_archive_index)
18802 {
2cf0635d 18803 if (arch.sym_table == NULL)
dda8d76d 18804 error (_("%s: unable to dump the index as none was found\n"), filedata->file_name);
4145f1d5
NC
18805 else
18806 {
591f7597 18807 unsigned long i, l;
4145f1d5
NC
18808 unsigned long current_pos;
18809
591f7597 18810 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
dda8d76d
NC
18811 filedata->file_name, (unsigned long) arch.index_num, arch.sym_size);
18812
18813 current_pos = ftell (filedata->handle);
4145f1d5 18814
2cf0635d 18815 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 18816 {
2cf0635d
NC
18817 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
18818 {
18819 char * member_name;
4145f1d5 18820
2cf0635d
NC
18821 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
18822
18823 if (member_name != NULL)
18824 {
18825 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
18826
18827 if (qualified_name != NULL)
18828 {
c2a7d3f5
NC
18829 printf (_("Contents of binary %s at offset "), qualified_name);
18830 (void) print_vma (arch.index_array[i], PREFIX_HEX);
18831 putchar ('\n');
2cf0635d
NC
18832 free (qualified_name);
18833 }
4145f1d5
NC
18834 }
18835 }
2cf0635d
NC
18836
18837 if (l >= arch.sym_size)
4145f1d5
NC
18838 {
18839 error (_("%s: end of the symbol table reached before the end of the index\n"),
dda8d76d 18840 filedata->file_name);
32ec8896 18841 ret = FALSE;
cb8f3167 18842 break;
4145f1d5 18843 }
591f7597
NC
18844 /* PR 17531: file: 0b6630b2. */
18845 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
18846 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
18847 }
18848
c2a7d3f5
NC
18849 if (arch.uses_64bit_indicies)
18850 l = (l + 7) & ~ 7;
18851 else
18852 l += l & 1;
18853
2cf0635d 18854 if (l < arch.sym_size)
32ec8896 18855 {
d3a49aa8
AM
18856 error (ngettext ("%s: %ld byte remains in the symbol table, "
18857 "but without corresponding entries in "
18858 "the index table\n",
18859 "%s: %ld bytes remain in the symbol table, "
18860 "but without corresponding entries in "
18861 "the index table\n",
18862 arch.sym_size - l),
dda8d76d 18863 filedata->file_name, arch.sym_size - l);
32ec8896
NC
18864 ret = FALSE;
18865 }
4145f1d5 18866
dda8d76d 18867 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 18868 {
dda8d76d
NC
18869 error (_("%s: failed to seek back to start of object files in the archive\n"),
18870 filedata->file_name);
32ec8896 18871 ret = FALSE;
2cf0635d 18872 goto out;
4145f1d5 18873 }
fb52b2f4 18874 }
4145f1d5
NC
18875
18876 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
18877 && !do_segments && !do_header && !do_dump && !do_version
18878 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 18879 && !do_section_groups && !do_dyn_syms)
2cf0635d 18880 {
32ec8896 18881 ret = TRUE; /* Archive index only. */
2cf0635d
NC
18882 goto out;
18883 }
fb52b2f4
NC
18884 }
18885
fb52b2f4
NC
18886 while (1)
18887 {
2cf0635d
NC
18888 char * name;
18889 size_t namelen;
18890 char * qualified_name;
18891
18892 /* Read the next archive header. */
dda8d76d 18893 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
2cf0635d 18894 {
dda8d76d 18895 error (_("%s: failed to seek to next archive header\n"), filedata->file_name);
32ec8896 18896 return FALSE;
2cf0635d 18897 }
dda8d76d 18898 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d
NC
18899 if (got != sizeof arch.arhdr)
18900 {
18901 if (got == 0)
18902 break;
dda8d76d 18903 error (_("%s: failed to read archive header\n"), filedata->file_name);
32ec8896 18904 ret = FALSE;
2cf0635d
NC
18905 break;
18906 }
18907 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
18908 {
18909 error (_("%s: did not find a valid archive header\n"), arch.file_name);
32ec8896 18910 ret = FALSE;
2cf0635d
NC
18911 break;
18912 }
18913
18914 arch.next_arhdr_offset += sizeof arch.arhdr;
18915
18916 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
18917 if (archive_file_size & 01)
18918 ++archive_file_size;
18919
18920 name = get_archive_member_name (&arch, &nested_arch);
18921 if (name == NULL)
fb52b2f4 18922 {
dda8d76d 18923 error (_("%s: bad archive file name\n"), filedata->file_name);
32ec8896 18924 ret = FALSE;
d989285c 18925 break;
fb52b2f4 18926 }
2cf0635d 18927 namelen = strlen (name);
fb52b2f4 18928
2cf0635d
NC
18929 qualified_name = make_qualified_name (&arch, &nested_arch, name);
18930 if (qualified_name == NULL)
fb52b2f4 18931 {
dda8d76d 18932 error (_("%s: bad archive file name\n"), filedata->file_name);
32ec8896 18933 ret = FALSE;
d989285c 18934 break;
fb52b2f4
NC
18935 }
18936
2cf0635d
NC
18937 if (is_thin_archive && arch.nested_member_origin == 0)
18938 {
18939 /* This is a proxy for an external member of a thin archive. */
dda8d76d
NC
18940 Filedata * member_filedata;
18941 char * member_file_name = adjust_relative_path
18942 (filedata->file_name, name, namelen);
32ec8896 18943
2cf0635d
NC
18944 if (member_file_name == NULL)
18945 {
32ec8896 18946 ret = FALSE;
2cf0635d
NC
18947 break;
18948 }
18949
dda8d76d
NC
18950 member_filedata = open_file (member_file_name);
18951 if (member_filedata == NULL)
2cf0635d
NC
18952 {
18953 error (_("Input file '%s' is not readable.\n"), member_file_name);
18954 free (member_file_name);
32ec8896 18955 ret = FALSE;
2cf0635d
NC
18956 break;
18957 }
18958
18959 archive_file_offset = arch.nested_member_origin;
dda8d76d 18960 member_filedata->file_name = qualified_name;
2cf0635d 18961
dda8d76d 18962 if (! process_object (member_filedata))
32ec8896 18963 ret = FALSE;
2cf0635d 18964
dda8d76d 18965 close_file (member_filedata);
2cf0635d
NC
18966 free (member_file_name);
18967 }
18968 else if (is_thin_archive)
18969 {
eb02c04d
PK
18970 Filedata thin_filedata;
18971
18972 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 18973
a043396b
NC
18974 /* PR 15140: Allow for corrupt thin archives. */
18975 if (nested_arch.file == NULL)
18976 {
18977 error (_("%s: contains corrupt thin archive: %s\n"),
dda8d76d 18978 filedata->file_name, name);
32ec8896 18979 ret = FALSE;
a043396b
NC
18980 break;
18981 }
18982
2cf0635d
NC
18983 /* This is a proxy for a member of a nested archive. */
18984 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
18985
18986 /* The nested archive file will have been opened and setup by
18987 get_archive_member_name. */
18988 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
18989 {
18990 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
32ec8896 18991 ret = FALSE;
2cf0635d
NC
18992 break;
18993 }
18994
dda8d76d
NC
18995 thin_filedata.handle = nested_arch.file;
18996 thin_filedata.file_name = qualified_name;
18997
18998 if (! process_object (& thin_filedata))
32ec8896 18999 ret = FALSE;
2cf0635d
NC
19000 }
19001 else
19002 {
19003 archive_file_offset = arch.next_arhdr_offset;
19004 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 19005
6a6196fc 19006 filedata->file_name = qualified_name;
dda8d76d 19007 if (! process_object (filedata))
32ec8896 19008 ret = FALSE;
2cf0635d 19009 }
fb52b2f4 19010
dda8d76d 19011 if (filedata->dump_sects != NULL)
2b52916e 19012 {
dda8d76d
NC
19013 free (filedata->dump_sects);
19014 filedata->dump_sects = NULL;
19015 filedata->num_dump_sects = 0;
2b52916e
L
19016 }
19017
2cf0635d 19018 free (qualified_name);
fb52b2f4
NC
19019 }
19020
4145f1d5 19021 out:
2cf0635d
NC
19022 if (nested_arch.file != NULL)
19023 fclose (nested_arch.file);
19024 release_archive (&nested_arch);
19025 release_archive (&arch);
fb52b2f4 19026
d989285c 19027 return ret;
fb52b2f4
NC
19028}
19029
32ec8896 19030static bfd_boolean
2cf0635d 19031process_file (char * file_name)
fb52b2f4 19032{
dda8d76d 19033 Filedata * filedata = NULL;
fb52b2f4
NC
19034 struct stat statbuf;
19035 char armag[SARMAG];
32ec8896 19036 bfd_boolean ret = TRUE;
fb52b2f4
NC
19037
19038 if (stat (file_name, &statbuf) < 0)
19039 {
f24ddbdd
NC
19040 if (errno == ENOENT)
19041 error (_("'%s': No such file\n"), file_name);
19042 else
19043 error (_("Could not locate '%s'. System error message: %s\n"),
19044 file_name, strerror (errno));
32ec8896 19045 return FALSE;
f24ddbdd
NC
19046 }
19047
19048 if (! S_ISREG (statbuf.st_mode))
19049 {
19050 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 19051 return FALSE;
fb52b2f4
NC
19052 }
19053
dda8d76d
NC
19054 filedata = calloc (1, sizeof * filedata);
19055 if (filedata == NULL)
19056 {
19057 error (_("Out of memory allocating file data structure\n"));
19058 return FALSE;
19059 }
19060
19061 filedata->file_name = file_name;
19062 filedata->handle = fopen (file_name, "rb");
19063 if (filedata->handle == NULL)
fb52b2f4 19064 {
f24ddbdd 19065 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 19066 free (filedata);
32ec8896 19067 return FALSE;
fb52b2f4
NC
19068 }
19069
dda8d76d 19070 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 19071 {
4145f1d5 19072 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
19073 fclose (filedata->handle);
19074 free (filedata);
32ec8896 19075 return FALSE;
fb52b2f4
NC
19076 }
19077
dda8d76d 19078 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 19079
fb52b2f4 19080 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 19081 {
dda8d76d 19082 if (! process_archive (filedata, FALSE))
32ec8896
NC
19083 ret = FALSE;
19084 }
2cf0635d 19085 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 19086 {
dda8d76d 19087 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
19088 ret = FALSE;
19089 }
fb52b2f4
NC
19090 else
19091 {
4145f1d5
NC
19092 if (do_archive_index)
19093 error (_("File %s is not an archive so its index cannot be displayed.\n"),
19094 file_name);
19095
dda8d76d 19096 rewind (filedata->handle);
fb52b2f4 19097 archive_file_size = archive_file_offset = 0;
32ec8896 19098
dda8d76d 19099 if (! process_object (filedata))
32ec8896 19100 ret = FALSE;
fb52b2f4
NC
19101 }
19102
dda8d76d
NC
19103 fclose (filedata->handle);
19104 free (filedata);
32ec8896 19105
fb52b2f4
NC
19106 return ret;
19107}
19108
252b5132
RH
19109#ifdef SUPPORT_DISASSEMBLY
19110/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 19111 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 19112 symbols. */
252b5132
RH
19113
19114void
2cf0635d 19115print_address (unsigned int addr, FILE * outfile)
252b5132
RH
19116{
19117 fprintf (outfile,"0x%8.8x", addr);
19118}
19119
e3c8793a 19120/* Needed by the i386 disassembler. */
dda8d76d 19121
252b5132
RH
19122void
19123db_task_printsym (unsigned int addr)
19124{
19125 print_address (addr, stderr);
19126}
19127#endif
19128
19129int
2cf0635d 19130main (int argc, char ** argv)
252b5132 19131{
ff78d6d6
L
19132 int err;
19133
252b5132
RH
19134#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
19135 setlocale (LC_MESSAGES, "");
3882b010
L
19136#endif
19137#if defined (HAVE_SETLOCALE)
19138 setlocale (LC_CTYPE, "");
252b5132
RH
19139#endif
19140 bindtextdomain (PACKAGE, LOCALEDIR);
19141 textdomain (PACKAGE);
19142
869b9d07
MM
19143 expandargv (&argc, &argv);
19144
dda8d76d
NC
19145 cmdline.file_name = "<cmdline>";
19146 parse_args (& cmdline, argc, argv);
59f14fc0 19147
18bd398b 19148 if (optind < (argc - 1))
32ec8896 19149 show_name = TRUE;
5656ba2c
L
19150 else if (optind >= argc)
19151 {
19152 warn (_("Nothing to do.\n"));
19153 usage (stderr);
19154 }
18bd398b 19155
32ec8896 19156 err = FALSE;
252b5132 19157 while (optind < argc)
32ec8896
NC
19158 if (! process_file (argv[optind++]))
19159 err = TRUE;
252b5132 19160
dda8d76d
NC
19161 if (cmdline.dump_sects != NULL)
19162 free (cmdline.dump_sects);
252b5132 19163
32ec8896 19164 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 19165}